summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2017-06-14 05:38:18 -0700
committerH.J. Lu <hjl.tools@gmail.com>2017-06-15 04:07:29 -0700
commit1fcda1fa00cf64039c12eca99b5673f3dba312ff (patch)
tree693a00fd54d907ed580ec4d843f07805bc56623e
parent08c7881b814c546efc3996fd1decdf0877f7a779 (diff)
downloadbinutils-gdb-1fcda1fa00cf64039c12eca99b5673f3dba312ff.tar.gz
ELF: Hide .startof.SECNAME and .sizeof.SECNAME
Exporting .startof.SECNAME and .sizeof.SECNAME as dynamic symbols may lead to unexpected behavior. Reference to .startof.SECNAME and .sizeof.SECNAME to section SECNAME within a DSO will be resolved to .startof.SECNAME and .sizeof.SECNAME in another DSO or executable. This patch marks .startof.SECNAME and .sizeof.SECNAME as hidden. bfd/ PR ld/21593 * elf-bfd.h (_bfd_elf_link_setup_section_symbols): New. * elflink.c (elf_lookup_and_hide_section_symbol): New function. (_bfd_elf_link_setup_section_symbols): Likewise. ld/ PR ld/21593 * emultempl/elf32.em (gld${EMULATION_NAME}_after_open): Call _bfd_elf_link_setup_section_symbols. * testsuite/ld-elf/sizeofb.d: Expect local .sizeof.scnfoo. * testsuite/ld-elf/startofb.d: Expect local .startof.scnfoo.
-rw-r--r--bfd/elf-bfd.h3
-rw-r--r--bfd/elflink.c67
-rw-r--r--ld/emultempl/elf32.em57
-rw-r--r--ld/testsuite/ld-elf/sizeofb.d2
-rw-r--r--ld/testsuite/ld-elf/startofb.d2
5 files changed, 73 insertions, 58 deletions
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index fe15b93342a..bc7e128bab6 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -2273,6 +2273,9 @@ extern bfd_reloc_status_type bfd_elf_perform_complex_relocation
extern bfd_boolean _bfd_elf_setup_sections
(bfd *);
+extern void _bfd_elf_link_setup_section_symbols
+ (struct bfd_link_info *);
+
extern void _bfd_elf_post_process_headers (bfd * , struct bfd_link_info *);
extern const bfd_target *bfd_elf32_object_p
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 9b0f5443520..ff1fc44b358 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -14193,3 +14193,70 @@ elf_append_rel (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
BFD_ASSERT (loc + bed->s->sizeof_rel <= s->contents + s->size);
bed->s->swap_reloc_out (abfd, rel, loc);
}
+
+/* Lookup and hide SYMBOL for section SEC. */
+
+static void
+elf_lookup_and_hide_section_symbol (struct bfd_link_info *info,
+ const char *symbol, asection *sec)
+{
+ struct elf_link_hash_entry *h
+ = elf_link_hash_lookup (elf_hash_table (info), symbol, FALSE,
+ FALSE, TRUE);
+ if (h != NULL
+ && (h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak)
+ && h->u2.start_stop_section == NULL)
+ {
+ h->start_stop = 1;
+ h->u2.start_stop_section = sec;
+ _bfd_elf_link_hash_hide_symbol (info, h, TRUE);
+ if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL)
+ h->other = ((h->other & ~ELF_ST_VISIBILITY (-1))
+ | STV_HIDDEN);
+ }
+}
+
+/* Check for input sections whose names match references to
+ __start_SECNAME, __stop_SECNAME, .startof.SECNAME or
+ .sizeof.SECNAME symbols. Mark the matched symbols as hidden
+ and set start_stop for garbage collection. */
+
+void
+_bfd_elf_link_setup_section_symbols (struct bfd_link_info *info)
+{
+ bfd *abfd;
+ asection *s;
+ char leading_char = bfd_get_symbol_leading_char (info->output_bfd);
+
+ for (abfd = info->input_bfds; abfd; abfd = abfd->link.next)
+ for (s = abfd->sections; s; s = s->next)
+ {
+ const char *ps;
+ const char *name = bfd_get_section_name (abfd, s);
+ char *symbol = (char *) xmalloc (strlen (name) + 10);
+
+ sprintf (symbol, ".startof.%s", name);
+ elf_lookup_and_hide_section_symbol (info, symbol, s);
+
+ sprintf (symbol, ".sizeof.%s", name);
+ elf_lookup_and_hide_section_symbol (info, symbol, s);
+
+ for (ps = name; *ps != '\0'; ps++)
+ if (!ISALNUM ((unsigned char) *ps) && *ps != '_')
+ break;
+ if (*ps == '\0')
+ {
+
+ symbol[0] = leading_char;
+ sprintf (symbol + (leading_char != 0), "__start_%s", name);
+ elf_lookup_and_hide_section_symbol (info, symbol, s);
+
+ symbol[0] = leading_char;
+ sprintf (symbol + (leading_char != 0), "__stop_%s", name);
+ elf_lookup_and_hide_section_symbol (info, symbol, s);
+ }
+
+ free (symbol);
+ }
+}
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index 9468f7d29f2..27300a31a77 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -1218,7 +1218,6 @@ gld${EMULATION_NAME}_after_open (void)
struct elf_link_hash_table *htab;
asection *s;
bfd *abfd;
- char leading_char;
after_open_default ();
@@ -1277,61 +1276,7 @@ gld${EMULATION_NAME}_after_open (void)
return;
}
- leading_char = bfd_get_symbol_leading_char (link_info.output_bfd);
-
- /* Check for input sections whose names match references to
- __start_SECNAME or __stop_SECNAME symbols. Mark the matched
- symbols as hidden and set start_stop for garbage collection. */
- for (abfd = link_info.input_bfds; abfd; abfd = abfd->link.next)
- for (s = abfd->sections; s; s = s->next)
- {
- const char *name = bfd_get_section_name (abfd, s);
- const char *ps;
-
- for (ps = name; *ps != '\0'; ps++)
- if (!ISALNUM ((unsigned char) *ps) && *ps != '_')
- break;
- if (*ps == '\0')
- {
- struct elf_link_hash_entry *h;
- char *symbol = (char *) xmalloc (ps - name
- + sizeof "__start_" + 1);
-
- symbol[0] = leading_char;
- sprintf (symbol + (leading_char != 0), "__start_%s", name);
- h = elf_link_hash_lookup (elf_hash_table (&link_info),
- symbol, FALSE, FALSE, TRUE);
- if (h != NULL
- && (h->root.type == bfd_link_hash_undefined
- || h->root.type == bfd_link_hash_undefweak)
- && h->u2.start_stop_section == NULL)
- {
- h->start_stop = 1;
- h->u2.start_stop_section = s;
- _bfd_elf_link_hash_hide_symbol (&link_info, h, TRUE);
- if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL)
- h->other = ((h->other & ~ELF_ST_VISIBILITY (-1))
- | STV_HIDDEN);
- }
-
- symbol[0] = leading_char;
- sprintf (symbol + (leading_char != 0), "__stop_%s", name);
- h = elf_link_hash_lookup (elf_hash_table (&link_info),
- symbol, FALSE, FALSE, TRUE);
- if (h != NULL
- && (h->root.type == bfd_link_hash_undefined
- || h->root.type == bfd_link_hash_undefweak)
- && h->u2.start_stop_section == NULL)
- {
- h->start_stop = 1;
- h->u2.start_stop_section = s;
- _bfd_elf_link_hash_hide_symbol (&link_info, h, TRUE);
- if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL)
- h->other = ((h->other & ~ELF_ST_VISIBILITY (-1))
- | STV_HIDDEN);
- }
- }
- }
+ _bfd_elf_link_setup_section_symbols (&link_info);
if (!link_info.traditional_format)
{
diff --git a/ld/testsuite/ld-elf/sizeofb.d b/ld/testsuite/ld-elf/sizeofb.d
index cd3920b006d..15f46c386e0 100644
--- a/ld/testsuite/ld-elf/sizeofb.d
+++ b/ld/testsuite/ld-elf/sizeofb.d
@@ -13,5 +13,5 @@ Symbol table '\.dynsym' contains [0-9]+ entries:
#...
+[0-9]+: +[a-f0-9]+ +0 +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__stop_scnfoo
#...
- +[0-9]+: 0+10 + +0 +NOTYPE +GLOBAL +DEFAULT +ABS +.sizeof.scnfoo
+ +[0-9]+: 0+10 + +0 +NOTYPE +LOCAL +DEFAULT +ABS +.sizeof.scnfoo
#pass
diff --git a/ld/testsuite/ld-elf/startofb.d b/ld/testsuite/ld-elf/startofb.d
index 0d1da663bdd..477e9c7d5a1 100644
--- a/ld/testsuite/ld-elf/startofb.d
+++ b/ld/testsuite/ld-elf/startofb.d
@@ -11,7 +11,7 @@ Symbol table '\.dynsym' contains [0-9]+ entries:
+Num: +Value +Size Type +Bind +Vis +Ndx Name
+0: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND +
#...
- +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +.startof.scnfoo
+ +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +LOCAL +DEFAULT +[0-9]+ +.startof.scnfoo
#...
+[0-9]+: +[a-f0-9]+ +0 +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__start_scnfoo
#pass