X-Git-Url: http://drtracing.org/?a=blobdiff_plain;ds=sidebyside;f=ld%2Fpe-dll.c;h=f72b6583411847ee327049fb48917a0d8b887db8;hb=1a20473059c7a088b9f3c4188c09976eebbc3ab4;hp=577b911da8a6ffb5b845fee6c4789da1da169c47;hpb=de07a745805b28ed2c973635752719c4a6a32b1d;p=deliverable%2Fbinutils-gdb.git diff --git a/ld/pe-dll.c b/ld/pe-dll.c index 577b911da8..f72b658341 100644 --- a/ld/pe-dll.c +++ b/ld/pe-dll.c @@ -1,5 +1,5 @@ /* Routines to help build PEI-format DLLs (Win32 etc) - Copyright (C) 1998-2019 Free Software Foundation, Inc. + Copyright (C) 1998-2020 Free Software Foundation, Inc. Written by DJ Delorie This file is part of the GNU Binutils. @@ -25,6 +25,7 @@ #include "libiberty.h" #include "filenames.h" #include "safe-ctype.h" +#include "ctf-api.h" #include @@ -159,6 +160,7 @@ int pe_dll_extra_pe_debug = 0; int pe_use_nul_prefixed_import_tables = 0; int pe_use_coff_long_section_names = -1; int pe_leading_underscore = -1; +int pe_dll_enable_reloc_section = 0; /* Static variables and types. */ @@ -278,6 +280,16 @@ static pe_details_type pe_detail_list[] = FALSE, autofilter_symbollist_i386 }, +#else + { + "pei-i386", + "pe-bigobj-i386", + 7 /* R_IMAGEBASE */, + PE_ARCH_i386, + bfd_arch_i386, + TRUE, + autofilter_symbollist_i386 + }, #endif { "pei-shl", @@ -444,16 +456,25 @@ typedef struct bfd_vma vma; char type; short extra; + int idx; } reloc_data_type; static int reloc_sort (const void *va, const void *vb) { - bfd_vma a = ((const reloc_data_type *) va)->vma; - bfd_vma b = ((const reloc_data_type *) vb)->vma; + const reloc_data_type *a = (const reloc_data_type *) va; + const reloc_data_type *b = (const reloc_data_type *) vb; - return (a > b) ? 1 : ((a < b) ? -1 : 0); + if (a->vma > b->vma) + return 1; + if (a->vma < b->vma) + return -1; + if (a->idx > b->idx) + return 1; + if (a->idx < b->idx) + return -1; + return 0; } static int @@ -539,7 +560,7 @@ auto_export (bfd *abfd, def_file *d, const char *n) const char * libname = NULL; if (abfd && abfd->my_archive) - libname = lbasename (abfd->my_archive->filename); + libname = lbasename (bfd_get_filename (abfd->my_archive)); key.name = key.its_name = (char *) n; @@ -573,7 +594,7 @@ auto_export (bfd *abfd, def_file *d, const char *n) /* Next, exclude symbols from certain startup objects. */ - if (abfd && (p = lbasename (abfd->filename))) + if (abfd && (p = lbasename (bfd_get_filename (abfd)))) { afptr = autofilter_objlist; while (afptr->name) @@ -634,7 +655,7 @@ auto_export (bfd *abfd, def_file *d, const char *n) } else if (ex->type == EXCLUDEFORIMPLIB) { - if (filename_cmp (abfd->filename, ex->string) == 0) + if (filename_cmp (bfd_get_filename (abfd), ex->string) == 0) return 0; } else if (strcmp (n, ex->string) == 0) @@ -870,12 +891,9 @@ process_def_file_and_drectve (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info * e[j - 1].flag_constant |= e[i].flag_constant; e[j - 1].flag_noname |= e[i].flag_noname; e[j - 1].flag_data |= e[i].flag_data; - if (e[i].name) - free (e[i].name); - if (e[i].internal_name) - free (e[i].internal_name); - if (e[i].its_name) - free (e[i].its_name); + free (e[i].name); + free (e[i].internal_name); + free (e[i].its_name); } else { @@ -1014,33 +1032,31 @@ build_filler_bfd (int include_edata) { edata_s = bfd_make_section_old_way (filler_bfd, ".edata"); if (edata_s == NULL - || !bfd_set_section_flags (filler_bfd, edata_s, - (SEC_HAS_CONTENTS - | SEC_ALLOC - | SEC_LOAD - | SEC_KEEP - | SEC_IN_MEMORY))) + || !bfd_set_section_flags (edata_s, (SEC_HAS_CONTENTS + | SEC_ALLOC + | SEC_LOAD + | SEC_KEEP + | SEC_IN_MEMORY))) { einfo (_("%X%P: can not create .edata section: %E\n")); return; } - bfd_set_section_size (filler_bfd, edata_s, edata_sz); + bfd_set_section_size (edata_s, edata_sz); } reloc_s = bfd_make_section_old_way (filler_bfd, ".reloc"); if (reloc_s == NULL - || !bfd_set_section_flags (filler_bfd, reloc_s, - (SEC_HAS_CONTENTS - | SEC_ALLOC - | SEC_LOAD - | SEC_KEEP - | SEC_IN_MEMORY))) + || !bfd_set_section_flags (reloc_s, (SEC_HAS_CONTENTS + | SEC_ALLOC + | SEC_LOAD + | SEC_KEEP + | SEC_IN_MEMORY))) { einfo (_("%X%P: can not create .reloc section: %E\n")); return; } - bfd_set_section_size (filler_bfd, reloc_s, 0); + bfd_set_section_size (reloc_s, 0); ldlang_add_file (filler_file); } @@ -1060,7 +1076,7 @@ generate_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED) dll_name = pe_def_file->name; else { - dll_name = abfd->filename; + dll_name = bfd_get_filename (abfd); for (dlnp = dll_name; *dlnp; dlnp++) if (*dlnp == '\\' || *dlnp == '/' || *dlnp == ':') @@ -1202,8 +1218,10 @@ fill_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED) memset (edata_d, 0, edata_sz); - if (pe_data (abfd)->insert_timestamp) + if (pe_data (abfd)->timestamp == -1) H_PUT_32 (abfd, time (0), edata_d + 4); + else + H_PUT_32 (abfd, pe_data (abfd)->timestamp, edata_d + 4); if (pe_def_file->version_major != -1) { @@ -1303,7 +1321,7 @@ pe_walk_relocs (struct bfd_link_info *info, { arelent **relocs; int relsize, nrelocs, i; - int flags = bfd_get_section_flags (b, s); + int flags = bfd_section_flags (s); /* Skip discarded linkonce sections. */ if (flags & SEC_LINK_ONCE @@ -1597,6 +1615,7 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info) } reloc_data[total_relocs].vma = sec_vma + relocs[i]->address; + reloc_data[total_relocs].idx = total_relocs; #define BITS_AND_SHIFT(bits, shift) (bits * 1000 | shift) @@ -1947,8 +1966,8 @@ quick_section (bfd *abfd, const char *name, int flags, int align) asymbol *sym; sec = bfd_make_section_old_way (abfd, name); - bfd_set_section_flags (abfd, sec, flags | SEC_ALLOC | SEC_LOAD | SEC_KEEP); - bfd_set_section_alignment (abfd, sec, align); + bfd_set_section_flags (sec, flags | SEC_ALLOC | SEC_LOAD | SEC_KEEP); + bfd_set_section_alignment (sec, align); /* Remember to undo this before trying to link internally! */ sec->output_section = sec; @@ -2072,7 +2091,7 @@ make_head (bfd *parent) pointer to the list points to the *end* of this section, which is the start of the list of sections from other objects. */ - bfd_set_section_size (abfd, id2, 20); + bfd_set_section_size (id2, 20); d2 = xmalloc (20); id2->contents = d2; memset (d2, 0, 20); @@ -2084,16 +2103,16 @@ make_head (bfd *parent) save_relocs (id2); if (pe_use_nul_prefixed_import_tables) - bfd_set_section_size (abfd, id5, PE_IDATA5_SIZE); + bfd_set_section_size (id5, PE_IDATA5_SIZE); else - bfd_set_section_size (abfd, id5, 0); + bfd_set_section_size (id5, 0); d5 = xmalloc (PE_IDATA5_SIZE); id5->contents = d5; memset (d5, 0, PE_IDATA5_SIZE); if (pe_use_nul_prefixed_import_tables) - bfd_set_section_size (abfd, id4, PE_IDATA4_SIZE); + bfd_set_section_size (id4, PE_IDATA4_SIZE); else - bfd_set_section_size (abfd, id4, 0); + bfd_set_section_size (id4, 0); d4 = xmalloc (PE_IDATA4_SIZE); id4->contents = d4; memset (d4, 0, PE_IDATA4_SIZE); @@ -2154,12 +2173,12 @@ make_tail (bfd *parent) id7 = quick_section (abfd, ".idata$7", SEC_HAS_CONTENTS, 2); quick_symbol (abfd, U (""), dll_symname, "_iname", id7, BSF_GLOBAL, 0); - bfd_set_section_size (abfd, id4, PE_IDATA4_SIZE); + bfd_set_section_size (id4, PE_IDATA4_SIZE); d4 = xmalloc (PE_IDATA4_SIZE); id4->contents = d4; memset (d4, 0, PE_IDATA4_SIZE); - bfd_set_section_size (abfd, id5, PE_IDATA5_SIZE); + bfd_set_section_size (id5, PE_IDATA5_SIZE); d5 = xmalloc (PE_IDATA5_SIZE); id5->contents = d5; memset (d5, 0, PE_IDATA5_SIZE); @@ -2167,7 +2186,7 @@ make_tail (bfd *parent) len = strlen (dll_filename) + 1; if (len & 1) len++; - bfd_set_section_size (abfd, id7, len); + bfd_set_section_size (id7, len); d7 = xmalloc (len); id7->contents = d7; strcpy ((char *) d7, dll_filename); @@ -2339,7 +2358,7 @@ make_one (def_file_export *exp, bfd *parent, bfd_boolean include_jmp_stub) if (include_jmp_stub) { - bfd_set_section_size (abfd, tx, jmp_byte_count); + bfd_set_section_size (tx, jmp_byte_count); td = xmalloc (jmp_byte_count); tx->contents = td; memcpy (td, jmp_bytes, jmp_byte_count); @@ -2374,16 +2393,16 @@ make_one (def_file_export *exp, bfd *parent, bfd_boolean include_jmp_stub) save_relocs (tx); } else - bfd_set_section_size (abfd, tx, 0); + bfd_set_section_size (tx, 0); - bfd_set_section_size (abfd, id7, 4); + bfd_set_section_size (id7, 4); d7 = xmalloc (4); id7->contents = d7; memset (d7, 0, 4); quick_reloc (abfd, 0, BFD_RELOC_RVA, 5); save_relocs (id7); - bfd_set_section_size (abfd, id5, PE_IDATA5_SIZE); + bfd_set_section_size (id5, PE_IDATA5_SIZE); d5 = xmalloc (PE_IDATA5_SIZE); id5->contents = d5; memset (d5, 0, PE_IDATA5_SIZE); @@ -2400,7 +2419,7 @@ make_one (def_file_export *exp, bfd *parent, bfd_boolean include_jmp_stub) save_relocs (id5); } - bfd_set_section_size (abfd, id4, PE_IDATA4_SIZE); + bfd_set_section_size (id4, PE_IDATA4_SIZE); d4 = xmalloc (PE_IDATA4_SIZE); id4->contents = d4; memset (d4, 0, PE_IDATA4_SIZE); @@ -2420,7 +2439,7 @@ make_one (def_file_export *exp, bfd *parent, bfd_boolean include_jmp_stub) if (exp->flag_noname) { len = 0; - bfd_set_section_size (abfd, id6, 0); + bfd_set_section_size (id6, 0); } else { @@ -2433,7 +2452,7 @@ make_one (def_file_export *exp, bfd *parent, bfd_boolean include_jmp_stub) len = 2 + strlen (exp->name) + 1; if (len & 1) len++; - bfd_set_section_size (abfd, id6, len); + bfd_set_section_size (id6, len); d6 = xmalloc (len); id6->contents = d6; memset (d6, 0, len); @@ -2491,7 +2510,7 @@ make_singleton_name_thunk (const char *import, bfd *parent) quick_symbol (abfd, "__nm_", import, "", UNDSEC, BSF_GLOBAL, 0); /* We need space for the real thunk and for the null terminator. */ - bfd_set_section_size (abfd, id4, PE_IDATA4_SIZE * 2); + bfd_set_section_size (id4, PE_IDATA4_SIZE * 2); d4 = xmalloc (PE_IDATA4_SIZE * 2); id4->contents = d4; memset (d4, 0, PE_IDATA4_SIZE * 2); @@ -2568,7 +2587,7 @@ make_import_fixup_entry (const char *name, quick_symbol (abfd, U (""), symname, "_iname", UNDSEC, BSF_GLOBAL, 0); quick_symbol (abfd, "", fixup_name, "", UNDSEC, BSF_GLOBAL, 0); - bfd_set_section_size (abfd, id2, 20); + bfd_set_section_size (id2, 20); d2 = xmalloc (20); id2->contents = d2; memset (d2, 0, 20); @@ -2643,7 +2662,7 @@ make_runtime_pseudo_reloc (const char *name ATTRIBUTE_UNUSED, quick_symbol (abfd, "__imp_", name, "", UNDSEC, BSF_GLOBAL, 0); - bfd_set_section_size (abfd, rt_rel, size); + bfd_set_section_size (rt_rel, size); rt_rel_d = xmalloc (size); rt_rel->contents = rt_rel_d; memset (rt_rel_d, 0, size); @@ -2660,7 +2679,7 @@ make_runtime_pseudo_reloc (const char *name ATTRIBUTE_UNUSED, } else { - bfd_set_section_size (abfd, rt_rel, 8); + bfd_set_section_size (rt_rel, 8); rt_rel_d = xmalloc (8); rt_rel->contents = rt_rel_d; memset (rt_rel_d, 0, 8); @@ -2708,7 +2727,7 @@ pe_create_runtime_relocator_reference (bfd *parent) quick_symbol (abfd, "", U ("_pei386_runtime_relocator"), "", UNDSEC, BSF_NO_FLAGS, 0); - bfd_set_section_size (abfd, extern_rt_rel, PE_IDATA5_SIZE); + bfd_set_section_size (extern_rt_rel, PE_IDATA5_SIZE); extern_rt_rel_d = xcalloc (1, PE_IDATA5_SIZE); extern_rt_rel->contents = extern_rt_rel_d; @@ -2745,7 +2764,7 @@ pe_create_import_fixup (arelent *rel, asection *s, bfd_vma addend, char *name, if (!(name_thunk_sym && name_thunk_sym->type == bfd_link_hash_defined)) { b = make_singleton_name_thunk (name, link_info.output_bfd); - add_bfd_to_link (b, b->filename, &link_info); + add_bfd_to_link (b, bfd_get_filename (b), &link_info); /* If we ever use autoimport, we have to cast text section writable. */ config.text_read_only = FALSE; @@ -2756,7 +2775,7 @@ pe_create_import_fixup (arelent *rel, asection *s, bfd_vma addend, char *name, { b = make_import_fixup_entry (name, fixup_name, symname, link_info.output_bfd); - add_bfd_to_link (b, b->filename, &link_info); + add_bfd_to_link (b, bfd_get_filename (b), &link_info); } } @@ -2772,12 +2791,12 @@ pe_create_import_fixup (arelent *rel, asection *s, bfd_vma addend, char *name, b = make_runtime_pseudo_reloc (name, fixup_name, addend, rel->howto->bitsize, link_info.output_bfd); - add_bfd_to_link (b, b->filename, &link_info); + add_bfd_to_link (b, bfd_get_filename (b), &link_info); if (runtime_pseudo_relocs_created++ == 0) { b = pe_create_runtime_relocator_reference (link_info.output_bfd); - add_bfd_to_link (b, b->filename, &link_info); + add_bfd_to_link (b, bfd_get_filename (b), &link_info); } } @@ -2833,7 +2852,7 @@ pe_dll_generate_implib (def_file *def, const char *impfilename, struct bfd_link_ { if (ex->type != EXCLUDEFORIMPLIB) continue; - found = (filename_cmp (ex->string, ibfd->filename) == 0); + found = (filename_cmp (ex->string, bfd_get_filename (ibfd)) == 0); } /* If it matched, we must open a fresh BFD for it (the original input BFD is still needed for the DLL's final link) and add @@ -2841,10 +2860,11 @@ pe_dll_generate_implib (def_file *def, const char *impfilename, struct bfd_link_ if (found) { bfd *newbfd = bfd_openr (ibfd->my_archive - ? ibfd->my_archive->filename : ibfd->filename, NULL); + ? bfd_get_filename (ibfd->my_archive) + : bfd_get_filename (ibfd), NULL); if (!newbfd) { - einfo (_("%X%P: bfd_openr %s: %E\n"), ibfd->filename); + einfo (_("%X%P: bfd_openr %s: %E\n"), bfd_get_filename (ibfd)); return; } if (ibfd->my_archive) @@ -2857,19 +2877,22 @@ pe_dll_generate_implib (def_file *def, const char *impfilename, struct bfd_link_ if (!bfd_check_format_matches (arbfd, bfd_archive, NULL)) { einfo (_("%X%P: %s(%s): can't find member in non-archive file"), - ibfd->my_archive->filename, ibfd->filename); + bfd_get_filename (ibfd->my_archive), + bfd_get_filename (ibfd)); return; } newbfd = NULL; while ((newbfd = bfd_openr_next_archived_file (arbfd, newbfd)) != 0) { - if (filename_cmp (newbfd->filename, ibfd->filename) == 0) + if (filename_cmp (bfd_get_filename (newbfd), + bfd_get_filename (ibfd)) == 0) break; } if (!newbfd) { einfo (_("%X%P: %s(%s): can't find member in archive"), - ibfd->my_archive->filename, ibfd->filename); + bfd_get_filename (ibfd->my_archive), + bfd_get_filename (ibfd)); return; } } @@ -3226,7 +3249,7 @@ pe_process_import_defs (bfd *output_bfd, struct bfd_link_info *linfo) if (!do_this_dll) { bfd *ar_head = make_head (output_bfd); - add_bfd_to_link (ar_head, ar_head->filename, linfo); + add_bfd_to_link (ar_head, bfd_get_filename (ar_head), linfo); do_this_dll = 1; } exp.internal_name = imp[i].internal_name; @@ -3239,13 +3262,13 @@ pe_process_import_defs (bfd *output_bfd, struct bfd_link_info *linfo) exp.flag_data = imp[i].data; exp.flag_noname = exp.name ? 0 : 1; one = make_one (&exp, output_bfd, (! exp.flag_data) && include_jmp_stub); - add_bfd_to_link (one, one->filename, linfo); + add_bfd_to_link (one, bfd_get_filename (one), linfo); } } if (do_this_dll) { bfd *ar_tail = make_tail (output_bfd); - add_bfd_to_link (ar_tail, ar_tail->filename, linfo); + add_bfd_to_link (ar_tail, bfd_get_filename (ar_tail), linfo); } free (dll_symname); @@ -3280,7 +3303,7 @@ pe_get32 (bfd *abfd, int where) bfd_seek (abfd, (file_ptr) where, SEEK_SET); bfd_bread (b, (bfd_size_type) 4, abfd); - return b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24); + return b[0] + (b[1] << 8) + (b[2] << 16) + ((unsigned) b[3] << 24); } static unsigned int @@ -3288,7 +3311,7 @@ pe_as32 (void *ptr) { unsigned char *b = ptr; - return b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24); + return b[0] + (b[1] << 8) + (b[2] << 16) + ((unsigned) b[3] << 24); } bfd_boolean @@ -3545,7 +3568,14 @@ pe_dll_build_sections (bfd *abfd, struct bfd_link_info *info) process_def_file_and_drectve (abfd, info); if (pe_def_file->num_exports == 0 && !bfd_link_pic (info)) - return; + { + if (pe_dll_enable_reloc_section) + { + build_filler_bfd (0); + pe_output_file_set_long_section_names (filler_bfd); + } + return; + } generate_edata (abfd, info); build_filler_bfd (1); @@ -3564,33 +3594,16 @@ pe_exe_build_sections (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED) void pe_dll_fill_sections (bfd *abfd, struct bfd_link_info *info) { - pe_dll_id_target (bfd_get_target (abfd)); - pe_output_file_set_long_section_names (abfd); - image_base = pe_data (abfd)->pe_opthdr.ImageBase; + pe_exe_fill_sections (abfd, info); - generate_reloc (abfd, info); - if (reloc_sz > 0) + if (edata_s) { - bfd_set_section_size (filler_bfd, reloc_s, reloc_sz); - - /* Resize the sections. */ - lang_reset_memory_regions (); - lang_size_sections (NULL, TRUE); - - /* Redo special stuff. */ - ldemul_after_allocation (); - - /* Do the assignments again. */ - lang_do_assignments (lang_final_phase_enum); + fill_edata (abfd, info); + edata_s->contents = edata_d; } - fill_edata (abfd, info); - if (bfd_link_dll (info)) pe_data (abfd)->dll = 1; - - edata_s->contents = edata_d; - reloc_s->contents = reloc_d; } void @@ -3603,7 +3616,7 @@ pe_exe_fill_sections (bfd *abfd, struct bfd_link_info *info) generate_reloc (abfd, info); if (reloc_sz > 0) { - bfd_set_section_size (filler_bfd, reloc_s, reloc_sz); + bfd_set_section_size (reloc_s, reloc_sz); /* Resize the sections. */ lang_reset_memory_regions ();