Clean up the dwarf code a little and make
acidtypes handle gcc 3.3.3 binaries.
This commit is contained in:
parent
e37302c4b9
commit
87a478a361
4 changed files with 153 additions and 188 deletions
|
|
@ -1,6 +1,7 @@
|
|||
typedef struct Type Type;
|
||||
typedef struct Typeref Typeref;
|
||||
typedef struct TypeList TypeList;
|
||||
typedef struct Sym Sym;
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
@ -47,6 +48,14 @@ struct TypeList
|
|||
TypeList *tl;
|
||||
};
|
||||
|
||||
struct Sym
|
||||
{
|
||||
char *fn;
|
||||
char *name;
|
||||
Type *type;
|
||||
Sym *next;
|
||||
};
|
||||
|
||||
void *erealloc(void*, uint);
|
||||
void *emalloc(uint);
|
||||
char *estrdup(char*);
|
||||
|
|
@ -70,3 +79,9 @@ void freetypes(void);
|
|||
|
||||
extern char *prefix;
|
||||
char *fixname(char*);
|
||||
|
||||
void addsymx(char*, char*, Type*);
|
||||
void dumpsyms(Biobuf*);
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
#include <dwarf.h>
|
||||
#include "dat.h"
|
||||
|
||||
static void ds2acid(Dwarf*, DwarfSym*, Biobuf*, char*);
|
||||
|
||||
static ulong
|
||||
valof(uint ty, DwarfVal *v)
|
||||
{
|
||||
|
|
@ -32,162 +34,147 @@ xnewtype(uint ty, DwarfSym *s)
|
|||
int
|
||||
dwarf2acid(Dwarf *d, Biobuf *b)
|
||||
{
|
||||
char *fn;
|
||||
DwarfSym s;
|
||||
Type *t;
|
||||
|
||||
/* pass over dwarf section pulling out type info */
|
||||
|
||||
if(dwarfenum(d, &s) < 0)
|
||||
return -1;
|
||||
|
||||
while(dwarfnextsym(d, &s, s.depth!=1) == 1){
|
||||
top:
|
||||
switch(s.attrs.tag){
|
||||
case TagSubprogram:
|
||||
case TagLexDwarfBlock:
|
||||
dwarfnextsym(d, &s, 1);
|
||||
goto top;
|
||||
|
||||
case TagTypedef:
|
||||
t = xnewtype(Typedef, &s);
|
||||
t->name = s.attrs.name;
|
||||
t->sub = typebynum(s.attrs.type, 0);
|
||||
break;
|
||||
case TagBaseType:
|
||||
t = xnewtype(Base, &s);
|
||||
t->xsizeof = s.attrs.bytesize;
|
||||
switch(s.attrs.encoding){
|
||||
default:
|
||||
case TypeAddress:
|
||||
t->printfmt = 'x';
|
||||
break;
|
||||
case TypeBoolean:
|
||||
case TypeUnsigned:
|
||||
case TypeSigned:
|
||||
case TypeSignedChar:
|
||||
case TypeUnsignedChar:
|
||||
t->printfmt = 'd';
|
||||
break;
|
||||
case TypeFloat:
|
||||
t->printfmt = 'f';
|
||||
break;
|
||||
case TypeComplexFloat:
|
||||
t->printfmt = 'F';
|
||||
break;
|
||||
case TypeImaginaryFloat:
|
||||
t->printfmt = 'i';
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TagPointerType:
|
||||
t = xnewtype(Pointer, &s);
|
||||
t->sub = typebynum(s.attrs.type, 0);
|
||||
break;
|
||||
case TagStructType:
|
||||
case TagUnionType:
|
||||
t = xnewtype(Aggr, &s);
|
||||
t->sue = s.attrs.tag==TagStructType ? 's' : 'u';
|
||||
t->xsizeof = s.attrs.bytesize;
|
||||
t->suename = s.attrs.name;
|
||||
t->isunion = s.attrs.tag==TagUnionType;
|
||||
dwarfnextsym(d, &s, 1);
|
||||
if(s.depth != 2)
|
||||
goto top;
|
||||
do{
|
||||
if(!s.attrs.have.name || !s.attrs.have.type || s.attrs.tag != TagMember)
|
||||
continue;
|
||||
if(t->n%32 == 0){
|
||||
t->tname = erealloc(t->tname, (t->n+32)*sizeof(t->tname[0]));
|
||||
t->val = erealloc(t->val, (t->n+32)*sizeof(t->val[0]));
|
||||
t->t = erealloc(t->t, (t->n+32)*sizeof(t->t[0]));
|
||||
}
|
||||
t->tname[t->n] = s.attrs.name;
|
||||
if(t->isunion)
|
||||
t->val[t->n] = 0;
|
||||
else
|
||||
t->val[t->n] = valof(s.attrs.have.datamemberloc, &s.attrs.datamemberloc);
|
||||
t->t[t->n] = typebynum(s.attrs.type, 0);
|
||||
t->n++;
|
||||
}while(dwarfnextsym(d, &s, 1) == 1 && s.depth==2);
|
||||
goto top;
|
||||
break;
|
||||
case TagSubroutineType:
|
||||
t = xnewtype(Function, &s);
|
||||
break;
|
||||
case TagConstType:
|
||||
case TagVolatileType:
|
||||
t = xnewtype(Defer, &s);
|
||||
t->sub = typebynum(s.attrs.type, 0);
|
||||
break;
|
||||
case TagArrayType:
|
||||
t = xnewtype(Array, &s);
|
||||
t->sub = typebynum(s.attrs.type, 0);
|
||||
break;
|
||||
case TagEnumerationType:
|
||||
t = xnewtype(Enum, &s);
|
||||
t->sue = 'e';
|
||||
t->suename = s.attrs.name;
|
||||
t->xsizeof = s.attrs.bytesize;
|
||||
dwarfnextsym(d, &s, 1);
|
||||
if(s.depth != 2)
|
||||
goto top;
|
||||
do{
|
||||
if(!s.attrs.have.name || !s.attrs.have.constvalue || s.attrs.tag != TagEnumerator)
|
||||
continue;
|
||||
if(t->n%32 == 0){
|
||||
t->tname = erealloc(t->tname, (t->n+32)*sizeof(t->tname[0]));
|
||||
t->val = erealloc(t->val, (t->n+32)*sizeof(t->val[0]));
|
||||
}
|
||||
t->tname[t->n] = s.attrs.name;
|
||||
t->val[t->n] = valof(s.attrs.have.constvalue, &s.attrs.constvalue);
|
||||
t->n++;
|
||||
}while(dwarfnextsym(d, &s, 1) == 1 && s.depth==2);
|
||||
goto top;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while(dwarfnextsymat(d, &s, 0) == 1)
|
||||
ds2acid(d, &s, b, nil);
|
||||
|
||||
printtypes(b);
|
||||
|
||||
/* pass over dwarf section pulling out type definitions */
|
||||
|
||||
if(dwarfenum(d, &s) < 0)
|
||||
goto out;
|
||||
|
||||
fn = nil;
|
||||
while(dwarfnextsym(d, &s, 1) == 1){
|
||||
if(s.depth == 1)
|
||||
fn = nil;
|
||||
switch(s.attrs.tag){
|
||||
case TagSubprogram:
|
||||
fn = s.attrs.name;
|
||||
break;
|
||||
case TagFormalParameter:
|
||||
if(s.depth != 2)
|
||||
break;
|
||||
/* fall through */
|
||||
case TagVariable:
|
||||
if(s.attrs.name == nil || s.attrs.type == 0)
|
||||
continue;
|
||||
t = typebynum(s.attrs.type, 0);
|
||||
if(t->ty == Pointer){
|
||||
t = t->sub;
|
||||
if(t && t->equiv)
|
||||
t = t->equiv;
|
||||
}
|
||||
if(t == nil)
|
||||
break;
|
||||
if(t->ty != Aggr)
|
||||
break;
|
||||
Bprint(b, "complex %s %s%s%s;\n", nameof(t, 1),
|
||||
fn ? fixname(fn) : "", fn ? ":" : "", fixname(s.attrs.name));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
dumpsyms(b);
|
||||
freetypes();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ds2acid(Dwarf *d, DwarfSym *s, Biobuf *b, char *fn)
|
||||
{
|
||||
int depth;
|
||||
Type *t;
|
||||
|
||||
depth = s->depth;
|
||||
|
||||
switch(s->attrs.tag){
|
||||
case TagSubroutineType:
|
||||
t = xnewtype(Function, s);
|
||||
goto Recurse;
|
||||
|
||||
case TagSubprogram:
|
||||
fn = s->attrs.name;
|
||||
goto Recurse;
|
||||
|
||||
case TagCompileUnit:
|
||||
case TagLexDwarfBlock:
|
||||
Recurse:
|
||||
/* recurse into substructure */
|
||||
while(dwarfnextsymat(d, s, depth+1) == 1)
|
||||
ds2acid(d, s, b, fn);
|
||||
break;
|
||||
|
||||
case TagTypedef:
|
||||
t = xnewtype(Typedef, s);
|
||||
t->name = s->attrs.name;
|
||||
t->sub = typebynum(s->attrs.type, 0);
|
||||
break;
|
||||
|
||||
case TagBaseType:
|
||||
t = xnewtype(Base, s);
|
||||
t->xsizeof = s->attrs.bytesize;
|
||||
switch(s->attrs.encoding){
|
||||
default:
|
||||
case TypeAddress:
|
||||
t->printfmt = 'x';
|
||||
break;
|
||||
case TypeBoolean:
|
||||
case TypeUnsigned:
|
||||
case TypeSigned:
|
||||
case TypeSignedChar:
|
||||
case TypeUnsignedChar:
|
||||
t->printfmt = 'd';
|
||||
break;
|
||||
case TypeFloat:
|
||||
t->printfmt = 'f';
|
||||
break;
|
||||
case TypeComplexFloat:
|
||||
t->printfmt = 'F';
|
||||
break;
|
||||
case TypeImaginaryFloat:
|
||||
t->printfmt = 'i';
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case TagPointerType:
|
||||
t = xnewtype(Pointer, s);
|
||||
t->sub = typebynum(s->attrs.type, 0);
|
||||
break;
|
||||
|
||||
|
||||
case TagConstType:
|
||||
case TagVolatileType:
|
||||
t = xnewtype(Defer, s);
|
||||
t->sub = typebynum(s->attrs.type, 0);
|
||||
break;
|
||||
|
||||
case TagArrayType:
|
||||
t = xnewtype(Array, s);
|
||||
t->sub = typebynum(s->attrs.type, 0);
|
||||
break;
|
||||
|
||||
case TagStructType:
|
||||
case TagUnionType:
|
||||
t = xnewtype(Aggr, s);
|
||||
t->sue = s->attrs.tag==TagStructType ? 's' : 'u';
|
||||
t->xsizeof = s->attrs.bytesize;
|
||||
t->suename = s->attrs.name;
|
||||
t->isunion = s->attrs.tag==TagUnionType;
|
||||
while(dwarfnextsymat(d, s, depth+1) == 1){
|
||||
if(s->attrs.tag != TagMember){
|
||||
ds2acid(d, s, b, fn);
|
||||
continue;
|
||||
}
|
||||
if(!s->attrs.have.name || !s->attrs.have.type)
|
||||
continue;
|
||||
if(t->n%32 == 0){
|
||||
t->tname = erealloc(t->tname, (t->n+32)*sizeof(t->tname[0]));
|
||||
t->val = erealloc(t->val, (t->n+32)*sizeof(t->val[0]));
|
||||
t->t = erealloc(t->t, (t->n+32)*sizeof(t->t[0]));
|
||||
}
|
||||
t->tname[t->n] = s->attrs.name;
|
||||
if(t->isunion)
|
||||
t->val[t->n] = 0;
|
||||
else
|
||||
t->val[t->n] = valof(s->attrs.have.datamemberloc, &s->attrs.datamemberloc);
|
||||
t->t[t->n] = typebynum(s->attrs.type, 0);
|
||||
t->n++;
|
||||
}
|
||||
break;
|
||||
|
||||
case TagEnumerationType:
|
||||
t = xnewtype(Enum, s);
|
||||
t->sue = 'e';
|
||||
t->suename = s->attrs.name;
|
||||
t->xsizeof = s->attrs.bytesize;
|
||||
while(dwarfnextsymat(d, s, depth+1) == 1){
|
||||
if(s->attrs.tag != TagEnumerator){
|
||||
ds2acid(d, s, b, fn);
|
||||
continue;
|
||||
}
|
||||
if(!s->attrs.have.name || !s->attrs.have.constvalue)
|
||||
continue;
|
||||
if(t->n%32 == 0){
|
||||
t->tname = erealloc(t->tname, (t->n+32)*sizeof(t->tname[0]));
|
||||
t->val = erealloc(t->val, (t->n+32)*sizeof(t->val[0]));
|
||||
}
|
||||
t->tname[t->n] = s->attrs.name;
|
||||
t->val[t->n] = valof(s->attrs.have.constvalue, &s->attrs.constvalue);
|
||||
t->n++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ OFILES=\
|
|||
dwarf.$O\
|
||||
main.$O\
|
||||
stabs.$O\
|
||||
sym.$O\
|
||||
type.$O\
|
||||
util.$O\
|
||||
|
||||
|
|
|
|||
|
|
@ -17,15 +17,6 @@ static Type *parsedefn(char *p, Type *t, char **pp);
|
|||
static int parsebound(char**);
|
||||
static vlong parsebigint(char**);
|
||||
|
||||
typedef struct Sym Sym;
|
||||
struct Sym
|
||||
{
|
||||
char *fn;
|
||||
char *name;
|
||||
Type *type;
|
||||
Sym *next;
|
||||
};
|
||||
|
||||
typedef struct Ftypes Ftypes;
|
||||
struct Ftypes
|
||||
{
|
||||
|
|
@ -38,18 +29,6 @@ struct Ftypes
|
|||
Ftypes *fstack;
|
||||
Ftypes *allftypes;
|
||||
|
||||
static Sym*
|
||||
mksym(char *fn, char *name, Type *type)
|
||||
{
|
||||
Sym *s;
|
||||
|
||||
s = emalloc(sizeof *s);
|
||||
s->fn = fn;
|
||||
s->name = name;
|
||||
s->type = type;
|
||||
return s;
|
||||
}
|
||||
|
||||
static char*
|
||||
estrndup(char *s, int n)
|
||||
{
|
||||
|
|
@ -626,15 +605,11 @@ stabs2acid(Stab *stabs, Biobuf *b)
|
|||
Ftypes *f;
|
||||
Type *t, *tt;
|
||||
StabSym sym;
|
||||
Sym *symbols, *s;
|
||||
Sym **lsym;
|
||||
|
||||
dir = nil;
|
||||
file = nil;
|
||||
fno = 0;
|
||||
fn = nil;
|
||||
symbols = nil;
|
||||
lsym = &symbols;
|
||||
for(i=0; stabsym(stabs, i, &sym)>=0; i++){
|
||||
switch(sym.type){
|
||||
case N_SO:
|
||||
|
|
@ -737,8 +712,7 @@ stabs2acid(Stab *stabs, Biobuf *b)
|
|||
if(c != 't' && c != 'T')
|
||||
switch(sym.type){
|
||||
case N_GSYM:
|
||||
*lsym = mksym(nil, name, t);
|
||||
lsym = &(*lsym)->next;
|
||||
addsymx(nil, name, t);
|
||||
break;
|
||||
case N_FUN:
|
||||
fn = name;
|
||||
|
|
@ -748,8 +722,7 @@ stabs2acid(Stab *stabs, Biobuf *b)
|
|||
case N_LCSYM:
|
||||
case N_STSYM:
|
||||
case N_RSYM:
|
||||
*lsym = mksym(fn, name, t);
|
||||
lsym = &(*lsym)->next;
|
||||
addsymx(fn, name, t);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
@ -757,19 +730,8 @@ stabs2acid(Stab *stabs, Biobuf *b)
|
|||
}
|
||||
|
||||
printtypes(b);
|
||||
|
||||
for(s=symbols; s; s=s->next){
|
||||
t = s->type;
|
||||
if(t->ty == Pointer){
|
||||
t = t->sub;
|
||||
if(t && t->equiv)
|
||||
t = t->equiv;
|
||||
}
|
||||
if(t == nil || t->ty != Aggr)
|
||||
continue;
|
||||
Bprint(b, "complex %s %s%s%s;\n", nameof(t, 1),
|
||||
s->fn ? fixname(s->fn) : "", s->fn ? ":" : "", fixname(s->name));
|
||||
}
|
||||
dumpsyms(b);
|
||||
freetypes();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue