diff options
author | Nick Clifton <nickc@redhat.com> | 1998-03-25 23:48:55 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 1998-03-25 23:48:55 +0000 |
commit | 38c574bbd3142416766620fe2b5a1fa276a811b7 (patch) | |
tree | 1bd018bdad0c471bd0a945744bf09702f6206bd5 /bfd/peicode.h | |
parent | 98f1f62cb40df91db06637c9bb74483e911a75db (diff) | |
download | gdb-38c574bbd3142416766620fe2b5a1fa276a811b7.zip gdb-38c574bbd3142416766620fe2b5a1fa276a811b7.tar.gz gdb-38c574bbd3142416766620fe2b5a1fa276a811b7.tar.bz2 |
Support interworking for thumb-pe and arm-pe targets.
Diffstat (limited to 'bfd/peicode.h')
-rw-r--r-- | bfd/peicode.h | 309 |
1 files changed, 207 insertions, 102 deletions
diff --git a/bfd/peicode.h b/bfd/peicode.h index 1a45ad2..9026066 100644 --- a/bfd/peicode.h +++ b/bfd/peicode.h @@ -1,5 +1,5 @@ /* Support for the generic parts of most COFF variants, for BFD. - Copyright 1995, 1996, 1997 Free Software Foundation, Inc. + Copyright 1995, 1996, 1997, 1998 Free Software Foundation, Inc. Written by Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -285,16 +285,12 @@ coff_swap_filehdr_in (abfd, src, dst) filehdr_dst->f_flags = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_flags); filehdr_dst->f_symptr = bfd_h_get_32 (abfd, (bfd_byte *) filehdr_src->f_symptr); - /* Other people's tools sometimes generate headers - with an nsyms but a zero symptr. */ - if (filehdr_dst->f_nsyms && filehdr_dst->f_symptr) - { - filehdr_dst->f_flags |= HAS_SYMS; - } - else + /* Other people's tools sometimes generate headers with an nsyms but + a zero symptr. */ + if (filehdr_dst->f_nsyms != 0 && filehdr_dst->f_symptr == 0) { filehdr_dst->f_nsyms = 0; - filehdr_dst->f_flags &= ~HAS_SYMS; + filehdr_dst->f_flags |= F_LSYMS; } filehdr_dst->f_opthdr = bfd_h_get_16(abfd, @@ -778,38 +774,38 @@ coff_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1) GET_AOUTHDR_DATA_START (abfd, (bfd_byte *) aouthdr_ext->data_start); a = &aouthdr_int->pe; - a->ImageBase = bfd_h_get_32 (abfd, src->ImageBase); - a->SectionAlignment = bfd_h_get_32 (abfd, src->SectionAlignment); - a->FileAlignment = bfd_h_get_32 (abfd, src->FileAlignment); + a->ImageBase = bfd_h_get_32 (abfd, (bfd_byte *) src->ImageBase); + a->SectionAlignment = bfd_h_get_32 (abfd, (bfd_byte *) src->SectionAlignment); + a->FileAlignment = bfd_h_get_32 (abfd, (bfd_byte *) src->FileAlignment); a->MajorOperatingSystemVersion = - bfd_h_get_16 (abfd, src->MajorOperatingSystemVersion); + bfd_h_get_16 (abfd, (bfd_byte *) src->MajorOperatingSystemVersion); a->MinorOperatingSystemVersion = - bfd_h_get_16 (abfd, src->MinorOperatingSystemVersion); - a->MajorImageVersion = bfd_h_get_16 (abfd, src->MajorImageVersion); - a->MinorImageVersion = bfd_h_get_16 (abfd, src->MinorImageVersion); - a->MajorSubsystemVersion = bfd_h_get_16 (abfd, src->MajorSubsystemVersion); - a->MinorSubsystemVersion = bfd_h_get_16 (abfd, src->MinorSubsystemVersion); - a->Reserved1 = bfd_h_get_32 (abfd, src->Reserved1); - a->SizeOfImage = bfd_h_get_32 (abfd, src->SizeOfImage); - a->SizeOfHeaders = bfd_h_get_32 (abfd, src->SizeOfHeaders); - a->CheckSum = bfd_h_get_32 (abfd, src->CheckSum); - a->Subsystem = bfd_h_get_16 (abfd, src->Subsystem); - a->DllCharacteristics = bfd_h_get_16 (abfd, src->DllCharacteristics); - a->SizeOfStackReserve = bfd_h_get_32 (abfd, src->SizeOfStackReserve); - a->SizeOfStackCommit = bfd_h_get_32 (abfd, src->SizeOfStackCommit); - a->SizeOfHeapReserve = bfd_h_get_32 (abfd, src->SizeOfHeapReserve); - a->SizeOfHeapCommit = bfd_h_get_32 (abfd, src->SizeOfHeapCommit); - a->LoaderFlags = bfd_h_get_32 (abfd, src->LoaderFlags); - a->NumberOfRvaAndSizes = bfd_h_get_32 (abfd, src->NumberOfRvaAndSizes); + bfd_h_get_16 (abfd, (bfd_byte *) src->MinorOperatingSystemVersion); + a->MajorImageVersion = bfd_h_get_16 (abfd, (bfd_byte *) src->MajorImageVersion); + a->MinorImageVersion = bfd_h_get_16 (abfd, (bfd_byte *) src->MinorImageVersion); + a->MajorSubsystemVersion = bfd_h_get_16 (abfd, (bfd_byte *) src->MajorSubsystemVersion); + a->MinorSubsystemVersion = bfd_h_get_16 (abfd, (bfd_byte *) src->MinorSubsystemVersion); + a->Reserved1 = bfd_h_get_32 (abfd, (bfd_byte *) src->Reserved1); + a->SizeOfImage = bfd_h_get_32 (abfd, (bfd_byte *) src->SizeOfImage); + a->SizeOfHeaders = bfd_h_get_32 (abfd, (bfd_byte *) src->SizeOfHeaders); + a->CheckSum = bfd_h_get_32 (abfd, (bfd_byte *) src->CheckSum); + a->Subsystem = bfd_h_get_16 (abfd, (bfd_byte *) src->Subsystem); + a->DllCharacteristics = bfd_h_get_16 (abfd, (bfd_byte *) src->DllCharacteristics); + a->SizeOfStackReserve = bfd_h_get_32 (abfd, (bfd_byte *) src->SizeOfStackReserve); + a->SizeOfStackCommit = bfd_h_get_32 (abfd, (bfd_byte *) src->SizeOfStackCommit); + a->SizeOfHeapReserve = bfd_h_get_32 (abfd, (bfd_byte *) src->SizeOfHeapReserve); + a->SizeOfHeapCommit = bfd_h_get_32 (abfd, (bfd_byte *) src->SizeOfHeapCommit); + a->LoaderFlags = bfd_h_get_32 (abfd, (bfd_byte *) src->LoaderFlags); + a->NumberOfRvaAndSizes = bfd_h_get_32 (abfd, (bfd_byte *) src->NumberOfRvaAndSizes); { int idx; for (idx=0; idx < 16; idx++) { a->DataDirectory[idx].VirtualAddress = - bfd_h_get_32 (abfd, src->DataDirectory[idx][0]); + bfd_h_get_32 (abfd, (bfd_byte *) src->DataDirectory[idx][0]); a->DataDirectory[idx].Size = - bfd_h_get_32 (abfd, src->DataDirectory[idx][1]); + bfd_h_get_32 (abfd, (bfd_byte *) src->DataDirectory[idx][1]); } } @@ -1138,13 +1134,13 @@ coff_swap_scnhdr_out (abfd, in, out) int flags = scnhdr_int->s_flags; if (strcmp (scnhdr_int->s_name, ".data") == 0 || strcmp (scnhdr_int->s_name, ".CRT") == 0 || - strcmp (scnhdr_int->s_name, ".rsrc") == 0 || strcmp (scnhdr_int->s_name, ".bss") == 0) flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE; else if (strcmp (scnhdr_int->s_name, ".text") == 0) flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE; else if (strcmp (scnhdr_int->s_name, ".reloc") == 0) - flags = SEC_DATA| IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE; + flags = (SEC_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE + | IMAGE_SCN_MEM_SHARED); else if (strcmp (scnhdr_int->s_name, ".idata") == 0) flags = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | SEC_DATA; else if (strcmp (scnhdr_int->s_name, ".rdata") == 0 @@ -1164,9 +1160,12 @@ coff_swap_scnhdr_out (abfd, in, out) else if (strncmp (scnhdr_int->s_name, ".drectve", 8) == 0) flags = IMAGE_SCN_LNK_INFO | IMAGE_SCN_LNK_REMOVE ; else if (strncmp (scnhdr_int->s_name, ".stab", 5) == 0) - flags |= IMAGE_SCN_LNK_INFO | IMAGE_SCN_MEM_DISCARDABLE; + flags |= (IMAGE_SCN_LNK_INFO | IMAGE_SCN_MEM_DISCARDABLE + | IMAGE_SCN_MEM_SHARED | IMAGE_SCN_MEM_READ); + else if (strcmp (scnhdr_int->s_name, ".rsrc") == 0) + flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_SHARED; else - flags = IMAGE_SCN_MEM_READ; + flags |= IMAGE_SCN_MEM_READ; bfd_h_put_32(abfd, flags, (bfd_byte *) scnhdr_ext->s_flags); } @@ -1225,12 +1224,15 @@ pe_print_idata(abfd, vfile) FILE *file = (FILE *) vfile; bfd_byte *data = 0; asection *section = bfd_get_section_by_name (abfd, ".idata"); + unsigned long adj; #ifdef POWERPC_LE_PE asection *rel_section = bfd_get_section_by_name (abfd, ".reldata"); #endif - bfd_size_type datasize = 0; + bfd_size_type datasize; + bfd_size_type dataoff; + bfd_size_type secsize; bfd_size_type i; bfd_size_type start, stop; int onaline = 20; @@ -1238,8 +1240,41 @@ pe_print_idata(abfd, vfile) pe_data_type *pe = pe_data (abfd); struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr; - if (section == 0) - return true; + if (section != NULL) + { + datasize = bfd_section_size (abfd, section); + dataoff = 0; + + if (datasize == 0) + return true; + } + else + { + bfd_vma addr, size; + + addr = extra->DataDirectory[1].VirtualAddress; + size = extra->DataDirectory[1].Size; + + if (addr == 0 || size == 0) + return true; + + for (section = abfd->sections; section != NULL; section = section->next) + { + if (section->vma - extra->ImageBase <= addr + && ((section->vma - extra->ImageBase + + bfd_section_size (abfd, section)) + >= addr + size)) + break; + } + if (section == NULL) + return true; + + /* For some reason the import table size is not reliable. The + import data will extend past the indicated size, and before + the indicated address. */ + dataoff = addr - (section->vma - extra->ImageBase); + datasize = size; + } #ifdef POWERPC_LE_PE if (rel_section != 0 && bfd_section_size (abfd, rel_section) != 0) @@ -1291,27 +1326,22 @@ pe_print_idata(abfd, vfile) fprintf(file, "\nThe Import Tables (interpreted .idata section contents)\n"); fprintf(file, - " vma: Hint Time Forward DLL First\n"); + " vma: Hint Time Forward DLL First\n"); fprintf(file, - " Table Stamp Chain Name Thunk\n"); + " Table Stamp Chain Name Thunk\n"); - if (bfd_section_size (abfd, section) == 0) - return true; - - data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section)); - datasize = bfd_section_size (abfd, section); - if (data == NULL && datasize != 0) + secsize = bfd_section_size (abfd, section); + data = (bfd_byte *) bfd_malloc (secsize); + if (data == NULL && secsize != 0) return false; - bfd_get_section_contents (abfd, - section, - (PTR) data, 0, - bfd_section_size (abfd, section)); - - start = 0; + if (! bfd_get_section_contents (abfd, section, (PTR) data, 0, secsize)) + return false; - stop = bfd_section_size (abfd, section); + adj = (extra->ImageBase - section->vma) & 0xffffffff; + start = dataoff; + stop = dataoff + datasize; for (i = start; i < stop; i += onaline) { bfd_vma hint_addr; @@ -1322,11 +1352,10 @@ pe_print_idata(abfd, vfile) int idx; int j; char *dll; - int adj = (extra->ImageBase - section->vma) & 0xffffffff; fprintf (file, - " %04lx\t", - (unsigned long int) (i + section->vma)); + " %08lx\t", + (unsigned long int) (i + section->vma + dataoff)); if (i+20 > stop) { @@ -1347,33 +1376,52 @@ pe_print_idata(abfd, vfile) dll_name, first_thunk); - if (hint_addr ==0) - { - break; - } + if (hint_addr == 0 && first_thunk == 0) + break; /* the image base is present in the section->vma */ dll = (char *) data + dll_name + adj; fprintf(file, "\n\tDLL Name: %s\n", dll); - fprintf(file, "\tvma: Ordinal Member-Name\n"); - idx = hint_addr + adj; - - for (j=0;j<stop;j+=4) + if (hint_addr != 0) { - int ordinal; - char *member_name; - bfd_vma member = bfd_get_32(abfd, data + idx + j); - if (member == 0) - break; - ordinal = bfd_get_16(abfd, - data + member + adj); - member_name = (char *) data + member + adj + 2; - fprintf(file, "\t%04lx\t %4d %s\n", - member, ordinal, member_name); + fprintf (file, "\tvma: Hint/Ord Member-Name\n"); + + idx = hint_addr + adj; + + for (j = 0; j < stop; j += 4) + { + unsigned long member = bfd_get_32 (abfd, data + idx + j); + + if (member == 0) + break; + if (member & 0x80000000) + fprintf (file, "\t%04lx\t %4lu", member, + member & 0x7fffffff); + else + { + int ordinal; + char *member_name; + + ordinal = bfd_get_16 (abfd, data + member + adj); + member_name = (char *) data + member + adj + 2; + fprintf (file, "\t%04lx\t %4d %s", + member, ordinal, member_name); + } + + /* If the time stamp is not zero, the import address + table holds actual addresses. */ + if (time_stamp != 0 + && first_thunk != 0 + && first_thunk != hint_addr) + fprintf (file, "\t%04lx", + bfd_get_32 (abfd, data + first_thunk + adj + j)); + + fprintf (file, "\n"); + } } - if (hint_addr != first_thunk) + if (hint_addr != first_thunk && time_stamp == 0) { int differ = 0; int idx2; @@ -1384,15 +1432,27 @@ pe_print_idata(abfd, vfile) { int ordinal; char *member_name; - bfd_vma hint_member = bfd_get_32(abfd, data + idx + j); - bfd_vma iat_member = bfd_get_32(abfd, data + idx2 + j); - if (hint_member != iat_member) + bfd_vma hint_member; + bfd_vma iat_member; + + if (time_stamp != 0) + { + } + + if (hint_addr != 0) + hint_member = bfd_get_32 (abfd, data + idx + j); + iat_member = bfd_get_32 (abfd, data + idx2 + j); + + if (hint_addr == 0 && iat_member == 0) + break; + + if (hint_addr == 0 || hint_member != iat_member) { if (differ == 0) { - fprintf(file, - "\tThe Import Address Table (difference found)\n"); - fprintf(file, "\tvma: Ordinal Member-Name\n"); + fprintf (file, + "\tThe Import Address Table (difference found)\n"); + fprintf(file, "\tvma: Hint/Ord Member-Name\n"); differ = 1; } if (iat_member == 0) @@ -1408,9 +1468,9 @@ pe_print_idata(abfd, vfile) fprintf(file, "\t%04lx\t %4d %s\n", iat_member, ordinal, member_name); } - break; } - if (hint_member == 0) + + if (hint_addr != 0 && hint_member == 0) break; } if (differ == 0) @@ -1438,7 +1498,8 @@ pe_print_edata (abfd, vfile) bfd_byte *data = 0; asection *section = bfd_get_section_by_name (abfd, ".edata"); - bfd_size_type datasize = 0; + bfd_size_type datasize; + bfd_size_type dataoff; bfd_size_type i; int adj; @@ -1460,20 +1521,43 @@ pe_print_edata (abfd, vfile) pe_data_type *pe = pe_data (abfd); struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr; - if (section == 0) - return true; + if (section != NULL) + { + datasize = bfd_section_size (abfd, section); + dataoff = 0; + } + else + { + bfd_vma addr, size; - data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, - section)); - datasize = bfd_section_size (abfd, section); + addr = extra->DataDirectory[0].VirtualAddress; + size = extra->DataDirectory[0].Size; + if (addr == 0 || size == 0) + return true; + + for (section = abfd->sections; section != NULL; section = section->next) + { + if (section->vma - extra->ImageBase <= addr + && ((section->vma - extra->ImageBase + + bfd_section_size (abfd, section)) + >= addr + size)) + break; + } + if (section == NULL) + return true; + + datasize = size; + dataoff = addr - (section->vma - extra->ImageBase); + } + + data = (bfd_byte *) bfd_malloc (datasize); if (data == NULL && datasize != 0) return false; - bfd_get_section_contents (abfd, - section, - (PTR) data, 0, - bfd_section_size (abfd, section)); + if (! bfd_get_section_contents (abfd, section, (PTR) data, dataoff, + datasize)) + return false; /* Go get Export Directory Table */ edt.export_flags = bfd_get_32(abfd, data+0); @@ -1488,7 +1572,7 @@ pe_print_edata (abfd, vfile) edt.npt_addr = bfd_get_32(abfd, data+32); edt.ot_addr = bfd_get_32(abfd, data+36); - adj = (extra->ImageBase - section->vma) & 0xffffffff; + adj = (extra->ImageBase - (section->vma + dataoff)) & 0xffffffff; /* Dump the EDT first first */ @@ -1558,12 +1642,11 @@ pe_print_edata (abfd, vfile) for (i = 0; i < edt.num_functions; ++i) { - bfd_vma eat_member = bfd_get_32(abfd, - data + edt.eat_addr + (i*4) + adj); + bfd_vma eat_member = bfd_get_32 (abfd, + data + edt.eat_addr + (i * 4) + adj); bfd_vma eat_actual = (extra->ImageBase + eat_member) & 0xffffffff; - bfd_vma edata_start = bfd_get_section_vma(abfd,section); - bfd_vma edata_end = edata_start + bfd_section_size (abfd, section); - + bfd_vma edata_start = bfd_get_section_vma (abfd,section) + dataoff; + bfd_vma edata_end = edata_start + datasize; if (eat_member == 0) continue; @@ -1827,6 +1910,24 @@ pe_print_private_bfd_data (abfd, vfile) pe_data_type *pe = pe_data (abfd); struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr; + /* The MS dumpbin program reportedly ands with 0xff0f before + printing the characteristics field. Not sure why. No reason to + emulate it here. */ + fprintf (file, "\nCharacteristics 0x%x\n", pe->real_flags); +#undef PF +#define PF(x, y) if (pe->real_flags & x) { fprintf (file, "\t%s\n", y); } + PF (F_RELFLG, "relocations stripped"); + PF (F_EXEC, "executable"); + PF (F_LNNO, "line numbers stripped"); + PF (F_LSYMS, "symbols stripped"); + PF (0x80, "little endian"); + PF (F_AR32WR, "32 bit words"); + PF (0x200, "debugging information removed"); + PF (0x1000, "system file"); + PF (F_DLL, "DLL"); + PF (0x8000, "big endian"); +#undef PF + fprintf (file,"\nImageBase\t\t"); fprintf_vma (file, i->ImageBase); fprintf (file,"\nSectionAlignment\t"); @@ -1870,7 +1971,8 @@ pe_print_private_bfd_data (abfd, vfile) pe_print_pdata(abfd, vfile); pe_print_reloc(abfd, vfile); - return true; + fputc ('\n', file); + return coff_arm_bfd_print_private_bfd_data (abfd, vfile); } static boolean @@ -1933,6 +2035,9 @@ pe_mkobject_hook (abfd, filehdr, aouthdr) } #endif + if (! coff_arm_bfd_set_private_flags (abfd, internal_f->f_flags)) + coff_data (abfd) ->flags = 0; + return (PTR) pe; } @@ -1956,7 +2061,7 @@ pe_bfd_copy_private_bfd_data (ibfd, obfd) pe_data (obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr; pe_data (obfd)->dll = pe_data (ibfd)->dll; - return true; + return coff_arm_bfd_copy_private_bfd_data (ibfd, obfd); } #ifdef COFF_IMAGE_WITH_PE |