diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2017-06-14 05:38:18 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2017-06-15 04:07:29 -0700 |
commit | 1fcda1fa00cf64039c12eca99b5673f3dba312ff (patch) | |
tree | 693a00fd54d907ed580ec4d843f07805bc56623e | |
parent | 08c7881b814c546efc3996fd1decdf0877f7a779 (diff) | |
download | binutils-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.h | 3 | ||||
-rw-r--r-- | bfd/elflink.c | 67 | ||||
-rw-r--r-- | ld/emultempl/elf32.em | 57 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/sizeofb.d | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/startofb.d | 2 |
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 |