summaryrefslogtreecommitdiff
path: root/libiberty
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2018-04-17 13:53:38 +0100
committerNick Clifton <nickc@redhat.com>2018-04-17 13:53:38 +0100
commite9301e762ab6d533f7110d6c9c1dbe8e68e875d7 (patch)
tree0b133fb3acaf736f204ecb924bb26e9aa6664037 /libiberty
parentbdd7c8fc34dc65806ec14df84c76e17690a16f50 (diff)
Resync libiberty sources with master version in GCC repository.
2018-04-13 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> PR lto/81968 * simple-object.c (handle_lto_debug_sections): Keep .comment section. 2018-03-02 David Malcolm <dmalcolm@redhat.com> * cp-demangle.c: Update URL for g++ V3 ABI. 2018-01-20 Eli Zaretskii <eliz@gnu.org> * simple-object-xcoff.c (simple_object_xcoff_find_sections): Use ulong_type to avoid warning about 32-bit shift. 2018-01-11 Richard Biener <rguenther@suse.de> Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> 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 <daniel@vangerpen.de> * argv.c (expandargv): Correct check for dynamically allocated argv.
Diffstat (limited to 'libiberty')
-rw-r--r--libiberty/ChangeLog39
-rw-r--r--libiberty/argv.c6
-rw-r--r--libiberty/cp-demangle.c2
-rw-r--r--libiberty/simple-object-common.h2
-rw-r--r--libiberty/simple-object-elf.c384
-rw-r--r--libiberty/simple-object-xcoff.c13
-rw-r--r--libiberty/simple-object.c41
7 files changed, 314 insertions, 173 deletions
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index 5e96b8b11b..742b2fa48d 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,8 +1,39 @@
-2018-01-27 Eli Zaretskii <eliz@gnu.org>
+2018-04-13 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
- * 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 <dmalcolm@redhat.com>
+
+ * cp-demangle.c: Update URL for g++ V3 ABI.
+
+2018-01-20 Eli Zaretskii <eliz@gnu.org>
+
+ * simple-object-xcoff.c (simple_object_xcoff_find_sections): Use
+ ulong_type to avoid warning about 32-bit shift.
+
+2018-01-11 Richard Biener <rguenther@suse.de>
+ Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ 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 <daniel@vangerpen.de>
+
+ * argv.c (expandargv): Correct check for dynamically
+ allocated argv.
2018-01-03 Jakub Jelinek <jakub@redhat.com>
diff --git a/libiberty/argv.c b/libiberty/argv.c
index c6a79d215e..4f66c8979b 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 1d5b855ddf..3f2a097e7f 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 <samuel@codesourcery.com>.
diff --git a/libiberty/simple-object-common.h b/libiberty/simple-object-common.h
index 53501df8fd..858209f9b0 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 b249146fc6..7468a1adc3 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 0ef2a465bc..1e3d9e01b0 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 5b95fb2d56..42aa6ac4e6 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. */