Clean up the dwarf code a little and make

acidtypes handle gcc 3.3.3 binaries.
This commit is contained in:
rsc 2004-04-21 02:02:47 +00:00
parent e37302c4b9
commit 87a478a361
4 changed files with 153 additions and 188 deletions

View file

@ -1,6 +1,7 @@
typedef struct Type Type; typedef struct Type Type;
typedef struct Typeref Typeref; typedef struct Typeref Typeref;
typedef struct TypeList TypeList; typedef struct TypeList TypeList;
typedef struct Sym Sym;
enum enum
{ {
@ -47,6 +48,14 @@ struct TypeList
TypeList *tl; TypeList *tl;
}; };
struct Sym
{
char *fn;
char *name;
Type *type;
Sym *next;
};
void *erealloc(void*, uint); void *erealloc(void*, uint);
void *emalloc(uint); void *emalloc(uint);
char *estrdup(char*); char *estrdup(char*);
@ -70,3 +79,9 @@ void freetypes(void);
extern char *prefix; extern char *prefix;
char *fixname(char*); char *fixname(char*);
void addsymx(char*, char*, Type*);
void dumpsyms(Biobuf*);

View file

@ -6,6 +6,8 @@
#include <dwarf.h> #include <dwarf.h>
#include "dat.h" #include "dat.h"
static void ds2acid(Dwarf*, DwarfSym*, Biobuf*, char*);
static ulong static ulong
valof(uint ty, DwarfVal *v) valof(uint ty, DwarfVal *v)
{ {
@ -32,32 +34,57 @@ xnewtype(uint ty, DwarfSym *s)
int int
dwarf2acid(Dwarf *d, Biobuf *b) dwarf2acid(Dwarf *d, Biobuf *b)
{ {
char *fn;
DwarfSym s; DwarfSym s;
Type *t;
/* pass over dwarf section pulling out type info */ /* pass over dwarf section pulling out type info */
if(dwarfenum(d, &s) < 0) if(dwarfenum(d, &s) < 0)
return -1; return -1;
while(dwarfnextsym(d, &s, s.depth!=1) == 1){ while(dwarfnextsymat(d, &s, 0) == 1)
top: ds2acid(d, &s, b, nil);
switch(s.attrs.tag){
printtypes(b);
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: case TagSubprogram:
fn = s->attrs.name;
goto Recurse;
case TagCompileUnit:
case TagLexDwarfBlock: case TagLexDwarfBlock:
dwarfnextsym(d, &s, 1); Recurse:
goto top; /* recurse into substructure */
while(dwarfnextsymat(d, s, depth+1) == 1)
ds2acid(d, s, b, fn);
break;
case TagTypedef: case TagTypedef:
t = xnewtype(Typedef, &s); t = xnewtype(Typedef, s);
t->name = s.attrs.name; t->name = s->attrs.name;
t->sub = typebynum(s.attrs.type, 0); t->sub = typebynum(s->attrs.type, 0);
break; break;
case TagBaseType: case TagBaseType:
t = xnewtype(Base, &s); t = xnewtype(Base, s);
t->xsizeof = s.attrs.bytesize; t->xsizeof = s->attrs.bytesize;
switch(s.attrs.encoding){ switch(s->attrs.encoding){
default: default:
case TypeAddress: case TypeAddress:
t->printfmt = 'x'; t->printfmt = 'x';
@ -80,114 +107,74 @@ dwarf2acid(Dwarf *d, Biobuf *b)
break; break;
} }
break; break;
case TagPointerType: case TagPointerType:
t = xnewtype(Pointer, &s); t = xnewtype(Pointer, s);
t->sub = typebynum(s.attrs.type, 0); t->sub = typebynum(s->attrs.type, 0);
break; 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 TagStructType:
case TagUnionType: case TagUnionType:
t = xnewtype(Aggr, &s); t = xnewtype(Aggr, s);
t->sue = s.attrs.tag==TagStructType ? 's' : 'u'; t->sue = s->attrs.tag==TagStructType ? 's' : 'u';
t->xsizeof = s.attrs.bytesize; t->xsizeof = s->attrs.bytesize;
t->suename = s.attrs.name; t->suename = s->attrs.name;
t->isunion = s.attrs.tag==TagUnionType; t->isunion = s->attrs.tag==TagUnionType;
dwarfnextsym(d, &s, 1); while(dwarfnextsymat(d, s, depth+1) == 1){
if(s.depth != 2) if(s->attrs.tag != TagMember){
goto top; ds2acid(d, s, b, fn);
do{ continue;
if(!s.attrs.have.name || !s.attrs.have.type || s.attrs.tag != TagMember) }
if(!s->attrs.have.name || !s->attrs.have.type)
continue; continue;
if(t->n%32 == 0){ if(t->n%32 == 0){
t->tname = erealloc(t->tname, (t->n+32)*sizeof(t->tname[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->val = erealloc(t->val, (t->n+32)*sizeof(t->val[0]));
t->t = erealloc(t->t, (t->n+32)*sizeof(t->t[0])); t->t = erealloc(t->t, (t->n+32)*sizeof(t->t[0]));
} }
t->tname[t->n] = s.attrs.name; t->tname[t->n] = s->attrs.name;
if(t->isunion) if(t->isunion)
t->val[t->n] = 0; t->val[t->n] = 0;
else else
t->val[t->n] = valof(s.attrs.have.datamemberloc, &s.attrs.datamemberloc); t->val[t->n] = valof(s->attrs.have.datamemberloc, &s->attrs.datamemberloc);
t->t[t->n] = typebynum(s.attrs.type, 0); t->t[t->n] = typebynum(s->attrs.type, 0);
t->n++; 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; break;
case TagEnumerationType: case TagEnumerationType:
t = xnewtype(Enum, &s); t = xnewtype(Enum, s);
t->sue = 'e'; t->sue = 'e';
t->suename = s.attrs.name; t->suename = s->attrs.name;
t->xsizeof = s.attrs.bytesize; t->xsizeof = s->attrs.bytesize;
dwarfnextsym(d, &s, 1); while(dwarfnextsymat(d, s, depth+1) == 1){
if(s.depth != 2) if(s->attrs.tag != TagEnumerator){
goto top; ds2acid(d, s, b, fn);
do{ continue;
if(!s.attrs.have.name || !s.attrs.have.constvalue || s.attrs.tag != TagEnumerator) }
if(!s->attrs.have.name || !s->attrs.have.constvalue)
continue; continue;
if(t->n%32 == 0){ if(t->n%32 == 0){
t->tname = erealloc(t->tname, (t->n+32)*sizeof(t->tname[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->val = erealloc(t->val, (t->n+32)*sizeof(t->val[0]));
} }
t->tname[t->n] = s.attrs.name; t->tname[t->n] = s->attrs.name;
t->val[t->n] = valof(s.attrs.have.constvalue, &s.attrs.constvalue); t->val[t->n] = valof(s->attrs.have.constvalue, &s->attrs.constvalue);
t->n++; t->n++;
}while(dwarfnextsym(d, &s, 1) == 1 && s.depth==2); }
goto top;
break; break;
} }
} }
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:
freetypes();
return 0;
}

View file

@ -6,6 +6,7 @@ OFILES=\
dwarf.$O\ dwarf.$O\
main.$O\ main.$O\
stabs.$O\ stabs.$O\
sym.$O\
type.$O\ type.$O\
util.$O\ util.$O\

View file

@ -17,15 +17,6 @@ static Type *parsedefn(char *p, Type *t, char **pp);
static int parsebound(char**); static int parsebound(char**);
static vlong parsebigint(char**); static vlong parsebigint(char**);
typedef struct Sym Sym;
struct Sym
{
char *fn;
char *name;
Type *type;
Sym *next;
};
typedef struct Ftypes Ftypes; typedef struct Ftypes Ftypes;
struct Ftypes struct Ftypes
{ {
@ -38,18 +29,6 @@ struct Ftypes
Ftypes *fstack; Ftypes *fstack;
Ftypes *allftypes; 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* static char*
estrndup(char *s, int n) estrndup(char *s, int n)
{ {
@ -626,15 +605,11 @@ stabs2acid(Stab *stabs, Biobuf *b)
Ftypes *f; Ftypes *f;
Type *t, *tt; Type *t, *tt;
StabSym sym; StabSym sym;
Sym *symbols, *s;
Sym **lsym;
dir = nil; dir = nil;
file = nil; file = nil;
fno = 0; fno = 0;
fn = nil; fn = nil;
symbols = nil;
lsym = &symbols;
for(i=0; stabsym(stabs, i, &sym)>=0; i++){ for(i=0; stabsym(stabs, i, &sym)>=0; i++){
switch(sym.type){ switch(sym.type){
case N_SO: case N_SO:
@ -737,8 +712,7 @@ stabs2acid(Stab *stabs, Biobuf *b)
if(c != 't' && c != 'T') if(c != 't' && c != 'T')
switch(sym.type){ switch(sym.type){
case N_GSYM: case N_GSYM:
*lsym = mksym(nil, name, t); addsymx(nil, name, t);
lsym = &(*lsym)->next;
break; break;
case N_FUN: case N_FUN:
fn = name; fn = name;
@ -748,8 +722,7 @@ stabs2acid(Stab *stabs, Biobuf *b)
case N_LCSYM: case N_LCSYM:
case N_STSYM: case N_STSYM:
case N_RSYM: case N_RSYM:
*lsym = mksym(fn, name, t); addsymx(fn, name, t);
lsym = &(*lsym)->next;
break; break;
} }
break; break;
@ -757,19 +730,8 @@ stabs2acid(Stab *stabs, Biobuf *b)
} }
printtypes(b); printtypes(b);
dumpsyms(b);
for(s=symbols; s; s=s->next){ freetypes();
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));
}
return 0; return 0;
} }