X-Git-Url: http://drtracing.org/?a=blobdiff_plain;ds=sidebyside;f=ld%2Femultempl%2Fpe.em;h=979cc8b8e960486a2867a8f8fd573ea5b9dd768c;hb=0cdcdbf8dbadc70194d46b4c3400ba8cc2a10fc0;hp=b936199e10722baf5c756eeefd4a8e4cbea7e1b4;hpb=8a9eab9b5ee88bda4d83a237e3a3c0723530a51e;p=deliverable%2Fbinutils-gdb.git diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em index b936199e10..979cc8b8e9 100644 --- a/ld/emultempl/pe.em +++ b/ld/emultempl/pe.em @@ -8,8 +8,7 @@ fi rm -f e${EMULATION_NAME}.c (echo;echo;echo;echo;echo)>e${EMULATION_NAME}.c # there, now line numbers match ;-) fragment < Set size of the initial stack\n")); fprintf (file, _(" --subsystem [:] Set required OS subsystem [& version]\n")); fprintf (file, _(" --support-old-code Support interworking with old code\n")); + fprintf (file, _(" --[no-]leading-underscore Set explicit symbol underscore prefix mode\n")); fprintf (file, _(" --thumb-entry= Set the entry point to be Thumb \n")); + fprintf (file, _(" --[no-]insert-timestamp Use a real timestamp rather than zero (default).\n")); + fprintf (file, _(" This makes binaries non-deterministic\n")); #ifdef DLL_SUPPORT fprintf (file, _(" --add-stdcall-alias Export symbols with and without @nn\n")); fprintf (file, _(" --disable-stdcall-fixup Don't link _sym to _sym@nn\n")); @@ -397,16 +463,17 @@ gld_${EMULATION_NAME}_list_options (FILE *file) fprintf (file, _(" --kill-at Remove @nn from exported symbols\n")); fprintf (file, _(" --out-implib Generate import library\n")); fprintf (file, _(" --output-def Generate a .DEF file for the built DLL\n")); - fprintf (file, _(" --warn-duplicate-exports Warn about duplicate exports.\n")); + fprintf (file, _(" --warn-duplicate-exports Warn about duplicate exports\n")); fprintf (file, _(" --compat-implib Create backward compatible import libs;\n\ create __imp_ as well.\n")); - fprintf (file, _(" --enable-auto-image-base Automatically choose image base for DLLs\n\ - unless user specifies one\n")); + fprintf (file, _(" --enable-auto-image-base[=
] Automatically choose image base for DLLs\n\ + (optionally starting with address) unless\n\ + specifically set with --image-base\n")); fprintf (file, _(" --disable-auto-image-base Do not auto-choose image base. (default)\n")); fprintf (file, _(" --dll-search-prefix= When linking dynamically to a dll without\n\ an importlib, use .dll\n\ in preference to lib.dll \n")); - fprintf (file, _(" --enable-auto-import Do sophistcated linking of _sym to\n\ + fprintf (file, _(" --enable-auto-import Do sophisticated linking of _sym to\n\ __imp_sym for DATA references\n")); fprintf (file, _(" --disable-auto-import Do not auto-import DATA items from DLLs\n")); fprintf (file, _(" --enable-runtime-pseudo-reloc Work around auto-import limitations by\n\ @@ -419,6 +486,8 @@ gld_${EMULATION_NAME}_list_options (FILE *file) #endif fprintf (file, _(" --large-address-aware Executable supports virtual addresses\n\ greater than 2 gigabytes\n")); + fprintf (file, _(" --disable-large-address-aware Executable does not support virtual\n\ + addresses greater than 2 gigabytes\n")); fprintf (file, _(" --enable-long-section-names Use long COFF section names even in\n\ executable image files\n")); fprintf (file, _(" --disable-long-section-names Never use long COFF section names, even\n\ @@ -432,7 +501,8 @@ gld_${EMULATION_NAME}_list_options (FILE *file) be called in this image\n")); fprintf (file, _(" --no-bind Do not bind this image\n")); fprintf (file, _(" --wdmdriver Driver uses the WDM model\n")); - fprintf (file, _(" --tsaware Image is Terminal Server aware\n")); + fprintf (file, _(" --tsaware Image is Terminal Server aware\n")); + fprintf (file, _(" --build-id[=STYLE] Generate build ID\n")); } @@ -440,11 +510,12 @@ static void set_pe_name (char *name, long val) { int i; + is_underscoring (); /* Find the name and set it. */ for (i = 0; init[i].ptr; i++) { - if (strcmp (name, init[i].symbol) == 0) + if (strcmp (name, GET_INIT_SYMBOL_NAME (i)) == 0) { init[i].value = val; init[i].inited = 1; @@ -504,7 +575,8 @@ set_entry_point (void) entry = default_entry; } - initial_symbol_char = ${INITIAL_SYMBOL_CHAR}; + initial_symbol_char = (is_underscoring () != 0 ? "_" : ""); + if (*initial_symbol_char != '\0') { char *alc_entry; @@ -625,6 +697,7 @@ set_pe_stack_heap (char *resname, char *comname) einfo (_("%P%F: strange hex info for PE parameter '%s'\n"), optarg); } +#define DEFAULT_BUILD_ID_STYLE "md5" static bfd_boolean gld${EMULATION_NAME}_handle_option (int optc) @@ -637,12 +710,7 @@ gld${EMULATION_NAME}_handle_option (int optc) case OPTION_BASE_FILE: link_info.base_file = fopen (optarg, FOPEN_WB); if (link_info.base_file == NULL) - { - /* xgettext:c-format */ - fprintf (stderr, _("%s: Can't open base file %s\n"), - program_name, optarg); - xexit (1); - } + einfo (_("%F%P: cannot open base file %s\n"), optarg); break; /* PE options. */ @@ -694,6 +762,18 @@ gld${EMULATION_NAME}_handle_option (int optc) case OPTION_USE_NUL_PREFIXED_IMPORT_TABLES: pe_use_nul_prefixed_import_tables = TRUE; break; + case OPTION_NO_LEADING_UNDERSCORE: + pe_leading_underscore = 0; + break; + case OPTION_LEADING_UNDERSCORE: + pe_leading_underscore = 1; + break; + case OPTION_INSERT_TIMESTAMP: + insert_timestamp = TRUE; + break; + case OPTION_NO_INSERT_TIMESTAMP: + insert_timestamp = FALSE; + break; #ifdef DLL_SUPPORT case OPTION_OUT_DEF: pe_out_def_filename = xstrdup (optarg); @@ -736,6 +816,12 @@ gld${EMULATION_NAME}_handle_option (int optc) break; case OPTION_ENABLE_AUTO_IMAGE_BASE: pe_enable_auto_image_base = 1; + if (optarg && *optarg) + { + char *end; + pe_auto_image_base = strtoul (optarg, &end, 0); + /* XXX should check that we actually parsed something */ + } break; case OPTION_DISABLE_AUTO_IMAGE_BASE: pe_enable_auto_image_base = 0; @@ -772,6 +858,9 @@ gld${EMULATION_NAME}_handle_option (int optc) case OPTION_LARGE_ADDRESS_AWARE: real_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE; break; + case OPTION_DISABLE_LARGE_ADDRESS_AWARE: + real_flags &= ~ IMAGE_FILE_LARGE_ADDRESS_AWARE; + break; case OPTION_ENABLE_LONG_SECTION_NAMES: pe_use_coff_long_section_names = 1; break; @@ -803,6 +892,17 @@ gld${EMULATION_NAME}_handle_option (int optc) case OPTION_TERMINAL_SERVER_AWARE: pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE; break; + case OPTION_BUILD_ID: + if (emit_build_id != NULL) + { + free ((char *) emit_build_id); + emit_build_id = NULL; + } + if (optarg == NULL) + optarg = DEFAULT_BUILD_ID_STYLE; + if (strcmp (optarg, "none")) + emit_build_id = xstrdup (optarg); + break; } /* Set DLLCharacteristics bits */ @@ -842,7 +942,7 @@ static unsigned long compute_dll_image_base (const char *ofile) { unsigned long hash = strhash (ofile); - return 0x61300000 + ((hash << 16) & 0x0FFC0000); + return pe_auto_image_base + ((hash << 16) & 0x0FFC0000); } #endif @@ -856,6 +956,8 @@ gld_${EMULATION_NAME}_set_symbols (void) names and insert the defaults. */ int j; + is_underscoring (); + if (!init[IMAGEBASEOFF].inited) { if (link_info.relocatable) @@ -886,8 +988,9 @@ gld_${EMULATION_NAME}_set_symbols (void) { long val = init[j].value; lang_assignment_statement_type *rv; - rv = lang_add_assignment (exp_assop ('=', init[j].symbol, - exp_intop (val))); + + rv = lang_add_assignment (exp_assign (GET_INIT_SYMBOL_NAME (j), + exp_intop (val), FALSE)); if (init[j].size == sizeof (short)) *(short *) init[j].ptr = val; else if (init[j].size == sizeof (int)) @@ -1110,14 +1213,15 @@ This should work unless it involves constant data structures referencing symbols for (i = 0; i < nsyms; i++) { - if (! CONST_STRNEQ (symbols[i]->name, U ("_head_"))) + if (! CONST_STRNEQ (symbols[i]->name, + U ("_head_"))) continue; if (pe_dll_extra_pe_debug) printf ("->%s\n", symbols[i]->name); - pe_data_import_dll = (char*) (symbols[i]->name + - sizeof (U ("_head_")) - 1); + pe_data_import_dll = (char *) (symbols[i]->name + + U_SIZE ("_head_") - 1); break; } @@ -1140,14 +1244,13 @@ This should work unless it involves constant data structures referencing symbols static bfd_boolean pr_sym (struct bfd_hash_entry *h, void *inf ATTRIBUTE_UNUSED) { - if (pe_dll_extra_pe_debug) - printf ("+%s\n", h->string); + printf ("+%s\n", h->string); return TRUE; } #endif /* DLL_SUPPORT */ -static void +static void debug_section_p (bfd *abfd ATTRIBUTE_UNUSED, asection *sect, void *obj) { int *found = (int *) obj; @@ -1155,9 +1258,174 @@ debug_section_p (bfd *abfd ATTRIBUTE_UNUSED, asection *sect, void *obj) *found = 1; } +static bfd_boolean +pecoff_checksum_contents (bfd *abfd, + void (*process) (const void *, size_t, void *), + void *arg) +{ + file_ptr filepos = (file_ptr) 0; + + while (1) + { + unsigned char b; + int status; + + if (bfd_seek (abfd, filepos, SEEK_SET) != 0) + return 0; + + status = bfd_bread (&b, (bfd_size_type) 1, abfd); + if (status < 1) + { + break; + } + + (*process) (&b, 1, arg); + filepos += 1; + } + + return TRUE; +} + +static bfd_boolean +write_build_id (bfd *abfd) +{ + struct pe_tdata *t = pe_data (abfd); + asection *asec; + struct bfd_link_order *link_order = NULL; + unsigned char *contents; + bfd_size_type size; + bfd_size_type build_id_size; + unsigned char *build_id; + + /* Find the section the .buildid output section has been merged info. */ + for (asec = abfd->sections; asec != NULL; asec = asec->next) + { + struct bfd_link_order *l = NULL; + for (l = asec->map_head.link_order; l != NULL; l = l->next) + { + if ((l->type == bfd_indirect_link_order)) + { + if (l->u.indirect.section == t->build_id.sec) + { + link_order = l; + break; + } + } + } + + if (link_order) + break; + } + + if (!link_order) + { + einfo (_("%P: warning: .buildid section discarded," + " --build-id ignored.\n")); + return TRUE; + } + + if (t->build_id.sec->contents == NULL) + t->build_id.sec->contents = (unsigned char *) xmalloc (t->build_id.sec->size); + contents = t->build_id.sec->contents; + size = t->build_id.sec->size; + + build_id_size = compute_build_id_size (t->build_id.style); + build_id = xmalloc (build_id_size); + generate_build_id (abfd, t->build_id.style, pecoff_checksum_contents, build_id, build_id_size); + + bfd_vma ib = pe_data (link_info.output_bfd)->pe_opthdr.ImageBase; + + /* Construct a debug directory entry which points to an immediately following CodeView record. */ + struct internal_IMAGE_DEBUG_DIRECTORY idd; + idd.Characteristics = 0; + idd.TimeDateStamp = 0; + idd.MajorVersion = 0; + idd.MinorVersion = 0; + idd.Type = PE_IMAGE_DEBUG_TYPE_CODEVIEW; + idd.SizeOfData = sizeof (CV_INFO_PDB70) + 1; + idd.AddressOfRawData = asec->vma - ib + link_order->offset + + sizeof (struct external_IMAGE_DEBUG_DIRECTORY); + idd.PointerToRawData = asec->filepos + link_order->offset + + sizeof (struct external_IMAGE_DEBUG_DIRECTORY); + + struct external_IMAGE_DEBUG_DIRECTORY *ext = (struct external_IMAGE_DEBUG_DIRECTORY *)contents; + _bfd_XXi_swap_debugdir_out (abfd, &idd, ext); + + /* Write the debug directory entry. */ + if (bfd_seek (abfd, asec->filepos + link_order->offset, SEEK_SET) != 0) + return 0; + + if ((bfd_bwrite (contents, size, abfd) != size)) + return 0; + + /* Construct the CodeView record. */ + CODEVIEW_INFO cvinfo; + cvinfo.CVSignature = CVINFO_PDB70_CVSIGNATURE; + cvinfo.Age = 1; + + /* Zero pad or truncate the generated build_id to fit in the CodeView record. */ + memset (&(cvinfo.Signature), 0, CV_INFO_SIGNATURE_LENGTH); + memcpy (&(cvinfo.Signature), build_id, (build_id_size > CV_INFO_SIGNATURE_LENGTH) + ? CV_INFO_SIGNATURE_LENGTH : build_id_size); + + free (build_id); + + /* Write the codeview record. */ + if (_bfd_XXi_write_codeview_record (abfd, idd.PointerToRawData, &cvinfo) == 0) + return 0; + + /* Record the location of the debug directory in the data directory. */ + pe_data (link_info.output_bfd)->pe_opthdr.DataDirectory[PE_DEBUG_DATA].VirtualAddress + = asec->vma - ib + link_order->offset; + pe_data (link_info.output_bfd)->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size + = sizeof (struct external_IMAGE_DEBUG_DIRECTORY); + + return TRUE; +} + +/* Make .buildid section, and set up coff_tdata->build_id. */ +static bfd_boolean +setup_build_id (bfd *ibfd) +{ + asection *s; + flagword flags; + + if (!validate_build_id_style (emit_build_id)) + { + einfo ("%P: warning: unrecognized --build-id style ignored.\n"); + return FALSE; + } + + flags = (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_IN_MEMORY + | SEC_LINKER_CREATED | SEC_READONLY | SEC_DATA); + s = bfd_make_section_anyway_with_flags (ibfd, ".buildid", flags); + if (s != NULL) + { + struct pe_tdata *t = pe_data (link_info.output_bfd); + t->build_id.after_write_object_contents = &write_build_id; + t->build_id.style = emit_build_id; + t->build_id.sec = s; + + /* Section is a fixed size: + One IMAGE_DEBUG_DIRECTORY entry, of type IMAGE_DEBUG_TYPE_CODEVIEW, + pointing at a CV_INFO_PDB70 record containing the build-id, with a + null byte for PdbFileName. */ + s->size = sizeof (struct external_IMAGE_DEBUG_DIRECTORY) + + sizeof (CV_INFO_PDB70) + 1; + + return TRUE; + } + + einfo ("%P: warning: Cannot create .buildid section," + " --build-id ignored.\n"); + return FALSE; +} + static void gld_${EMULATION_NAME}_after_open (void) { + after_open_default (); + #ifdef DLL_SUPPORT if (pe_dll_extra_pe_debug) { @@ -1170,11 +1438,31 @@ gld_${EMULATION_NAME}_after_open (void) printf ("-%s\n", sym->root.string); bfd_hash_traverse (&link_info.hash->table, pr_sym, NULL); - for (a = link_info.input_bfds; a; a = a->link_next) + for (a = link_info.input_bfds; a; a = a->link.next) printf ("*%s\n",a->filename); } #endif + if (emit_build_id != NULL) + { + bfd *abfd; + + /* Find a COFF input. */ + for (abfd = link_info.input_bfds; + abfd != (bfd *) NULL; abfd = abfd->link.next) + if (bfd_get_flavour (abfd) == bfd_target_coff_flavour) + break; + + /* If there are no COFF input files do not try to + add a build-id section. */ + if (abfd == NULL + || !setup_build_id (abfd)) + { + free ((char *) emit_build_id); + emit_build_id = NULL; + } + } + /* Pass the wacky PE command line options into the output bfd. FIXME: This should be done via a function, rather than by including an internal BFD header. */ @@ -1187,6 +1475,7 @@ gld_${EMULATION_NAME}_after_open (void) pe_data (link_info.output_bfd)->pe_opthdr = pe; pe_data (link_info.output_bfd)->dll = init[DLLOFF].value; pe_data (link_info.output_bfd)->real_flags |= real_flags; + pe_data (link_info.output_bfd)->insert_timestamp = insert_timestamp; /* At this point we must decide whether to use long section names in the output or not. If the user hasn't explicitly specified @@ -1196,17 +1485,23 @@ gld_${EMULATION_NAME}_after_open (void) find it, so enable it in that case. */ if (pe_use_coff_long_section_names < 0 && link_info.strip == strip_none) { - /* Iterate over all sections of all input BFDs, checking - for any that begin 'debug_' and are long names. */ - LANG_FOR_EACH_INPUT_STATEMENT (is) + if (link_info.relocatable) + pe_use_coff_long_section_names = 1; + else { - int found_debug = 0; - bfd_map_over_sections (is->the_bfd, debug_section_p, &found_debug); - if (found_debug) - { - pe_use_coff_long_section_names = 1; - break; - } + /* Iterate over all sections of all input BFDs, checking + for any that begin 'debug_' and are long names. */ + LANG_FOR_EACH_INPUT_STATEMENT (is) + { + int found_debug = 0; + + bfd_map_over_sections (is->the_bfd, debug_section_p, &found_debug); + if (found_debug) + { + pe_use_coff_long_section_names = 1; + break; + } + } } } @@ -1347,8 +1642,9 @@ gld_${EMULATION_NAME}_after_open (void) ? bfd_get_filename (blhe->u.def.section->owner->my_archive) : bfd_get_filename (blhe->u.def.section->owner); - if (strcmp (bfd_get_filename (is->the_bfd->my_archive), - other_bfd_filename) == 0) + if (filename_cmp (bfd_get_filename + (is->the_bfd->my_archive), + other_bfd_filename) == 0) continue; /* Rename this implib to match the other one. */ @@ -1402,7 +1698,7 @@ gld_${EMULATION_NAME}_after_open (void) extension, and use that for the remainder of the comparisons. */ pnt = strrchr (is3->the_bfd->filename, '.'); - if (pnt != NULL && strcmp (pnt, ".dll") == 0) + if (pnt != NULL && filename_cmp (pnt, ".dll") == 0) break; } @@ -1419,11 +1715,11 @@ gld_${EMULATION_NAME}_after_open (void) /* Skip static members, ie anything with a .obj extension. */ pnt = strrchr (is2->the_bfd->filename, '.'); - if (pnt != NULL && strcmp (pnt, ".obj") == 0) + if (pnt != NULL && filename_cmp (pnt, ".obj") == 0) continue; - if (strcmp (is3->the_bfd->filename, - is2->the_bfd->filename)) + if (filename_cmp (is3->the_bfd->filename, + is2->the_bfd->filename)) { is_ms_arch = 0; break; @@ -1437,7 +1733,7 @@ gld_${EMULATION_NAME}_after_open (void) then leave the filename alone. */ pnt = strrchr (is->the_bfd->filename, '.'); - if (is_ms_arch && (strcmp (pnt, ".dll") == 0)) + if (is_ms_arch && (filename_cmp (pnt, ".dll") == 0)) { int idata2 = 0, reloc_count=0; asection *sec; @@ -1530,8 +1826,10 @@ gld_${EMULATION_NAME}_after_open (void) /* If the symbol in the stub section has no other undefined references, exclude the stub section from the final link. */ - if (blhe && (blhe->type == bfd_link_hash_defined) - && (blhe->u.undef.next == NULL)) + if (blhe != NULL + && blhe->type == bfd_link_hash_defined + && blhe->u.undef.next == NULL + && blhe != link_info.hash->undefs_tail) stub_sec->flags |= SEC_EXCLUDE; } } @@ -1598,7 +1896,7 @@ saw_option (char *option) int i; for (i = 0; init[i].ptr; i++) - if (strcmp (init[i].symbol, option) == 0) + if (strcmp (GET_INIT_SYMBOL_NAME (i), option) == 0) return init[i].inited; return 0; } @@ -1610,7 +1908,7 @@ gld_${EMULATION_NAME}_unrecognized_file (lang_input_statement_type *entry ATTRIB #ifdef DLL_SUPPORT const char *ext = entry->filename + strlen (entry->filename) - 4; - if (strcmp (ext, ".def") == 0 || strcmp (ext, ".DEF") == 0) + if (filename_cmp (ext, ".def") == 0 || filename_cmp (ext, ".DEF") == 0) { pe_def_file = def_file_parse (entry->filename, pe_def_file); @@ -1632,7 +1930,8 @@ gld_${EMULATION_NAME}_unrecognized_file (lang_input_statement_type *entry ATTRIB { struct bfd_link_hash_entry *h; - sprintf (buf, "%s%s", U (""), pe_def_file->exports[i].internal_name); + sprintf (buf, "%s%s", U (""), + pe_def_file->exports[i].internal_name); h = bfd_link_hash_lookup (link_info.hash, buf, TRUE, TRUE, TRUE); if (h == (struct bfd_link_hash_entry *) NULL) @@ -1658,8 +1957,9 @@ gld_${EMULATION_NAME}_unrecognized_file (lang_input_statement_type *entry ATTRIB = pe_def_file->base_address; init[IMAGEBASEOFF].inited = 1; if (image_base_statement) - image_base_statement->exp = exp_assop ('=', "__image_base__", - exp_intop (pe.ImageBase)); + image_base_statement->exp + = exp_assign ("__image_base__", exp_intop (pe.ImageBase), + FALSE); } if (pe_def_file->stack_reserve != -1 @@ -1693,9 +1993,6 @@ gld_${EMULATION_NAME}_recognized_file (lang_input_statement_type *entry ATTRIBUT #ifdef TARGET_IS_shpe pe_dll_id_target ("pei-shl"); #endif -#ifdef TARGET_IS_mipspe - pe_dll_id_target ("pei-mips"); -#endif #ifdef TARGET_IS_armpe pe_dll_id_target ("pei-arm-little"); #endif @@ -1760,7 +2057,7 @@ gld_${EMULATION_NAME}_finish (void) #ifdef DLL_SUPPORT if (link_info.shared -#if !defined(TARGET_IS_shpe) && !defined(TARGET_IS_mipspe) +#if !defined(TARGET_IS_shpe) || (!link_info.relocatable && pe_def_file->num_exports != 0) #endif ) @@ -1769,7 +2066,7 @@ gld_${EMULATION_NAME}_finish (void) if (pe_implib_filename) pe_dll_generate_implib (pe_def_file, pe_implib_filename, &link_info); } -#if defined(TARGET_IS_shpe) || defined(TARGET_IS_mipspe) +#if defined(TARGET_IS_shpe) /* ARM doesn't need relocs. */ else { @@ -1816,6 +2113,7 @@ gld_${EMULATION_NAME}_place_orphan (asection *s, char *dollar = NULL; lang_output_section_statement_type *os; lang_statement_list_type add_child; + lang_output_section_statement_type *match_by_name = NULL; lang_statement_union_type **pl; /* Look through the script to see where to place this section. */ @@ -1851,11 +2149,24 @@ gld_${EMULATION_NAME}_place_orphan (asection *s, If the section already exists but does not have any flags set, then it has been created by the linker, probably as a result of a --section-start command line switch. */ - lang_add_section (&add_child, s, os); + lang_add_section (&add_child, s, NULL, os); break; } + + /* Save unused output sections in case we can match them + against orphans later. */ + if (os->bfd_section == NULL) + match_by_name = os; } + /* If we didn't match an active output section, see if we matched an + unused one and use that. */ + if (os == NULL && match_by_name) + { + lang_add_section (&match_by_name->children, s, NULL, match_by_name); + return match_by_name; + } + if (os == NULL) { static struct orphan_save hold[] = @@ -1863,6 +2174,9 @@ gld_${EMULATION_NAME}_place_orphan (asection *s, { ".text", SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE, 0, 0, 0, 0 }, + { ".idata", + SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA, + 0, 0, 0, 0 }, { ".rdata", SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA, 0, 0, 0, 0 }, @@ -1876,6 +2190,7 @@ gld_${EMULATION_NAME}_place_orphan (asection *s, enum orphan_save_index { orphan_text = 0, + orphan_idata, orphan_rodata, orphan_data, orphan_bss @@ -1909,7 +2224,10 @@ gld_${EMULATION_NAME}_place_orphan (asection *s, else if ((s->flags & SEC_READONLY) == 0) place = &hold[orphan_data]; else if ((s->flags & SEC_CODE) == 0) - place = &hold[orphan_rodata]; + { + place = (!strncmp (secname, ".idata\$", 7) ? &hold[orphan_idata] + : &hold[orphan_rodata]); + } else place = &hold[orphan_text]; @@ -1927,10 +2245,17 @@ gld_${EMULATION_NAME}_place_orphan (asection *s, ->output_section_statement); } - /* All sections in an executable must be aligned to a page boundary. */ + /* All sections in an executable must be aligned to a page boundary. + In a relocatable link, just preserve the incoming alignment; the + address is discarded by lang_insert_orphan in that case, anyway. */ address = exp_unop (ALIGN_K, exp_nameop (NAME, "__section_alignment__")); os = lang_insert_orphan (s, secname, constraint, after, place, address, &add_child); + if (link_info.relocatable) + { + os->section_alignment = s->alignment_power; + os->bfd_section->alignment_power = s->alignment_power; + } } /* If the section name has a '\$', sort it with the other '\$' @@ -2003,7 +2328,7 @@ gld_${EMULATION_NAME}_open_dynamic_archive unsigned int i; - if (! entry->is_archive) + if (! entry->flags.maybe_archive || entry->flags.full_name_provided) return FALSE; filename = entry->filename; @@ -2093,7 +2418,7 @@ sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c if test -n "$GENERATE_AUTO_IMPORT_SCRIPT" ; then -echo ' ; else if (link_info.pei386_auto_import == 1) return' >> e${EMULATION_NAME}.c +echo ' ; else if (link_info.pei386_auto_import == 1 && (MERGE_RDATA_V2 || link_info.pei386_runtime_pseudo_reloc != 2)) return' >> e${EMULATION_NAME}.c sed $sc ldscripts/${EMULATION_NAME}.xa >> e${EMULATION_NAME}.c fi echo ' ; else return' >> e${EMULATION_NAME}.c @@ -2129,6 +2454,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = gld_${EMULATION_NAME}_list_options, gld_${EMULATION_NAME}_recognized_file, gld_${EMULATION_NAME}_find_potential_libraries, - NULL /* new_vers_pattern. */ + NULL, /* new_vers_pattern. */ + NULL /* extra_map_file_text. */ }; EOF