X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Fpeicode.h;h=0183f98ca5c40e1d0188f8a708dab01bf843b90c;hb=1e490350fff9619fd30dbea910412308eb7c8661;hp=213c20ce8eb9c6ac9f18db4f40eb617acd65e343;hpb=9ca108cdd07df42ff3331a61ce8bbd558de9b4da;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/peicode.h b/bfd/peicode.h index 213c20ce8e..0183f98ca5 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 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. @@ -23,10 +23,48 @@ Most of this hacked by Steve Chamberlain, sac@cygnus.com */ +/* Hey look, some documentation [and in a place you expect to find it]! + + The main reference for the pei format is "Microsoft Portable Executable + and Common Object File Format Specification 4.1". Get it if you need to + do some serious hacking on this code. + + Another reference: + "Peering Inside the PE: A Tour of the Win32 Portable Executable + File Format", MSJ 1994, Volume 9. + + The *sole* difference between the pe format and the pei format is that the + latter has an MSDOS 2.0 .exe header on the front that prints the message + "This app must be run under Windows." (or some such). + (FIXME: Whether that statement is *really* true or not is unknown. + Are there more subtle differences between pe and pei formats? + For now assume there aren't. If you find one, then for God sakes + document it here!) + + The Microsoft docs use the word "image" instead of "executable" because + the former can also refer to a DLL (shared library). Confusion can arise + because the `i' in `pei' also refers to "image". The `pe' format can + also create images (i.e. executables), it's just that to run on a win32 + system you need to use the pei format. + + FIXME: Please add more docs here so the next poor fool that has to hack + on this code has a chance of getting something accomplished without + wasting too much time. +*/ - +#ifdef coff_bfd_print_private_bfd_data +static boolean (*pe_saved_coff_bfd_print_private_bfd_data) + PARAMS ((bfd *, PTR)) + = coff_bfd_print_private_bfd_data; +#undef coff_bfd_print_private_bfd_data +#else +static boolean (*pe_saved_coff_bfd_print_private_bfd_data) + PARAMS ((bfd *, PTR)) + = NULL; +#endif #define coff_bfd_print_private_bfd_data pe_print_private_bfd_data -#define coff_mkobject pe_mkobject + +#define coff_mkobject pe_mkobject #define coff_mkobject_hook pe_mkobject_hook #ifndef GET_FCN_LNNOPTR @@ -166,7 +204,31 @@ Most of this hacked by Steve Chamberlain, #define PUT_SCNHDR_LNNOPTR bfd_h_put_32 #endif - +static void coff_swap_reloc_in PARAMS ((bfd *, PTR, PTR)); +static unsigned int coff_swap_reloc_out PARAMS ((bfd *, PTR, PTR)); +static void coff_swap_filehdr_in PARAMS ((bfd *, PTR, PTR)); +static unsigned int coff_swap_filehdr_out PARAMS ((bfd *, PTR, PTR)); +static void coff_swap_sym_in PARAMS ((bfd *, PTR, PTR)); +static unsigned int coff_swap_sym_out PARAMS ((bfd *, PTR, PTR)); +static void coff_swap_aux_in PARAMS ((bfd *, PTR, int, int, int, int, PTR)); +static unsigned int coff_swap_aux_out + PARAMS ((bfd *, PTR, int, int, int, int, PTR)); +static void coff_swap_lineno_in PARAMS ((bfd *, PTR, PTR)); +static unsigned int coff_swap_lineno_out PARAMS ((bfd *, PTR, PTR)); +static void coff_swap_aouthdr_in PARAMS ((bfd *, PTR, PTR)); +static void add_data_entry + PARAMS ((bfd *, struct internal_extra_pe_aouthdr *, int, char *, bfd_vma)); +static unsigned int coff_swap_aouthdr_out PARAMS ((bfd *, PTR, PTR)); +static void coff_swap_scnhdr_in PARAMS ((bfd *, PTR, PTR)); +static unsigned int coff_swap_scnhdr_out PARAMS ((bfd *, PTR, PTR)); +static boolean pe_print_idata PARAMS ((bfd *, PTR)); +static boolean pe_print_edata PARAMS ((bfd *, PTR)); +static boolean pe_print_pdata PARAMS ((bfd *, PTR)); +static boolean pe_print_reloc PARAMS ((bfd *, PTR)); +static boolean pe_print_private_bfd_data PARAMS ((bfd *, PTR)); +static boolean pe_mkobject PARAMS ((bfd *)); +static PTR pe_mkobject_hook PARAMS ((bfd *, PTR, PTR)); +static boolean pe_bfd_copy_private_bfd_data PARAMS ((bfd *, bfd *)); /**********************************************************************/ @@ -213,7 +275,7 @@ coff_swap_reloc_out (abfd, src, dst) #ifdef SWAP_OUT_RELOC_EXTRA SWAP_OUT_RELOC_EXTRA(abfd,reloc_src, reloc_dst); #endif - return sizeof(struct external_reloc); + return RELSZ; } @@ -233,16 +295,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, @@ -376,7 +434,7 @@ coff_swap_filehdr_out (abfd, in, out) - return sizeof(FILHDR); + return FILHSZ; } #else @@ -398,7 +456,7 @@ coff_swap_filehdr_out (abfd, in, out) bfd_h_put_16(abfd, filehdr_in->f_opthdr, (bfd_byte *) filehdr_out->f_opthdr); bfd_h_put_16(abfd, filehdr_in->f_flags, (bfd_byte *) filehdr_out->f_flags); - return sizeof(FILHDR); + return FILHSZ; } #endif @@ -493,7 +551,7 @@ coff_swap_sym_out (abfd, inp, extp) bfd_h_put_8(abfd, in->n_sclass , ext->e_sclass); bfd_h_put_8(abfd, in->n_numaux , ext->e_numaux); - return sizeof(SYMENT); + return SYMESZ; } static void @@ -608,7 +666,7 @@ coff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp) memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN); #endif } - return sizeof (AUXENT); + return AUXESZ; case C_STAT: @@ -626,7 +684,7 @@ coff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp) (bfd_byte *) ext->x_scn.x_associated); bfd_h_put_8 (abfd, in->x_scn.x_comdat, (bfd_byte *) ext->x_scn.x_comdat); - return sizeof (AUXENT); + return AUXESZ; } break; } @@ -665,7 +723,7 @@ coff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp) PUT_LNSZ_SIZE (abfd, in->x_sym.x_misc.x_lnsz.x_size, ext); } - return sizeof(AUXENT); + return AUXESZ; } @@ -694,7 +752,7 @@ coff_swap_lineno_out (abfd, inp, outp) ext->l_addr.l_symndx); PUT_LINENO_LNNO (abfd, in->l_lnno, ext); - return sizeof(struct external_lineno); + return LINESZ; } @@ -726,47 +784,66 @@ 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]); } } if (aouthdr_int->entry) - aouthdr_int->entry += a->ImageBase; + { + aouthdr_int->entry += a->ImageBase; + aouthdr_int->entry &= 0xffffffff; + } if (aouthdr_int->tsize) - aouthdr_int->text_start += a->ImageBase; + { + aouthdr_int->text_start += a->ImageBase; + aouthdr_int->text_start &= 0xffffffff; + } if (aouthdr_int->dsize) - aouthdr_int->data_start += a->ImageBase; + { + aouthdr_int->data_start += a->ImageBase; + aouthdr_int->data_start &= 0xffffffff; + } + +#ifdef POWERPC_LE_PE + /* These three fields are normally set up by ppc_relocate_section. + In the case of reading a file in, we can pick them up from + the DataDirectory. + */ + first_thunk_address = a->DataDirectory[12].VirtualAddress ; + thunk_size = a->DataDirectory[12].Size; + import_table_size = a->DataDirectory[1].Size; +#endif } @@ -780,9 +857,11 @@ static void add_data_entry (abfd, aout, idx, name, base) asection *sec = bfd_get_section_by_name (abfd, name); /* add import directory information if it exists */ - if (sec != NULL) + if (sec != NULL + && coff_section_data (abfd, sec) != NULL + && pei_section_data (abfd, sec) != NULL) { - aout->DataDirectory[idx].VirtualAddress = sec->vma - base; + aout->DataDirectory[idx].VirtualAddress = (sec->vma - base) & 0xffffffff; aout->DataDirectory[idx].Size = pei_section_data (abfd, sec)->virt_size; sec->flags |= SEC_DATA; } @@ -803,11 +882,20 @@ coff_swap_aouthdr_out (abfd, in, out) bfd_vma ib = extra->ImageBase ; if (aouthdr_in->tsize) - aouthdr_in->text_start -= ib; + { + aouthdr_in->text_start -= ib; + aouthdr_in->text_start &= 0xffffffff; + } if (aouthdr_in->dsize) - aouthdr_in->data_start -= ib; + { + aouthdr_in->data_start -= ib; + aouthdr_in->data_start &= 0xffffffff; + } if (aouthdr_in->entry) - aouthdr_in->entry -= ib; + { + aouthdr_in->entry -= ib; + aouthdr_in->entry &= 0xffffffff; + } #define FA(x) (((x) + fa -1 ) & (- fa)) #define SA(x) (((x) + sa -1 ) & (- sa)) @@ -947,7 +1035,7 @@ coff_swap_aouthdr_out (abfd, in, out) } } - return sizeof(AOUTHDR); + return AOUTSZ; } static void @@ -980,6 +1068,7 @@ static void if (scnhdr_int->s_vaddr != 0) { scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase; + scnhdr_int->s_vaddr &= 0xffffffff; } if (strcmp (scnhdr_int->s_name, _BSS) == 0) { @@ -996,15 +1085,16 @@ coff_swap_scnhdr_out (abfd, in, out) { struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *)in; SCNHDR *scnhdr_ext = (SCNHDR *)out; - unsigned int ret = sizeof (SCNHDR); + unsigned int ret = SCNHSZ; bfd_vma ps; bfd_vma ss; memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name)); PUT_SCNHDR_VADDR (abfd, - (scnhdr_int->s_vaddr - - pe_data(abfd)->pe_opthdr.ImageBase), + ((scnhdr_int->s_vaddr + - pe_data(abfd)->pe_opthdr.ImageBase) + & 0xffffffff), (bfd_byte *) scnhdr_ext->s_vaddr); /* NT wants the size data to be rounded up to the next NT_FILE_ALIGNMENT @@ -1049,17 +1139,20 @@ coff_swap_scnhdr_out (abfd, in, out) /* FIXME: even worse, I don't see how to get the original alignment field*/ /* back... */ + /* FIXME: Basing this on section names is bogus. Also, this should + be in sec_to_styp_flags. */ + { 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 @@ -1070,24 +1163,21 @@ coff_swap_scnhdr_out (abfd, in, out) IMAGE_SCN_MEM_READ ; /* Remember this field is a max of 8 chars, so the null is _not_ there for an 8 character name like ".reldata". (yep. Stupid bug) */ - else if (strncmp (scnhdr_int->s_name, ".reldata", strlen(".reldata")) == 0) + else if (strncmp (scnhdr_int->s_name, ".reldata", 8) == 0) flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ; else if (strcmp (scnhdr_int->s_name, ".ydata") == 0) flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ; - else if (strncmp (scnhdr_int->s_name, ".drectve", strlen(".drectve")) == 0) + else if (strncmp (scnhdr_int->s_name, ".drectve", 8) == 0) flags = IMAGE_SCN_LNK_INFO | IMAGE_SCN_LNK_REMOVE ; -#ifdef POWERPC_LE_PE - else if (strncmp (scnhdr_int->s_name, ".stabstr", strlen(".stabstr")) == 0) - { - flags = IMAGE_SCN_LNK_INFO; - } - else if (strcmp (scnhdr_int->s_name, ".stab") == 0) - { - flags = IMAGE_SCN_LNK_INFO; - } -#endif + else if (strncmp (scnhdr_int->s_name, ".stab", 5) == 0) + 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; bfd_h_put_32(abfd, flags, (bfd_byte *) scnhdr_ext->s_flags); } @@ -1096,7 +1186,7 @@ coff_swap_scnhdr_out (abfd, in, out) bfd_h_put_16(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno); else { - (*_bfd_error_handler) ("%s: line number overflow: 0x%lx > 0xffff", + (*_bfd_error_handler) (_("%s: line number overflow: 0x%lx > 0xffff"), bfd_get_filename (abfd), scnhdr_int->s_nlnno); bfd_set_error (bfd_error_file_truncated); @@ -1107,7 +1197,7 @@ coff_swap_scnhdr_out (abfd, in, out) bfd_h_put_16(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc); else { - (*_bfd_error_handler) ("%s: reloc overflow: 0x%lx > 0xffff", + (*_bfd_error_handler) (_("%s: reloc overflow: 0x%lx > 0xffff"), bfd_get_filename (abfd), scnhdr_int->s_nreloc); bfd_set_error (bfd_error_file_truncated); @@ -1119,39 +1209,42 @@ coff_swap_scnhdr_out (abfd, in, out) static char * dir_names[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] = { - "Export Directory [.edata]", - "Import Directory [parts of .idata]", - "Resource Directory [.rsrc]", - "Exception Directory [.pdata]", - "Security Directory", - "Base Relocation Directory [.reloc]", - "Debug Directory", - "Description Directory", - "Special Directory", - "Thread Storage Directory [.tls]", - "Load Configuration Directory", - "Bound Import Directory", - "Import Address Table Directory", - "Reserved", - "Reserved", - "Reserved" + N_ ("Export Directory [.edata (or where ever we found it)]"), + N_ ("Import Directory [parts of .idata]"), + N_ ("Resource Directory [.rsrc]"), + N_ ("Exception Directory [.pdata]"), + N_ ("Security Directory"), + N_ ("Base Relocation Directory [.reloc]"), + N_ ("Debug Directory"), + N_ ("Description Directory"), + N_ ("Special Directory"), + N_ ("Thread Storage Directory [.tls]"), + N_ ("Load Configuration Directory"), + N_ ("Bound Import Directory"), + N_ ("Import Address Table Directory"), + N_ ("Reserved"), + N_ ("Reserved"), + N_ ("Reserved") }; /**********************************************************************/ static boolean pe_print_idata(abfd, vfile) - bfd*abfd; - void *vfile; + bfd *abfd; + PTR vfile; { - FILE *file = 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; @@ -1159,8 +1252,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) @@ -1196,38 +1322,38 @@ pe_print_idata(abfd, vfile) toc_address = loadable_toc_address - 32768; fprintf(file, - "\nFunction descriptor located at the start address: %04lx\n", + _("\nFunction descriptor located at the start address: %04lx\n"), (unsigned long int) (abfd->start_address)); fprintf (file, - "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n", + _("\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"), start_address, loadable_toc_address, toc_address); } + else + { + fprintf(file, + _("\nNo reldata section! Function descriptor not decoded.\n")); + } #endif fprintf(file, - "\nThe Import Tables (interpreted .idata section contents)\n"); + _("\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; @@ -1235,14 +1361,13 @@ pe_print_idata(abfd, vfile) bfd_vma forward_chain; bfd_vma dll_name; bfd_vma first_thunk; - int idx; - int j; + int idx = 0; + bfd_size_type j; char *dll; - int adj = extra->ImageBase - section->vma; fprintf (file, - " %04lx\t", - (unsigned long int) (i + section->vma)); + " %08lx\t", + (unsigned long int) (i + section->vma + dataoff)); if (i+20 > stop) { @@ -1263,33 +1388,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; + fprintf(file, _("\n\tDLL Name: %s\n"), dll); - for (j=0;j>> Ran out of IAT members!\n"); + _("\t>>> Ran out of IAT members!\n")); } else { @@ -1324,15 +1476,15 @@ 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) { fprintf(file, - "\tThe Import Address Table is identical\n"); + _("\tThe Import Address Table is identical\n")); } } @@ -1346,15 +1498,16 @@ pe_print_idata(abfd, vfile) } static boolean -pe_print_edata(abfd, vfile) - bfd*abfd; - void *vfile; +pe_print_edata (abfd, vfile) + bfd *abfd; + PTR vfile; { - FILE *file = vfile; + FILE *file = (FILE *) 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; @@ -1366,8 +1519,8 @@ pe_print_edata(abfd, vfile) short minor_ver; bfd_vma name; /* rva - relative to image base */ long base; /* ordinal base */ - long num_functions; /* Number in the export address table */ - long num_names; /* Number in the name pointer table */ + unsigned long num_functions; /* Number in the export address table */ + unsigned long num_names; /* Number in the name pointer table */ bfd_vma eat_addr; /* rva to the export address table */ bfd_vma npt_addr; /* rva to the Export Name Pointer Table */ bfd_vma ot_addr; /* rva to the Ordinal Table */ @@ -1376,20 +1529,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); @@ -1404,56 +1580,56 @@ 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; + adj = (extra->ImageBase - (section->vma + dataoff)) & 0xffffffff; /* Dump the EDT first first */ fprintf(file, - "\nThe Export Tables (interpreted .edata section contents)\n\n"); + _("\nThe Export Tables (interpreted .edata section contents)\n\n")); fprintf(file, - "Export Flags \t\t\t%lx\n", (unsigned long) edt.export_flags); + _("Export Flags \t\t\t%lx\n"), (unsigned long) edt.export_flags); fprintf(file, - "Time/Date stamp \t\t%lx\n", (unsigned long) edt.time_stamp); + _("Time/Date stamp \t\t%lx\n"), (unsigned long) edt.time_stamp); fprintf(file, - "Major/Minor \t\t\t%d/%d\n", edt.major_ver, edt.minor_ver); + _("Major/Minor \t\t\t%d/%d\n"), edt.major_ver, edt.minor_ver); fprintf (file, - "Name \t\t\t\t"); + _("Name \t\t\t\t")); fprintf_vma (file, edt.name); fprintf (file, - "%s\n", data + edt.name + adj); + " %s\n", data + edt.name + adj); fprintf(file, - "Ordinal Base \t\t\t%ld\n", edt.base); + _("Ordinal Base \t\t\t%ld\n"), edt.base); fprintf(file, - "Number in:\n"); + _("Number in:\n")); fprintf(file, - "\tExport Address Table \t\t%lx\n", - (unsigned long) edt.num_functions); + _("\tExport Address Table \t\t%lx\n"), + edt.num_functions); fprintf(file, - "\t[Name Pointer/Ordinal] Table\t%ld\n", edt.num_names); + _("\t[Name Pointer/Ordinal] Table\t%lu\n"), edt.num_names); fprintf(file, - "Table Addresses\n"); + _("Table Addresses\n")); fprintf (file, - "\tExport Address Table \t\t"); + _("\tExport Address Table \t\t")); fprintf_vma (file, edt.eat_addr); fprintf (file, "\n"); fprintf (file, - "\tName Pointer Table \t\t"); + _("\tName Pointer Table \t\t")); fprintf_vma (file, edt.npt_addr); fprintf (file, "\n"); fprintf (file, - "\tOrdinal Table \t\t\t"); + _("\tOrdinal Table \t\t\t")); fprintf_vma (file, edt.ot_addr); fprintf (file, "\n"); @@ -1469,17 +1645,16 @@ pe_print_edata(abfd, vfile) */ fprintf(file, - "\nExport Address Table -- Ordinal Base %ld\n", + _("\nExport Address Table -- Ordinal Base %ld\n"), edt.base); 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_actual = extra->ImageBase + eat_member; - bfd_vma edata_start = bfd_get_section_vma(abfd,section); - bfd_vma edata_end = edata_start + bfd_section_size (abfd, section); - + 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) + dataoff; + bfd_vma edata_end = edata_start + datasize; if (eat_member == 0) continue; @@ -1505,7 +1680,7 @@ pe_print_edata(abfd, vfile) /* The Export Name Pointer Table is paired with the Export Ordinal Table */ /* Dump them in parallel for clarity */ fprintf(file, - "\n[Ordinal/Name Pointer] Table\n"); + _("\n[Ordinal/Name Pointer] Table\n")); for (i = 0; i < edt.num_names; ++i) { @@ -1531,11 +1706,11 @@ pe_print_edata(abfd, vfile) } static boolean -pe_print_pdata(abfd, vfile) - bfd*abfd; - void *vfile; +pe_print_pdata (abfd, vfile) + bfd *abfd; + PTR vfile; { - FILE *file = vfile; + FILE *file = (FILE *) vfile; bfd_byte *data = 0; asection *section = bfd_get_section_by_name (abfd, ".pdata"); bfd_size_type datasize = 0; @@ -1548,15 +1723,15 @@ pe_print_pdata(abfd, vfile) stop = bfd_section_size (abfd, section); if ((stop % onaline) != 0) - fprintf (file, "Warning, .pdata section size (%ld) is not a multiple of %d\n", + fprintf (file, _("Warning, .pdata section size (%ld) is not a multiple of %d\n"), (long)stop, onaline); fprintf(file, - "\nThe Function Table (interpreted .pdata section contents)\n"); + _("\nThe Function Table (interpreted .pdata section contents)\n")); fprintf(file, - " vma:\t\tBegin End EH EH PrologEnd\n"); + _(" vma:\t\tBegin End EH EH PrologEnd\n")); fprintf(file, - " \t\tAddress Address Handler Data Address\n"); + _(" \t\tAddress Address Handler Data Address\n")); if (bfd_section_size (abfd, section) == 0) return true; @@ -1623,13 +1798,13 @@ pe_print_pdata(abfd, vfile) switch (eh_data) { case 0x01: - fprintf(file, " Register save millicode"); + fprintf(file, _(" Register save millicode")); break; case 0x02: - fprintf(file, " Register restore millicode"); + fprintf(file, _(" Register restore millicode")); break; case 0x03: - fprintf(file, " Glue code sequence"); + fprintf(file, _(" Glue code sequence")); break; default: break; @@ -1651,15 +1826,15 @@ static const char *tbl[6] = "LOW", "HIGHLOW", "HIGHADJ", -"unknown" +"MIPS_JMPADDR" }; static boolean -pe_print_reloc(abfd, vfile) - bfd*abfd; - void *vfile; +pe_print_reloc (abfd, vfile) + bfd *abfd; + PTR vfile; { - FILE *file = vfile; + FILE *file = (FILE *) vfile; bfd_byte *data = 0; asection *section = bfd_get_section_by_name (abfd, ".reloc"); bfd_size_type datasize = 0; @@ -1673,7 +1848,7 @@ pe_print_reloc(abfd, vfile) return true; fprintf(file, - "\n\nPE File Base Relocations (interpreted .reloc section contents)\n"); + _("\n\nPE File Base Relocations (interpreted .reloc section contents)\n")); data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section)); datasize = bfd_section_size (abfd, section); @@ -1708,7 +1883,7 @@ pe_print_reloc(abfd, vfile) } fprintf (file, - "\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n", + _("\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"), virtual_address, size, size, number); for (j = 0; j < number; ++j) @@ -1721,7 +1896,7 @@ pe_print_reloc(abfd, vfile) abort(); fprintf(file, - "\treloc %4d offset %4x [%4lx] %s\n", + _("\treloc %4d offset %4x [%4lx] %s\n"), j, off, (long) (off + virtual_address), tbl[t]); } @@ -1743,6 +1918,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"); @@ -1781,10 +1974,17 @@ pe_print_private_bfd_data (abfd, vfile) fprintf (file, "%s\n", dir_names[j]); } - pe_print_idata(abfd, vfile); - pe_print_edata(abfd, vfile); - pe_print_pdata(abfd, vfile); - pe_print_reloc(abfd, vfile); + pe_print_idata (abfd, vfile); + pe_print_edata (abfd, vfile); + pe_print_pdata (abfd, vfile); + pe_print_reloc (abfd, vfile); + + if (pe_saved_coff_bfd_print_private_bfd_data != NULL) + { + fputc ('\n', file); + + return pe_saved_coff_bfd_print_private_bfd_data (abfd, vfile); + } return true; } @@ -1839,13 +2039,19 @@ pe_mkobject_hook (abfd, filehdr, aouthdr) pe->real_flags = internal_f->f_flags; + if ((internal_f->f_flags & F_DLL) != 0) + pe->dll = 1; + #ifdef COFF_IMAGE_WITH_PE if (aouthdr) - { - pe->pe_opthdr = ((struct internal_aouthdr *)aouthdr)->pe; - } + pe->pe_opthdr = ((struct internal_aouthdr *)aouthdr)->pe; #endif +#ifdef ARM + if (! _bfd_coff_arm_set_private_flags (abfd, internal_f->f_flags)) + coff_data (abfd) ->flags = 0; +#endif + return (PTR) pe; } @@ -1854,6 +2060,16 @@ pe_mkobject_hook (abfd, filehdr, aouthdr) /* Copy any private info we understand from the input bfd to the output bfd. */ +#ifdef coff_bfd_copy_private_bfd_data +static boolean (*pe_saved_coff_bfd_copy_private_bfd_data) + PARAMS ((bfd *, bfd *)) + = coff_bfd_copy_private_bfd_data; +#undef coff_bfd_copy_private_bfd_data +#else +static boolean (*pe_saved_coff_bfd_copy_private_bfd_data) + PARAMS ((bfd *, bfd *)) + = NULL; +#endif #define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data static boolean @@ -1865,8 +2081,12 @@ pe_bfd_copy_private_bfd_data (ibfd, obfd) || obfd->xvec->flavour != bfd_target_coff_flavour) return true; - pe_data(obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr; + pe_data (obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr; + pe_data (obfd)->dll = pe_data (ibfd)->dll; + if (pe_saved_coff_bfd_copy_private_bfd_data) + return pe_saved_coff_bfd_copy_private_bfd_data (ibfd, obfd); + return true; } @@ -1886,6 +2106,10 @@ pe_bfd_copy_private_section_data (ibfd, isec, obfd, osec) bfd *obfd; asection *osec; { + if (bfd_get_flavour (ibfd) != bfd_target_coff_flavour + || bfd_get_flavour (obfd) != bfd_target_coff_flavour) + return true; + if (coff_section_data (ibfd, isec) != NULL && pei_section_data (ibfd, isec) != NULL) {