Use FreeBSD's libdwarf which is BSD licensed instead of the GPL'd one that
is used in Solaris.
This commit is contained in:
parent
c01977ed3b
commit
e9c7a60421
@ -84,6 +84,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <libelf.h>
|
#include <libelf.h>
|
||||||
@ -128,7 +129,7 @@
|
|||||||
typedef struct dwarf {
|
typedef struct dwarf {
|
||||||
Dwarf_Debug dw_dw; /* for libdwarf */
|
Dwarf_Debug dw_dw; /* for libdwarf */
|
||||||
Dwarf_Error dw_err; /* for libdwarf */
|
Dwarf_Error dw_err; /* for libdwarf */
|
||||||
Dwarf_Unsigned dw_maxoff; /* highest legal offset in this cu */
|
Dwarf_Off dw_maxoff; /* highest legal offset in this cu */
|
||||||
tdata_t *dw_td; /* root of the tdesc/iidesc tree */
|
tdata_t *dw_td; /* root of the tdesc/iidesc tree */
|
||||||
hash_t *dw_tidhash; /* hash of tdescs by t_id */
|
hash_t *dw_tidhash; /* hash of tdescs by t_id */
|
||||||
hash_t *dw_fwdhash; /* hash of fwd decls by name */
|
hash_t *dw_fwdhash; /* hash of fwd decls by name */
|
||||||
@ -159,11 +160,12 @@ tdesc_add(dwarf_t *dw, tdesc_t *tdp)
|
|||||||
static tdesc_t *
|
static tdesc_t *
|
||||||
tdesc_lookup(dwarf_t *dw, int tid)
|
tdesc_lookup(dwarf_t *dw, int tid)
|
||||||
{
|
{
|
||||||
tdesc_t tmpl, *tdp;
|
tdesc_t tmpl;
|
||||||
|
void *tdp;
|
||||||
|
|
||||||
tmpl.t_id = tid;
|
tmpl.t_id = tid;
|
||||||
|
|
||||||
if (hash_find(dw->dw_tidhash, &tmpl, (void **)&tdp))
|
if (hash_find(dw->dw_tidhash, &tmpl, &tdp))
|
||||||
return (tdp);
|
return (tdp);
|
||||||
else
|
else
|
||||||
return (NULL);
|
return (NULL);
|
||||||
@ -271,7 +273,7 @@ die_off(dwarf_t *dw, Dwarf_Die die)
|
|||||||
return (off);
|
return (off);
|
||||||
|
|
||||||
terminate("failed to get offset for die: %s\n",
|
terminate("failed to get offset for die: %s\n",
|
||||||
dwarf_errmsg(dw->dw_err));
|
dwarf_errmsg(&dw->dw_err));
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -289,7 +291,7 @@ die_sibling(dwarf_t *dw, Dwarf_Die die)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
terminate("die %llu: failed to find type sibling: %s\n",
|
terminate("die %llu: failed to find type sibling: %s\n",
|
||||||
die_off(dw, die), dwarf_errmsg(dw->dw_err));
|
die_off(dw, die), dwarf_errmsg(&dw->dw_err));
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
@ -306,7 +308,7 @@ die_child(dwarf_t *dw, Dwarf_Die die)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
terminate("die %llu: failed to find type child: %s\n",
|
terminate("die %llu: failed to find type child: %s\n",
|
||||||
die_off(dw, die), dwarf_errmsg(dw->dw_err));
|
die_off(dw, die), dwarf_errmsg(&dw->dw_err));
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
@ -320,7 +322,7 @@ die_tag(dwarf_t *dw, Dwarf_Die die)
|
|||||||
return (tag);
|
return (tag);
|
||||||
|
|
||||||
terminate("die %llu: failed to get tag for type: %s\n",
|
terminate("die %llu: failed to get tag for type: %s\n",
|
||||||
die_off(dw, die), dwarf_errmsg(dw->dw_err));
|
die_off(dw, die), dwarf_errmsg(&dw->dw_err));
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -343,43 +345,23 @@ die_attr(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, int req)
|
|||||||
}
|
}
|
||||||
|
|
||||||
terminate("die %llu: failed to get attribute for type: %s\n",
|
terminate("die %llu: failed to get attribute for type: %s\n",
|
||||||
die_off(dw, die), dwarf_errmsg(dw->dw_err));
|
die_off(dw, die), dwarf_errmsg(&dw->dw_err));
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Dwarf_Half
|
|
||||||
die_attr_form(dwarf_t *dw, Dwarf_Attribute attr)
|
|
||||||
{
|
|
||||||
Dwarf_Half form;
|
|
||||||
|
|
||||||
if (dwarf_whatform(attr, &form, &dw->dw_err) == DW_DLV_OK)
|
|
||||||
return (form);
|
|
||||||
|
|
||||||
terminate("failed to get attribute form for type: %s\n",
|
|
||||||
dwarf_errmsg(dw->dw_err));
|
|
||||||
/*NOTREACHED*/
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
die_signed(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, Dwarf_Signed *valp,
|
die_signed(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, Dwarf_Signed *valp,
|
||||||
int req)
|
int req)
|
||||||
{
|
{
|
||||||
Dwarf_Attribute attr;
|
*valp = 0;
|
||||||
Dwarf_Signed val;
|
if (dwarf_attrval_signed(die, name, valp, &dw->dw_err) != DWARF_E_NONE) {
|
||||||
|
if (req)
|
||||||
if ((attr = die_attr(dw, die, name, req)) == NULL)
|
terminate("die %llu: failed to get signed: %s\n",
|
||||||
return (0); /* die_attr will terminate for us if necessary */
|
die_off(dw, die), dwarf_errmsg(&dw->dw_err));
|
||||||
|
return (0);
|
||||||
if (dwarf_formsdata(attr, &val, &dw->dw_err) != DW_DLV_OK) {
|
|
||||||
terminate("die %llu: failed to get signed (form 0x%x)\n",
|
|
||||||
die_off(dw, die), die_attr_form(dw, attr));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dwarf_dealloc(dw->dw_dw, attr, DW_DLA_ATTR);
|
|
||||||
|
|
||||||
*valp = val;
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,59 +369,47 @@ static int
|
|||||||
die_unsigned(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, Dwarf_Unsigned *valp,
|
die_unsigned(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, Dwarf_Unsigned *valp,
|
||||||
int req)
|
int req)
|
||||||
{
|
{
|
||||||
Dwarf_Attribute attr;
|
*valp = 0;
|
||||||
Dwarf_Unsigned val;
|
if (dwarf_attrval_unsigned(die, name, valp, &dw->dw_err) != DWARF_E_NONE) {
|
||||||
|
if (req)
|
||||||
if ((attr = die_attr(dw, die, name, req)) == NULL)
|
terminate("die %llu: failed to get unsigned: %s\n",
|
||||||
return (0); /* die_attr will terminate for us if necessary */
|
die_off(dw, die), dwarf_errmsg(&dw->dw_err));
|
||||||
|
return (0);
|
||||||
if (dwarf_formudata(attr, &val, &dw->dw_err) != DW_DLV_OK) {
|
|
||||||
terminate("die %llu: failed to get unsigned (form 0x%x)\n",
|
|
||||||
die_off(dw, die), die_attr_form(dw, attr));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dwarf_dealloc(dw->dw_dw, attr, DW_DLA_ATTR);
|
|
||||||
|
|
||||||
*valp = val;
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
die_bool(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, Dwarf_Bool *valp, int req)
|
die_bool(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, Dwarf_Bool *valp, int req)
|
||||||
{
|
{
|
||||||
Dwarf_Attribute attr;
|
*valp = 0;
|
||||||
Dwarf_Bool val;
|
|
||||||
|
|
||||||
if ((attr = die_attr(dw, die, name, req)) == NULL)
|
if (dwarf_attrval_flag(die, name, valp, &dw->dw_err) != DWARF_E_NONE) {
|
||||||
return (0); /* die_attr will terminate for us if necessary */
|
if (req)
|
||||||
|
terminate("die %llu: failed to get flag: %s\n",
|
||||||
if (dwarf_formflag(attr, &val, &dw->dw_err) != DW_DLV_OK) {
|
die_off(dw, die), dwarf_errmsg(&dw->dw_err));
|
||||||
terminate("die %llu: failed to get bool (form 0x%x)\n",
|
return (0);
|
||||||
die_off(dw, die), die_attr_form(dw, attr));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dwarf_dealloc(dw->dw_dw, attr, DW_DLA_ATTR);
|
|
||||||
|
|
||||||
*valp = val;
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
die_string(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, char **strp, int req)
|
die_string(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, char **strp, int req)
|
||||||
{
|
{
|
||||||
Dwarf_Attribute attr;
|
const char *str = NULL;
|
||||||
char *str;
|
|
||||||
|
|
||||||
if ((attr = die_attr(dw, die, name, req)) == NULL)
|
if (dwarf_attrval_string(die, name, &str, &dw->dw_err) != DWARF_E_NONE ||
|
||||||
return (0); /* die_attr will terminate for us if necessary */
|
str == NULL) {
|
||||||
|
if (req)
|
||||||
if (dwarf_formstring(attr, &str, &dw->dw_err) != DW_DLV_OK) {
|
terminate("die %llu: failed to get string: %s\n",
|
||||||
terminate("die %llu: failed to get string (form 0x%x)\n",
|
die_off(dw, die), dwarf_errmsg(&dw->dw_err));
|
||||||
die_off(dw, die), die_attr_form(dw, attr));
|
else
|
||||||
}
|
*strp = NULL;
|
||||||
|
return (0);
|
||||||
*strp = xstrdup(str);
|
} else
|
||||||
dwarf_dealloc(dw->dw_dw, str, DW_DLA_STRING);
|
*strp = xstrdup(str);
|
||||||
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
@ -447,18 +417,13 @@ die_string(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, char **strp, int req)
|
|||||||
static Dwarf_Off
|
static Dwarf_Off
|
||||||
die_attr_ref(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name)
|
die_attr_ref(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name)
|
||||||
{
|
{
|
||||||
Dwarf_Attribute attr;
|
|
||||||
Dwarf_Off off;
|
Dwarf_Off off;
|
||||||
|
|
||||||
attr = die_attr(dw, die, name, DW_ATTR_REQ);
|
if (dwarf_attrval_unsigned(die, name, &off, &dw->dw_err) != DWARF_E_NONE) {
|
||||||
|
terminate("die %llu: failed to get ref: %s\n",
|
||||||
if (dwarf_formref(attr, &off, &dw->dw_err) != DW_DLV_OK) {
|
die_off(dw, die), dwarf_errmsg(&dw->dw_err));
|
||||||
terminate("die %llu: failed to get ref (form 0x%x)\n",
|
|
||||||
die_off(dw, die), die_attr_form(dw, attr));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dwarf_dealloc(dw->dw_dw, attr, DW_DLA_ATTR);
|
|
||||||
|
|
||||||
return (off);
|
return (off);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -522,21 +487,13 @@ die_lookup_pass1(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name)
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
die_mem_offset(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name,
|
die_mem_offset(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name,
|
||||||
Dwarf_Unsigned *valp, int req)
|
Dwarf_Unsigned *valp, int req __unused)
|
||||||
{
|
{
|
||||||
Dwarf_Attribute attr;
|
Dwarf_Locdesc *loc = NULL;
|
||||||
Dwarf_Locdesc *loc;
|
Dwarf_Signed locnum = 0;
|
||||||
Dwarf_Signed locnum;
|
|
||||||
|
|
||||||
if ((attr = die_attr(dw, die, name, req)) == NULL)
|
if (dwarf_locdesc(die, name, &loc, &locnum, &dw->dw_err) != DW_DLV_OK)
|
||||||
return (0); /* die_attr will terminate for us if necessary */
|
return (0);
|
||||||
|
|
||||||
if (dwarf_loclist(attr, &loc, &locnum, &dw->dw_err) != DW_DLV_OK) {
|
|
||||||
terminate("die %llu: failed to get mem offset location list\n",
|
|
||||||
die_off(dw, die));
|
|
||||||
}
|
|
||||||
|
|
||||||
dwarf_dealloc(dw->dw_dw, attr, DW_DLA_ATTR);
|
|
||||||
|
|
||||||
if (locnum != 1 || loc->ld_s->lr_atom != DW_OP_plus_uconst) {
|
if (locnum != 1 || loc->ld_s->lr_atom != DW_OP_plus_uconst) {
|
||||||
terminate("die %llu: cannot parse member offset\n",
|
terminate("die %llu: cannot parse member offset\n",
|
||||||
@ -545,8 +502,10 @@ die_mem_offset(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name,
|
|||||||
|
|
||||||
*valp = loc->ld_s->lr_number;
|
*valp = loc->ld_s->lr_number;
|
||||||
|
|
||||||
dwarf_dealloc(dw->dw_dw, loc->ld_s, DW_DLA_LOC_BLOCK);
|
if (loc != NULL)
|
||||||
dwarf_dealloc(dw->dw_dw, loc, DW_DLA_LOCDESC);
|
if (dwarf_locdesc_free(loc, &dw->dw_err) != DW_DLV_OK)
|
||||||
|
terminate("die %llu: cannot free location descriptor: %s\n",
|
||||||
|
die_off(dw, die), dwarf_errmsg(&dw->dw_err));
|
||||||
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
@ -640,7 +599,7 @@ tdesc_array_create(dwarf_t *dw, Dwarf_Die dim, tdesc_t *arrtdp,
|
|||||||
{
|
{
|
||||||
Dwarf_Unsigned uval;
|
Dwarf_Unsigned uval;
|
||||||
Dwarf_Signed sval;
|
Dwarf_Signed sval;
|
||||||
tdesc_t *ctdp;
|
tdesc_t *ctdp = NULL;
|
||||||
Dwarf_Die dim2;
|
Dwarf_Die dim2;
|
||||||
ardef_t *ar;
|
ardef_t *ar;
|
||||||
|
|
||||||
@ -703,7 +662,7 @@ die_array_create(dwarf_t *dw, Dwarf_Die arr, Dwarf_Off off, tdesc_t *tdp)
|
|||||||
Dwarf_Unsigned uval;
|
Dwarf_Unsigned uval;
|
||||||
Dwarf_Die dim;
|
Dwarf_Die dim;
|
||||||
|
|
||||||
debug(3, "die %llu: creating array\n", off);
|
debug(3, "die %llu <%llx>: creating array\n", off, off);
|
||||||
|
|
||||||
if ((dim = die_child(dw, arr)) == NULL ||
|
if ((dim = die_child(dw, arr)) == NULL ||
|
||||||
die_tag(dw, dim) != DW_TAG_subrange_type)
|
die_tag(dw, dim) != DW_TAG_subrange_type)
|
||||||
@ -734,13 +693,13 @@ die_array_create(dwarf_t *dw, Dwarf_Die arr, Dwarf_Off off, tdesc_t *tdp)
|
|||||||
tdp->t_flags |= flags;
|
tdp->t_flags |= flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug(3, "die %llu: array nelems %u size %u\n", off,
|
debug(3, "die %llu <%llx>: array nelems %u size %u\n", off, off,
|
||||||
tdp->t_ardef->ad_nelems, tdp->t_size);
|
tdp->t_ardef->ad_nelems, tdp->t_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*ARGSUSED1*/
|
/*ARGSUSED1*/
|
||||||
static int
|
static int
|
||||||
die_array_resolve(tdesc_t *tdp, tdesc_t **tdpp, void *private)
|
die_array_resolve(tdesc_t *tdp, tdesc_t **tdpp __unused, void *private)
|
||||||
{
|
{
|
||||||
dwarf_t *dw = private;
|
dwarf_t *dw = private;
|
||||||
size_t sz;
|
size_t sz;
|
||||||
@ -770,7 +729,7 @@ die_array_resolve(tdesc_t *tdp, tdesc_t **tdpp, void *private)
|
|||||||
|
|
||||||
/*ARGSUSED1*/
|
/*ARGSUSED1*/
|
||||||
static int
|
static int
|
||||||
die_array_failed(tdesc_t *tdp, tdesc_t **tdpp, void *private)
|
die_array_failed(tdesc_t *tdp, tdesc_t **tdpp __unused, void *private __unused)
|
||||||
{
|
{
|
||||||
tdesc_t *cont = tdp->t_ardef->ad_contents;
|
tdesc_t *cont = tdp->t_ardef->ad_contents;
|
||||||
|
|
||||||
@ -866,7 +825,7 @@ die_enum_match(void *arg1, void *arg2)
|
|||||||
|
|
||||||
/*ARGSUSED1*/
|
/*ARGSUSED1*/
|
||||||
static int
|
static int
|
||||||
die_enum_resolve(tdesc_t *tdp, tdesc_t **tdpp, void *private)
|
die_enum_resolve(tdesc_t *tdp, tdesc_t **tdpp __unused, void *private)
|
||||||
{
|
{
|
||||||
dwarf_t *dw = private;
|
dwarf_t *dw = private;
|
||||||
tdesc_t *full = NULL;
|
tdesc_t *full = NULL;
|
||||||
@ -938,8 +897,9 @@ die_sou_create(dwarf_t *dw, Dwarf_Die str, Dwarf_Off off, tdesc_t *tdp,
|
|||||||
/*
|
/*
|
||||||
* GCC allows empty SOUs as an extension.
|
* GCC allows empty SOUs as an extension.
|
||||||
*/
|
*/
|
||||||
if ((mem = die_child(dw, str)) == NULL)
|
if ((mem = die_child(dw, str)) == NULL) {
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
mlastp = &tdp->t_members;
|
mlastp = &tdp->t_members;
|
||||||
|
|
||||||
@ -966,7 +926,7 @@ die_sou_create(dwarf_t *dw, Dwarf_Die str, Dwarf_Off off, tdesc_t *tdp,
|
|||||||
* bug 11816).
|
* bug 11816).
|
||||||
*/
|
*/
|
||||||
if ((ml->ml_name = die_name(dw, mem)) == NULL)
|
if ((ml->ml_name = die_name(dw, mem)) == NULL)
|
||||||
ml->ml_name = "";
|
ml->ml_name = NULL;
|
||||||
|
|
||||||
ml->ml_type = die_lookup_pass1(dw, mem, DW_AT_type);
|
ml->ml_type = die_lookup_pass1(dw, mem, DW_AT_type);
|
||||||
|
|
||||||
@ -983,7 +943,7 @@ die_sou_create(dwarf_t *dw, Dwarf_Die str, Dwarf_Off off, tdesc_t *tdp,
|
|||||||
ml->ml_size = tdesc_bitsize(ml->ml_type);
|
ml->ml_size = tdesc_bitsize(ml->ml_type);
|
||||||
|
|
||||||
if (die_unsigned(dw, mem, DW_AT_bit_offset, &bitoff, 0)) {
|
if (die_unsigned(dw, mem, DW_AT_bit_offset, &bitoff, 0)) {
|
||||||
#ifdef _BIG_ENDIAN
|
#if BYTE_ORDER == _BIG_ENDIAN
|
||||||
ml->ml_offset += bitoff;
|
ml->ml_offset += bitoff;
|
||||||
#else
|
#else
|
||||||
ml->ml_offset += tdesc_bitsize(ml->ml_type) - bitoff -
|
ml->ml_offset += tdesc_bitsize(ml->ml_type) - bitoff -
|
||||||
@ -1057,7 +1017,7 @@ die_union_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp)
|
|||||||
|
|
||||||
/*ARGSUSED1*/
|
/*ARGSUSED1*/
|
||||||
static int
|
static int
|
||||||
die_sou_resolve(tdesc_t *tdp, tdesc_t **tdpp, void *private)
|
die_sou_resolve(tdesc_t *tdp, tdesc_t **tdpp __unused, void *private)
|
||||||
{
|
{
|
||||||
dwarf_t *dw = private;
|
dwarf_t *dw = private;
|
||||||
mlist_t *ml;
|
mlist_t *ml;
|
||||||
@ -1116,7 +1076,7 @@ die_sou_resolve(tdesc_t *tdp, tdesc_t **tdpp, void *private)
|
|||||||
|
|
||||||
/*ARGSUSED1*/
|
/*ARGSUSED1*/
|
||||||
static int
|
static int
|
||||||
die_sou_failed(tdesc_t *tdp, tdesc_t **tdpp, void *private)
|
die_sou_failed(tdesc_t *tdp, tdesc_t **tdpp __unused, void *private __unused)
|
||||||
{
|
{
|
||||||
const char *typename = (tdp->t_type == STRUCT ? "struct" : "union");
|
const char *typename = (tdp->t_type == STRUCT ? "struct" : "union");
|
||||||
mlist_t *ml;
|
mlist_t *ml;
|
||||||
@ -1126,10 +1086,11 @@ die_sou_failed(tdesc_t *tdp, tdesc_t **tdpp, void *private)
|
|||||||
|
|
||||||
for (ml = tdp->t_members; ml != NULL; ml = ml->ml_next) {
|
for (ml = tdp->t_members; ml != NULL; ml = ml->ml_next) {
|
||||||
if (ml->ml_size == 0) {
|
if (ml->ml_size == 0) {
|
||||||
fprintf(stderr, "%s %d: failed to size member \"%s\" "
|
fprintf(stderr, "%s %d <%x>: failed to size member \"%s\" "
|
||||||
"of type %s (%d)\n", typename, tdp->t_id,
|
"of type %s (%d <%x>)\n", typename, tdp->t_id,
|
||||||
|
tdp->t_id,
|
||||||
ml->ml_name, tdesc_name(ml->ml_type),
|
ml->ml_name, tdesc_name(ml->ml_type),
|
||||||
ml->ml_type->t_id);
|
ml->ml_type->t_id, ml->ml_type->t_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1145,7 +1106,7 @@ die_funcptr_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp)
|
|||||||
fndef_t *fn;
|
fndef_t *fn;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
debug(3, "die %llu: creating function pointer\n", off);
|
debug(3, "die %llu <%llx>: creating function pointer\n", off, off);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We'll begin by processing any type definition nodes that may be
|
* We'll begin by processing any type definition nodes that may be
|
||||||
@ -1175,7 +1136,6 @@ die_funcptr_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp)
|
|||||||
tdp->t_type = FUNCTION;
|
tdp->t_type = FUNCTION;
|
||||||
|
|
||||||
if ((attr = die_attr(dw, die, DW_AT_type, 0)) != NULL) {
|
if ((attr = die_attr(dw, die, DW_AT_type, 0)) != NULL) {
|
||||||
dwarf_dealloc(dw->dw_dw, attr, DW_DLA_ATTR);
|
|
||||||
fn->fn_ret = die_lookup_pass1(dw, die, DW_AT_type);
|
fn->fn_ret = die_lookup_pass1(dw, die, DW_AT_type);
|
||||||
} else {
|
} else {
|
||||||
fn->fn_ret = tdesc_intr_void(dw);
|
fn->fn_ret = tdesc_intr_void(dw);
|
||||||
@ -1199,7 +1159,7 @@ die_funcptr_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp)
|
|||||||
|
|
||||||
fn->fn_args = xcalloc(sizeof (tdesc_t *) * fn->fn_nargs);
|
fn->fn_args = xcalloc(sizeof (tdesc_t *) * fn->fn_nargs);
|
||||||
for (i = 0, arg = die_child(dw, die);
|
for (i = 0, arg = die_child(dw, die);
|
||||||
arg != NULL && i < fn->fn_nargs;
|
arg != NULL && i < (int) fn->fn_nargs;
|
||||||
arg = die_sibling(dw, arg)) {
|
arg = die_sibling(dw, arg)) {
|
||||||
if (die_tag(dw, arg) != DW_TAG_formal_parameter)
|
if (die_tag(dw, arg) != DW_TAG_formal_parameter)
|
||||||
continue;
|
continue;
|
||||||
@ -1224,7 +1184,8 @@ static intr_t *
|
|||||||
die_base_name_parse(const char *name, char **newp)
|
die_base_name_parse(const char *name, char **newp)
|
||||||
{
|
{
|
||||||
char buf[100];
|
char buf[100];
|
||||||
char *base, *c;
|
char const *base;
|
||||||
|
char *c;
|
||||||
int nlong = 0, nshort = 0, nchar = 0, nint = 0;
|
int nlong = 0, nshort = 0, nchar = 0, nint = 0;
|
||||||
int sign = 1;
|
int sign = 1;
|
||||||
char fmt = '\0';
|
char fmt = '\0';
|
||||||
@ -1308,7 +1269,7 @@ static const fp_size_map_t fp_encodings[] = {
|
|||||||
#else
|
#else
|
||||||
{ { 12, 16 }, { CTF_FP_LDOUBLE, CTF_FP_LDCPLX, CTF_FP_LDIMAGRY } },
|
{ { 12, 16 }, { CTF_FP_LDOUBLE, CTF_FP_LDCPLX, CTF_FP_LDIMAGRY } },
|
||||||
#endif
|
#endif
|
||||||
{ { 0, 0 } }
|
{ { 0, 0 }, { 0, 0, 0 } }
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint_t
|
static uint_t
|
||||||
@ -1321,8 +1282,11 @@ die_base_type2enc(dwarf_t *dw, Dwarf_Off off, Dwarf_Signed enc, size_t sz)
|
|||||||
if (enc == DW_ATE_complex_float) {
|
if (enc == DW_ATE_complex_float) {
|
||||||
mult = 2;
|
mult = 2;
|
||||||
col = 1;
|
col = 1;
|
||||||
} else if (enc == DW_ATE_imaginary_float ||
|
} else if (enc == DW_ATE_imaginary_float
|
||||||
enc == DW_ATE_SUN_imaginary_float)
|
#if defined(sun)
|
||||||
|
|| enc == DW_ATE_SUN_imaginary_float
|
||||||
|
#endif
|
||||||
|
)
|
||||||
col = 2;
|
col = 2;
|
||||||
|
|
||||||
while (map->fsm_typesz[szidx] != 0) {
|
while (map->fsm_typesz[szidx] != 0) {
|
||||||
@ -1370,8 +1334,10 @@ die_base_from_dwarf(dwarf_t *dw, Dwarf_Die base, Dwarf_Off off, size_t sz)
|
|||||||
case DW_ATE_float:
|
case DW_ATE_float:
|
||||||
case DW_ATE_complex_float:
|
case DW_ATE_complex_float:
|
||||||
case DW_ATE_imaginary_float:
|
case DW_ATE_imaginary_float:
|
||||||
|
#if defined(sun)
|
||||||
case DW_ATE_SUN_imaginary_float:
|
case DW_ATE_SUN_imaginary_float:
|
||||||
case DW_ATE_SUN_interval_float:
|
case DW_ATE_SUN_interval_float:
|
||||||
|
#endif
|
||||||
intr->intr_type = INTR_REAL;
|
intr->intr_type = INTR_REAL;
|
||||||
intr->intr_signed = 1;
|
intr->intr_signed = 1;
|
||||||
intr->intr_fformat = die_base_type2enc(dw, off, enc, sz);
|
intr->intr_fformat = die_base_type2enc(dw, off, enc, sz);
|
||||||
@ -1441,12 +1407,11 @@ die_through_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp,
|
|||||||
{
|
{
|
||||||
Dwarf_Attribute attr;
|
Dwarf_Attribute attr;
|
||||||
|
|
||||||
debug(3, "die %llu: creating %s\n", off, typename);
|
debug(3, "die %llu <%llx>: creating %s type %d\n", off, off, typename, type);
|
||||||
|
|
||||||
tdp->t_type = type;
|
tdp->t_type = type;
|
||||||
|
|
||||||
if ((attr = die_attr(dw, die, DW_AT_type, 0)) != NULL) {
|
if ((attr = die_attr(dw, die, DW_AT_type, 0)) != NULL) {
|
||||||
dwarf_dealloc(dw->dw_dw, attr, DW_DLA_ATTR);
|
|
||||||
tdp->t_tdesc = die_lookup_pass1(dw, die, DW_AT_type);
|
tdp->t_tdesc = die_lookup_pass1(dw, die, DW_AT_type);
|
||||||
} else {
|
} else {
|
||||||
tdp->t_tdesc = tdesc_intr_void(dw);
|
tdp->t_tdesc = tdesc_intr_void(dw);
|
||||||
@ -1499,14 +1464,14 @@ die_volatile_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp)
|
|||||||
|
|
||||||
/*ARGSUSED3*/
|
/*ARGSUSED3*/
|
||||||
static void
|
static void
|
||||||
die_function_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp)
|
die_function_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp __unused)
|
||||||
{
|
{
|
||||||
Dwarf_Die arg;
|
Dwarf_Die arg;
|
||||||
Dwarf_Half tag;
|
Dwarf_Half tag;
|
||||||
iidesc_t *ii;
|
iidesc_t *ii;
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
debug(3, "die %llu: creating function definition\n", off);
|
debug(3, "die %llu <%llx>: creating function definition\n", off, off);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We'll begin by processing any type definition nodes that may be
|
* We'll begin by processing any type definition nodes that may be
|
||||||
@ -1545,7 +1510,7 @@ die_function_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp)
|
|||||||
|
|
||||||
for (arg = die_child(dw, die); arg != NULL;
|
for (arg = die_child(dw, die); arg != NULL;
|
||||||
arg = die_sibling(dw, arg)) {
|
arg = die_sibling(dw, arg)) {
|
||||||
char *name;
|
char *name1;
|
||||||
|
|
||||||
debug(3, "die %llu: looking at sub member at %llu\n",
|
debug(3, "die %llu: looking at sub member at %llu\n",
|
||||||
off, die_off(dw, die));
|
off, die_off(dw, die));
|
||||||
@ -1553,13 +1518,13 @@ die_function_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp)
|
|||||||
if (die_tag(dw, arg) != DW_TAG_formal_parameter)
|
if (die_tag(dw, arg) != DW_TAG_formal_parameter)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((name = die_name(dw, arg)) == NULL) {
|
if ((name1 = die_name(dw, arg)) == NULL) {
|
||||||
terminate("die %llu: func arg %d has no name\n",
|
terminate("die %llu: func arg %d has no name\n",
|
||||||
off, ii->ii_nargs + 1);
|
off, ii->ii_nargs + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(name, "...") == 0) {
|
if (strcmp(name1, "...") == 0) {
|
||||||
free(name);
|
free(name1);
|
||||||
ii->ii_vargs = 1;
|
ii->ii_vargs = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1591,7 +1556,7 @@ die_function_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp)
|
|||||||
|
|
||||||
/*ARGSUSED3*/
|
/*ARGSUSED3*/
|
||||||
static void
|
static void
|
||||||
die_variable_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp)
|
die_variable_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp __unused)
|
||||||
{
|
{
|
||||||
iidesc_t *ii;
|
iidesc_t *ii;
|
||||||
char *name;
|
char *name;
|
||||||
@ -1613,7 +1578,7 @@ die_variable_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp)
|
|||||||
|
|
||||||
/*ARGSUSED2*/
|
/*ARGSUSED2*/
|
||||||
static int
|
static int
|
||||||
die_fwd_resolve(tdesc_t *fwd, tdesc_t **fwdp, void *private)
|
die_fwd_resolve(tdesc_t *fwd, tdesc_t **fwdp, void *private __unused)
|
||||||
{
|
{
|
||||||
if (fwd->t_flags & TDESC_F_RESOLVED)
|
if (fwd->t_flags & TDESC_F_RESOLVED)
|
||||||
return (1);
|
return (1);
|
||||||
@ -1631,7 +1596,7 @@ die_fwd_resolve(tdesc_t *fwd, tdesc_t **fwdp, void *private)
|
|||||||
|
|
||||||
/*ARGSUSED*/
|
/*ARGSUSED*/
|
||||||
static void
|
static void
|
||||||
die_lexblk_descend(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp)
|
die_lexblk_descend(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off __unused, tdesc_t *tdp __unused)
|
||||||
{
|
{
|
||||||
Dwarf_Die child = die_child(dw, die);
|
Dwarf_Die child = die_child(dw, die);
|
||||||
|
|
||||||
@ -1669,7 +1634,7 @@ static const die_creator_t die_creators[] = {
|
|||||||
{ DW_TAG_variable, DW_F_NOTDP, die_variable_create },
|
{ DW_TAG_variable, DW_F_NOTDP, die_variable_create },
|
||||||
{ DW_TAG_volatile_type, 0, die_volatile_create },
|
{ DW_TAG_volatile_type, 0, die_volatile_create },
|
||||||
{ DW_TAG_restrict_type, 0, die_restrict_create },
|
{ DW_TAG_restrict_type, 0, die_restrict_create },
|
||||||
{ 0, NULL }
|
{ 0, 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const die_creator_t *
|
static const die_creator_t *
|
||||||
@ -1693,7 +1658,7 @@ die_create_one(dwarf_t *dw, Dwarf_Die die)
|
|||||||
Dwarf_Half tag;
|
Dwarf_Half tag;
|
||||||
tdesc_t *tdp;
|
tdesc_t *tdp;
|
||||||
|
|
||||||
debug(3, "die %llu: create_one\n", off);
|
debug(3, "die %llu <%llx>: create_one\n", off, off);
|
||||||
|
|
||||||
if (off > dw->dw_maxoff) {
|
if (off > dw->dw_maxoff) {
|
||||||
terminate("illegal die offset %llu (max %llu)\n", off,
|
terminate("illegal die offset %llu (max %llu)\n", off,
|
||||||
@ -1777,7 +1742,7 @@ die_resolve(dwarf_t *dw)
|
|||||||
|
|
||||||
debug(3, "resolve: pass %d, %u left\n", pass, dw->dw_nunres);
|
debug(3, "resolve: pass %d, %u left\n", pass, dw->dw_nunres);
|
||||||
|
|
||||||
if (dw->dw_nunres == last) {
|
if ((int) dw->dw_nunres == last) {
|
||||||
fprintf(stderr, "%s: failed to resolve the following "
|
fprintf(stderr, "%s: failed to resolve the following "
|
||||||
"types:\n", progname);
|
"types:\n", progname);
|
||||||
|
|
||||||
@ -1795,11 +1760,12 @@ die_resolve(dwarf_t *dw)
|
|||||||
|
|
||||||
/*ARGSUSED*/
|
/*ARGSUSED*/
|
||||||
int
|
int
|
||||||
dw_read(tdata_t *td, Elf *elf, const char *filename)
|
dw_read(tdata_t *td, Elf *elf, char *filename __unused)
|
||||||
{
|
{
|
||||||
Dwarf_Unsigned abboff, hdrlen, nxthdr;
|
Dwarf_Unsigned abboff, hdrlen, nxthdr;
|
||||||
Dwarf_Half vers, addrsz;
|
Dwarf_Half vers, addrsz;
|
||||||
Dwarf_Die cu, child;
|
Dwarf_Die cu = 0;
|
||||||
|
Dwarf_Die child = 0;
|
||||||
dwarf_t dw;
|
dwarf_t dw;
|
||||||
char *prod = NULL;
|
char *prod = NULL;
|
||||||
int rc;
|
int rc;
|
||||||
@ -1814,12 +1780,12 @@ dw_read(tdata_t *td, Elf *elf, const char *filename)
|
|||||||
dw.dw_enumhash = hash_new(TDESC_HASH_BUCKETS, tdesc_namehash,
|
dw.dw_enumhash = hash_new(TDESC_HASH_BUCKETS, tdesc_namehash,
|
||||||
tdesc_namecmp);
|
tdesc_namecmp);
|
||||||
|
|
||||||
if ((rc = dwarf_elf_init(elf, DW_DLC_READ, NULL, NULL, &dw.dw_dw,
|
if ((rc = dwarf_elf_init(elf, DW_DLC_READ, &dw.dw_dw,
|
||||||
&dw.dw_err)) == DW_DLV_NO_ENTRY) {
|
&dw.dw_err)) == DW_DLV_NO_ENTRY) {
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
return (-1);
|
return (-1);
|
||||||
} else if (rc != DW_DLV_OK) {
|
} else if (rc != DW_DLV_OK) {
|
||||||
if (dwarf_errno(dw.dw_err) == DW_DLE_DEBUG_INFO_NULL) {
|
if (dwarf_errno(&dw.dw_err) == DW_DLE_DEBUG_INFO_NULL) {
|
||||||
/*
|
/*
|
||||||
* There's no type data in the DWARF section, but
|
* There's no type data in the DWARF section, but
|
||||||
* libdwarf is too clever to handle that properly.
|
* libdwarf is too clever to handle that properly.
|
||||||
@ -1828,13 +1794,14 @@ dw_read(tdata_t *td, Elf *elf, const char *filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
terminate("failed to initialize DWARF: %s\n",
|
terminate("failed to initialize DWARF: %s\n",
|
||||||
dwarf_errmsg(dw.dw_err));
|
dwarf_errmsg(&dw.dw_err));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((rc = dwarf_next_cu_header(dw.dw_dw, &hdrlen, &vers, &abboff,
|
if ((rc = dwarf_next_cu_header(dw.dw_dw, &hdrlen, &vers, &abboff,
|
||||||
&addrsz, &nxthdr, &dw.dw_err)) != DW_DLV_OK ||
|
&addrsz, &nxthdr, &dw.dw_err)) != DW_DLV_OK)
|
||||||
(cu = die_sibling(&dw, NULL)) == NULL ||
|
terminate("rc = %d %s\n", rc, dwarf_errmsg(&dw.dw_err));
|
||||||
(child = die_child(&dw, cu)) == NULL)
|
|
||||||
|
if ((cu = die_sibling(&dw, NULL)) == NULL)
|
||||||
terminate("file does not contain dwarf type data "
|
terminate("file does not contain dwarf type data "
|
||||||
"(try compiling with -g)\n");
|
"(try compiling with -g)\n");
|
||||||
|
|
||||||
@ -1862,13 +1829,14 @@ dw_read(tdata_t *td, Elf *elf, const char *filename)
|
|||||||
debug(1, "CU name: %s\n", dw.dw_cuname);
|
debug(1, "CU name: %s\n", dw.dw_cuname);
|
||||||
}
|
}
|
||||||
|
|
||||||
die_create(&dw, child);
|
if ((child = die_child(&dw, cu)) != NULL)
|
||||||
|
die_create(&dw, child);
|
||||||
|
|
||||||
if ((rc = dwarf_next_cu_header(dw.dw_dw, &hdrlen, &vers, &abboff,
|
if ((rc = dwarf_next_cu_header(dw.dw_dw, &hdrlen, &vers, &abboff,
|
||||||
&addrsz, &nxthdr, &dw.dw_err)) != DW_DLV_NO_ENTRY)
|
&addrsz, &nxthdr, &dw.dw_err)) != DW_DLV_NO_ENTRY)
|
||||||
terminate("multiple compilation units not supported\n");
|
terminate("multiple compilation units not supported\n");
|
||||||
|
|
||||||
(void) dwarf_finish(dw.dw_dw, &dw.dw_err);
|
(void) dwarf_finish(&dw.dw_dw, &dw.dw_err);
|
||||||
|
|
||||||
die_resolve(&dw);
|
die_resolve(&dw);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user