FreeBSD Bugzilla – Attachment 157135 Details for
Bug 198611
Libraries build with libtool are no longer stripped with elftoolchain strip
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Update to r3222 (from r3197) with GRP_COMDAT backwards compatibility shim restored
elftc-r3222.diff (text/plain), 39.52 KB, created by
Ed Maste
on 2015-05-25 19:40:02 UTC
(
hide
)
Description:
Update to r3222 (from r3197) with GRP_COMDAT backwards compatibility shim restored
Filename:
MIME Type:
Creator:
Ed Maste
Created:
2015-05-25 19:40:02 UTC
Size:
39.52 KB
patch
obsolete
>diff --git a/contrib/elftoolchain/common/_elftc.h b/contrib/elftoolchain/common/_elftc.h >index 45f0abd..f800922 100644 >--- a/contrib/elftoolchain/common/_elftc.h >+++ b/contrib/elftoolchain/common/_elftc.h >@@ -342,12 +342,13 @@ struct name { \ > > > #if defined(__GLIBC__) || defined(__linux__) >- >+#ifndef _GNU_SOURCE > /* > * GLIBC based systems have a global 'char *' pointer referencing > * the executable's name. > */ > extern const char *program_invocation_short_name; >+#endif /* !_GNU_SOURCE */ > > #define ELFTC_GETPROGNAME() program_invocation_short_name > >diff --git a/contrib/elftoolchain/common/elfdefinitions.h b/contrib/elftoolchain/common/elfdefinitions.h >index a53acde..d81d8d6 100644 >--- a/contrib/elftoolchain/common/elfdefinitions.h >+++ b/contrib/elftoolchain/common/elfdefinitions.h >@@ -565,6 +565,7 @@ _ELF_DEFINE_EM(EM_SPARC, 2, "SPARC") \ > _ELF_DEFINE_EM(EM_386, 3, "Intel 80386") \ > _ELF_DEFINE_EM(EM_68K, 4, "Motorola 68000") \ > _ELF_DEFINE_EM(EM_88K, 5, "Motorola 88000") \ >+_ELF_DEFINE_EM(EM_IAMCU, 6, "Intel MCU") \ > _ELF_DEFINE_EM(EM_860, 7, "Intel 80860") \ > _ELF_DEFINE_EM(EM_MIPS, 8, "MIPS I Architecture") \ > _ELF_DEFINE_EM(EM_S370, 9, "IBM System/370 Processor") \ >diff --git a/contrib/elftoolchain/elfcopy/elfcopy.h b/contrib/elftoolchain/elfcopy/elfcopy.h >index b750246..e64e0cf 100644 >--- a/contrib/elftoolchain/elfcopy/elfcopy.h >+++ b/contrib/elftoolchain/elfcopy/elfcopy.h >@@ -237,6 +237,7 @@ struct elfcopy { > uint64_t *secndx; /* section index map. */ > uint64_t *symndx; /* symbol index map. */ > unsigned char *v_rel; /* symbols needed by relocation. */ >+ unsigned char *v_grp; /* symbols refered by section group. */ > unsigned char *v_secsym; /* sections with section symbol. */ > STAILQ_HEAD(, segment) v_seg; /* list of segments. */ > STAILQ_HEAD(, sec_action) v_sac;/* list of section operations. */ >diff --git a/contrib/elftoolchain/elfcopy/main.c b/contrib/elftoolchain/elfcopy/main.c >index a48aea5..9546f6e 100644 >--- a/contrib/elftoolchain/elfcopy/main.c >+++ b/contrib/elftoolchain/elfcopy/main.c >@@ -404,8 +404,19 @@ create_elf(struct elfcopy *ecp) > * Insert SHDR table into the internal section list as a "pseudo" > * section, so later it will get sorted and resynced just as "normal" > * sections. >+ * >+ * Under FreeBSD, Binutils objcopy always put the section header >+ * at the end of all the sections. We want to do the same here. >+ * >+ * However, note that the behaviour is still different with Binutils: >+ * elfcopy checks the FreeBSD OSABI tag to tell whether it needs to >+ * move the section headers, while Binutils is probably configured >+ * this way when it's compiled on FreeBSD. > */ >- shtab = insert_shtab(ecp, 0); >+ if (oeh.e_ident[EI_OSABI] == ELFOSABI_FREEBSD) >+ shtab = insert_shtab(ecp, 1); >+ else >+ shtab = insert_shtab(ecp, 0); > > /* > * Resync section offsets in the output object. This is needed >@@ -485,6 +496,11 @@ free_elf(struct elfcopy *ecp) > free(sec); > } > } >+ >+ if (ecp->secndx != NULL) { >+ free(ecp->secndx); >+ ecp->secndx = NULL; >+ } > } > > /* Create a temporary file. */ >diff --git a/contrib/elftoolchain/elfcopy/sections.c b/contrib/elftoolchain/elfcopy/sections.c >index 7c43a35..fe6b22f 100644 >--- a/contrib/elftoolchain/elfcopy/sections.c >+++ b/contrib/elftoolchain/elfcopy/sections.c >@@ -56,6 +56,7 @@ static void print_data(const char *d, size_t sz); > static void print_section(struct section *s); > static void *read_section(struct section *s, size_t *size); > static void update_reloc(struct elfcopy *ecp, struct section *s); >+static void update_section_group(struct elfcopy *ecp, struct section *s); > > int > is_remove_section(struct elfcopy *ecp, const char *name) >@@ -552,6 +553,14 @@ copy_content(struct elfcopy *ecp) > (s->type == SHT_REL || s->type == SHT_RELA)) > filter_reloc(ecp, s); > >+ /* >+ * The section indices in the SHT_GROUP section needs >+ * to be updated since we might have stripped some >+ * sections and changed section numbering. >+ */ >+ if (s->type == SHT_GROUP) >+ update_section_group(ecp, s); >+ > if (is_modify_section(ecp, s->name)) > modify_section(ecp, s); > >@@ -571,6 +580,71 @@ copy_content(struct elfcopy *ecp) > } > } > >+ >+/* >+ * Update section group section. The section indices in the SHT_GROUP >+ * section need update after section numbering changed. >+ */ >+static void >+update_section_group(struct elfcopy *ecp, struct section *s) >+{ >+ GElf_Shdr ish; >+ Elf_Data *id; >+ uint32_t *ws, *wd; >+ uint64_t n; >+ size_t ishnum; >+ int i, j; >+ >+ if (!elf_getshnum(ecp->ein, &ishnum)) >+ errx(EXIT_FAILURE, "elf_getshnum failed: %s", >+ elf_errmsg(-1)); >+ >+ if (gelf_getshdr(s->is, &ish) == NULL) >+ errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", >+ elf_errmsg(-1)); >+ >+ if ((id = elf_getdata(s->is, NULL)) == NULL) >+ errx(EXIT_FAILURE, "elf_getdata() failed: %s", >+ elf_errmsg(-1)); >+ >+ if (ish.sh_size == 0) >+ return; >+ >+ if (ish.sh_entsize == 0) >+ ish.sh_entsize = 4; >+ >+ ws = id->d_buf; >+ >+ /* We only support COMDAT section. */ >+#ifndef GRP_COMDAT >+#define GRP_COMDAT 0x1 >+#endif >+ if ((*ws & GRP_COMDAT) == 0) >+ return; >+ >+ if ((s->buf = malloc(ish.sh_size)) == NULL) >+ err(EXIT_FAILURE, "malloc failed"); >+ >+ s->sz = ish.sh_size; >+ >+ wd = s->buf; >+ >+ /* Copy the flag word as-is. */ >+ *wd = *ws; >+ >+ /* Update the section indices. */ >+ n = ish.sh_size / ish.sh_entsize; >+ for(i = 1, j = 1; (uint64_t)i < n; i++) { >+ if (ws[i] != SHN_UNDEF && ws[i] < ishnum && >+ ecp->secndx[ws[i]] != 0) >+ wd[j++] = ecp->secndx[ws[i]]; >+ else >+ s->sz -= 4; >+ } >+ >+ s->nocopy = 1; >+} >+ > /* > * Filter relocation entries, only keep those entries whose > * symbol is in the keep list. >@@ -1028,8 +1102,11 @@ copy_shdr(struct elfcopy *ecp, struct section *s, const char *name, int copy, > osh.sh_flags |= SHF_WRITE; > if (sec_flags & SF_CODE) > osh.sh_flags |= SHF_EXECINSTR; >- } else >+ } else { > osh.sh_flags = ish.sh_flags; >+ if (ish.sh_type == SHT_REL || ish.sh_type == SHT_RELA) >+ osh.sh_flags |= SHF_INFO_LINK; >+ } > } > > if (name == NULL) >diff --git a/contrib/elftoolchain/elfcopy/symbols.c b/contrib/elftoolchain/elfcopy/symbols.c >index 4a7d38a..c0f7a51 100644 >--- a/contrib/elftoolchain/elfcopy/symbols.c >+++ b/contrib/elftoolchain/elfcopy/symbols.c >@@ -77,7 +77,8 @@ static int is_weak_symbol(unsigned char st_info); > static int lookup_exact_string(hash_head *hash, const char *buf, > const char *s); > static int generate_symbols(struct elfcopy *ecp); >-static void mark_symbols(struct elfcopy *ecp, size_t sc); >+static void mark_reloc_symbols(struct elfcopy *ecp, size_t sc); >+static void mark_section_group_symbols(struct elfcopy *ecp, size_t sc); > static int match_wildcard(const char *name, const char *pattern); > uint32_t str_hash(const char *s); > >@@ -160,6 +161,10 @@ is_needed_symbol(struct elfcopy *ecp, int i, GElf_Sym *s) > if (BIT_ISSET(ecp->v_rel, i)) > return (1); > >+ /* Symbols refered by COMDAT sections are needed. */ >+ if (BIT_ISSET(ecp->v_grp, i)) >+ return (1); >+ > /* > * For relocatable files (.o files), global and weak symbols > * are needed. >@@ -207,7 +212,10 @@ is_remove_symbol(struct elfcopy *ecp, size_t sc, int i, GElf_Sym *s, > return (1); > > if (ecp->v_rel == NULL) >- mark_symbols(ecp, sc); >+ mark_reloc_symbols(ecp, sc); >+ >+ if (ecp->v_grp == NULL) >+ mark_section_group_symbols(ecp, sc); > > if (is_needed_symbol(ecp, i, s)) > return (0); >@@ -233,7 +241,7 @@ is_remove_symbol(struct elfcopy *ecp, size_t sc, int i, GElf_Sym *s, > * Mark symbols refered by relocation entries. > */ > static void >-mark_symbols(struct elfcopy *ecp, size_t sc) >+mark_reloc_symbols(struct elfcopy *ecp, size_t sc) > { > const char *name; > Elf_Data *d; >@@ -311,6 +319,49 @@ mark_symbols(struct elfcopy *ecp, size_t sc) > elf_errmsg(elferr)); > } > >+static void >+mark_section_group_symbols(struct elfcopy *ecp, size_t sc) >+{ >+ const char *name; >+ Elf_Scn *s; >+ GElf_Shdr sh; >+ size_t indx; >+ int elferr; >+ >+ ecp->v_grp = calloc((sc + 7) / 8, 1); >+ if (ecp->v_grp == NULL) >+ err(EXIT_FAILURE, "calloc failed"); >+ >+ if (elf_getshstrndx(ecp->ein, &indx) == 0) >+ errx(EXIT_FAILURE, "elf_getshstrndx failed: %s", >+ elf_errmsg(-1)); >+ >+ s = NULL; >+ while ((s = elf_nextscn(ecp->ein, s)) != NULL) { >+ if (gelf_getshdr(s, &sh) != &sh) >+ errx(EXIT_FAILURE, "elf_getshdr failed: %s", >+ elf_errmsg(-1)); >+ >+ if (sh.sh_type != SHT_GROUP) >+ continue; >+ >+ if ((name = elf_strptr(ecp->ein, indx, sh.sh_name)) == NULL) >+ errx(EXIT_FAILURE, "elf_strptr failed: %s", >+ elf_errmsg(-1)); >+ if (is_remove_section(ecp, name)) >+ continue; >+ >+ if (sh.sh_info > 0 && sh.sh_info < sc) >+ BIT_SET(ecp->v_grp, sh.sh_info); >+ else if (sh.sh_info != 0) >+ warnx("invalid symbox index"); >+ } >+ elferr = elf_errno(); >+ if (elferr != 0) >+ errx(EXIT_FAILURE, "elf_nextscn failed: %s", >+ elf_errmsg(elferr)); >+} >+ > static int > generate_symbols(struct elfcopy *ecp) > { >@@ -351,6 +402,8 @@ generate_symbols(struct elfcopy *ecp) > ecp->symtab->buf = sy_buf; > ecp->strtab->buf = st_buf; > >+ gsym = NULL; >+ > /* > * Create bit vector v_secsym, which is used to mark sections > * that already have corresponding STT_SECTION symbols. >@@ -384,7 +437,7 @@ generate_symbols(struct elfcopy *ecp) > /* Symbol table should exist if this function is called. */ > if (symndx == 0) { > warnx("can't find .strtab section"); >- return (0); >+ goto clean; > } > > /* Locate .symtab of input object. */ >@@ -413,7 +466,6 @@ generate_symbols(struct elfcopy *ecp) > * output object, it is used by update_reloc() later to update > * relocation information. > */ >- gsym = NULL; > sc = ish.sh_size / ish.sh_entsize; > if (sc > 0) { > ecp->symndx = calloc(sc, sizeof(*ecp->symndx)); >@@ -427,7 +479,7 @@ generate_symbols(struct elfcopy *ecp) > if (elferr != 0) > errx(EXIT_FAILURE, "elf_getdata failed: %s", > elf_errmsg(elferr)); >- return (0); >+ goto clean; > } > } else > return (0); >@@ -523,7 +575,7 @@ generate_symbols(struct elfcopy *ecp) > * check if that only local symbol is the reserved symbol. > */ > if (sy_buf->nls <= 1 && sy_buf->ngs == 0) >- return (0); >+ goto clean; > > /* > * Create STT_SECTION symbols for sections that do not already >@@ -550,6 +602,7 @@ generate_symbols(struct elfcopy *ecp) > sym.st_value = s->vma; > sym.st_size = 0; > sym.st_info = GELF_ST_INFO(STB_LOCAL, STT_SECTION); >+ sym.st_other = STV_DEFAULT; > /* > * Don't let add_to_symtab() touch sym.st_shndx. > * In this case, we know the index already. >@@ -583,6 +636,12 @@ generate_symbols(struct elfcopy *ecp) > } > > return (1); >+ >+clean: >+ free(gsym); >+ free_symtab(ecp); >+ >+ return (0); > } > > void >@@ -624,7 +683,9 @@ create_symtab(struct elfcopy *ecp) > if (((ecp->flags & SYMTAB_INTACT) == 0) && !generate_symbols(ecp)) { > TAILQ_REMOVE(&ecp->v_sec, ecp->symtab, sec_list); > TAILQ_REMOVE(&ecp->v_sec, ecp->strtab, sec_list); >+ free(ecp->symtab->buf); > free(ecp->symtab); >+ free(ecp->strtab->buf); > free(ecp->strtab); > ecp->symtab = NULL; > ecp->strtab = NULL; >@@ -697,6 +758,23 @@ free_symtab(struct elfcopy *ecp) > } > } > } >+ >+ if (ecp->symndx != NULL) { >+ free(ecp->symndx); >+ ecp->symndx = NULL; >+ } >+ if (ecp->v_rel != NULL) { >+ free(ecp->v_rel); >+ ecp->v_rel = NULL; >+ } >+ if (ecp->v_grp != NULL) { >+ free(ecp->v_grp); >+ ecp->v_grp = NULL; >+ } >+ if (ecp->v_secsym != NULL) { >+ free(ecp->v_secsym); >+ ecp->v_secsym = NULL; >+ } > } > > void >diff --git a/contrib/elftoolchain/libdwarf/libdwarf_reloc.c b/contrib/elftoolchain/libdwarf/libdwarf_reloc.c >index 96bb785..25b21bd 100644 >--- a/contrib/elftoolchain/libdwarf/libdwarf_reloc.c >+++ b/contrib/elftoolchain/libdwarf/libdwarf_reloc.c >@@ -75,6 +75,7 @@ _dwarf_get_reloc_size(Dwarf_Debug dbg, Dwarf_Unsigned rel_type) > return (4); > break; > case EM_386: >+ case EM_IAMCU: > if (rel_type == R_386_32) > return (4); > break; >diff --git a/contrib/elftoolchain/libelftc/libelftc_dem_gnu3.c b/contrib/elftoolchain/libelftc/libelftc_dem_gnu3.c >index 1cdb0e7..897c618 100644 >--- a/contrib/elftoolchain/libelftc/libelftc_dem_gnu3.c >+++ b/contrib/elftoolchain/libelftc/libelftc_dem_gnu3.c >@@ -50,7 +50,7 @@ ELFTC_VCSID("$Id: libelftc_dem_gnu3.c 3194 2015-05-05 17:55:16Z emaste $"); > > enum type_qualifier { > TYPE_PTR, TYPE_REF, TYPE_CMX, TYPE_IMG, TYPE_EXT, TYPE_RST, TYPE_VAT, >- TYPE_CST >+ TYPE_CST, TYPE_VEC > }; > > struct vector_type_qualifier { >@@ -84,6 +84,7 @@ struct cpp_demangle_data { > int func_type; > const char *cur; /* current mangled name ptr */ > const char *last_sname; /* last source name */ >+ int push_head; > }; > > #define CPP_DEMANGLE_TRY_LIMIT 128 >@@ -112,6 +113,8 @@ static int cpp_demangle_read_array(struct cpp_demangle_data *); > static int cpp_demangle_read_encoding(struct cpp_demangle_data *); > static int cpp_demangle_read_expr_primary(struct cpp_demangle_data *); > static int cpp_demangle_read_expression(struct cpp_demangle_data *); >+static int cpp_demangle_read_expression_flat(struct cpp_demangle_data *, >+ char **); > static int cpp_demangle_read_expression_binary(struct cpp_demangle_data *, > const char *, size_t); > static int cpp_demangle_read_expression_unary(struct cpp_demangle_data *, >@@ -123,8 +126,12 @@ static int cpp_demangle_read_function(struct cpp_demangle_data *, int *, > static int cpp_demangle_local_source_name(struct cpp_demangle_data *ddata); > static int cpp_demangle_read_local_name(struct cpp_demangle_data *); > static int cpp_demangle_read_name(struct cpp_demangle_data *); >+static int cpp_demangle_read_name_flat(struct cpp_demangle_data *, >+ char**); > static int cpp_demangle_read_nested_name(struct cpp_demangle_data *); > static int cpp_demangle_read_number(struct cpp_demangle_data *, long *); >+static int cpp_demangle_read_number_as_string(struct cpp_demangle_data *, >+ char **); > static int cpp_demangle_read_nv_offset(struct cpp_demangle_data *); > static int cpp_demangle_read_offset(struct cpp_demangle_data *); > static int cpp_demangle_read_offset_number(struct cpp_demangle_data *); >@@ -138,6 +145,8 @@ static int cpp_demangle_read_tmpl_arg(struct cpp_demangle_data *); > static int cpp_demangle_read_tmpl_args(struct cpp_demangle_data *); > static int cpp_demangle_read_tmpl_param(struct cpp_demangle_data *); > static int cpp_demangle_read_type(struct cpp_demangle_data *, int); >+static int cpp_demangle_read_type_flat(struct cpp_demangle_data *, >+ char **); > static int cpp_demangle_read_uqname(struct cpp_demangle_data *); > static int cpp_demangle_read_v_offset(struct cpp_demangle_data *); > static char *decode_fp_to_double(const char *, size_t); >@@ -156,8 +165,6 @@ static int vector_type_qualifier_init(struct vector_type_qualifier *); > static int vector_type_qualifier_push(struct vector_type_qualifier *, > enum type_qualifier); > >-static int cpp_demangle_gnu3_push_head; >- > /** > * @brief Decode the input string by IA-64 C++ ABI style. > * >@@ -190,7 +197,6 @@ cpp_demangle_gnu3(const char *org) > if (!cpp_demangle_data_init(&ddata, org + 2)) > return (NULL); > >- cpp_demangle_gnu3_push_head = 0; > rtn = NULL; > > if (!cpp_demangle_read_encoding(&ddata)) >@@ -277,6 +283,7 @@ cpp_demangle_data_init(struct cpp_demangle_data *d, const char *cur) > d->func_type = 0; > d->cur = cur; > d->last_sname = NULL; >+ d->push_head = 0; > > return (1); > >@@ -309,7 +316,6 @@ cpp_demangle_push_fp(struct cpp_demangle_data *ddata, > fp = ddata->cur; > while (*ddata->cur != 'E') > ++ddata->cur; >- ++ddata->cur; > > if ((f = decoder(fp, ddata->cur - fp)) == NULL) > return (0); >@@ -320,6 +326,8 @@ cpp_demangle_push_fp(struct cpp_demangle_data *ddata, > > free(f); > >+ ++ddata->cur; >+ > return (rtn); > } > >@@ -331,7 +339,7 @@ cpp_demangle_push_str(struct cpp_demangle_data *ddata, const char *str, > if (ddata == NULL || str == NULL || len == 0) > return (0); > >- if (cpp_demangle_gnu3_push_head > 0) >+ if (ddata->push_head > 0) > return (vector_str_push(&ddata->output_tmp, str, len)); > > return (vector_str_push(&ddata->output, str, len)); >@@ -403,7 +411,8 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_data *ddata, > if (type_str != NULL) { > if (!vector_str_push(&subst_v, "*", 1)) > goto clean; >- if (!cpp_demangle_push_subst_v(ddata, &subst_v)) >+ if (!cpp_demangle_push_subst_v(ddata, >+ &subst_v)) > goto clean; > } > break; >@@ -414,7 +423,8 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_data *ddata, > if (type_str != NULL) { > if (!vector_str_push(&subst_v, "&", 1)) > goto clean; >- if (!cpp_demangle_push_subst_v(ddata, &subst_v)) >+ if (!cpp_demangle_push_subst_v(ddata, >+ &subst_v)) > goto clean; > } > break; >@@ -425,7 +435,8 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_data *ddata, > if (type_str != NULL) { > if (!vector_str_push(&subst_v, " complex", 8)) > goto clean; >- if (!cpp_demangle_push_subst_v(ddata, &subst_v)) >+ if (!cpp_demangle_push_subst_v(ddata, >+ &subst_v)) > goto clean; > } > break; >@@ -434,23 +445,26 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_data *ddata, > if (!cpp_demangle_push_str(ddata, " imaginary", 10)) > goto clean; > if (type_str != NULL) { >- if (!vector_str_push(&subst_v, " imaginary", 10)) >+ if (!vector_str_push(&subst_v, " imaginary", >+ 10)) > goto clean; >- if (!cpp_demangle_push_subst_v(ddata, &subst_v)) >+ if (!cpp_demangle_push_subst_v(ddata, >+ &subst_v)) > goto clean; > } > break; > > case TYPE_EXT: >- if (e_idx > v->ext_name.size - 1) >+ if (v->ext_name.size == 0 || >+ e_idx > v->ext_name.size - 1) > goto clean; >- if ((e_len = strlen(v->ext_name.container[e_idx])) == 0) >+ if ((e_len = strlen(v->ext_name.container[e_idx])) == >+ 0) > goto clean; >- if ((buf = malloc(sizeof(char) * (e_len + 1))) == NULL) >+ if ((buf = malloc(e_len + 2)) == NULL) > goto clean; >- >- memcpy(buf, " ", 1); >- memcpy(buf + 1, v->ext_name.container[e_idx], e_len); >+ snprintf(buf, e_len + 2, " %s", >+ v->ext_name.container[e_idx]); > > if (!cpp_demangle_push_str(ddata, buf, e_len + 1)) { > free(buf); >@@ -463,7 +477,8 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_data *ddata, > free(buf); > goto clean; > } >- if (!cpp_demangle_push_subst_v(ddata, &subst_v)) { >+ if (!cpp_demangle_push_subst_v(ddata, >+ &subst_v)) { > free(buf); > goto clean; > } >@@ -478,7 +493,8 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_data *ddata, > if (type_str != NULL) { > if (!vector_str_push(&subst_v, " restrict", 9)) > goto clean; >- if (!cpp_demangle_push_subst_v(ddata, &subst_v)) >+ if (!cpp_demangle_push_subst_v(ddata, >+ &subst_v)) > goto clean; > } > break; >@@ -489,7 +505,8 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_data *ddata, > if (type_str != NULL) { > if (!vector_str_push(&subst_v, " volatile", 9)) > goto clean; >- if (!cpp_demangle_push_subst_v(ddata, &subst_v)) >+ if (!cpp_demangle_push_subst_v(ddata, >+ &subst_v)) > goto clean; > } > break; >@@ -500,11 +517,42 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_data *ddata, > if (type_str != NULL) { > if (!vector_str_push(&subst_v, " const", 6)) > goto clean; >- if (!cpp_demangle_push_subst_v(ddata, &subst_v)) >+ if (!cpp_demangle_push_subst_v(ddata, >+ &subst_v)) > goto clean; > } > break; > >+ case TYPE_VEC: >+ if (v->ext_name.size == 0 || >+ e_idx > v->ext_name.size - 1) >+ goto clean; >+ if ((e_len = strlen(v->ext_name.container[e_idx])) == >+ 0) >+ goto clean; >+ if ((buf = malloc(e_len + 12)) == NULL) >+ goto clean; >+ snprintf(buf, e_len + 12, " __vector(%s)", >+ v->ext_name.container[e_idx]); >+ if (!cpp_demangle_push_str(ddata, buf, e_len + 11)) { >+ free(buf); >+ goto clean; >+ } >+ if (type_str != NULL) { >+ if (!vector_str_push(&subst_v, buf, >+ e_len + 11)) { >+ free(buf); >+ goto clean; >+ } >+ if (!cpp_demangle_push_subst_v(ddata, >+ &subst_v)) { >+ free(buf); >+ goto clean; >+ } >+ } >+ free(buf); >+ ++e_idx; >+ break; > }; > --idx; > } >@@ -655,10 +703,14 @@ cpp_demangle_read_expr_primary(struct cpp_demangle_data *ddata) > > switch (*ddata->cur) { > case 'b': >+ if (*(ddata->cur + 2) != 'E') >+ return (0); > switch (*(++ddata->cur)) { > case '0': >+ ddata->cur += 2; > return (cpp_demangle_push_str(ddata, "false", 5)); > case '1': >+ ddata->cur += 2; > return (cpp_demangle_push_str(ddata, "true", 4)); > default: > return (0); >@@ -707,7 +759,8 @@ cpp_demangle_read_expr_primary(struct cpp_demangle_data *ddata) > ++ddata->cur; > } > ++ddata->cur; >- return (cpp_demangle_push_str(ddata, num, ddata->cur - num)); >+ return (cpp_demangle_push_str(ddata, num, >+ ddata->cur - num - 1)); > > default: > return (0); >@@ -999,6 +1052,38 @@ cpp_demangle_read_expression(struct cpp_demangle_data *ddata) > } > > static int >+cpp_demangle_read_expression_flat(struct cpp_demangle_data *ddata, char **str) >+{ >+ struct vector_str *output; >+ size_t i, p_idx, idx, exp_len; >+ char *exp; >+ >+ output = ddata->push_head > 0 ? &ddata->output_tmp : >+ &ddata->output; >+ >+ p_idx = output->size; >+ >+ if (!cpp_demangle_read_expression(ddata)) >+ return (0); >+ >+ if ((exp = vector_str_substr(output, p_idx, output->size - 1, >+ &exp_len)) == NULL) >+ return (0); >+ >+ idx = output->size; >+ for (i = p_idx; i < idx; ++i) { >+ if (!vector_str_pop(output)) { >+ free(exp); >+ return (0); >+ } >+ } >+ >+ *str = exp; >+ >+ return (1); >+} >+ >+static int > cpp_demangle_read_expression_binary(struct cpp_demangle_data *ddata, > const char *name, size_t len) > { >@@ -1127,12 +1212,65 @@ cpp_demangle_read_function(struct cpp_demangle_data *ddata, int *ext_c, > static int > cpp_demangle_read_encoding(struct cpp_demangle_data *ddata) > { >+ char *name, *type, *num_str; >+ long offset; >+ int rtn; > > if (ddata == NULL || *ddata->cur == '\0') > return (0); > > /* special name */ > switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { >+ case SIMPLE_HASH('G', 'A'): >+ if (!cpp_demangle_push_str(ddata, "hidden alias for ", 17)) >+ return (0); >+ ddata->cur += 2; >+ if (*ddata->cur == '\0') >+ return (0); >+ return (cpp_demangle_read_encoding(ddata)); >+ >+ case SIMPLE_HASH('G', 'R'): >+ if (!cpp_demangle_push_str(ddata, "reference temporary #", 21)) >+ return (0); >+ ddata->cur += 2; >+ if (*ddata->cur == '\0') >+ return (0); >+ if (!cpp_demangle_read_name_flat(ddata, &name)) >+ return (0); >+ rtn = 0; >+ if (!cpp_demangle_read_number_as_string(ddata, &num_str)) >+ goto clean1; >+ if (!cpp_demangle_push_str(ddata, num_str, strlen(num_str))) >+ goto clean2; >+ if (!cpp_demangle_push_str(ddata, " for ", 5)) >+ goto clean2; >+ if (!cpp_demangle_push_str(ddata, name, strlen(name))) >+ goto clean2; >+ rtn = 1; >+ clean2: >+ free(num_str); >+ clean1: >+ free(name); >+ return (rtn); >+ >+ case SIMPLE_HASH('G', 'T'): >+ ddata->cur += 2; >+ if (*ddata->cur == '\0') >+ return (0); >+ switch (*ddata->cur) { >+ case 'n': >+ if (!cpp_demangle_push_str(ddata, >+ "non-transaction clone for ", 26)) >+ return (0); >+ case 't': >+ default: >+ if (!cpp_demangle_push_str(ddata, >+ "transaction clone for ", 22)) >+ return (0); >+ } >+ ++ddata->cur; >+ return (cpp_demangle_read_encoding(ddata)); >+ > case SIMPLE_HASH('G', 'V'): > /* sentry object for 1 time init */ > if (!cpp_demangle_push_str(ddata, "guard variable for ", 20)) >@@ -1154,14 +1292,49 @@ cpp_demangle_read_encoding(struct cpp_demangle_data *ddata) > return (0); > return (cpp_demangle_read_encoding(ddata)); > >+ case SIMPLE_HASH('T', 'C'): >+ /* construction vtable */ >+ if (!cpp_demangle_push_str(ddata, "construction vtable for ", >+ 24)) >+ return (0); >+ ddata->cur += 2; >+ if (*ddata->cur == '\0') >+ return (0); >+ if (!cpp_demangle_read_type_flat(ddata, &type)) >+ return (0); >+ rtn = 0; >+ if (!cpp_demangle_read_number(ddata, &offset)) >+ goto clean3; >+ if (*ddata->cur++ != '_') >+ goto clean3; >+ if (!cpp_demangle_read_type(ddata, 0)) >+ goto clean3; >+ if (!cpp_demangle_push_str(ddata, "-in-", 4)) >+ goto clean3; >+ if (!cpp_demangle_push_str(ddata, type, strlen(type))) >+ goto clean3; >+ rtn = 1; >+ clean3: >+ free(type); >+ return (rtn); >+ > case SIMPLE_HASH('T', 'D'): > /* typeinfo common proxy */ > break; > >+ case SIMPLE_HASH('T', 'F'): >+ /* typeinfo fn */ >+ if (!cpp_demangle_push_str(ddata, "typeinfo fn for ", 16)) >+ return (0); >+ ddata->cur += 2; >+ if (*ddata->cur == '\0') >+ return (0); >+ return (cpp_demangle_read_type(ddata, 0)); >+ > case SIMPLE_HASH('T', 'h'): > /* virtual function non-virtual override thunk */ >- if (cpp_demangle_push_str(ddata, >- "virtual function non-virtual override ", 38) == 0) >+ if (!cpp_demangle_push_str(ddata, >+ "virtual function non-virtual override ", 38)) > return (0); > ddata->cur += 2; > if (*ddata->cur == '\0') >@@ -1170,24 +1343,51 @@ cpp_demangle_read_encoding(struct cpp_demangle_data *ddata) > return (0); > return (cpp_demangle_read_encoding(ddata)); > >+ case SIMPLE_HASH('T', 'H'): >+ /* TLS init function */ >+ if (!cpp_demangle_push_str(ddata, "TLS init function for ", >+ 22)) >+ return (0); >+ ddata->cur += 2; >+ if (*ddata->cur == '\0') >+ return (0); >+ break; >+ > case SIMPLE_HASH('T', 'I'): > /* typeinfo structure */ >- /* FALLTHROUGH */ >+ if (!cpp_demangle_push_str(ddata, "typeinfo for ", 13)) >+ return (0); >+ ddata->cur += 2; >+ if (*ddata->cur == '\0') >+ return (0); >+ return (cpp_demangle_read_type(ddata, 0)); >+ >+ case SIMPLE_HASH('T', 'J'): >+ /* java class */ >+ if (!cpp_demangle_push_str(ddata, "java Class for ", 15)) >+ return (0); >+ ddata->cur += 2; >+ if (*ddata->cur == '\0') >+ return (0); >+ return (cpp_demangle_read_type(ddata, 0)); >+ > case SIMPLE_HASH('T', 'S'): > /* RTTI name (NTBS) */ >- if (!cpp_demangle_push_str(ddata, "typeinfo for ", 14)) >+ if (!cpp_demangle_push_str(ddata, "typeinfo name for ", 18)) > return (0); > ddata->cur += 2; > if (*ddata->cur == '\0') > return (0); >- return (cpp_demangle_read_type(ddata, 1)); >+ return (cpp_demangle_read_type(ddata, 0)); > > case SIMPLE_HASH('T', 'T'): > /* VTT table */ > if (!cpp_demangle_push_str(ddata, "VTT for ", 8)) > return (0); > ddata->cur += 2; >- return (cpp_demangle_read_type(ddata, 1)); >+ if (*ddata->cur == '\0') >+ return (0); >+ return (cpp_demangle_read_type(ddata, 0)); > > case SIMPLE_HASH('T', 'v'): > /* virtual function virtual override thunk */ >@@ -1208,7 +1408,17 @@ cpp_demangle_read_encoding(struct cpp_demangle_data *ddata) > ddata->cur += 2; > if (*ddata->cur == '\0') > return (0); >- return (cpp_demangle_read_type(ddata, 1)); >+ return (cpp_demangle_read_type(ddata, 0)); >+ >+ case SIMPLE_HASH('T', 'W'): >+ /* TLS wrapper function */ >+ if (!cpp_demangle_push_str(ddata, "TLS wrapper function for ", >+ 25)) >+ return (0); >+ ddata->cur += 2; >+ if (*ddata->cur == '\0') >+ return (0); >+ break; > }; > > return (cpp_demangle_read_name(ddata)); >@@ -1270,8 +1480,7 @@ cpp_demangle_read_name(struct cpp_demangle_data *ddata) > if (ddata == NULL || *ddata->cur == '\0') > return (0); > >- output = cpp_demangle_gnu3_push_head > 0 ? >- &ddata->output_tmp : &ddata->output; >+ output = ddata->push_head > 0 ? &ddata->output_tmp : &ddata->output; > > subst_str = NULL; > >@@ -1327,6 +1536,38 @@ clean: > } > > static int >+cpp_demangle_read_name_flat(struct cpp_demangle_data *ddata, char **str) >+{ >+ struct vector_str *output; >+ size_t i, p_idx, idx, name_len; >+ char *name; >+ >+ output = ddata->push_head > 0 ? &ddata->output_tmp : >+ &ddata->output; >+ >+ p_idx = output->size; >+ >+ if (!cpp_demangle_read_name(ddata)) >+ return (0); >+ >+ if ((name = vector_str_substr(output, p_idx, output->size - 1, >+ &name_len)) == NULL) >+ return (0); >+ >+ idx = output->size; >+ for (i = p_idx; i < idx; ++i) { >+ if (!vector_str_pop(output)) { >+ free(name); >+ return (0); >+ } >+ } >+ >+ *str = name; >+ >+ return (1); >+} >+ >+static int > cpp_demangle_read_nested_name(struct cpp_demangle_data *ddata) > { > struct vector_str *output, v; >@@ -1355,8 +1596,7 @@ cpp_demangle_read_nested_name(struct cpp_demangle_data *ddata) > ++ddata->cur; > } > >- output = cpp_demangle_gnu3_push_head > 0 ? >- &ddata->output_tmp : &ddata->output; >+ output = ddata->push_head > 0 ? &ddata->output_tmp : &ddata->output; > if (!vector_str_init(&v)) > return (0); > >@@ -1453,6 +1693,24 @@ cpp_demangle_read_number(struct cpp_demangle_data *ddata, long *rtn) > } > > static int >+cpp_demangle_read_number_as_string(struct cpp_demangle_data *ddata, char **str) >+{ >+ long n; >+ >+ if (!cpp_demangle_read_number(ddata, &n)) { >+ *str = NULL; >+ return (0); >+ } >+ >+ if (asprintf(str, "%ld", n) < 0) { >+ *str = NULL; >+ return (0); >+ } >+ >+ return (1); >+} >+ >+static int > cpp_demangle_read_nv_offset(struct cpp_demangle_data *ddata) > { > >@@ -1581,9 +1839,18 @@ static int > cpp_demangle_read_sname(struct cpp_demangle_data *ddata) > { > long len; >+ int err; > > if (ddata == NULL || cpp_demangle_read_number(ddata, &len) == 0 || >- len <= 0 || cpp_demangle_push_str(ddata, ddata->cur, len) == 0) >+ len <= 0) >+ return (0); >+ >+ if (len == 12 && (memcmp("_GLOBAL__N_1", ddata->cur, 12) == 0)) >+ err = cpp_demangle_push_str(ddata, "(anonymous namespace)", 21); >+ else >+ err = cpp_demangle_push_str(ddata, ddata->cur, len); >+ >+ if (err == 0) > return (0); > > assert(ddata->output.size > 0); >@@ -1732,8 +1999,7 @@ cpp_demangle_read_subst_std(struct cpp_demangle_data *ddata) > > ddata->cur += 2; > >- output = cpp_demangle_gnu3_push_head > 0 ? >- &ddata->output_tmp : &ddata->output; >+ output = ddata->push_head > 0 ? &ddata->output_tmp : &ddata->output; > > p_idx = output->size; > if (!cpp_demangle_read_uqname(ddata)) >@@ -1783,8 +2049,7 @@ cpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *ddata, > if (ddata == NULL || str == NULL || len == 0) > return (0); > >- output = cpp_demangle_gnu3_push_head > 0 ? &ddata->output_tmp : >- &ddata->output; >+ output = ddata->push_head > 0 ? &ddata->output_tmp : &ddata->output; > > p_idx = output->size; > substr = NULL; >@@ -1852,8 +2117,7 @@ cpp_demangle_read_tmpl_args(struct cpp_demangle_data *ddata) > return (0); > > limit = 0; >- v = cpp_demangle_gnu3_push_head > 0 ? >- &ddata->output_tmp : &ddata->output; >+ v = ddata->push_head > 0 ? &ddata->output_tmp : &ddata->output; > for (;;) { > idx = v->size; > if (!cpp_demangle_read_tmpl_arg(ddata)) >@@ -1936,14 +2200,14 @@ cpp_demangle_read_type(struct cpp_demangle_data *ddata, int delimit) > size_t p_idx, type_str_len; > int extern_c, is_builtin; > long len; >- char *type_str; >+ char *type_str, *exp_str, *num_str; > > if (ddata == NULL) > return (0); > > output = &ddata->output; > if (!strncmp(ddata->output.container[ddata->output.size - 1], ">", 1)) { >- cpp_demangle_gnu3_push_head++; >+ ddata->push_head++; > output = &ddata->output_tmp; > } else if (delimit == 1) { > if (ddata->paren == false) { >@@ -1978,7 +2242,7 @@ cpp_demangle_read_type(struct cpp_demangle_data *ddata, int delimit) > extern_c = 0; > is_builtin = 1; > p_idx = output->size; >- type_str = NULL; >+ type_str = exp_str = num_str = NULL; > again: > /* builtin type */ > switch (*ddata->cur) { >@@ -2024,6 +2288,82 @@ again: > ++ddata->cur; > goto rtn; > >+ case 'D': >+ ++ddata->cur; >+ switch (*ddata->cur) { >+ case 'd': >+ /* IEEE 754r decimal floating point (64 bits) */ >+ if (!cpp_demangle_push_str(ddata, "decimal64", 9)) >+ goto clean; >+ ++ddata->cur; >+ break; >+ case 'e': >+ /* IEEE 754r decimal floating point (128 bits) */ >+ if (!cpp_demangle_push_str(ddata, "decimal128", 10)) >+ goto clean; >+ ++ddata->cur; >+ break; >+ case 'f': >+ /* IEEE 754r decimal floating point (32 bits) */ >+ if (!cpp_demangle_push_str(ddata, "decimal32", 9)) >+ goto clean; >+ ++ddata->cur; >+ break; >+ case 'h': >+ /* IEEE 754r half-precision floating point (16 bits) */ >+ if (!cpp_demangle_push_str(ddata, "half", 4)) >+ goto clean; >+ ++ddata->cur; >+ break; >+ case 'i': >+ /* char32_t */ >+ if (!cpp_demangle_push_str(ddata, "char32_t", 8)) >+ goto clean; >+ ++ddata->cur; >+ break; >+ case 'n': >+ /* std::nullptr_t (i.e., decltype(nullptr)) */ >+ if (!cpp_demangle_push_str(ddata, "decltype(nullptr)", >+ 17)) >+ goto clean; >+ ++ddata->cur; >+ break; >+ case 's': >+ /* char16_t */ >+ if (!cpp_demangle_push_str(ddata, "char16_t", 8)) >+ goto clean; >+ ++ddata->cur; >+ break; >+ case 'v': >+ /* gcc vector_size extension. */ >+ ++ddata->cur; >+ if (*ddata->cur == '_') { >+ ++ddata->cur; >+ if (!cpp_demangle_read_expression_flat(ddata, >+ &exp_str)) >+ goto clean; >+ if (!vector_str_push(&v.ext_name, exp_str, >+ strlen(exp_str))) >+ goto clean; >+ } else { >+ if (!cpp_demangle_read_number_as_string(ddata, >+ &num_str)) >+ goto clean; >+ if (!vector_str_push(&v.ext_name, num_str, >+ strlen(num_str))) >+ goto clean; >+ } >+ if (*ddata->cur != '_') >+ goto clean; >+ ++ddata->cur; >+ if (!vector_type_qualifier_push(&v, TYPE_VEC)) >+ goto clean; >+ goto again; >+ default: >+ goto clean; >+ } >+ goto rtn; >+ > case 'e': > /* long double */ > if (!cpp_demangle_push_str(ddata, "long double", 11)) >@@ -2118,7 +2458,7 @@ again: > > case 'o': > /* unsigned __int128 */ >- if (!cpp_demangle_push_str(ddata, "unsigned _;int128", 17)) >+ if (!cpp_demangle_push_str(ddata, "unsigned __int128", 17)) > goto clean; > ++ddata->cur; > goto rtn; >@@ -2189,6 +2529,8 @@ again: > if (!vector_str_push(&v.ext_name, ddata->cur, len)) > return (0); > ddata->cur += len; >+ if (!vector_type_qualifier_push(&v, TYPE_EXT)) >+ goto clean; > goto again; > > case 'v': >@@ -2253,14 +2595,16 @@ rtn: > goto clean; > > free(type_str); >+ free(exp_str); >+ free(num_str); > vector_type_qualifier_dest(&v); > >- if (cpp_demangle_gnu3_push_head > 0) { >+ if (ddata->push_head > 0) { > if (*ddata->cur == 'I' && cpp_demangle_read_tmpl_args(ddata) > == 0) > return (0); > >- if (--cpp_demangle_gnu3_push_head > 0) >+ if (--ddata->push_head > 0) > return (1); > > if (!vector_str_push(&ddata->output_tmp, " ", 1)) >@@ -2284,11 +2628,45 @@ rtn: > return (1); > clean: > free(type_str); >+ free(exp_str); >+ free(num_str); > vector_type_qualifier_dest(&v); > > return (0); > } > >+static int >+cpp_demangle_read_type_flat(struct cpp_demangle_data *ddata, char **str) >+{ >+ struct vector_str *output; >+ size_t i, p_idx, idx, type_len; >+ char *type; >+ >+ output = ddata->push_head > 0 ? &ddata->output_tmp : >+ &ddata->output; >+ >+ p_idx = output->size; >+ >+ if (!cpp_demangle_read_type(ddata, 0)) >+ return (0); >+ >+ if ((type = vector_str_substr(output, p_idx, output->size - 1, >+ &type_len)) == NULL) >+ return (0); >+ >+ idx = output->size; >+ for (i = p_idx; i < idx; ++i) { >+ if (!vector_str_pop(output)) { >+ free(type); >+ return (0); >+ } >+ } >+ >+ *str = type; >+ >+ return (1); >+} >+ > /* > * read unqualified-name, unqualified name are operator-name, ctor-dtor-name, > * source-name >diff --git a/contrib/elftoolchain/libelftc/os.Linux.mk b/contrib/elftoolchain/libelftc/os.Linux.mk >index 9730bf6..7978005 100644 >--- a/contrib/elftoolchain/libelftc/os.Linux.mk >+++ b/contrib/elftoolchain/libelftc/os.Linux.mk >@@ -1,3 +1,3 @@ > # $Id: os.Linux.mk 994 2010-06-13 10:39:19Z jkoshy $ > >-CFLAGS+= -Wall >+CFLAGS+= -Wall -D_GNU_SOURCE >diff --git a/contrib/elftoolchain/readelf/readelf.1 b/contrib/elftoolchain/readelf/readelf.1 >index a71e85f..09e279173 100644 >--- a/contrib/elftoolchain/readelf/readelf.1 >+++ b/contrib/elftoolchain/readelf/readelf.1 >@@ -90,7 +90,7 @@ sections in the ELF object. > .It Fl e | Fl -headers > Print all program, file and section headers in the ELF object. > .It Fl g | Fl -section-groups >-This option is recognized, but is ignored. >+Print the contents of the section groups in the ELF object. > .It Fl h | Fl -file-header > Print the file header of the ELF object. > .It Fl l | Fl -program-headers >diff --git a/contrib/elftoolchain/readelf/readelf.c b/contrib/elftoolchain/readelf/readelf.c >index 29bc389..785f97e 100644 >--- a/contrib/elftoolchain/readelf/readelf.c >+++ b/contrib/elftoolchain/readelf/readelf.c >@@ -1,5 +1,5 @@ > /*- >- * Copyright (c) 2009-2014 Kai Wang >+ * Copyright (c) 2009-2015 Kai Wang > * All rights reserved. > * > * Redistribution and use in source and binary forms, with or without >@@ -302,6 +302,7 @@ static void dump_gnu_hash(struct readelf *re, struct section *s); > static void dump_hash(struct readelf *re); > static void dump_phdr(struct readelf *re); > static void dump_ppc_attributes(uint8_t *p, uint8_t *pe); >+static void dump_section_groups(struct readelf *re); > static void dump_symtab(struct readelf *re, int i); > static void dump_symtabs(struct readelf *re); > static uint8_t *dump_unknown_tag(uint64_t tag, uint8_t *p); >@@ -445,6 +446,7 @@ elf_machine(unsigned int mach) > case EM_SPARC: return "Sun SPARC"; > case EM_386: return "Intel i386"; > case EM_68K: return "Motorola 68000"; >+ case EM_IAMCU: return "Intel MCU"; > case EM_88K: return "Motorola 88000"; > case EM_860: return "Intel i860"; > case EM_MIPS: return "MIPS R3000 Big-Endian only"; >@@ -1050,6 +1052,7 @@ r_type(unsigned int mach, unsigned int type) > switch(mach) { > case EM_NONE: return ""; > case EM_386: >+ case EM_IAMCU: > switch(type) { > case 0: return "R_386_NONE"; > case 1: return "R_386_32"; >@@ -2381,6 +2384,7 @@ dwarf_reg(unsigned int mach, unsigned int reg) > > switch (mach) { > case EM_386: >+ case EM_IAMCU: > switch (reg) { > case 0: return "eax"; > case 1: return "ecx"; >@@ -4047,6 +4051,61 @@ dump_liblist(struct readelf *re) > > #undef Elf_Lib > >+static void >+dump_section_groups(struct readelf *re) >+{ >+ struct section *s; >+ const char *symname; >+ Elf_Data *d; >+ uint32_t *w; >+ int i, j, elferr; >+ size_t n; >+ >+ for (i = 0; (size_t) i < re->shnum; i++) { >+ s = &re->sl[i]; >+ if (s->type != SHT_GROUP) >+ continue; >+ (void) elf_errno(); >+ if ((d = elf_getdata(s->scn, NULL)) == NULL) { >+ elferr = elf_errno(); >+ if (elferr != 0) >+ warnx("elf_getdata failed: %s", >+ elf_errmsg(elferr)); >+ continue; >+ } >+ if (d->d_size <= 0) >+ continue; >+ >+ w = d->d_buf; >+ >+ /* We only support COMDAT section. */ >+#ifndef GRP_COMDAT >+#define GRP_COMDAT 0x1 >+#endif >+ if ((*w++ & GRP_COMDAT) == 0) >+ return; >+ >+ if (s->entsize == 0) >+ s->entsize = 4; >+ >+ symname = get_symbol_name(re, s->link, s->info); >+ n = s->sz / s->entsize; >+ if (n-- < 1) >+ return; >+ >+ printf("\nCOMDAT group section [%5d] `%s' [%s] contains %ju" >+ " sections:\n", i, s->name, symname, n); >+ printf(" %-10.10s %s\n", "[Index]", "Name"); >+ for (j = 0; (size_t) j < n; j++, w++) { >+ if (*w >= re->shnum) { >+ warnx("invalid section index: %u", *w); >+ continue; >+ } >+ printf(" [%5u] %s\n", *w, re->sl[*w].name); >+ } >+ } >+} >+ > static uint8_t * > dump_unknown_tag(uint64_t tag, uint8_t *p) > { >@@ -6838,6 +6897,8 @@ dump_elf(struct readelf *re) > dump_phdr(re); > if (re->options & RE_SS) > dump_shdr(re); >+ if (re->options & RE_G) >+ dump_section_groups(re); > if (re->options & RE_D) > dump_dynamic(re); > if (re->options & RE_R) >@@ -7311,7 +7372,7 @@ Usage: %s [options] file...\n\ > -c | --archive-index Print the archive symbol table for archives.\n\ > -d | --dynamic Print the contents of SHT_DYNAMIC sections.\n\ > -e | --headers Print all headers in the object.\n\ >- -g | --section-groups (accepted, but ignored)\n\ >+ -g | --section-groups Print the contents of the section groups.\n\ > -h | --file-header Print the file header for the object.\n\ > -l | --program-headers Print the PHDR table for the object.\n\ > -n | --notes Print the contents of SHT_NOTE sections.\n\ >@@ -7365,8 +7426,8 @@ main(int argc, char **argv) > re->options |= RE_AA; > break; > case 'a': >- re->options |= RE_AA | RE_D | RE_H | RE_II | RE_L | >- RE_R | RE_SS | RE_S | RE_VV; >+ re->options |= RE_AA | RE_D | RE_G | RE_H | RE_II | >+ RE_L | RE_R | RE_SS | RE_S | RE_VV; > break; > case 'c': > re->options |= RE_C; >diff --git a/lib/libelftc/elftc_version.c b/lib/libelftc/elftc_version.c >index fb0a731..ab11320 100644 >--- a/lib/libelftc/elftc_version.c >+++ b/lib/libelftc/elftc_version.c >@@ -6,5 +6,5 @@ > const char * > elftc_version(void) > { >- return "elftoolchain r3197M"; >+ return "elftoolchain r3222M"; > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 198611
:
154393
|
155564
|
156881
|
157132
|
157135
|
157136
|
157201