X-Git-Url: https://oss.titaniummirror.com/gitweb?p=msp430-binutils.git;a=blobdiff_plain;f=bfd%2FpeXXigen.c;fp=bfd%2FpeXXigen.c;h=6ee03a758358bef383357ce8f24497236b036f6f;hp=2d09561e33b1ef25e66d0a36228cb1377d879603;hb=d5da4f291af551c0b8b79e1d4a9b173d60e5c10e;hpb=7b5ea4fcdf2819e070665ab5610f8b48e3867c10 diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c index 2d09561..6ee03a7 100644 --- a/bfd/peXXigen.c +++ b/bfd/peXXigen.c @@ -1,6 +1,6 @@ /* Support for the generic parts of PE/PEI; the common executable parts. Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007 Free Software Foundation, Inc. + 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. Written by Cygnus Solutions. This file is part of BFD, the Binary File Descriptor library. @@ -129,6 +129,9 @@ _bfd_XXi_swap_sym_in (bfd * abfd, void * ext1, void * in1) they will be handled somewhat correctly in the bfd code. */ if (in->n_sclass == C_SECTION) { + char namebuf[SYMNMLEN + 1]; + const char *name = NULL; + in->n_value = 0x0; /* Create synthetic empty sections as needed. DJ */ @@ -136,33 +139,38 @@ _bfd_XXi_swap_sym_in (bfd * abfd, void * ext1, void * in1) { asection *sec; - for (sec = abfd->sections; sec; sec = sec->next) - { - if (strcmp (sec->name, in->n_name) == 0) - { - in->n_scnum = sec->target_index; - break; - } - } + name = _bfd_coff_internal_syment_name (abfd, in, namebuf); + if (name == NULL) + /* FIXME: Return error. */ + abort (); + sec = bfd_get_section_by_name (abfd, name); + if (sec != NULL) + in->n_scnum = sec->target_index; } if (in->n_scnum == 0) { int unused_section_number = 0; asection *sec; - char *name; flagword flags; for (sec = abfd->sections; sec; sec = sec->next) if (unused_section_number <= sec->target_index) unused_section_number = sec->target_index + 1; - name = bfd_alloc (abfd, (bfd_size_type) strlen (in->n_name) + 10); - if (name == NULL) - return; - strcpy (name, in->n_name); + if (name == namebuf) + { + name = (const char *) bfd_alloc (abfd, strlen (namebuf) + 1); + if (name == NULL) + /* FIXME: Return error. */ + abort (); + strcpy ((char *) name, namebuf); + } flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD; sec = bfd_make_section_anyway_with_flags (abfd, name, flags); + if (sec == NULL) + /* FIXME: Return error. */ + abort (); sec->vma = 0; sec->lma = 0; @@ -223,7 +231,7 @@ void _bfd_XXi_swap_aux_in (bfd * abfd, void * ext1, int type, - int class, + int in_class, int indx ATTRIBUTE_UNUSED, int numaux ATTRIBUTE_UNUSED, void * in1) @@ -231,7 +239,7 @@ _bfd_XXi_swap_aux_in (bfd * abfd, AUXENT *ext = (AUXENT *) ext1; union internal_auxent *in = (union internal_auxent *) in1; - switch (class) + switch (in_class) { case C_FILE: if (ext->x_file.x_fname[0] == 0) @@ -262,7 +270,8 @@ _bfd_XXi_swap_aux_in (bfd * abfd, in->x_sym.x_tagndx.l = H_GET_32 (abfd, ext->x_sym.x_tagndx); in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx); - if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class)) + if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type) + || ISTAG (in_class)) { in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext); in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext); @@ -294,7 +303,7 @@ unsigned int _bfd_XXi_swap_aux_out (bfd * abfd, void * inp, int type, - int class, + int in_class, int indx ATTRIBUTE_UNUSED, int numaux ATTRIBUTE_UNUSED, void * extp) @@ -304,7 +313,7 @@ _bfd_XXi_swap_aux_out (bfd * abfd, memset (ext, 0, AUXESZ); - switch (class) + switch (in_class) { case C_FILE: if (in->x_file.x_fname[0] == 0) @@ -336,7 +345,8 @@ _bfd_XXi_swap_aux_out (bfd * abfd, H_PUT_32 (abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx); H_PUT_16 (abfd, in->x_sym.x_tvndx, ext->x_sym.x_tvndx); - if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class)) + if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type) + || ISTAG (in_class)) { PUT_FCN_LNNOPTR (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext); PUT_FCN_ENDNDX (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext); @@ -540,17 +550,6 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out) bfd_vma sa, fa, ib; IMAGE_DATA_DIRECTORY idata2, idata5, tls; - if (pe->force_minimum_alignment) - { - if (!extra->FileAlignment) - extra->FileAlignment = PE_DEF_FILE_ALIGNMENT; - if (!extra->SectionAlignment) - extra->SectionAlignment = PE_DEF_SECTION_ALIGNMENT; - } - - if (extra->Subsystem == IMAGE_SUBSYSTEM_UNKNOWN) - extra->Subsystem = pe->target_subsystem; - sa = extra->SectionAlignment; fa = extra->FileAlignment; ib = extra->ImageBase; @@ -879,7 +878,7 @@ _bfd_XXi_swap_scnhdr_out (bfd * abfd, void * in, void * out) sometimes). */ if ((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0) { - if (bfd_pe_executable_p (abfd)) + if (bfd_pei_p (abfd)) { ps = scnhdr_int->s_size; ss = 0; @@ -892,7 +891,7 @@ _bfd_XXi_swap_scnhdr_out (bfd * abfd, void * in, void * out) } else { - if (bfd_pe_executable_p (abfd)) + if (bfd_pei_p (abfd)) ps = scnhdr_int->s_paddr; else ps = 0; @@ -1264,7 +1263,7 @@ pe_print_idata (bfd * abfd, void * vfile) else { ft_idx = first_thunk - (ft_section->vma - extra->ImageBase); - ft_data = bfd_malloc (datasize); + ft_data = (bfd_byte *) bfd_malloc (datasize); if (ft_data == NULL) continue; @@ -1310,7 +1309,7 @@ pe_print_idata (bfd * abfd, void * vfile) && first_thunk != 0 && first_thunk != hint_addr) fprintf (file, "\t%04lx", - (long) bfd_get_32 (abfd, ft_data + ft_idx + j)); + (unsigned long) bfd_get_32 (abfd, ft_data + ft_idx + j)); fprintf (file, "\n"); } #else @@ -1342,7 +1341,7 @@ pe_print_idata (bfd * abfd, void * vfile) && first_thunk != 0 && first_thunk != hint_addr) fprintf (file, "\t%04lx", - (long) bfd_get_32 (abfd, ft_data + ft_idx + j)); + (unsigned long) bfd_get_32 (abfd, ft_data + ft_idx + j)); fprintf (file, "\n"); } @@ -1433,7 +1432,7 @@ pe_print_edata (bfd * abfd, void * vfile) fprintf (file, _("\nThere is an export table in %s at 0x%lx\n"), section->name, (unsigned long) addr); - data = bfd_malloc (datasize); + data = (bfd_byte *) bfd_malloc (datasize); if (data == NULL) return FALSE; @@ -1472,7 +1471,7 @@ pe_print_edata (bfd * abfd, void * vfile) fprintf (file, _("Name \t\t\t\t")); - fprintf_vma (file, edt.name); + bfd_fprintf_vma (abfd, file, edt.name); fprintf (file, " %s\n", data + edt.name - adj); @@ -1494,17 +1493,17 @@ pe_print_edata (bfd * abfd, void * vfile) fprintf (file, _("\tExport Address Table \t\t")); - fprintf_vma (file, edt.eat_addr); + bfd_fprintf_vma (abfd, file, edt.eat_addr); fprintf (file, "\n"); fprintf (file, _("\tName Pointer Table \t\t")); - fprintf_vma (file, edt.npt_addr); + bfd_fprintf_vma (abfd, file, edt.npt_addr); fprintf (file, "\n"); fprintf (file, _("\tOrdinal Table \t\t\t")); - fprintf_vma (file, edt.ot_addr); + bfd_fprintf_vma (abfd, file, edt.ot_addr); fprintf (file, "\n"); /* The next table to find is the Export Address Table. It's basically @@ -1581,7 +1580,14 @@ pe_print_edata (bfd * abfd, void * vfile) /* This really is architecture dependent. On IA-64, a .pdata entry consists of three dwords containing relative virtual addresses that specify the start and end address of the code range the entry - covers and the address of the corresponding unwind info data. */ + covers and the address of the corresponding unwind info data. + + On ARM and SH-4, a compressed PDATA structure is used : + _IMAGE_CE_RUNTIME_FUNCTION_ENTRY, whereas MIPS is documented to use + _IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY. + See http://msdn2.microsoft.com/en-us/library/ms253988(VS.80).aspx . + + This is the version for uncompressed data. */ static bfd_boolean pe_print_pdata (bfd * abfd, void * vfile) @@ -1662,14 +1668,14 @@ pe_print_pdata (bfd * abfd, void * vfile) prolog_end_addr &= ~(bfd_vma) 0x3; fputc (' ', file); - fprintf_vma (file, i + section->vma); fputc ('\t', file); - fprintf_vma (file, begin_addr); fputc (' ', file); - fprintf_vma (file, end_addr); fputc (' ', file); - fprintf_vma (file, eh_handler); + bfd_fprintf_vma (abfd, file, i + section->vma); fputc ('\t', file); + bfd_fprintf_vma (abfd, file, begin_addr); fputc (' ', file); + bfd_fprintf_vma (abfd, file, end_addr); fputc (' ', file); + bfd_fprintf_vma (abfd, file, eh_handler); #if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) fputc (' ', file); - fprintf_vma (file, eh_data); fputc (' ', file); - fprintf_vma (file, prolog_end_addr); + bfd_fprintf_vma (abfd, file, eh_data); fputc (' ', file); + bfd_fprintf_vma (abfd, file, prolog_end_addr); fprintf (file, " %x", em_data); #endif @@ -1705,8 +1711,190 @@ pe_print_pdata (bfd * abfd, void * vfile) free (data); return TRUE; +#undef PDATA_ROW_SIZE +} + +typedef struct sym_cache +{ + int symcount; + asymbol ** syms; +} sym_cache; + +static asymbol ** +slurp_symtab (bfd *abfd, sym_cache *psc) +{ + asymbol ** sy = NULL; + long storage; + + if (!(bfd_get_file_flags (abfd) & HAS_SYMS)) + { + psc->symcount = 0; + return NULL; + } + + storage = bfd_get_symtab_upper_bound (abfd); + if (storage < 0) + return NULL; + if (storage) + sy = (asymbol **) bfd_malloc (storage); + + psc->symcount = bfd_canonicalize_symtab (abfd, sy); + if (psc->symcount < 0) + return NULL; + return sy; +} + +static const char * +my_symbol_for_address (bfd *abfd, bfd_vma func, sym_cache *psc) +{ + int i; + + if (psc->syms == 0) + psc->syms = slurp_symtab (abfd, psc); + + for (i = 0; i < psc->symcount; i++) + { + if (psc->syms[i]->section->vma + psc->syms[i]->value == func) + return psc->syms[i]->name; + } + + return NULL; +} + +static void +cleanup_syms (sym_cache *psc) +{ + psc->symcount = 0; + free (psc->syms); + psc->syms = NULL; } +/* This is the version for "compressed" pdata. */ + +bfd_boolean +_bfd_XX_print_ce_compressed_pdata (bfd * abfd, void * vfile) +{ +# define PDATA_ROW_SIZE (2 * 4) + FILE *file = (FILE *) vfile; + bfd_byte *data = NULL; + asection *section = bfd_get_section_by_name (abfd, ".pdata"); + bfd_size_type datasize = 0; + bfd_size_type i; + bfd_size_type start, stop; + int onaline = PDATA_ROW_SIZE; + struct sym_cache sym_cache = {0, 0} ; + + if (section == NULL + || coff_section_data (abfd, section) == NULL + || pei_section_data (abfd, section) == NULL) + return TRUE; + + stop = pei_section_data (abfd, section)->virt_size; + if ((stop % onaline) != 0) + 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")); + + fprintf (file, _("\ + vma:\t\tBegin Prolog Function Flags Exception EH\n\ + \t\tAddress Length Length 32b exc Handler Data\n")); + + datasize = section->size; + if (datasize == 0) + return TRUE; + + if (! bfd_malloc_and_get_section (abfd, section, &data)) + { + if (data != NULL) + free (data); + return FALSE; + } + + start = 0; + + for (i = start; i < stop; i += onaline) + { + bfd_vma begin_addr; + bfd_vma other_data; + bfd_vma prolog_length, function_length; + int flag32bit, exception_flag; + bfd_byte *tdata = 0; + asection *tsection; + + if (i + PDATA_ROW_SIZE > stop) + break; + + begin_addr = GET_PDATA_ENTRY (abfd, data + i ); + other_data = GET_PDATA_ENTRY (abfd, data + i + 4); + + if (begin_addr == 0 && other_data == 0) + /* We are probably into the padding of the section now. */ + break; + + prolog_length = (other_data & 0x000000FF); + function_length = (other_data & 0x3FFFFF00) >> 8; + flag32bit = (int)((other_data & 0x40000000) >> 30); + exception_flag = (int)((other_data & 0x80000000) >> 31); + + fputc (' ', file); + bfd_fprintf_vma (abfd, file, i + section->vma); fputc ('\t', file); + bfd_fprintf_vma (abfd, file, begin_addr); fputc (' ', file); + bfd_fprintf_vma (abfd, file, prolog_length); fputc (' ', file); + bfd_fprintf_vma (abfd, file, function_length); fputc (' ', file); + fprintf (file, "%2d %2d ", flag32bit, exception_flag); + + /* Get the exception handler's address and the data passed from the + .text section. This is really the data that belongs with the .pdata + but got "compressed" out for the ARM and SH4 architectures. */ + tsection = bfd_get_section_by_name (abfd, ".text"); + if (tsection && coff_section_data (abfd, tsection) + && pei_section_data (abfd, tsection)) + { + if (bfd_malloc_and_get_section (abfd, tsection, & tdata)) + { + int xx = (begin_addr - 8) - tsection->vma; + + tdata = (bfd_byte *) bfd_malloc (8); + if (bfd_get_section_contents (abfd, tsection, tdata, (bfd_vma) xx, 8)) + { + bfd_vma eh, eh_data; + + eh = bfd_get_32 (abfd, tdata); + eh_data = bfd_get_32 (abfd, tdata + 4); + fprintf (file, "%08x ", (unsigned int) eh); + fprintf (file, "%08x", (unsigned int) eh_data); + if (eh != 0) + { + const char *s = my_symbol_for_address (abfd, eh, &sym_cache); + + if (s) + fprintf (file, " (%s) ", s); + } + } + free (tdata); + } + else + { + if (tdata) + free (tdata); + } + } + + fprintf (file, "\n"); + } + + free (data); + + cleanup_syms (& sym_cache); + + return TRUE; +#undef PDATA_ROW_SIZE +} + + #define IMAGE_REL_BASED_HIGHADJ 4 static const char * const tbl[] = { @@ -1773,7 +1961,7 @@ pe_print_reloc (bfd * abfd, void * vfile) fprintf (file, _("\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"), - (unsigned long) virtual_address, size, size, number); + (unsigned long) virtual_address, size, (unsigned long) size, number); for (j = 0; j < number; ++j) { @@ -1786,7 +1974,7 @@ pe_print_reloc (bfd * abfd, void * vfile) fprintf (file, _("\treloc %4d offset %4x [%4lx] %s"), - j, off, (long) (off + virtual_address), tbl[t]); + j, off, (unsigned long) (off + virtual_address), tbl[t]); /* HIGHADJ takes an argument, - the next record *is* the low 16 bits of addend. */ @@ -1876,37 +2064,37 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile) fprintf (file, "\t(%s)",name); fprintf (file, "\nMajorLinkerVersion\t%d\n", i->MajorLinkerVersion); fprintf (file, "MinorLinkerVersion\t%d\n", i->MinorLinkerVersion); - fprintf (file, "SizeOfCode\t\t%08lx\n", i->SizeOfCode); + fprintf (file, "SizeOfCode\t\t%08lx\n", (unsigned long) i->SizeOfCode); fprintf (file, "SizeOfInitializedData\t%08lx\n", - i->SizeOfInitializedData); + (unsigned long) i->SizeOfInitializedData); fprintf (file, "SizeOfUninitializedData\t%08lx\n", - i->SizeOfUninitializedData); + (unsigned long) i->SizeOfUninitializedData); fprintf (file, "AddressOfEntryPoint\t"); - fprintf_vma (file, i->AddressOfEntryPoint); + bfd_fprintf_vma (abfd, file, i->AddressOfEntryPoint); fprintf (file, "\nBaseOfCode\t\t"); - fprintf_vma (file, i->BaseOfCode); + bfd_fprintf_vma (abfd, file, i->BaseOfCode); #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) /* PE32+ does not have BaseOfData member! */ fprintf (file, "\nBaseOfData\t\t"); - fprintf_vma (file, i->BaseOfData); + bfd_fprintf_vma (abfd, file, i->BaseOfData); #endif fprintf (file, "\nImageBase\t\t"); - fprintf_vma (file, i->ImageBase); + bfd_fprintf_vma (abfd, file, i->ImageBase); fprintf (file, "\nSectionAlignment\t"); - fprintf_vma (file, i->SectionAlignment); + bfd_fprintf_vma (abfd, file, i->SectionAlignment); fprintf (file, "\nFileAlignment\t\t"); - fprintf_vma (file, i->FileAlignment); + bfd_fprintf_vma (abfd, file, i->FileAlignment); fprintf (file, "\nMajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion); fprintf (file, "MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion); fprintf (file, "MajorImageVersion\t%d\n", i->MajorImageVersion); fprintf (file, "MinorImageVersion\t%d\n", i->MinorImageVersion); fprintf (file, "MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion); fprintf (file, "MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion); - fprintf (file, "Win32Version\t\t%08lx\n", i->Reserved1); - fprintf (file, "SizeOfImage\t\t%08lx\n", i->SizeOfImage); - fprintf (file, "SizeOfHeaders\t\t%08lx\n", i->SizeOfHeaders); - fprintf (file, "CheckSum\t\t%08lx\n", i->CheckSum); + fprintf (file, "Win32Version\t\t%08lx\n", (unsigned long) i->Reserved1); + fprintf (file, "SizeOfImage\t\t%08lx\n", (unsigned long) i->SizeOfImage); + fprintf (file, "SizeOfHeaders\t\t%08lx\n", (unsigned long) i->SizeOfHeaders); + fprintf (file, "CheckSum\t\t%08lx\n", (unsigned long) i->CheckSum); switch (i->Subsystem) { @@ -1928,6 +2116,7 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile) case IMAGE_SUBSYSTEM_WINDOWS_CE_GUI: subsystem_name = "Wince CUI"; break; + // These are from UEFI Platform Initialization Specification 1.1. case IMAGE_SUBSYSTEM_EFI_APPLICATION: subsystem_name = "EFI application"; break; @@ -1937,10 +2126,10 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile) case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER: subsystem_name = "EFI runtime driver"; break; - // These are from revision 8.0 of the MS PE/COFF spec - case IMAGE_SUBSYSTEM_EFI_ROM: - subsystem_name = "EFI ROM"; + case IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER: + subsystem_name = "SAL runtime driver"; break; + // This is from revision 8.0 of the MS PE/COFF spec case IMAGE_SUBSYSTEM_XBOX: subsystem_name = "XBOX"; break; @@ -1954,28 +2143,32 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile) fprintf (file, "\t(%s)", subsystem_name); fprintf (file, "\nDllCharacteristics\t%08x\n", i->DllCharacteristics); fprintf (file, "SizeOfStackReserve\t"); - fprintf_vma (file, i->SizeOfStackReserve); + bfd_fprintf_vma (abfd, file, i->SizeOfStackReserve); fprintf (file, "\nSizeOfStackCommit\t"); - fprintf_vma (file, i->SizeOfStackCommit); + bfd_fprintf_vma (abfd, file, i->SizeOfStackCommit); fprintf (file, "\nSizeOfHeapReserve\t"); - fprintf_vma (file, i->SizeOfHeapReserve); + bfd_fprintf_vma (abfd, file, i->SizeOfHeapReserve); fprintf (file, "\nSizeOfHeapCommit\t"); - fprintf_vma (file, i->SizeOfHeapCommit); - fprintf (file, "\nLoaderFlags\t\t%08lx\n", i->LoaderFlags); - fprintf (file, "NumberOfRvaAndSizes\t%08lx\n", i->NumberOfRvaAndSizes); + bfd_fprintf_vma (abfd, file, i->SizeOfHeapCommit); + fprintf (file, "\nLoaderFlags\t\t%08lx\n", (unsigned long) i->LoaderFlags); + fprintf (file, "NumberOfRvaAndSizes\t%08lx\n", + (unsigned long) i->NumberOfRvaAndSizes); fprintf (file, "\nThe Data Directory\n"); for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++) { fprintf (file, "Entry %1x ", j); - fprintf_vma (file, i->DataDirectory[j].VirtualAddress); - fprintf (file, " %08lx ", i->DataDirectory[j].Size); + bfd_fprintf_vma (abfd, file, i->DataDirectory[j].VirtualAddress); + fprintf (file, " %08lx ", (unsigned long) i->DataDirectory[j].Size); fprintf (file, "%s\n", dir_names[j]); } pe_print_idata (abfd, vfile); pe_print_edata (abfd, vfile); - pe_print_pdata (abfd, vfile); + if (bfd_coff_have_print_pdata (abfd)) + bfd_coff_print_pdata (abfd, vfile); + else + pe_print_pdata (abfd, vfile); pe_print_reloc (abfd, vfile); return TRUE; @@ -1987,13 +2180,22 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile) bfd_boolean _bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd) { + pe_data_type *ipe, *ope; + /* One day we may try to grok other private data. */ if (ibfd->xvec->flavour != bfd_target_coff_flavour || obfd->xvec->flavour != bfd_target_coff_flavour) return TRUE; - pe_data (obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr; - pe_data (obfd)->dll = pe_data (ibfd)->dll; + ipe = pe_data (ibfd); + ope = pe_data (obfd); + + /* pe_opthdr is copied in copy_object. */ + ope->dll = ipe->dll; + + /* Don't copy input subsystem if output is different from input. */ + if (obfd->xvec != ibfd->xvec) + ope->pe_opthdr.Subsystem = IMAGE_SUBSYSTEM_UNKNOWN; /* For strip: if we removed .reloc, we'll make a real mess of things if we don't remove this entry as well. */ @@ -2076,7 +2278,9 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo) /* PR ld/2729: We cannot rely upon all the output sections having been created properly, so check before referencing them. Issue a warning message for any sections tht could not be found. */ - if (h1->root.u.def.section != NULL + if ((h1->root.type == bfd_link_hash_defined + || h1->root.type == bfd_link_hash_defweak) + && h1->root.u.def.section != NULL && h1->root.u.def.section->output_section != NULL) pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_TABLE].VirtualAddress = (h1->root.u.def.value @@ -2093,6 +2297,8 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo) h1 = coff_link_hash_lookup (coff_hash_table (info), ".idata$4", FALSE, FALSE, TRUE); if (h1 != NULL + && (h1->root.type == bfd_link_hash_defined + || h1->root.type == bfd_link_hash_defweak) && h1->root.u.def.section != NULL && h1->root.u.def.section->output_section != NULL) pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_TABLE].Size = @@ -2113,6 +2319,8 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo) h1 = coff_link_hash_lookup (coff_hash_table (info), ".idata$5", FALSE, FALSE, TRUE); if (h1 != NULL + && (h1->root.type == bfd_link_hash_defined + || h1->root.type == bfd_link_hash_defweak) && h1->root.u.def.section != NULL && h1->root.u.def.section->output_section != NULL) pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].VirtualAddress = @@ -2130,6 +2338,8 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo) h1 = coff_link_hash_lookup (coff_hash_table (info), ".idata$6", FALSE, FALSE, TRUE); if (h1 != NULL + && (h1->root.type == bfd_link_hash_defined + || h1->root.type == bfd_link_hash_defweak) && h1->root.u.def.section != NULL && h1->root.u.def.section->output_section != NULL) pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].Size = @@ -2150,7 +2360,9 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo) "__tls_used", FALSE, FALSE, TRUE); if (h1 != NULL) { - if (h1->root.u.def.section != NULL + if ((h1->root.type == bfd_link_hash_defined + || h1->root.type == bfd_link_hash_defweak) + && h1->root.u.def.section != NULL && h1->root.u.def.section->output_section != NULL) pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].VirtualAddress = (h1->root.u.def.value