summaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2022-01-12 23:42:23 +1030
committerAlan Modra <amodra@gmail.com>2022-01-18 11:18:45 +1030
commit97da0e2677c4a38df2406576428ec27d1da26e7c (patch)
tree3f7a0a7c2dbf856d95a0fb876ec3257f848d316d /ld
parent1f95afb8894820f99682bd9379804f5d2a1e324e (diff)
tweak __ehdr_start visibility and flags for check_relocs
bfd/ * elf-bfd.h (UNDEFWEAK_NO_DYNAMIC_RELOC): Test linker_def. ld/ * ldelf.c (ldelf_before_allocation): Don't force __ehdr_start local and hidden here.. * ldlang.c (lang_symbol_tweaks): ..do so here instead and set def_regular and linker_def for check_relocs. New function extracted from lang_process.
Diffstat (limited to 'ld')
-rw-r--r--ld/ldelf.c5
-rw-r--r--ld/ldlang.c43
2 files changed, 38 insertions, 10 deletions
diff --git a/ld/ldelf.c b/ld/ldelf.c
index 799f779601..121c25d948 100644
--- a/ld/ldelf.c
+++ b/ld/ldelf.c
@@ -1607,11 +1607,6 @@ ldelf_before_allocation (char *audit, char *depaudit,
|| h->root.type == bfd_link_hash_undefweak
|| h->root.type == bfd_link_hash_common))
{
- const struct elf_backend_data *bed;
- bed = get_elf_backend_data (link_info.output_bfd);
- (*bed->elf_backend_hide_symbol) (&link_info, h, true);
- if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL)
- h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
/* Don't leave the symbol undefined. Undefined hidden
symbols typically won't have dynamic relocations, but
we most likely will need dynamic relocations for
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 48e4082863..499a9c7182 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -6995,6 +6995,43 @@ lang_finalize_start_stop (void)
}
static void
+lang_symbol_tweaks (void)
+{
+ /* Give initial values for __start and __stop symbols, so that ELF
+ gc_sections will keep sections referenced by these symbols. Must
+ be done before lang_do_assignments. */
+ if (config.build_constructors)
+ lang_init_start_stop ();
+
+ /* Make __ehdr_start hidden, and set def_regular even though it is
+ likely undefined at this stage. For lang_check_relocs. */
+ if (is_elf_hash_table (link_info.hash)
+ && !bfd_link_relocatable (&link_info))
+ {
+ struct elf_link_hash_entry *h = (struct elf_link_hash_entry *)
+ bfd_link_hash_lookup (link_info.hash, "__ehdr_start",
+ false, false, true);
+
+ /* Only adjust the export class if the symbol was referenced
+ and not defined, otherwise leave it alone. */
+ if (h != NULL
+ && (h->root.type == bfd_link_hash_new
+ || h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_common))
+ {
+ const struct elf_backend_data *bed;
+ bed = get_elf_backend_data (link_info.output_bfd);
+ (*bed->elf_backend_hide_symbol) (&link_info, h, true);
+ if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL)
+ h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
+ h->def_regular = 1;
+ h->root.linker_def = 1;
+ }
+ }
+}
+
+static void
lang_end (void)
{
struct bfd_link_hash_entry *h;
@@ -8210,11 +8247,7 @@ lang_process (void)
files. */
ldctor_build_sets ();
- /* Give initial values for __start and __stop symbols, so that ELF
- gc_sections will keep sections referenced by these symbols. Must
- be done before lang_do_assignments below. */
- if (config.build_constructors)
- lang_init_start_stop ();
+ lang_symbol_tweaks ();
/* PR 13683: We must rerun the assignments prior to running garbage
collection in order to make sure that all symbol aliases are resolved. */