diff options
-rw-r--r-- | ld/ChangeLog | 8 | ||||
-rw-r--r-- | ld/ldexp.c | 22 | ||||
-rw-r--r-- | ld/ldexp.h | 1 | ||||
-rw-r--r-- | ld/pe-dll.c | 12 | ||||
-rw-r--r-- | ld/testsuite/ld-pe/pe.exp | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-pe/reloc.d | 14 | ||||
-rw-r--r-- | ld/testsuite/ld-pe/reloc.s | 13 |
7 files changed, 69 insertions, 3 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog index 0f1da7f..95bb3f6 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,11 @@ +2021-03-04 Jan Beulich <jbeulich@suse.com> + + * ldexp.c (ldexp_is_final_sym_absolute): New. + * ldexp.h (ldexp_is_final_sym_absolute): Declare. + * pe-dll.c (generate_reloc): Skip absolute symbols. + * testsuite/ld-pe/reloc.s, testsuite/ld-pe/reloc.d: New. + * testsuite/ld-pe/pe.exp: Run new test. + 2021-03-03 Alan Modra <amodra@gmail.com> PR 27500 @@ -1699,6 +1699,28 @@ ldexp_finalize_syms (void) bfd_hash_traverse (&definedness_table, set_sym_sections, NULL); } +/* Determine whether a symbol is going to remain absolute even after + ldexp_finalize_syms() has run. */ + +bfd_boolean +ldexp_is_final_sym_absolute (const struct bfd_link_hash_entry *h) +{ + if (h->type == bfd_link_hash_defined + && h->u.def.section == bfd_abs_section_ptr) + { + const struct definedness_hash_entry *def; + + if (!h->ldscript_def) + return TRUE; + + def = symbol_defined (h->root.string); + if (def != NULL) + return def->final_sec == bfd_abs_section_ptr; + } + + return FALSE; +} + void ldexp_finish (void) { @@ -239,6 +239,7 @@ bfd_vma exp_get_abs_int (etree_type *, int, char *); void ldexp_init (void); void ldexp_finalize_syms (void); +bfd_boolean ldexp_is_final_sym_absolute (const struct bfd_link_hash_entry *); void ldexp_finish (void); #endif diff --git a/ld/pe-dll.c b/ld/pe-dll.c index 3c82f8d..afcf6fe 100644 --- a/ld/pe-dll.c +++ b/ld/pe-dll.c @@ -1579,13 +1579,13 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info) && relocs[i]->howto->type != pe_details->imagebase_reloc) { struct bfd_symbol *sym = *relocs[i]->sym_ptr_ptr; + const struct bfd_link_hash_entry *blhe + = bfd_wrapped_link_hash_lookup (abfd, info, sym->name, + FALSE, FALSE, FALSE); /* Don't create relocs for undefined weak symbols. */ if (sym->flags == BSF_WEAK) { - struct bfd_link_hash_entry *blhe - = bfd_wrapped_link_hash_lookup (abfd, info, sym->name, - FALSE, FALSE, FALSE); if (blhe && blhe->type == bfd_link_hash_undefweak) { /* Check aux sym and see if it is defined or not. */ @@ -1617,6 +1617,12 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info) if (!strcmp (s->name, ".eh_frame")) continue; } + /* Nor for absolute symbols. */ + else if (blhe && ldexp_is_final_sym_absolute (blhe) + && (!blhe->linker_def + || (strcmp (sym->name, "__image_base__") + && strcmp (sym->name, U ("__ImageBase"))))) + continue; reloc_data[total_relocs].vma = sec_vma + relocs[i]->address; reloc_data[total_relocs].idx = total_relocs; diff --git a/ld/testsuite/ld-pe/pe.exp b/ld/testsuite/ld-pe/pe.exp index de9e104..b1a2001 100644 --- a/ld/testsuite/ld-pe/pe.exp +++ b/ld/testsuite/ld-pe/pe.exp @@ -76,6 +76,8 @@ run_dump_test "longsecn-5" run_dump_test "orphan" run_dump_test "orphan_nu" +run_dump_test "reloc" + run_dump_test "weakdef-1" run_dump_test "pr19803" diff --git a/ld/testsuite/ld-pe/reloc.d b/ld/testsuite/ld-pe/reloc.d new file mode 100644 index 0000000..55888c3 --- /dev/null +++ b/ld/testsuite/ld-pe/reloc.d @@ -0,0 +1,14 @@ +#name: PE base relocations +#ld: --enable-reloc-section +#objdump: -p + +.*: file format .* + +#... +PE File Base Relocations.* +Virtual Address: .* Number of fixups 4 +[ ]*reloc 0 offset 0 .* (LOW|HIGHLOW|DIR64) +[ ]*reloc 1 offset [248] .* (LOW|HIGHLOW|DIR64) +[ ]*reloc 2 offset [124]0 .* (LOW|HIGHLOW|DIR64) +[ ]*reloc 3 offset 0 .* ABSOLUTE +#pass diff --git a/ld/testsuite/ld-pe/reloc.s b/ld/testsuite/ld-pe/reloc.s new file mode 100644 index 0000000..3ed2e02 --- /dev/null +++ b/ld/testsuite/ld-pe/reloc.s @@ -0,0 +1,13 @@ + .data + .p2align 4 +start: + .dc.a __image_base__ + .dc.a start + .dc.a __section_alignment__ + .dc.a __file_alignment__ + .dc.a __major_os_version__ + .dc.a __minor_os_version__ + .dc.a __major_subsystem_version__ + .dc.a __minor_subsystem_version__ + .dc.a end +end: |