#include #include #include #include #include #include #include "dat.h" 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) { 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; } } 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; }