Author: emaste
Date: Tue Dec 30 03:25:42 2014
New Revision: 276398
URL: https://svnweb.freebsd.org/changeset/base/276398

Log:
  Update elftoolchain to upstream rev 3136
  
  This fixes two strip(1) issues found during ports exp-run and adds a
  string hash implementation which significantly speeds up certain
  operations on objects with large numbers of symbols.
  
  This also improves libdwarf handling for stripped objects with
  .eh_frame or .debug_frame (but not other debug) sections.
  
  PR:           196107
  Sponsored by: The FreeBSD Foundation

Modified:
  head/contrib/elftoolchain/elfcopy/elfcopy.h
  head/contrib/elftoolchain/elfcopy/sections.c
  head/contrib/elftoolchain/elfcopy/segments.c
  head/contrib/elftoolchain/elfcopy/symbols.c
  head/contrib/elftoolchain/libdwarf/libdwarf_abbrev.c
  head/contrib/elftoolchain/libdwarf/libdwarf_info.c
  head/contrib/elftoolchain/libdwarf/libdwarf_init.c
Directory Properties:
  head/contrib/elftoolchain/   (props changed)

Modified: head/contrib/elftoolchain/elfcopy/elfcopy.h
==============================================================================
--- head/contrib/elftoolchain/elfcopy/elfcopy.h Tue Dec 30 03:19:46 2014        
(r276397)
+++ head/contrib/elftoolchain/elfcopy/elfcopy.h Tue Dec 30 03:25:42 2014        
(r276398)
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Id: elfcopy.h 2970 2013-12-01 15:22:12Z kaiwang27 $
+ * $Id: elfcopy.h 3134 2014-12-23 10:43:59Z kaiwang27 $
  */
 
 #include <sys/queue.h>
@@ -115,6 +115,7 @@ struct segment;
 /* Internal data structure for sections. */
 struct section {
        struct segment  *seg;   /* containing segment */
+       struct segment  *seg_tls; /* tls segment */
        const char      *name;  /* section name */
        char            *newname; /* new section name */
        Elf_Scn         *is;    /* input scn */

Modified: head/contrib/elftoolchain/elfcopy/sections.c
==============================================================================
--- head/contrib/elftoolchain/elfcopy/sections.c        Tue Dec 30 03:19:46 
2014        (r276397)
+++ head/contrib/elftoolchain/elfcopy/sections.c        Tue Dec 30 03:25:42 
2014        (r276398)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2007-2011 Kai Wang
+ * Copyright (c) 2007-2011,2014 Kai Wang
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,7 +35,7 @@
 
 #include "elfcopy.h"
 
-ELFTC_VCSID("$Id: sections.c 3126 2014-12-21 08:03:31Z kaiwang27 $");
+ELFTC_VCSID("$Id: sections.c 3134 2014-12-23 10:43:59Z kaiwang27 $");
 
 static void    add_gnu_debuglink(struct elfcopy *ecp);
 static uint32_t calc_crc32(const char *p, size_t len, uint32_t crc);
@@ -485,7 +485,10 @@ insert_shtab(struct elfcopy *ecp, int ta
        if ((shtab = calloc(1, sizeof(*shtab))) == NULL)
                errx(EXIT_FAILURE, "calloc failed");
        if (!tail) {
-               /* shoff of input object is used as a hint. */
+               /*
+                * "shoff" of input object is used as a hint for section
+                * resync later.
+                */
                if (gelf_getehdr(ecp->ein, &ieh) == NULL)
                        errx(EXIT_FAILURE, "gelf_getehdr() failed: %s",
                            elf_errmsg(-1));
@@ -764,6 +767,15 @@ resync_sections(struct elfcopy *ecp)
                        first = 0;
                }
 
+               /*
+                * Ignore TLS sections with load address 0 and without
+                * content. We don't need to adjust their file offset or
+                * VMA, only the size matters.
+                */
+               if (s->seg_tls != NULL && s->type == SHT_NOBITS &&
+                   s->off == 0)
+                       continue;
+
                /* Align section offset. */
                if (off <= s->off) {
                        if (!s->loadable)
@@ -1050,6 +1062,17 @@ copy_data(struct section *s)
                od->d_size      = id->d_size;
                od->d_version   = id->d_version;
        }
+
+       /*
+        * Alignment Fixup. libelf does not allow the alignment for
+        * Elf_Data descriptor to be set to 0. In this case we workaround
+        * it by setting the alignment to 1.
+        *
+        * According to the ELF ABI, alignment 0 and 1 has the same
+        * meaning: the section has no alignment constraints.
+        */
+       if (od->d_align == 0)
+               od->d_align = 1;
 }
 
 struct section *

Modified: head/contrib/elftoolchain/elfcopy/segments.c
==============================================================================
--- head/contrib/elftoolchain/elfcopy/segments.c        Tue Dec 30 03:19:46 
2014        (r276397)
+++ head/contrib/elftoolchain/elfcopy/segments.c        Tue Dec 30 03:25:42 
2014        (r276398)
@@ -35,7 +35,7 @@
 
 #include "elfcopy.h"
 
-ELFTC_VCSID("$Id: segments.c 3113 2014-12-20 08:33:29Z kaiwang27 $");
+ELFTC_VCSID("$Id: segments.c 3134 2014-12-23 10:43:59Z kaiwang27 $");
 
 static void    insert_to_inseg_list(struct segment *seg, struct section *sec);
 
@@ -86,6 +86,8 @@ add_to_inseg_list(struct elfcopy *ecp, s
                insert_to_inseg_list(seg, s);
                if (seg->type == PT_LOAD)
                        s->seg = seg;
+               else if (seg->type == PT_TLS)
+                       s->seg_tls = seg;
                s->lma = seg->addr + (s->off - seg->off);
                loadable = 1;
        }

Modified: head/contrib/elftoolchain/elfcopy/symbols.c
==============================================================================
--- head/contrib/elftoolchain/elfcopy/symbols.c Tue Dec 30 03:19:46 2014        
(r276397)
+++ head/contrib/elftoolchain/elfcopy/symbols.c Tue Dec 30 03:25:42 2014        
(r276398)
@@ -34,7 +34,7 @@
 
 #include "elfcopy.h"
 
-ELFTC_VCSID("$Id: symbols.c 3019 2014-04-17 14:53:40Z jkoshy $");
+ELFTC_VCSID("$Id: symbols.c 3135 2014-12-24 08:22:43Z kaiwang27 $");
 
 /* Symbol table buffer structure. */
 struct symbuf {
@@ -46,12 +46,25 @@ struct symbuf {
        size_t gcap, lcap;      /* buffer capacities. */
 };
 
+struct sthash {
+       LIST_ENTRY(sthash) sh_next;
+       size_t sh_off;
+};
+typedef LIST_HEAD(,sthash) hash_head;
+#define STHASHSIZE 65536
+
+struct strimpl {
+       char *buf;              /* string table */
+       size_t sz;              /* entries */
+       size_t cap;             /* buffer capacity */
+       hash_head hash[STHASHSIZE];
+};
+
+
 /* String table buffer structure. */
 struct strbuf {
-       char *l;                /* local symbol string table */
-       char *g;                /* global symbol string table */
-       size_t lsz, gsz;        /* size of each kind */
-       size_t gcap, lcap;      /* buffer capacities. */
+       struct strimpl l;       /* local symbols */
+       struct strimpl g;       /* global symbols */
 };
 
 static int     is_debug_symbol(unsigned char st_info);
@@ -62,10 +75,12 @@ static int  is_needed_symbol(struct elfco
 static int     is_remove_symbol(struct elfcopy *ecp, size_t sc, int i,
                    GElf_Sym *s, const char *name);
 static int     is_weak_symbol(unsigned char st_info);
-static int     lookup_exact_string(const char *buf, size_t sz, const char *s);
+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 int     match_wildcard(const char *name, const char *pattern);
+uint32_t       str_hash(const char *s);
 
 /* Convenient bit vector operation macros. */
 #define BIT_SET(v, n) (v[(n)>>3] |= 1U << ((n) & 7))
@@ -316,10 +331,10 @@ generate_symbols(struct elfcopy *ecp)
        if ((st_buf = calloc(1, sizeof(*st_buf))) == NULL)
                err(EXIT_FAILURE, "calloc failed");
        sy_buf->gcap = sy_buf->lcap = 64;
-       st_buf->gcap = 256;
-       st_buf->lcap = 64;
-       st_buf->lsz = 1;        /* '\0' at start. */
-       st_buf->gsz = 0;
+       st_buf->g.cap = 256;
+       st_buf->l.cap = 64;
+       st_buf->l.sz = 1;       /* '\0' at start. */
+       st_buf->g.sz = 0;
 
        ecp->symtab->sz = 0;
        ecp->strtab->sz = 0;
@@ -541,10 +556,10 @@ generate_symbols(struct elfcopy *ecp)
                        /* Update st_name. */
                        if (ec == ELFCLASS32)
                                sy_buf->g32[ecp->symndx[i]].st_name +=
-                                   st_buf->lsz;
+                                   st_buf->l.sz;
                        else
                                sy_buf->g64[ecp->symndx[i]].st_name +=
-                                   st_buf->lsz;
+                                   st_buf->l.sz;
 
                        /* Update index map. */
                        ecp->symndx[i] += sy_buf->nls;
@@ -633,6 +648,8 @@ free_symtab(struct elfcopy *ecp)
 {
        struct symbuf   *sy_buf;
        struct strbuf   *st_buf;
+       struct sthash   *sh, *shtmp;
+       int i;
 
        if (ecp->symtab != NULL && ecp->symtab->buf != NULL) {
                sy_buf = ecp->symtab->buf;
@@ -648,10 +665,22 @@ free_symtab(struct elfcopy *ecp)
 
        if (ecp->strtab != NULL && ecp->strtab->buf != NULL) {
                st_buf = ecp->strtab->buf;
-               if (st_buf->l != NULL)
-                       free(st_buf->l);
-               if (st_buf->g != NULL)
-                       free(st_buf->g);
+               if (st_buf->l.buf != NULL)
+                       free(st_buf->l.buf);
+               if (st_buf->g.buf != NULL)
+                       free(st_buf->g.buf);
+               for (i = 0; i < STHASHSIZE; i++) {
+                       LIST_FOREACH_SAFE(sh, &st_buf->l.hash[i], sh_next,
+                           shtmp) {
+                               LIST_REMOVE(sh, sh_next);
+                               free(sh);
+                       }
+                       LIST_FOREACH_SAFE(sh, &st_buf->g.hash[i], sh_next,
+                           shtmp) {
+                               LIST_REMOVE(sh, sh_next);
+                               free(sh);
+                       }
+               }
        }
 }
 
@@ -689,10 +718,10 @@ create_external_symtab(struct elfcopy *e
        if ((st_buf = calloc(1, sizeof(*st_buf))) == NULL)
                err(EXIT_FAILURE, "calloc failed");
        sy_buf->gcap = sy_buf->lcap = 64;
-       st_buf->gcap = 256;
-       st_buf->lcap = 64;
-       st_buf->lsz = 1;        /* '\0' at start. */
-       st_buf->gsz = 0;
+       st_buf->g.cap = 256;
+       st_buf->l.cap = 64;
+       st_buf->l.sz = 1;       /* '\0' at start. */
+       st_buf->g.sz = 0;
 
        ecp->symtab->sz = 0;
        ecp->strtab->sz = 0;
@@ -729,6 +758,8 @@ add_to_symtab(struct elfcopy *ecp, const
 {
        struct symbuf *sy_buf;
        struct strbuf *st_buf;
+       struct sthash *sh;
+       uint32_t hash;
        int pos;
 
        /*
@@ -761,32 +792,39 @@ add_to_symtab(struct elfcopy *ecp, const
        else                                                            \
                sy_buf->B##SZ[sy_buf->n##B##s].st_shndx =               \
                        ecp->secndx[st_shndx];                          \
-       if (st_buf->B == NULL) {                                        \
-               st_buf->B = calloc(st_buf->B##cap, sizeof(*st_buf->B)); \
-               if (st_buf->B == NULL)                                  \
+       if (st_buf->B.buf == NULL) {                                    \
+               st_buf->B.buf = calloc(st_buf->B.cap,                   \
+                   sizeof(*st_buf->B.buf));                            \
+               if (st_buf->B.buf == NULL)                              \
                        err(EXIT_FAILURE, "malloc failed");             \
        }                                                               \
        if (name != NULL && *name != '\0') {                            \
-               pos = lookup_exact_string(st_buf->B,                    \
-                   st_buf->B##sz, name);                               \
+               pos = lookup_exact_string(st_buf->B.hash, st_buf->B.buf,\
+                   name);                                              \
                if (pos != -1)                                          \
                        sy_buf->B##SZ[sy_buf->n##B##s].st_name = pos;   \
                else {                                                  \
                        sy_buf->B##SZ[sy_buf->n##B##s].st_name =        \
-                           st_buf->B##sz;                              \
-                       while (st_buf->B##sz + strlen(name) >=          \
-                           st_buf->B##cap - 1) {                       \
-                               st_buf->B##cap *= 2;                    \
-                               st_buf->B = realloc(st_buf->B,          \
-                                   st_buf->B##cap);                    \
-                               if (st_buf->B == NULL)                  \
+                           st_buf->B.sz;                               \
+                       while (st_buf->B.sz + strlen(name) >=           \
+                           st_buf->B.cap - 1) {                        \
+                               st_buf->B.cap *= 2;                     \
+                               st_buf->B.buf = realloc(st_buf->B.buf,  \
+                                   st_buf->B.cap);                     \
+                               if (st_buf->B.buf == NULL)              \
                                        err(EXIT_FAILURE,               \
                                            "realloc failed");          \
                        }                                               \
-                       strncpy(&st_buf->B[st_buf->B##sz], name,        \
+                       if ((sh = malloc(sizeof(*sh))) == NULL)         \
+                               err(EXIT_FAILURE, "malloc failed");     \
+                       sh->sh_off = st_buf->B.sz;                      \
+                       hash = str_hash(name);                          \
+                       LIST_INSERT_HEAD(&st_buf->B.hash[hash], sh,     \
+                           sh_next);                                   \
+                       strncpy(&st_buf->B.buf[st_buf->B.sz], name,     \
                            strlen(name));                              \
-                       st_buf->B[st_buf->B##sz + strlen(name)] = '\0'; \
-                       st_buf->B##sz += strlen(name) + 1;              \
+                       st_buf->B.buf[st_buf->B.sz + strlen(name)] = '\0'; \
+                       st_buf->B.sz += strlen(name) + 1;               \
                }                                                       \
        } else                                                          \
                sy_buf->B##SZ[sy_buf->n##B##s].st_name = 0;             \
@@ -811,7 +849,7 @@ add_to_symtab(struct elfcopy *ecp, const
        /* Update section size. */
        ecp->symtab->sz = (sy_buf->nls + sy_buf->ngs) *
            (ecp->oec == ELFCLASS32 ? sizeof(Elf32_Sym) : sizeof(Elf64_Sym));
-       ecp->strtab->sz = st_buf->lsz + st_buf->gsz;
+       ecp->strtab->sz = st_buf->l.sz + st_buf->g.sz;
 
 #undef _ADDSYM
 }
@@ -831,9 +869,9 @@ finalize_external_symtab(struct elfcopy 
        st_buf = ecp->strtab->buf;
        for (i = 0; (size_t) i < sy_buf->ngs; i++) {
                if (ecp->oec == ELFCLASS32)
-                       sy_buf->g32[i].st_name += st_buf->lsz;
+                       sy_buf->g32[i].st_name += st_buf->l.sz;
                else
-                       sy_buf->g64[i].st_name += st_buf->lsz;
+                       sy_buf->g64[i].st_name += st_buf->l.sz;
        }
 }
 
@@ -920,19 +958,19 @@ create_symtab_data(struct elfcopy *ecp)
                    elf_errmsg(-1));
        lstdata->d_align        = 1;
        lstdata->d_off          = 0;
-       lstdata->d_buf          = st_buf->l;
-       lstdata->d_size         = st_buf->lsz;
+       lstdata->d_buf          = st_buf->l.buf;
+       lstdata->d_size         = st_buf->l.sz;
        lstdata->d_type         = ELF_T_BYTE;
        lstdata->d_version      = EV_CURRENT;
 
-       if (st_buf->gsz > 0) {
+       if (st_buf->g.sz > 0) {
                if ((gstdata = elf_newdata(st->os)) == NULL)
                        errx(EXIT_FAILURE, "elf_newdata() failed: %s.",
                            elf_errmsg(-1));
                gstdata->d_align        = 1;
                gstdata->d_off          = lstdata->d_size;
-               gstdata->d_buf          = st_buf->g;
-               gstdata->d_size         = st_buf->gsz;
+               gstdata->d_buf          = st_buf->g.buf;
+               gstdata->d_size         = st_buf->g.sz;
                gstdata->d_type         = ELF_T_BYTE;
                gstdata->d_version      = EV_CURRENT;
        }
@@ -1022,18 +1060,25 @@ lookup_symop_list(struct elfcopy *ecp, c
 }
 
 static int
-lookup_exact_string(const char *buf, size_t sz, const char *s)
+lookup_exact_string(hash_head *buckets, const char *buf, const char *s)
 {
-       const char      *b;
-       size_t           slen;
-
-       slen = strlen(s);
-       for (b = buf; b < buf + sz; b += strlen(b) + 1) {
-               if (strlen(b) != slen)
-                       continue;
-               if (!strcmp(b, s))
-                       return (b - buf);
-       }
+       struct sthash   *sh;
+       uint32_t         hash;
 
+       hash = str_hash(s);
+       LIST_FOREACH(sh, &buckets[hash], sh_next)
+               if (strcmp(buf + sh->sh_off, s) == 0)
+                       return sh->sh_off;
        return (-1);
 }
+
+uint32_t
+str_hash(const char *s)
+{
+       uint32_t hash;
+
+       for (hash = 2166136261; *s; s++)
+               hash = (hash ^ *s) * 16777619;
+
+       return (hash & (STHASHSIZE - 1));
+}

Modified: head/contrib/elftoolchain/libdwarf/libdwarf_abbrev.c
==============================================================================
--- head/contrib/elftoolchain/libdwarf/libdwarf_abbrev.c        Tue Dec 30 
03:19:46 2014        (r276397)
+++ head/contrib/elftoolchain/libdwarf/libdwarf_abbrev.c        Tue Dec 30 
03:25:42 2014        (r276398)
@@ -27,7 +27,7 @@
 
 #include "_libdwarf.h"
 
-ELFTC_VCSID("$Id: libdwarf_abbrev.c 2070 2011-10-27 03:05:32Z jkoshy $");
+ELFTC_VCSID("$Id: libdwarf_abbrev.c 3136 2014-12-24 16:04:38Z kaiwang27 $");
 
 int
 _dwarf_abbrev_add(Dwarf_CU cu, uint64_t entry, uint64_t tag, uint8_t children,
@@ -180,7 +180,9 @@ _dwarf_abbrev_find(Dwarf_CU cu, uint64_t
 
        /* Load and search the abbrev table. */
        ds = _dwarf_find_section(cu->cu_dbg, ".debug_abbrev");
-       assert(ds != NULL);
+       if (ds == NULL)
+               return (DW_DLE_NO_ENTRY);
+
        offset = cu->cu_abbrev_offset_cur;
        while (offset < ds->ds_size) {
                ret = _dwarf_abbrev_parse(cu->cu_dbg, cu, &offset, &ab, error);

Modified: head/contrib/elftoolchain/libdwarf/libdwarf_info.c
==============================================================================
--- head/contrib/elftoolchain/libdwarf/libdwarf_info.c  Tue Dec 30 03:19:46 
2014        (r276397)
+++ head/contrib/elftoolchain/libdwarf/libdwarf_info.c  Tue Dec 30 03:25:42 
2014        (r276398)
@@ -27,7 +27,7 @@
 
 #include "_libdwarf.h"
 
-ELFTC_VCSID("$Id: libdwarf_info.c 3041 2014-05-18 15:11:03Z kaiwang27 $");
+ELFTC_VCSID("$Id: libdwarf_info.c 3136 2014-12-24 16:04:38Z kaiwang27 $");
 
 int
 _dwarf_info_first_cu(Dwarf_Debug dbg, Dwarf_Error *error)
@@ -153,7 +153,8 @@ _dwarf_info_load(Dwarf_Debug dbg, Dwarf_
                        return (ret);
                offset = dbg->dbg_info_off;
                ds = dbg->dbg_info_sec;
-               assert(ds != NULL);
+               if (ds == NULL)
+                       return (DW_DLE_NO_ENTRY);
        } else {
                if (dbg->dbg_types_loaded)
                        return (ret);

Modified: head/contrib/elftoolchain/libdwarf/libdwarf_init.c
==============================================================================
--- head/contrib/elftoolchain/libdwarf/libdwarf_init.c  Tue Dec 30 03:19:46 
2014        (r276397)
+++ head/contrib/elftoolchain/libdwarf/libdwarf_init.c  Tue Dec 30 03:25:42 
2014        (r276398)
@@ -26,7 +26,7 @@
 
 #include "_libdwarf.h"
 
-ELFTC_VCSID("$Id: libdwarf_init.c 3061 2014-06-02 00:42:41Z kaiwang27 $");
+ELFTC_VCSID("$Id: libdwarf_init.c 3136 2014-12-24 16:04:38Z kaiwang27 $");
 
 static int
 _dwarf_consumer_init(Dwarf_Debug dbg, Dwarf_Error *error)
@@ -93,12 +93,7 @@ _dwarf_consumer_init(Dwarf_Debug dbg, Dw
        }
        dbg->dbg_section[cnt].ds_name = NULL;
 
-       if (_dwarf_find_section(dbg, ".debug_abbrev") == NULL ||
-           ((dbg->dbg_info_sec = _dwarf_find_section(dbg, ".debug_info")) ==
-            NULL)) {
-               DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_INFO_NULL);
-               return (DW_DLE_DEBUG_INFO_NULL);
-       }
+       dbg->dbg_info_sec = _dwarf_find_section(dbg, ".debug_info");
 
        /* Try to find the optional DWARF4 .debug_types section. */
        dbg->dbg_types_sec = _dwarf_find_next_types_section(dbg, NULL);
_______________________________________________
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