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 | |
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')
-rw-r--r-- | bfd/ChangeLog | 11 | ||||
-rw-r--r-- | bfd/coff-arm.c | 52 | ||||
-rw-r--r-- | bfd/coffcode.h | 12 | ||||
-rw-r--r-- | bfd/peicode.h | 309 |
4 files changed, 262 insertions, 122 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 4677203..b454bd7 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,14 @@ +Wed Mar 25 15:45:55 1998 Nick Clifton <nickc@cygnus.com> + + * coffcode.h (coff_mkobject_hook): Set private falgs even for a PE + build. + + * peicode.h: Call arm-coff private data functions after handling + pe private data. + + * coff-arm.c: Turn statics into globals so that they can be shared + both pe and pei backends. + Wed Mar 25 15:19:38 1998 Ian Lance Taylor <ian@cygnus.com> * aoutf1.h (sunos_set_arch_mach): Use bfd_mach_m68* rather than diff --git a/bfd/coff-arm.c b/bfd/coff-arm.c index 2c9318c..af129eb 100644 --- a/bfd/coff-arm.c +++ b/bfd/coff-arm.c @@ -725,11 +725,28 @@ arm_reloc_type_lookup(abfd,code) #define ARM 1 /* Customize coffcode.h */ /* The set of global variables that mark the total size of each kind - of glue required. */ -static long int global_thumb_glue_size = 0; -static long int global_arm_glue_size = 0; + of glue required, plus a BFD to hang the glue sections onto. + Note: These variable should not be made static, since in a *-pe + build there are two versions of this file compiled, one for pe + objects and one for pei objects, and they want to share these + variables. */ +#if defined COFF_IMAGE_WITH_PE +extern long int global_thumb_glue_size; +#else +long int global_thumb_glue_size = 0; +#endif -static bfd * bfd_of_glue_owner = NULL; +#if defined COFF_IMAGE_WITH_PE +extern long int global_arm_glue_size; +#else +long int global_arm_glue_size = 0; +#endif + +#if defined COFF_IMAGE_WITH_PE +extern bfd * bfd_of_glue_owner; +#else +bfd * bfd_of_glue_owner = NULL; +#endif /* some typedefs for holding instructions */ typedef unsigned long int insn32; @@ -1105,7 +1122,7 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, (" first occurrence: %s: arm call to thumb", bfd_get_filename (input_bfd)); } - + --my_offset; myh->root.u.def.value = my_offset; @@ -1182,6 +1199,7 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, (" first occurrence: %s: thumb call to arm", bfd_get_filename (input_bfd)); } + -- my_offset; myh->root.u.def.value = my_offset; @@ -1658,6 +1676,8 @@ arm_process_before_allocation (abfd, info) _bfd_coff_get_external_symbols (abfd); + BFD_ASSERT (bfd_of_glue_owner != NULL); + /* Rummage around all the relocs and map the glue vectors. */ sec = abfd->sections; @@ -1788,9 +1808,10 @@ coff_arm_bfd_merge_private_bfd_data (ibfd, obfd) /* If the two formats are different we cannot merge anything. This is not an error, since it is permissable to change the input and output formats. */ - if (ibfd->xvec != obfd->xvec) + if ( ibfd->xvec->flavour != bfd_target_coff_flavour + || obfd->xvec->flavour != bfd_target_coff_flavour) return true; - + /* Verify that the APCS is the same for the two BFDs */ if (APCS_SET (ibfd)) { @@ -1841,7 +1862,7 @@ coff_arm_bfd_merge_private_bfd_data (ibfd, obfd) bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd)); } } - + /* Check the interworking support. */ if (INTERWORK_SET (ibfd)) { @@ -1871,7 +1892,7 @@ coff_arm_bfd_merge_private_bfd_data (ibfd, obfd) /* Display the flags field. */ -static boolean +boolean coff_arm_bfd_print_private_bfd_data (abfd, ptr) bfd * abfd; PTR ptr; @@ -1890,8 +1911,10 @@ coff_arm_bfd_print_private_bfd_data (abfd, ptr) ); if (INTERWORK_SET (abfd)) - fprintf (file, ": [interworking %ssupported]", + fprintf (file, " [interworking %ssupported]", INTERWORK_FLAG (abfd) ? "" : "not " ); + else + fprintf (file, " [interworking flag not initialised]"); fputc ('\n', file); @@ -1942,13 +1965,13 @@ coff_arm_bfd_set_private_flags (abfd, flags) /* Copy the important parts of the target specific data from one instance of a BFD to another. */ -static boolean +boolean coff_arm_bfd_copy_private_bfd_data (src, dest) bfd * src; bfd * dest; { BFD_ASSERT (src != NULL && dest != NULL); - + if (src == dest) return true; @@ -1991,14 +2014,13 @@ coff_arm_bfd_copy_private_bfd_data (src, dest) return true; } -#endif /* COFF_IMAGE_WITH_PE or not COFF_WITH_PE */ /* Note: the definitions here of LOCAL_LABEL_PREFIX and USER_LABEL_PREIFX *must* match the definitions on gcc/config/arm/semi.h. */ #define LOCAL_LABEL_PREFIX "." #define USER_LABEL_PREFIX "_" -static boolean +boolean coff_arm_is_local_label_name (abfd, name) bfd * abfd; const char * name; @@ -2030,6 +2052,7 @@ coff_arm_is_local_label_name (abfd, name) default: return false; /* Cannot make our minds up - default to false so that it will not be stripped by accident. */ } } +#endif /* COFF_IMAGE_WITH_PE or not COFF_WITH_PE */ #define coff_bfd_is_local_label_name coff_arm_is_local_label_name #define coff_adjust_symndx coff_arm_adjust_symndx @@ -2045,6 +2068,7 @@ extern boolean coff_arm_final_link_postscript (); extern boolean coff_arm_bfd_set_private_flags (); extern boolean coff_arm_bfd_merge_private_bfd_data (); extern boolean coff_arm_link_output_has_begun (); +extern boolean coff_arm_is_local_label_name (); #if defined COFF_IMAGE_WITH_PE || ! defined COFF_WITH_PE /* This piece of machinery exists only to guarantee that the bfd that holds diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 753b662..5d99b0a 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -1327,7 +1327,7 @@ coff_mkobject_hook (abfd, filehdr, aouthdr) } #endif -#if defined ARM && ! defined COFF_WITH_PE +#if defined ARM /* Set the flags field from the COFF header read in */ if (! coff_arm_bfd_set_private_flags (abfd, internal_f->f_flags)) coff->flags = 0; @@ -3461,7 +3461,7 @@ coff_slurp_symbol_table (abfd) #endif case C_EXT: -#if defined ARM || defined COFF_WITH_PE +#if defined ARM case C_THUMBEXT: case C_THUMBEXTFUNC: #endif @@ -3497,7 +3497,7 @@ coff_slurp_symbol_table (abfd) dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL; -#if defined (COFF_WITH_PE) || defined (COFF_IMAGE_WITH_PE) +#if defined COFF_WITH_PE /* PE sets the symbol to a value relative to the start of the section. */ dst->symbol.value = src->u.syment.n_value; @@ -3534,7 +3534,7 @@ coff_slurp_symbol_table (abfd) #ifdef I960 case C_LEAFSTAT: /* static leaf procedure */ #endif -#if defined ARM || defined COFF_WITH_PE +#if defined ARM case C_THUMBSTAT: /* Thumb static */ case C_THUMBLABEL: /* Thumb label */ case C_THUMBSTATFUNC:/* Thumb static function */ @@ -3549,7 +3549,7 @@ coff_slurp_symbol_table (abfd) section, if there is one. */ if (dst->symbol.section) { -#if defined (COFF_WITH_PE) || defined (COFF_IMAGE_WITH_PE) +#if defined COFF_WITH_PE /* PE sets the symbol to a value relative to the start of the section. */ dst->symbol.value = src->u.syment.n_value; @@ -3659,7 +3659,7 @@ coff_slurp_symbol_table (abfd) case C_FCN: /* ".bf" or ".ef" */ case C_EFCN: /* physical end of function */ dst->symbol.flags = BSF_LOCAL; -#if defined (COFF_WITH_PE) || defined (COFF_IMAGE_WITH_PE) +#if defined COFF_WITH_PE /* PE sets the symbol to a value relative to the start of the section. */ dst->symbol.value = src->u.syment.n_value; 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 |