Commit dc4b8c68 by Richard Biener Committed by Richard Biener

re PR lto/81968 (early lto debug objects make Solaris ld SEGV)

2017-09-15  Richard Biener  <rguenther@suse.de>

	PR lto/81968
	* simple-object-elf.c (simple_object_elf_copy_lto_debug_sections):
	Iterate marking dependent sections necessary.

From-SVN: r252807
parent 9d89efeb
2017-09-15 Richard Biener <rguenther@suse.de>
PR lto/81968
* simple-object-elf.c (simple_object_elf_copy_lto_debug_sections):
Iterate marking dependent sections necessary.
2017-09-15 Nathan Sidwell <nathan@acm.org> 2017-09-15 Nathan Sidwell <nathan@acm.org>
* cp-demangle.c (is_fnqual_component_type): Reimplement using * cp-demangle.c (is_fnqual_component_type): Reimplement using
......
...@@ -1158,70 +1158,84 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj, ...@@ -1158,70 +1158,84 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
/* Mark sections as preserved that are required by to be preserved /* Mark sections as preserved that are required by to be preserved
sections. */ sections. */
for (i = 1; i < shnum; ++i) int changed;
do
{ {
unsigned char *shdr; changed = 0;
unsigned int sh_type, sh_info, sh_link; for (i = 1; i < shnum; ++i)
off_t offset;
off_t length;
shdr = shdrs + (i - 1) * shdr_size;
sh_type = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
shdr, sh_type, Elf_Word);
sh_info = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
shdr, sh_info, Elf_Word);
sh_link = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
shdr, sh_link, Elf_Word);
if (sh_type == SHT_GROUP)
{ {
/* Mark groups containing copied sections. */ unsigned char *shdr;
unsigned entsize = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, unsigned int sh_type, sh_info, sh_link;
shdr, sh_entsize, Elf_Addr); off_t offset;
unsigned char *ent, *buf; off_t length;
int keep = 0;
offset = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, shdr = shdrs + (i - 1) * shdr_size;
shdr, sh_offset, Elf_Addr); sh_type = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
length = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, shdr, sh_type, Elf_Word);
shdr, sh_size, Elf_Addr); sh_info = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
buf = XNEWVEC (unsigned char, length); shdr, sh_info, Elf_Word);
if (!simple_object_internal_read (sobj->descriptor, sh_link = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
sobj->offset + offset, buf, shdr, sh_link, Elf_Word);
(size_t) length, &errmsg, err)) if (sh_type == SHT_GROUP)
{ {
XDELETEVEC (buf); /* Mark groups containing copied sections. */
XDELETEVEC (names); unsigned entsize = ELF_FETCH_FIELD (type_functions, ei_class,
XDELETEVEC (shdrs); Shdr, shdr, sh_entsize,
return errmsg; Elf_Addr);
} unsigned char *ent, *buf;
for (ent = buf + entsize; ent < buf + length; ent += entsize) int keep = 0;
{ offset = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
unsigned sec = type_functions->fetch_Elf_Word (ent); shdr, sh_offset, Elf_Addr);
if (pfnret[sec - 1] == 0) length = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
keep = 1; shdr, sh_size, Elf_Addr);
buf = XNEWVEC (unsigned char, length);
if (!simple_object_internal_read (sobj->descriptor,
sobj->offset + offset, buf,
(size_t) length, &errmsg, err))
{
XDELETEVEC (buf);
XDELETEVEC (names);
XDELETEVEC (shdrs);
return errmsg;
}
for (ent = buf + entsize; ent < buf + length; ent += entsize)
{
unsigned sec = type_functions->fetch_Elf_Word (ent);
if (pfnret[sec - 1] == 0)
keep = 1;
}
if (keep)
{
changed |= (pfnret[sh_link - 1] == -1
|| pfnret[i - 1] == -1);
pfnret[sh_link - 1] = 0;
pfnret[i - 1] = 0;
}
} }
if (keep) if (sh_type == SHT_RELA
|| sh_type == SHT_REL)
{ {
pfnret[sh_link - 1] = 0; /* Mark relocation sections and symtab of copied sections. */
pfnret[i - 1] = 0; if (pfnret[sh_info - 1] == 0)
{
changed |= (pfnret[sh_link - 1] == -1
|| pfnret[i - 1] == -1);
pfnret[sh_link - 1] = 0;
pfnret[i - 1] = 0;
}
} }
} if (sh_type == SHT_SYMTAB)
if (sh_type == SHT_RELA
|| sh_type == SHT_REL)
{
/* Mark relocation sections and symtab of copied sections. */
if (pfnret[sh_info - 1] == 0)
{ {
pfnret[sh_link - 1] = 0; /* Mark strings sections of copied symtabs. */
pfnret[i - 1] = 0; if (pfnret[i - 1] == 0)
{
changed |= pfnret[sh_link - 1] == -1;
pfnret[sh_link - 1] = 0;
}
} }
} }
if (sh_type == SHT_SYMTAB)
{
/* Mark strings sections of copied symtabs. */
if (pfnret[i - 1] == 0)
pfnret[sh_link - 1] = 0;
}
} }
while (changed);
/* Then perform the actual copying. */ /* Then perform the actual copying. */
for (i = 1; i < shnum; ++i) for (i = 1; i < shnum; ++i)
......
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