diff options
author | Martin Liska <mliska@suse.cz> | 2019-08-27 15:36:15 +0200 |
---|---|---|
committer | Martin Liska <marxin@gcc.gnu.org> | 2019-08-27 13:36:15 +0000 |
commit | d23db3858e7779b7a42ef3533e6c4c299cb026c7 (patch) | |
tree | c461b234939553ca119d3a63a5831c5cd312ebf8 /libiberty | |
parent | b5a6addb5b60ff6232d1e11367b44f969d2a3e8f (diff) | |
download | gcc-d23db3858e7779b7a42ef3533e6c4c299cb026c7.zip gcc-d23db3858e7779b7a42ef3533e6c4c299cb026c7.tar.gz gcc-d23db3858e7779b7a42ef3533e6c4c299cb026c7.tar.bz2 |
Share a prevailing name for remove debug info symbols w/ LTO.
2019-08-27 Martin Liska <mliska@suse.cz>
PR lto/91478
* simple-object-elf.c (simple_object_elf_copy_lto_debug_sections):
First find a WEAK HIDDEN symbol in symbol table that will be
preserved. Later, use the symbol name for all removed symbols.
From-SVN: r274955
Diffstat (limited to 'libiberty')
-rw-r--r-- | libiberty/ChangeLog | 7 | ||||
-rw-r--r-- | libiberty/simple-object-elf.c | 71 |
2 files changed, 56 insertions, 22 deletions
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index c1fe2f6..cf101e7 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,10 @@ +2019-08-27 Martin Liska <mliska@suse.cz> + + PR lto/91478 + * simple-object-elf.c (simple_object_elf_copy_lto_debug_sections): + First find a WEAK HIDDEN symbol in symbol table that will be + preserved. Later, use the symbol name for all removed symbols. + 2019-08-12 Martin Liska <mliska@suse.cz> * Makefile.in: Add filedescriptor.c. diff --git a/libiberty/simple-object-elf.c b/libiberty/simple-object-elf.c index 7515926..03ca424 100644 --- a/libiberty/simple-object-elf.c +++ b/libiberty/simple-object-elf.c @@ -1366,30 +1366,17 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj, return errmsg; } - /* If we are processing .symtab purge __gnu_lto_slim symbol - from it and any symbols in discarded sections. */ + /* If we are processing .symtab purge any symbols + in discarded sections. */ if (sh_type == SHT_SYMTAB) { unsigned entsize = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, shdr, sh_entsize, Elf_Addr); unsigned strtab = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, shdr, sh_link, Elf_Word); - unsigned char *strshdr = shdrs + (strtab - 1) * shdr_size; - off_t stroff = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, - strshdr, sh_offset, Elf_Addr); - size_t strsz = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, - strshdr, sh_size, Elf_Addr); - char *strings = XNEWVEC (char, strsz); - char *gnu_lto = strings; + size_t prevailing_name_idx = 0; unsigned char *ent; unsigned *shndx_table = NULL; - simple_object_internal_read (sobj->descriptor, - sobj->offset + stroff, - (unsigned char *)strings, - strsz, &errmsg, err); - /* Find first '\0' in strings. */ - gnu_lto = (char *) memchr (gnu_lto + 1, '\0', - strings + strsz - gnu_lto); /* Read the section index table if present. */ if (symtab_indices_shndx[i - 1] != 0) { @@ -1404,6 +1391,45 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj, (unsigned char *)shndx_table, sidxsz, &errmsg, err); } + + /* Find a WEAK HIDDEN symbol which name we will use for removed + symbols. We know there's a prevailing weak hidden symbol + at the start of the .debug_info section. */ + for (ent = buf; ent < buf + length; ent += entsize) + { + unsigned st_shndx = ELF_FETCH_FIELD (type_functions, ei_class, + Sym, ent, + st_shndx, Elf_Half); + unsigned char *st_info; + unsigned char *st_other; + if (ei_class == ELFCLASS32) + { + st_info = &((Elf32_External_Sym *)ent)->st_info; + st_other = &((Elf32_External_Sym *)ent)->st_other; + } + else + { + st_info = &((Elf64_External_Sym *)ent)->st_info; + st_other = &((Elf64_External_Sym *)ent)->st_other; + } + if (st_shndx == SHN_XINDEX) + st_shndx = type_functions->fetch_Elf_Word + ((unsigned char *)(shndx_table + (ent - buf) / entsize)); + + if (st_shndx != SHN_COMMON + && !(st_shndx != SHN_UNDEF + && st_shndx < shnum + && pfnret[st_shndx - 1] == -1) + && ELF_ST_BIND (*st_info) == STB_WEAK + && *st_other == STV_HIDDEN) + { + prevailing_name_idx = ELF_FETCH_FIELD (type_functions, + ei_class, Sym, ent, + st_name, Elf_Word); + break; + } + } + for (ent = buf; ent < buf + length; ent += entsize) { unsigned st_shndx = ELF_FETCH_FIELD (type_functions, ei_class, @@ -1426,9 +1452,10 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj, if (st_shndx == SHN_XINDEX) st_shndx = type_functions->fetch_Elf_Word ((unsigned char *)(shndx_table + (ent - buf) / entsize)); - /* Eliminate all COMMONs - this includes __gnu_lto_v1 - and __gnu_lto_slim which otherwise cause endless - LTO plugin invocation. */ + /* Eliminate all COMMONs - this includes __gnu_lto_slim + which otherwise cause endless LTO plugin invocation. + FIXME: remove the condition once we remove emission + of __gnu_lto_slim symbol. */ if (st_shndx == SHN_COMMON) discard = 1; /* We also need to remove symbols refering to sections @@ -1460,12 +1487,13 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj, else { /* Make discarded global symbols hidden weak - undefined and sharing the gnu_lto_ name. */ + undefined and sharing a name of a prevailing + symbol. */ bind = STB_WEAK; other = STV_HIDDEN; ELF_SET_FIELD (type_functions, ei_class, Sym, ent, st_name, Elf_Word, - gnu_lto - strings); + prevailing_name_idx); ELF_SET_FIELD (type_functions, ei_class, Sym, ent, st_shndx, Elf_Half, SHN_UNDEF); } @@ -1482,7 +1510,6 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj, ELF_SET_FIELD (type_functions, ei_class, Sym, ent, st_shndx, Elf_Half, sh_map[st_shndx]); } - XDELETEVEC (strings); XDELETEVEC (shndx_table); } else if (sh_type == SHT_GROUP) |