blob: f92942865ca193fe1c03fc8c9ec9e18fd4cb1d51 [file] [log] [blame]
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <mach.h>
#include <elf.h>
#include <dwarf.h>
#include "dat.h"
static void ds2acid(Dwarf*, DwarfSym*, Biobuf*, char*);
static ulong
valof(uint ty, DwarfVal *v)
{
switch(ty){
default:
fmtinstall('H', encodefmt);
fprint(2, "valof %d %.*H\n", ty, v->b.len, v->b.data);
return 0;
case TConstant:
return v->c;
}
}
static Type*
xnewtype(uint ty, DwarfSym *s)
{
Type *t;
t = typebynum(s->unit+s->uoff, 0);
t->ty = ty;
return t;
}
int
dwarf2acid(Dwarf *d, Biobuf *b)
{
DwarfSym s;
/* pass over dwarf section pulling out type info */
if(dwarfenum(d, &s) < 0)
return -1;
while(dwarfnextsymat(d, &s, 0) == 1)
ds2acid(d, &s, b, nil);
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:
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;
case TagFormalParameter:
case TagVariable:
if(s->attrs.name==nil || s->attrs.type==0)
break;
addsymx(fn, s->attrs.name, typebynum(s->attrs.type, 0));
break;
}
}