Author: emaste
Date: Wed May 27 14:28:19 2015
New Revision: 283616
URL: https://svnweb.freebsd.org/changeset/base/283616

Log:
  Update to ELF Tool Chain r3223
  
  Highlights (upstream revisions):
   - Fix SHT_GROUP handling in elfcopy/strip (3206 3220 3221)
   - Misc elfcopy / strip bug fixes (3215 3216 3217)
   - Many C++ demangler improvements (3199 3200 3201 3202 3203 3204 3205
     3208 3210 3211 3212)
   - Improve GNU binutils compatibility in elfcopy / strip (3213 3214)
   - Add -g option to readelf(1): dump contents of section groups (3219)
   - Add EM_IAMCU 32-bit Intel MCU (3198)
  
  Also add a compat #define for building with older FreeBSD ELF headers.
  The GRP_COMDAT flag was added to elf_common.h in r283110, but it's not
  available during the bootstrap build.  It is also convenient to be able
  to build on older hosts.
  
  Thanks to antoine@ for tracking down issues through multiple exp-runs
  and to kaiw@ for fixing.
  
  PR:           198611 (exp-run), 200350
  Sponsored by: The FreeBSD Foundation

Modified:
  head/contrib/elftoolchain/common/_elftc.h
  head/contrib/elftoolchain/common/elfdefinitions.h
  head/contrib/elftoolchain/elfcopy/elfcopy.h
  head/contrib/elftoolchain/elfcopy/main.c
  head/contrib/elftoolchain/elfcopy/sections.c
  head/contrib/elftoolchain/elfcopy/symbols.c
  head/contrib/elftoolchain/libdwarf/libdwarf_reloc.c
  head/contrib/elftoolchain/libelftc/libelftc_dem_gnu3.c
  head/contrib/elftoolchain/libelftc/os.Linux.mk
  head/contrib/elftoolchain/readelf/readelf.1
  head/contrib/elftoolchain/readelf/readelf.c
  head/lib/libelftc/elftc_version.c
Directory Properties:
  head/contrib/elftoolchain/   (props changed)

Modified: head/contrib/elftoolchain/common/_elftc.h
==============================================================================
--- head/contrib/elftoolchain/common/_elftc.h   Wed May 27 14:16:42 2015        
(r283615)
+++ head/contrib/elftoolchain/common/_elftc.h   Wed May 27 14:28:19 2015        
(r283616)
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Id: _elftc.h 3175 2015-03-27 17:21:24Z emaste $
+ * $Id: _elftc.h 3209 2015-05-17 13:40:46Z kaiwang27 $
  */
 
 /**
@@ -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
 

Modified: head/contrib/elftoolchain/common/elfdefinitions.h
==============================================================================
--- head/contrib/elftoolchain/common/elfdefinitions.h   Wed May 27 14:16:42 
2015        (r283615)
+++ head/contrib/elftoolchain/common/elfdefinitions.h   Wed May 27 14:28:19 
2015        (r283616)
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Id: elfdefinitions.h 3178 2015-03-30 18:29:13Z emaste $
+ * $Id: elfdefinitions.h 3198 2015-05-14 18:36:19Z emaste $
  */
 
 /*
@@ -565,6 +565,7 @@ _ELF_DEFINE_EM(EM_SPARC,            2, "
 _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")     \

Modified: head/contrib/elftoolchain/elfcopy/elfcopy.h
==============================================================================
--- head/contrib/elftoolchain/elfcopy/elfcopy.h Wed May 27 14:16:42 2015        
(r283615)
+++ head/contrib/elftoolchain/elfcopy/elfcopy.h Wed May 27 14:28:19 2015        
(r283616)
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Id: elfcopy.h 3173 2015-03-27 16:46:13Z emaste $
+ * $Id: elfcopy.h 3221 2015-05-24 23:42:43Z kaiwang27 $
  */
 
 #include <sys/queue.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. */

Modified: head/contrib/elftoolchain/elfcopy/main.c
==============================================================================
--- head/contrib/elftoolchain/elfcopy/main.c    Wed May 27 14:16:42 2015        
(r283615)
+++ head/contrib/elftoolchain/elfcopy/main.c    Wed May 27 14:28:19 2015        
(r283616)
@@ -39,7 +39,7 @@
 
 #include "elfcopy.h"
 
-ELFTC_VCSID("$Id: main.c 3174 2015-03-27 17:13:41Z emaste $");
+ELFTC_VCSID("$Id: main.c 3216 2015-05-23 21:16:36Z kaiwang27 $");
 
 enum options
 {
@@ -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. */

Modified: head/contrib/elftoolchain/elfcopy/sections.c
==============================================================================
--- head/contrib/elftoolchain/elfcopy/sections.c        Wed May 27 14:16:42 
2015        (r283615)
+++ head/contrib/elftoolchain/elfcopy/sections.c        Wed May 27 14:28:19 
2015        (r283616)
@@ -34,7 +34,7 @@
 
 #include "elfcopy.h"
 
-ELFTC_VCSID("$Id: sections.c 3185 2015-04-11 08:56:34Z kaiwang27 $");
+ELFTC_VCSID("$Id: sections.c 3220 2015-05-24 23:42:39Z kaiwang27 $");
 
 static void    add_gnu_debuglink(struct elfcopy *ecp);
 static uint32_t calc_crc32(const char *p, size_t len, uint32_t crc);
@@ -56,6 +56,7 @@ static void   print_data(const char *d, si
 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 se
                                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)

Modified: head/contrib/elftoolchain/elfcopy/symbols.c
==============================================================================
--- head/contrib/elftoolchain/elfcopy/symbols.c Wed May 27 14:16:42 2015        
(r283615)
+++ head/contrib/elftoolchain/elfcopy/symbols.c Wed May 27 14:28:19 2015        
(r283616)
@@ -33,7 +33,7 @@
 
 #include "elfcopy.h"
 
-ELFTC_VCSID("$Id: symbols.c 3191 2015-05-04 17:07:01Z jkoshy $");
+ELFTC_VCSID("$Id: symbols.c 3222 2015-05-24 23:47:23Z kaiwang27 $");
 
 /* Symbol table buffer structure. */
 struct symbuf {
@@ -77,7 +77,8 @@ static int    is_weak_symbol(unsigned char 
 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, in
        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, si
                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, si
  * 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
                    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

Modified: head/contrib/elftoolchain/libdwarf/libdwarf_reloc.c
==============================================================================
--- head/contrib/elftoolchain/libdwarf/libdwarf_reloc.c Wed May 27 14:16:42 
2015        (r283615)
+++ head/contrib/elftoolchain/libdwarf/libdwarf_reloc.c Wed May 27 14:28:19 
2015        (r283616)
@@ -26,7 +26,7 @@
 
 #include "_libdwarf.h"
 
-ELFTC_VCSID("$Id: libdwarf_reloc.c 3149 2015-02-15 19:00:06Z emaste $");
+ELFTC_VCSID("$Id: libdwarf_reloc.c 3198 2015-05-14 18:36:19Z emaste $");
 
 Dwarf_Unsigned
 _dwarf_get_reloc_type(Dwarf_P_Debug dbg, int is64)
@@ -75,6 +75,7 @@ _dwarf_get_reloc_size(Dwarf_Debug dbg, D
                        return (4);
                break;
        case EM_386:
+       case EM_IAMCU:
                if (rel_type == R_386_32)
                        return (4);
                break;

Modified: head/contrib/elftoolchain/libelftc/libelftc_dem_gnu3.c
==============================================================================
--- head/contrib/elftoolchain/libelftc/libelftc_dem_gnu3.c      Wed May 27 
14:16:42 2015        (r283615)
+++ head/contrib/elftoolchain/libelftc/libelftc_dem_gnu3.c      Wed May 27 
14:28:19 2015        (r283616)
@@ -36,7 +36,7 @@
 
 #include "_libelftc.h"
 
-ELFTC_VCSID("$Id: libelftc_dem_gnu3.c 3194 2015-05-05 17:55:16Z emaste $");
+ELFTC_VCSID("$Id: libelftc_dem_gnu3.c 3212 2015-05-17 13:40:55Z kaiwang27 $");
 
 /**
  * @file cpp_demangle.c
@@ -50,7 +50,7 @@ ELFTC_VCSID("$Id: libelftc_dem_gnu3.c 31
 
 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(struc
 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(st
 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(st
 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(st
 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_demang
        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
        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
 
        free(f);
 
+       ++ddata->cur;
+
        return (rtn);
 }
 
@@ -331,7 +339,7 @@ cpp_demangle_push_str(struct cpp_demangl
        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 
                        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 
                        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 
                        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 
                        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 
                                        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 
                        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 
                        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 
                        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 cp
 
        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 cp
                        ++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_
 }
 
 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_de
 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_de
                        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_de
                        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_de
                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_demang
        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

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to