diff -pruN binutils/binutils/dlltool.c binutils.new/binutils/dlltool.c --- binutils/binutils/dlltool.c 2012-10-29 11:09:28.000000000 +0100 +++ binutils.new/binutils/dlltool.c 2017-08-16 23:02:08.567923711 +0200 @@ -2290,8 +2290,9 @@ typedef struct #define IDATA5 4 #define IDATA4 5 #define IDATA6 6 +#define TEXTDL 7 -#define NSECS 7 +#define NSECS 8 #define TEXT_SEC_FLAGS \ (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY | SEC_HAS_CONTENTS) @@ -2306,7 +2307,8 @@ static sinfo secdata[NSECS] = INIT_SEC_DATA (IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2), INIT_SEC_DATA (IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2), INIT_SEC_DATA (IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2), - INIT_SEC_DATA (IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1) + INIT_SEC_DATA (IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1), + INIT_SEC_DATA (TEXTDL, ".text_dl", TEXT_SEC_FLAGS, 2) }; #else @@ -2500,7 +2502,7 @@ make_one_lib_file (export_type *exp, int exp_label->section = secdata[RDATA].sec; else #endif - exp_label->section = secdata[TEXT].sec; + exp_label->section = secdata[delay ? TEXTDL : TEXT].sec; exp_label->flags = BSF_GLOBAL; exp_label->value = 0; @@ -2586,6 +2588,7 @@ make_one_lib_file (export_type *exp, int switch (i) { + case TEXTDL: case TEXT: if (! exp->data) { @@ -2671,7 +2674,7 @@ make_one_lib_file (export_type *exp, int rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_64); else rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32); - rel->sym_ptr_ptr = secdata[TEXT].sympp; + rel->sym_ptr_ptr = secdata[delay ? TEXTDL : TEXT].sympp; sec->orelocation = rpp; break; } diff -pruN binutils/ld/emultempl/pe.em binutils.new/ld/emultempl/pe.em --- binutils/ld/emultempl/pe.em 2012-08-07 00:27:52.000000000 +0200 +++ binutils.new/ld/emultempl/pe.em 2017-08-16 22:58:26.037377767 +0200 @@ -1545,25 +1545,113 @@ gld_${EMULATION_NAME}_after_open (void) needed. The following code tries to identify jump stub sections in import libraries which are not referred to by anyone and marks them for exclusion from the final link. */ +#if 0 + LANG_FOR_EACH_INPUT_STATEMENT (is) + { + if (is->the_bfd->my_archive) + { + int is_imp = 0; + asection *sec, *stub_sec = NULL; + + /* See if this is an import library thunk. */ + for (sec = is->the_bfd->sections; sec; sec = sec->next) + { + if (strncmp (sec->name, ".idata\$", 7) == 0) + is_imp = 1; + /* The section containing the jmp stub has code + and has a reloc. */ + if ((sec->flags & SEC_CODE) && sec->reloc_count) + stub_sec = sec; + } + + if (is_imp && stub_sec) + { + asymbol **symbols; + long nsyms, src_count; + struct bfd_link_hash_entry * blhe; + + if (!bfd_generic_link_read_symbols (is->the_bfd)) + { + einfo (_("%B%F: could not read symbols: %E\n"), + is->the_bfd); + return; + } + symbols = bfd_get_outsymbols (is->the_bfd); + nsyms = bfd_get_symcount (is->the_bfd); + + for (src_count = 0; src_count < nsyms; src_count++) + { + printf("Symbol %s in section %d\n", symbols[src_count]->name, symbols[src_count]->section->id); + if (symbols[src_count]->section->id == stub_sec->id) + { + /* This symbol belongs to the section containing + the stub. */ + blhe = bfd_link_hash_lookup (link_info.hash, + symbols[src_count]->name, + FALSE, FALSE, TRUE); + /* If the symbol in the stub section has no other + undefined references, exclude the stub section + from the final link. */ + 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; + } + } + } + } + } +#else LANG_FOR_EACH_INPUT_STATEMENT (is) { if (is->the_bfd->my_archive) { int is_imp = 0; - asection *sec, *stub_sec = NULL; + asection *sec, *stub_sec = NULL, *imp_sec = NULL; /* See if this is an import library thunk. */ for (sec = is->the_bfd->sections; sec; sec = sec->next) { if (strncmp (sec->name, ".idata\$", 7) == 0) - is_imp = 1; + { + asymbol **symbols; + long nsyms, src_count; + int symbols_this_section = 0; + + if (!bfd_generic_link_read_symbols (is->the_bfd)) + { + einfo (_("%B%F: could not read symbols: %E\n"), + is->the_bfd); + return; + } + symbols = bfd_get_outsymbols (is->the_bfd); + nsyms = bfd_get_symcount (is->the_bfd); + + for (src_count = 0; src_count < nsyms; src_count++) + { + if (symbols[src_count]->section->id == sec->id) + { + symbols_this_section++; + printf("Found import section %s symbols %s\n", sec->name, symbols[src_count]->name); + } + } + is_imp = 1; + if (symbols_this_section > 1 && imp_sec == NULL) + imp_sec = sec; + } /* The section containing the jmp stub has code and has a reloc. */ if ((sec->flags & SEC_CODE) && sec->reloc_count) - stub_sec = sec; + { + printf("Found stub code section %s\n", sec->name); + stub_sec = sec; + } } - if (is_imp && stub_sec) + if (is_imp + && stub_sec + && strcmp(stub_sec->name, ".text_dl")) { asymbol **symbols; long nsyms, src_count; @@ -1592,14 +1680,39 @@ gld_${EMULATION_NAME}_after_open (void) from the final link. */ if (blhe != NULL && blhe->type == bfd_link_hash_defined - && blhe->u.undef.next == NULL + && blhe->u.def.next == NULL && blhe != link_info.hash->undefs_tail) - stub_sec->flags |= SEC_EXCLUDE; - } + { + printf("Excluding section for symbol %s\n", symbols[src_count]->name); + printf("Stub section was %s, idata section was %s\n", stub_sec->name, imp_sec->name); + stub_sec->flags |= SEC_EXCLUDE; + } + } + if (symbols[src_count]->section->id == imp_sec->id) + { + struct bfd_link_hash_entry *next_entry; + int undef_count = 0; + printf("Import section symbol %s\n", symbols[src_count]->name); + blhe = bfd_link_hash_lookup (link_info.hash, + symbols[src_count]->name, + FALSE, FALSE, TRUE); + if (blhe != NULL) + { + next_entry = blhe; + while (next_entry != NULL) + { + printf(" Reference type %d, section %s\n", next_entry->type, next_entry->u.def.section->name); + undef_count++; + next_entry = next_entry->u.undef.next; + } + printf("Import section symbol %s has type %d, undef %p (%d), %p vs %p\n", symbols[src_count]->name, blhe->type, blhe->u.undef.next, undef_count, blhe, link_info.hash->undefs_tail); + } + } } } } } +#endif } } diff -pruN binutils/ld/scripttempl/pe.sc binutils.new/ld/scripttempl/pe.sc --- binutils/ld/scripttempl/pe.sc 2012-10-18 19:42:29.000000000 +0200 +++ binutils.new/ld/scripttempl/pe.sc 2017-08-16 23:05:03.790078361 +0200 @@ -73,6 +73,7 @@ SECTIONS { ${RELOCATING+ *(.init)} *(.text) + *(.text_dl) ${R_TEXT} ${RELOCATING+ *(.text.*)} ${RELOCATING+ *(.gnu.linkonce.t.*)}