From e9301e762ab6d533f7110d6c9c1dbe8e68e875d7 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Tue, 17 Apr 2018 13:53:38 +0100 Subject: [PATCH] Resync libiberty sources with master version in GCC repository. 2018-04-13 Rainer Orth PR lto/81968 * simple-object.c (handle_lto_debug_sections): Keep .comment section. 2018-03-02 David Malcolm * cp-demangle.c: Update URL for g++ V3 ABI. 2018-01-20 Eli Zaretskii * simple-object-xcoff.c (simple_object_xcoff_find_sections): Use ulong_type to avoid warning about 32-bit shift. 2018-01-11 Richard Biener Rainer Orth PR lto/81968 * simple-object-common.h (struct simple_object_functions): Change copy_lto_debug_sections callback signature. * simple-object-elf.c (SHN_HIRESERVE, SHT_SYMTAB_SHNDX, SHF_INFO_LINK): Add defines. (simple_object_elf_copy_lto_debug_sections): Instead of leaving not to be copied sections empty unnamed SHT_NULL remove them from the target section headers and adjust section reference everywhere. Handle SHN_XINDEX in the symbol table processing properly. * simple-object.c (handle_lto_debug_sections): Change interface to return a modified string and handle renaming of relocation sections. 2018-01-10 Daniel van Gerpen * argv.c (expandargv): Correct check for dynamically allocated argv. --- libiberty/ChangeLog | 39 +++- libiberty/argv.c | 6 +- libiberty/cp-demangle.c | 2 +- libiberty/simple-object-common.h | 2 +- libiberty/simple-object-elf.c | 384 +++++++++++++++++++------------ libiberty/simple-object-xcoff.c | 13 +- libiberty/simple-object.c | 41 ++-- 7 files changed, 314 insertions(+), 173 deletions(-) diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 5e96b8b11b3..742b2fa48d7 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,8 +1,39 @@ -2018-01-27 Eli Zaretskii +2018-04-13 Rainer Orth - * simple-object-xcoff.c (simple_object_xcoff_find_sections): Avoid - compilation warning in 32-bit builds not supported by - AC_SYS_LARGEFILE. + PR lto/81968 + * simple-object.c (handle_lto_debug_sections): Keep .comment + section. + +2018-03-02 David Malcolm + + * cp-demangle.c: Update URL for g++ V3 ABI. + +2018-01-20 Eli Zaretskii + + * simple-object-xcoff.c (simple_object_xcoff_find_sections): Use + ulong_type to avoid warning about 32-bit shift. + +2018-01-11 Richard Biener + Rainer Orth + + PR lto/81968 + * simple-object-common.h (struct simple_object_functions): + Change copy_lto_debug_sections callback signature. + * simple-object-elf.c (SHN_HIRESERVE, SHT_SYMTAB_SHNDX, + SHF_INFO_LINK): Add defines. + (simple_object_elf_copy_lto_debug_sections): Instead of + leaving not to be copied sections empty unnamed SHT_NULL + remove them from the target section headers and adjust section + reference everywhere. Handle SHN_XINDEX in the symbol table + processing properly. + * simple-object.c (handle_lto_debug_sections): Change + interface to return a modified string and handle renaming + of relocation sections. + +2018-01-10 Daniel van Gerpen + + * argv.c (expandargv): Correct check for dynamically + allocated argv. 2018-01-03 Jakub Jelinek diff --git a/libiberty/argv.c b/libiberty/argv.c index c6a79d215e3..4f66c8979b2 100644 --- a/libiberty/argv.c +++ b/libiberty/argv.c @@ -367,8 +367,8 @@ expandargv (int *argcp, char ***argvp) { /* The argument we are currently processing. */ int i = 0; - /* Non-zero if ***argvp has been dynamically allocated. */ - int argv_dynamic = 0; + /* To check if ***argvp has been dynamically allocated. */ + char ** const original_argv = *argvp; /* Limit the number of response files that we parse in order to prevent infinite recursion. */ unsigned int iteration_limit = 2000; @@ -449,7 +449,7 @@ expandargv (int *argcp, char ***argvp) /* Parse the string. */ file_argv = buildargv (buffer); /* If *ARGVP is not already dynamically allocated, copy it. */ - if (!argv_dynamic) + if (*argvp == original_argv) *argvp = dupargv (*argvp); /* Count the number of arguments. */ file_argc = 0; diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index 1d5b855ddf2..3f2a097e7f2 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -30,7 +30,7 @@ /* This code implements a demangler for the g++ V3 ABI. The ABI is described on this web page: - http://www.codesourcery.com/cxx-abi/abi.html#mangling + https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling This code was written while looking at the demangler written by Alex Samuel . diff --git a/libiberty/simple-object-common.h b/libiberty/simple-object-common.h index 53501df8fd9..858209f9b05 100644 --- a/libiberty/simple-object-common.h +++ b/libiberty/simple-object-common.h @@ -145,7 +145,7 @@ struct simple_object_functions /* Copy LTO debug sections. */ const char *(*copy_lto_debug_sections) (simple_object_read *sobj, simple_object_write *dobj, - int (*pfn) (const char **), + char *(*pfn) (const char *), int *err); }; diff --git a/libiberty/simple-object-elf.c b/libiberty/simple-object-elf.c index b249146fc60..7468a1adc3d 100644 --- a/libiberty/simple-object-elf.c +++ b/libiberty/simple-object-elf.c @@ -126,6 +126,7 @@ typedef struct { #define SHN_LORESERVE 0xFF00 /* Begin range of reserved indices */ #define SHN_COMMON 0xFFF2 /* Associated symbol is in common */ #define SHN_XINDEX 0xFFFF /* Section index is held elsewhere */ +#define SHN_HIRESERVE 0xffff /* End of reserved indices */ /* 32-bit ELF program header. */ @@ -193,9 +194,11 @@ typedef struct { #define SHT_RELA 4 /* Relocation entries with addends */ #define SHT_REL 9 /* Relocation entries, no addends */ #define SHT_GROUP 17 /* Section contains a section group */ +#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ /* Values for sh_flags field. */ +#define SHF_INFO_LINK 0x00000040 /* `sh_info' contains SHT index */ #define SHF_EXECINSTR 0x00000004 /* Executable section. */ #define SHF_EXCLUDE 0x80000000 /* Link editor is to exclude this section from executable and @@ -1070,7 +1073,7 @@ simple_object_elf_release_write (void *data) static const char * simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj, simple_object_write *dobj, - int (*pfn) (const char **), + char *(*pfn) (const char *), int *err) { struct simple_object_elf_read *eor = @@ -1091,7 +1094,10 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj, int changed; int *pfnret; const char **pfnname; + unsigned new_i; + unsigned *sh_map; unsigned first_shndx = 0; + unsigned int *symtab_indices_shndx; shdr_size = (ei_class == ELFCLASS32 ? sizeof (Elf32_External_Shdr) @@ -1130,18 +1136,20 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj, return errmsg; } - eow->shdrs = XNEWVEC (unsigned char, shdr_size * (shnum - 1)); pfnret = XNEWVEC (int, shnum); pfnname = XNEWVEC (const char *, shnum); + /* Map of symtab to index section. */ + symtab_indices_shndx = XCNEWVEC (unsigned int, shnum - 1); + /* First perform the callbacks to know which sections to preserve and what name to use for those. */ for (i = 1; i < shnum; ++i) { unsigned char *shdr; - unsigned int sh_name; + unsigned int sh_name, sh_type; const char *name; - int ret; + char *ret; shdr = shdrs + (i - 1) * shdr_size; sh_name = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, @@ -1156,12 +1164,28 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj, name = (const char *) names + sh_name; - ret = (*pfn) (&name); - pfnret[i - 1] = ret == 1 ? 0 : -1; - pfnname[i - 1] = name; + ret = (*pfn) (name); + pfnret[i - 1] = ret == NULL ? -1 : 0; + pfnname[i - 1] = ret == NULL ? name : ret; if (first_shndx == 0 && pfnret[i - 1] == 0) first_shndx = i; + + /* Remember the indexes of existing SHT_SYMTAB_SHNDX sections. */ + sh_type = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, + shdr, sh_type, Elf_Word); + if (sh_type == SHT_SYMTAB_SHNDX) + { + unsigned int sh_link; + sh_link = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, + shdr, sh_link, Elf_Word); + symtab_indices_shndx[sh_link - 1] = i; + /* Always discard the extended index sections, after + copying it will not be needed. This way we don't need to + update it and deal with the ordering constraints of + processing the existing symtab and changing the index. */ + pfnret[i - 1] = -1; + } } /* Mark sections as preserved that are required by to be preserved @@ -1244,7 +1268,26 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj, } while (changed); + /* Compute a mapping of old -> new section numbers. */ + sh_map = XNEWVEC (unsigned, shnum); + sh_map[0] = 0; + new_i = 1; + for (i = 1; i < shnum; ++i) + { + if (pfnret[i - 1] == -1) + sh_map[i] = 0; + else + sh_map[i] = new_i++; + } + if (new_i - 1 >= SHN_LORESERVE) + { + *err = ENOTSUP; + return "Too many copied sections"; + } + eow->shdrs = XNEWVEC (unsigned char, shdr_size * (new_i - 1)); + /* Then perform the actual copying. */ + new_i = 0; for (i = 1; i < shnum; ++i) { unsigned char *shdr; @@ -1252,11 +1295,14 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj, const char *name; off_t offset; off_t length; - int ret; simple_object_write_section *dest; off_t flags; unsigned char *buf; + if (pfnret[i - 1]) + continue; + + new_i++; shdr = shdrs + (i - 1) * shdr_size; sh_name = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, shdr, sh_name, Elf_Word); @@ -1265,10 +1311,11 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj, *err = 0; XDELETEVEC (names); XDELETEVEC (shdrs); + XDELETEVEC (symtab_indices_shndx); return "ELF section name out of range"; } - name = (const char *) names + sh_name; + name = pfnname[i - 1]; offset = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, shdr, sh_offset, Elf_Addr); length = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, @@ -1276,178 +1323,223 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj, sh_type = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, shdr, sh_type, Elf_Word); - ret = pfnret[i - 1]; - name = ret == 0 ? pfnname[i - 1] : ""; - - dest = simple_object_write_create_section (dobj, name, 0, &errmsg, err); + dest = simple_object_write_create_section (dobj, pfnname[i - 1], + 0, &errmsg, err); if (dest == NULL) { XDELETEVEC (names); XDELETEVEC (shdrs); + XDELETEVEC (symtab_indices_shndx); return errmsg; } /* Record the SHDR of the source. */ - memcpy (eow->shdrs + (i - 1) * shdr_size, shdr, shdr_size); - shdr = eow->shdrs + (i - 1) * shdr_size; + memcpy (eow->shdrs + (new_i - 1) * shdr_size, shdr, shdr_size); + shdr = eow->shdrs + (new_i - 1) * shdr_size; /* Copy the data. ??? This is quite wasteful and ideally would be delayed until write_to_file (). Thus it questions the interfacing which eventually should contain destination creation plus writing. */ - /* Keep empty sections for sections we should discard. This avoids - the need to rewrite section indices in symtab and relocation + 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); + XDELETEVEC (symtab_indices_shndx); + return errmsg; + } + + /* If we are processing .symtab purge __gnu_lto_v1 and + __gnu_lto_slim symbols from it and any symbols in discarded sections. */ - if (ret == 0) + if (sh_type == SHT_SYMTAB) { - buf = XNEWVEC (unsigned char, length); - if (!simple_object_internal_read (sobj->descriptor, - sobj->offset + offset, buf, - (size_t) length, &errmsg, err)) + 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; + unsigned char *ent; + unsigned *shndx_table = NULL; + simple_object_internal_read (sobj->descriptor, + sobj->offset + stroff, + (unsigned char *)strings, + strsz, &errmsg, err); + /* Find gnu_lto_ in strings. */ + while ((gnu_lto = (char *) memchr (gnu_lto, 'g', + strings + strsz - gnu_lto))) + if (strncmp (gnu_lto, "gnu_lto_v1", + strings + strsz - gnu_lto) == 0) + break; + else + gnu_lto++; + /* Read the section index table if present. */ + if (symtab_indices_shndx[i - 1] != 0) { - XDELETEVEC (buf); - XDELETEVEC (names); - XDELETEVEC (shdrs); - return errmsg; + unsigned char *sidxhdr = shdrs + (strtab - 1) * shdr_size; + off_t sidxoff = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, + sidxhdr, sh_offset, Elf_Addr); + size_t sidxsz = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, + sidxhdr, sh_size, Elf_Addr); + shndx_table = (unsigned *)XNEWVEC (char, sidxsz); + simple_object_internal_read (sobj->descriptor, + sobj->offset + sidxoff, + (unsigned char *)shndx_table, + sidxsz, &errmsg, err); } - - /* If we are processing .symtab purge __gnu_lto_v1 and - __gnu_lto_slim symbols from it. */ - if (sh_type == SHT_SYMTAB) + for (ent = buf; ent < buf + length; ent += entsize) { - 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); - unsigned char *ent; - simple_object_internal_read (sobj->descriptor, - sobj->offset + stroff, - (unsigned char *)strings, - strsz, &errmsg, err); - /* Find gnu_lto_ in strings. */ - char *gnu_lto = strings; - while ((gnu_lto = memchr (gnu_lto, 'g', - strings + strsz - gnu_lto))) - if (strncmp (gnu_lto, "gnu_lto_v1", - strings + strsz - gnu_lto) == 0) - break; - else - gnu_lto++; - 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 raw_st_shndx = st_shndx; + unsigned char *st_info; + unsigned char *st_other; + int discard = 0; + if (ei_class == ELFCLASS32) { - unsigned st_shndx = ELF_FETCH_FIELD (type_functions, ei_class, - Sym, ent, - st_shndx, Elf_Half); - unsigned char *st_info; - unsigned char *st_other; - int discard = 0; - 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)); + /* Eliminate all COMMONs - this includes __gnu_lto_v1 + and __gnu_lto_slim which otherwise cause endless + LTO plugin invocation. */ + if (st_shndx == SHN_COMMON) + discard = 1; + /* We also need to remove symbols refering to sections + we'll eventually remove as with fat LTO objects + we otherwise get duplicate symbols at final link + (with GNU ld, gold is fine and ignores symbols in + sections marked as EXCLUDE). ld/20513 */ + else if (st_shndx != SHN_UNDEF + && st_shndx < shnum + && pfnret[st_shndx - 1] == -1) + discard = 1; + + if (discard) + { + /* Make discarded symbols undefined and unnamed + in case it is local. */ + int bind = ELF_ST_BIND (*st_info); + int other = STV_DEFAULT; + if (bind == STB_LOCAL) { - st_info = &((Elf32_External_Sym *)ent)->st_info; - st_other = &((Elf32_External_Sym *)ent)->st_other; + /* Make discarded local symbols unnamed and + defined in the first prevailing section. */ + ELF_SET_FIELD (type_functions, ei_class, Sym, + ent, st_name, Elf_Word, 0); + ELF_SET_FIELD (type_functions, ei_class, Sym, + ent, st_shndx, Elf_Half, + sh_map[first_shndx]); } else { - st_info = &((Elf64_External_Sym *)ent)->st_info; - st_other = &((Elf64_External_Sym *)ent)->st_other; - } - /* Eliminate all COMMONs - this includes __gnu_lto_v1 - and __gnu_lto_slim which otherwise cause endless - LTO plugin invocation. */ - if (st_shndx == SHN_COMMON) - discard = 1; - /* We also need to remove symbols refering to sections - we'll eventually remove as with fat LTO objects - we otherwise get duplicate symbols at final link - (with GNU ld, gold is fine and ignores symbols in - sections marked as EXCLUDE). ld/20513 */ - else if (st_shndx != SHN_UNDEF - && st_shndx < shnum - && pfnret[st_shndx - 1] == -1) - discard = 1; - - if (discard) - { - /* Make discarded symbols undefined and unnamed - in case it is local. */ - int bind = ELF_ST_BIND (*st_info); - int other = STV_DEFAULT; - if (bind == STB_LOCAL) - { - /* Make discarded local symbols unnamed and - defined in the first prevailing section. */ - ELF_SET_FIELD (type_functions, ei_class, Sym, - ent, st_name, Elf_Word, 0); - ELF_SET_FIELD (type_functions, ei_class, Sym, - ent, st_shndx, Elf_Half, first_shndx); - } - else - { - /* Make discarded global symbols hidden weak - undefined and sharing the gnu_lto_ name. */ - bind = STB_WEAK; - other = STV_HIDDEN; - if (gnu_lto) - ELF_SET_FIELD (type_functions, ei_class, Sym, - ent, st_name, Elf_Word, - gnu_lto - strings); - ELF_SET_FIELD (type_functions, ei_class, Sym, - ent, st_shndx, Elf_Half, SHN_UNDEF); - } - *st_other = other; - *st_info = ELF_ST_INFO (bind, STT_NOTYPE); - ELF_SET_FIELD (type_functions, ei_class, Sym, - ent, st_value, Elf_Addr, 0); + /* Make discarded global symbols hidden weak + undefined and sharing the gnu_lto_ name. */ + bind = STB_WEAK; + other = STV_HIDDEN; + if (gnu_lto) + ELF_SET_FIELD (type_functions, ei_class, Sym, + ent, st_name, Elf_Word, + gnu_lto - strings); ELF_SET_FIELD (type_functions, ei_class, Sym, - ent, st_size, Elf_Word, 0); + ent, st_shndx, Elf_Half, SHN_UNDEF); } + *st_other = other; + *st_info = ELF_ST_INFO (bind, STT_NOTYPE); + ELF_SET_FIELD (type_functions, ei_class, Sym, + ent, st_value, Elf_Addr, 0); + ELF_SET_FIELD (type_functions, ei_class, Sym, + ent, st_size, Elf_Word, 0); } - XDELETEVEC (strings); + else if (raw_st_shndx < SHN_LORESERVE + || raw_st_shndx == SHN_XINDEX) + /* Remap the section reference. */ + ELF_SET_FIELD (type_functions, ei_class, Sym, + ent, st_shndx, Elf_Half, sh_map[st_shndx]); } - - errmsg = simple_object_write_add_data (dobj, dest, - buf, length, 1, err); - XDELETEVEC (buf); - if (errmsg) + XDELETEVEC (strings); + XDELETEVEC (shndx_table); + } + else if (sh_type == SHT_GROUP) + { + /* Remap section indices in groups and remove removed members. */ + unsigned char *ent, *dst; + for (dst = ent = buf + 4; ent < buf + length; ent += 4) { - XDELETEVEC (names); - XDELETEVEC (shdrs); - return errmsg; + unsigned shndx = type_functions->fetch_Elf_Word (ent); + if (pfnret[shndx - 1] == -1) + ; + else + { + type_functions->set_Elf_Word (dst, sh_map[shndx]); + dst += 4; + } } + /* Adjust the length. */ + length = dst - buf; } - else + + errmsg = simple_object_write_add_data (dobj, dest, + buf, length, 1, err); + XDELETEVEC (buf); + if (errmsg) { - /* For deleted sections mark the section header table entry as - unused. That allows the link editor to remove it in a partial - link. */ - ELF_SET_FIELD (type_functions, ei_class, Shdr, - shdr, sh_type, Elf_Word, SHT_NULL); - ELF_SET_FIELD (type_functions, ei_class, Shdr, - shdr, sh_info, Elf_Word, 0); - ELF_SET_FIELD (type_functions, ei_class, Shdr, - shdr, sh_link, Elf_Word, 0); + XDELETEVEC (names); + XDELETEVEC (shdrs); + XDELETEVEC (symtab_indices_shndx); + return errmsg; } flags = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, shdr, sh_flags, Elf_Addr); - if (ret == 0) - { - /* The debugobj doesn't contain any code, thus no trampolines. - Even when the original object needs trampolines, debugobj - doesn't. */ - if (strcmp (name, ".note.GNU-stack") == 0) - flags &= ~SHF_EXECINSTR; - flags &= ~SHF_EXCLUDE; - } - else if (ret == -1) - flags = SHF_EXCLUDE; + /* Remap the section references. */ + { + unsigned int sh_info, sh_link; + if (flags & SHF_INFO_LINK || sh_type == SHT_REL || sh_type == SHT_RELA) + { + sh_info = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, + shdr, sh_info, Elf_Word); + if (sh_info < SHN_LORESERVE + || sh_info > SHN_HIRESERVE) + sh_info = sh_map[sh_info]; + ELF_SET_FIELD (type_functions, ei_class, Shdr, + shdr, sh_info, Elf_Word, sh_info); + } + sh_link = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, + shdr, sh_link, Elf_Word); + if (sh_link < SHN_LORESERVE + || sh_link > SHN_HIRESERVE) + sh_link = sh_map[sh_link]; + ELF_SET_FIELD (type_functions, ei_class, Shdr, + shdr, sh_link, Elf_Word, sh_link); + } + /* The debugobj doesn't contain any code, thus no trampolines. + Even when the original object needs trampolines, debugobj + doesn't. */ + if (strcmp (name, ".note.GNU-stack") == 0) + flags &= ~SHF_EXECINSTR; + /* Clear SHF_EXCLUDE on to be preserved sections. */ + flags &= ~SHF_EXCLUDE; ELF_SET_FIELD (type_functions, ei_class, Shdr, shdr, sh_flags, Elf_Addr, flags); } @@ -1456,6 +1548,8 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj, XDELETEVEC (shdrs); XDELETEVEC (pfnret); XDELETEVEC (pfnname); + XDELETEVEC (symtab_indices_shndx); + XDELETEVEC (sh_map); return NULL; } diff --git a/libiberty/simple-object-xcoff.c b/libiberty/simple-object-xcoff.c index 0ef2a465bca..1e3d9e01b04 100644 --- a/libiberty/simple-object-xcoff.c +++ b/libiberty/simple-object-xcoff.c @@ -606,11 +606,14 @@ simple_object_xcoff_find_sections (simple_object_read *sobj, || auxent->u.xcoff64.x_csect.x_smclas != XMC_XO) continue; - x_scnlen64 = fetch_32 (aux + offsetof (union external_auxent, - u.xcoff64.x_csect.x_scnlen_hi)); - x_scnlen = x_scnlen64 << 32 - | fetch_32 (aux + offsetof (union external_auxent, - u.xcoff64.x_csect.x_scnlen_lo)); + x_scnlen64 = + fetch_32 (aux + offsetof (union external_auxent, + u.xcoff64.x_csect.x_scnlen_hi)); + x_scnlen = + ((x_scnlen64 << 32) + | fetch_32 (aux + + offsetof (union external_auxent, + u.xcoff64.x_csect.x_scnlen_lo))); } else { diff --git a/libiberty/simple-object.c b/libiberty/simple-object.c index 5b95fb2d56d..42aa6ac4e60 100644 --- a/libiberty/simple-object.c +++ b/libiberty/simple-object.c @@ -253,30 +253,43 @@ simple_object_find_section (simple_object_read *sobj, const char *name, /* Callback to identify and rename LTO debug sections by name. Returns 1 if NAME is a LTO debug section, 0 if not. */ -static int -handle_lto_debug_sections (const char **name) +static char * +handle_lto_debug_sections (const char *name) { + char *newname = XCNEWVEC (char, strlen (name) + 1); + /* ??? So we can't use .gnu.lto_ prefixed sections as the assembler complains about bogus section flags. Which means we need to arrange for that to be fixed or .gnu.debuglto_ marked as SHF_EXCLUDE (to make fat lto object tooling work for the fat part). */ - /* ??? For now this handles both .gnu.lto_ and .gnu.debuglto_ prefixed - sections. */ - /* Copy LTO debug sections and rename them to their non-LTO name. */ - if (strncmp (*name, ".gnu.debuglto_", sizeof (".gnu.debuglto_") - 1) == 0) + /* Also include corresponding reloc sections. */ + if (strncmp (name, ".rela", sizeof (".rela") - 1) == 0) { - *name = *name + sizeof (".gnu.debuglto_") - 1; - return 1; + strncpy (newname, name, sizeof (".rela") - 1); + name += sizeof (".rela") - 1; } - else if (strncmp (*name, ".gnu.lto_.debug_", sizeof (".gnu.lto_.debug_") -1) == 0) + else if (strncmp (name, ".rel", sizeof (".rel") - 1) == 0) { - *name = *name + sizeof (".gnu.lto_") - 1; - return 1; + strncpy (newname, name, sizeof (".rel") - 1); + name += sizeof (".rel") - 1; } + /* ??? For now this handles both .gnu.lto_ and .gnu.debuglto_ prefixed + sections. */ + /* Copy LTO debug sections and rename them to their non-LTO name. */ + if (strncmp (name, ".gnu.debuglto_", sizeof (".gnu.debuglto_") - 1) == 0) + return strcat (newname, name + sizeof (".gnu.debuglto_") - 1); + else if (strncmp (name, ".gnu.lto_.debug_", + sizeof (".gnu.lto_.debug_") -1) == 0) + return strcat (newname, name + sizeof (".gnu.lto_") - 1); /* Copy over .note.GNU-stack section under the same name if present. */ - else if (strcmp (*name, ".note.GNU-stack") == 0) - return 1; - return 0; + else if (strcmp (name, ".note.GNU-stack") == 0) + return strcpy (newname, name); + /* Copy over .comment section under the same name if present. Solaris + ld uses them to relax its checking of ELF gABI access rules for + COMDAT sections in objects produced by GCC. */ + else if (strcmp (name, ".comment") == 0) + return strcpy (newname, name); + return NULL; } /* Copy LTO debug sections. */ -- 2.30.2