Commit d23db385 by Martin Liska Committed by Martin Liska

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
parent b5a6addb
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> 2019-08-12 Martin Liska <mliska@suse.cz>
* Makefile.in: Add filedescriptor.c. * Makefile.in: Add filedescriptor.c.
......
...@@ -1366,30 +1366,17 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj, ...@@ -1366,30 +1366,17 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
return errmsg; return errmsg;
} }
/* If we are processing .symtab purge __gnu_lto_slim symbol /* If we are processing .symtab purge any symbols
from it and any symbols in discarded sections. */ in discarded sections. */
if (sh_type == SHT_SYMTAB) if (sh_type == SHT_SYMTAB)
{ {
unsigned entsize = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, unsigned entsize = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
shdr, sh_entsize, Elf_Addr); shdr, sh_entsize, Elf_Addr);
unsigned strtab = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, unsigned strtab = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
shdr, sh_link, Elf_Word); shdr, sh_link, Elf_Word);
unsigned char *strshdr = shdrs + (strtab - 1) * shdr_size; size_t prevailing_name_idx = 0;
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;
unsigned char *ent; unsigned char *ent;
unsigned *shndx_table = NULL; 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. */ /* Read the section index table if present. */
if (symtab_indices_shndx[i - 1] != 0) if (symtab_indices_shndx[i - 1] != 0)
{ {
...@@ -1404,6 +1391,45 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj, ...@@ -1404,6 +1391,45 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
(unsigned char *)shndx_table, (unsigned char *)shndx_table,
sidxsz, &errmsg, err); 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) for (ent = buf; ent < buf + length; ent += entsize)
{ {
unsigned st_shndx = ELF_FETCH_FIELD (type_functions, ei_class, 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, ...@@ -1426,9 +1452,10 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
if (st_shndx == SHN_XINDEX) if (st_shndx == SHN_XINDEX)
st_shndx = type_functions->fetch_Elf_Word st_shndx = type_functions->fetch_Elf_Word
((unsigned char *)(shndx_table + (ent - buf) / entsize)); ((unsigned char *)(shndx_table + (ent - buf) / entsize));
/* Eliminate all COMMONs - this includes __gnu_lto_v1 /* Eliminate all COMMONs - this includes __gnu_lto_slim
and __gnu_lto_slim which otherwise cause endless which otherwise cause endless LTO plugin invocation.
LTO plugin invocation. */ FIXME: remove the condition once we remove emission
of __gnu_lto_slim symbol. */
if (st_shndx == SHN_COMMON) if (st_shndx == SHN_COMMON)
discard = 1; discard = 1;
/* We also need to remove symbols refering to sections /* We also need to remove symbols refering to sections
...@@ -1460,12 +1487,13 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj, ...@@ -1460,12 +1487,13 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
else else
{ {
/* Make discarded global symbols hidden weak /* 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; bind = STB_WEAK;
other = STV_HIDDEN; other = STV_HIDDEN;
ELF_SET_FIELD (type_functions, ei_class, Sym, ELF_SET_FIELD (type_functions, ei_class, Sym,
ent, st_name, Elf_Word, ent, st_name, Elf_Word,
gnu_lto - strings); prevailing_name_idx);
ELF_SET_FIELD (type_functions, ei_class, Sym, ELF_SET_FIELD (type_functions, ei_class, Sym,
ent, st_shndx, Elf_Half, SHN_UNDEF); ent, st_shndx, Elf_Half, SHN_UNDEF);
} }
...@@ -1482,7 +1510,6 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj, ...@@ -1482,7 +1510,6 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
ELF_SET_FIELD (type_functions, ei_class, Sym, ELF_SET_FIELD (type_functions, ei_class, Sym,
ent, st_shndx, Elf_Half, sh_map[st_shndx]); ent, st_shndx, Elf_Half, sh_map[st_shndx]);
} }
XDELETEVEC (strings);
XDELETEVEC (shndx_table); XDELETEVEC (shndx_table);
} }
else if (sh_type == SHT_GROUP) else if (sh_type == SHT_GROUP)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment