X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=libiberty%2Fsimple-object-elf.c;h=a421177f0c2077b809680c7d8168a9a208b59f30;hb=f1cee837665a932d3d747597d8512cd0d3650478;hp=6774eb273c9f838f4b518033c862faddb678f049;hpb=376dc015f275575e0aa7be9c46476db5506ff836;p=binutils-gdb.git diff --git a/libiberty/simple-object-elf.c b/libiberty/simple-object-elf.c index 6774eb273c9..a421177f0c2 100644 --- a/libiberty/simple-object-elf.c +++ b/libiberty/simple-object-elf.c @@ -1,5 +1,5 @@ /* simple-object-elf.c -- routines to manipulate ELF object files. - Copyright (C) 2010-2017 Free Software Foundation, Inc. + Copyright (C) 2010-2021 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. This program is free software; you can redistribute it and/or modify it @@ -22,6 +22,10 @@ Boston, MA 02110-1301, USA. */ #include "simple-object.h" #include +/* mingw.org's MinGW doesn't have ENOTSUP. */ +#ifndef ENOTSUP +# define ENOTSUP ENOSYS +#endif #include #ifdef HAVE_STDLIB_H @@ -126,6 +130,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 +198,12 @@ 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 shared library that it builds @@ -235,8 +243,10 @@ typedef struct #define STB_LOCAL 0 /* Local symbol */ #define STB_GLOBAL 1 /* Global symbol */ +#define STB_WEAK 2 /* Weak global */ #define STV_DEFAULT 0 /* Visibility is specified by binding type */ +#define STV_HIDDEN 2 /* Can only be seen inside currect component */ /* Functions to fetch and store different ELF types, depending on the endianness and size. */ @@ -538,7 +548,15 @@ simple_object_elf_match (unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN], XDELETE (eor); return NULL; } - + + if (eor->shstrndx == 0) + { + *errmsg = "invalid ELF shstrndx == 0"; + *err = 0; + XDELETE (eor); + return NULL; + } + return (void *) eor; } @@ -1067,7 +1085,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 = @@ -1085,8 +1103,13 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj, off_t shstroff; unsigned char *names; unsigned int i; + 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) @@ -1125,18 +1148,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, @@ -1151,79 +1176,130 @@ 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 - 1; + /* 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 sections. */ - for (i = 1; i < shnum; ++i) + do { - unsigned char *shdr; - unsigned int sh_type, sh_info, sh_link; - 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) + changed = 0; + for (i = 1; i < shnum; ++i) { - /* Mark groups containing copied sections. */ - unsigned entsize = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, - shdr, sh_entsize, Elf_Addr); - unsigned char *ent, *buf; - int keep = 0; - offset = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, - shdr, sh_offset, Elf_Addr); - length = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, - 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 char *shdr; + unsigned int sh_type, sh_info, sh_link; + 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) { - unsigned sec = type_functions->fetch_Elf_Word (ent); - if (pfnret[sec - 1] == 0) - keep = 1; + /* Mark groups containing copied sections. */ + unsigned entsize = ELF_FETCH_FIELD (type_functions, ei_class, + Shdr, shdr, sh_entsize, + Elf_Addr); + unsigned char *ent, *buf; + int keep = 0; + offset = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, + shdr, sh_offset, Elf_Addr); + length = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, + 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; - pfnret[i - 1] = 0; + /* Mark relocation sections and symtab of copied sections. */ + 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_RELA - || sh_type == SHT_REL) - { - /* Mark relocation sections and symtab of copied sections. */ - if (pfnret[sh_info - 1] == 0) + if (sh_type == SHT_SYMTAB) { - pfnret[sh_link - 1] = 0; - pfnret[i - 1] = 0; + /* Mark strings sections of copied symtabs. */ + 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); + + /* 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; @@ -1231,11 +1307,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); @@ -1244,10 +1323,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, @@ -1255,143 +1335,251 @@ 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 - sections. */ - if (ret == 0) + 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 any symbols + in discarded sections. */ + 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); + size_t prevailing_name_idx = 0; + unsigned char *ent; + unsigned *shndx_table = NULL; + /* 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 + symtab_indices_shndx[i - 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); + unsigned int shndx_type + = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, + sidxhdr, sh_type, Elf_Word); + if (shndx_type != SHT_SYMTAB_SHNDX) + return "Wrong section type of a SYMTAB SECTION INDICES section"; + 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) + /* 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 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); - 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) { - 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)); + + 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, + 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) + { + 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_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 + 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; + /* We also need to remove global UNDEFs which can + cause link fails later. */ + else if (st_shndx == SHN_UNDEF + && ELF_ST_BIND (*st_info) == STB_GLOBAL) + 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) - /* Setting st_name to "" seems to work to purge - COMMON symbols (in addition to setting their - size to zero). */ - 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. */ - if (ELF_ST_BIND (*st_info) == STB_LOCAL) - ELF_SET_FIELD (type_functions, ei_class, Sym, - ent, st_name, Elf_Word, 0); - ELF_SET_FIELD (type_functions, ei_class, Sym, - ent, st_value, Elf_Addr, 0); + /* Make discarded global symbols hidden weak + 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_size, Elf_Word, 0); + ent, st_name, Elf_Word, + prevailing_name_idx); ELF_SET_FIELD (type_functions, ei_class, Sym, ent, st_shndx, Elf_Half, SHN_UNDEF); - *st_info = ELF_ST_INFO (ELF_ST_BIND (*st_info), - STT_NOTYPE); - *st_other = STV_DEFAULT; } + *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 (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); + 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) - 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); } @@ -1400,6 +1588,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; }