Import elftoolchain rev 3136
From svn.code.sf.net/p/elftoolchain/code/trunk
This commit is contained in:
parent
5eccfb5cf5
commit
42bfa111d7
|
@ -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 */
|
||||
|
|
|
@ -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 tail)
|
|||
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 *
|
||||
|
|
|
@ -34,7 +34,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);
|
||||
|
||||
|
@ -85,6 +85,8 @@ add_to_inseg_list(struct elfcopy *ecp, struct section *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;
|
||||
}
|
||||
|
|
|
@ -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 elfcopy *ecp, int i, GElf_Sym *s);
|
|||
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 *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;
|
||||
|
@ -729,6 +758,8 @@ add_to_symtab(struct elfcopy *ecp, const char *name, uint64_t st_value,
|
|||
{
|
||||
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 char *name, uint64_t st_value,
|
|||
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 char *name, uint64_t st_value,
|
|||
/* 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 *ecp)
|
|||
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, const char *name, unsigned int op)
|
|||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
|
|
@ -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 entry, Dwarf_Abbrev *abp,
|
|||
|
||||
/* 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);
|
||||
|
|
|
@ -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_Bool load_all, Dwarf_Bool is_info,
|
|||
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);
|
||||
|
|
|
@ -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, Dwarf_Error *error)
|
|||
}
|
||||
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);
|
||||
|
|
Loading…
Reference in New Issue