plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

dwarf.c (3766B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <bio.h>
      4 #include <mach.h>
      5 #include <elf.h>
      6 #include <dwarf.h>
      7 #include "dat.h"
      8 
      9 static void ds2acid(Dwarf*, DwarfSym*, Biobuf*, char*);
     10 
     11 static ulong
     12 valof(uint ty, DwarfVal *v)
     13 {
     14 	switch(ty){
     15 	default:
     16 fmtinstall('H', encodefmt);
     17 fprint(2, "valof %d %.*H\n", ty, v->b.len, v->b.data);
     18 		return 0;
     19 	case TConstant:
     20 		return v->c;
     21 	}
     22 }
     23 
     24 static Type*
     25 xnewtype(uint ty, DwarfSym *s)
     26 {
     27 	Type *t;
     28 
     29 	t = typebynum(s->unit+s->uoff, 0);
     30 	t->ty = ty;
     31 	return t;
     32 }
     33 
     34 int
     35 dwarf2acid(Dwarf *d, Biobuf *b)
     36 {
     37 	DwarfSym s;
     38 
     39 	/* pass over dwarf section pulling out type info */
     40 
     41 	if(dwarfenum(d, &s) < 0)
     42 		return -1;
     43 
     44 	while(dwarfnextsymat(d, &s, 0) == 1)
     45 		ds2acid(d, &s, b, nil);
     46 
     47 	printtypes(b);
     48 	dumpsyms(b);
     49 	freetypes();
     50 	return 0;
     51 }
     52 
     53 static void
     54 ds2acid(Dwarf *d, DwarfSym *s, Biobuf *b, char *fn)
     55 {
     56 	int depth;
     57 	Type *t;
     58 
     59 	depth = s->depth;
     60 
     61 	switch(s->attrs.tag){
     62 	case TagSubroutineType:
     63 		t = xnewtype(Function, s);
     64 		goto Recurse;
     65 
     66 	case TagSubprogram:
     67 		fn = s->attrs.name;
     68 		goto Recurse;
     69 
     70 	case TagCompileUnit:
     71 	case TagLexDwarfBlock:
     72 	Recurse:
     73 		/* recurse into substructure */
     74 		while(dwarfnextsymat(d, s, depth+1) == 1)
     75 			ds2acid(d, s, b, fn);
     76 		break;
     77 
     78 	case TagTypedef:
     79 		t = xnewtype(Typedef, s);
     80 		t->name = s->attrs.name;
     81 		t->sub = typebynum(s->attrs.type, 0);
     82 		break;
     83 
     84 	case TagBaseType:
     85 		t = xnewtype(Base, s);
     86 		t->xsizeof = s->attrs.bytesize;
     87 		switch(s->attrs.encoding){
     88 		default:
     89 		case TypeAddress:
     90 			t->printfmt = 'x';
     91 			break;
     92 		case TypeBoolean:
     93 		case TypeUnsigned:
     94 		case TypeSigned:
     95 		case TypeSignedChar:
     96 		case TypeUnsignedChar:
     97 			t->printfmt = 'd';
     98 			break;
     99 		case TypeFloat:
    100 			t->printfmt = 'f';
    101 			break;
    102 		case TypeComplexFloat:
    103 			t->printfmt = 'F';
    104 			break;
    105 		case TypeImaginaryFloat:
    106 			t->printfmt = 'i';
    107 			break;
    108 		}
    109 		break;
    110 
    111 	case TagPointerType:
    112 		t = xnewtype(Pointer, s);
    113 		t->sub = typebynum(s->attrs.type, 0);
    114 		break;
    115 
    116 	case TagConstType:
    117 	case TagVolatileType:
    118 		t = xnewtype(Defer, s);
    119 		t->sub = typebynum(s->attrs.type, 0);
    120 		break;
    121 
    122 	case TagArrayType:
    123 		t = xnewtype(Array, s);
    124 		t->sub = typebynum(s->attrs.type, 0);
    125 		break;
    126 
    127 	case TagStructType:
    128 	case TagUnionType:
    129 		t = xnewtype(Aggr, s);
    130 		t->sue = s->attrs.tag==TagStructType ? 's' : 'u';
    131 		t->xsizeof = s->attrs.bytesize;
    132 		t->suename = s->attrs.name;
    133 		t->isunion = s->attrs.tag==TagUnionType;
    134 		while(dwarfnextsymat(d, s, depth+1) == 1){
    135 			if(s->attrs.tag != TagMember){
    136 				ds2acid(d, s, b, fn);
    137 				continue;
    138 			}
    139 			if(!s->attrs.have.name || !s->attrs.have.type)
    140 				continue;
    141 			if(t->n%32 == 0){
    142 				t->tname = erealloc(t->tname, (t->n+32)*sizeof(t->tname[0]));
    143 				t->val = erealloc(t->val, (t->n+32)*sizeof(t->val[0]));
    144 				t->t = erealloc(t->t, (t->n+32)*sizeof(t->t[0]));
    145 			}
    146 			t->tname[t->n] = s->attrs.name;
    147 			if(t->isunion)
    148 				t->val[t->n] = 0;
    149 			else
    150 				t->val[t->n] = valof(s->attrs.have.datamemberloc, &s->attrs.datamemberloc);
    151 			t->t[t->n] = typebynum(s->attrs.type, 0);
    152 			t->n++;
    153 		}
    154 		break;
    155 
    156 	case TagEnumerationType:
    157 		t = xnewtype(Enum, s);
    158 		t->sue = 'e';
    159 		t->suename = s->attrs.name;
    160 		t->xsizeof = s->attrs.bytesize;
    161 		while(dwarfnextsymat(d, s, depth+1) == 1){
    162 			if(s->attrs.tag != TagEnumerator){
    163 				ds2acid(d, s, b, fn);
    164 				continue;
    165 			}
    166 			if(!s->attrs.have.name || !s->attrs.have.constvalue)
    167 				continue;
    168 			if(t->n%32 == 0){
    169 				t->tname = erealloc(t->tname, (t->n+32)*sizeof(t->tname[0]));
    170 				t->val = erealloc(t->val, (t->n+32)*sizeof(t->val[0]));
    171 			}
    172 			t->tname[t->n] = s->attrs.name;
    173 			t->val[t->n] = valof(s->attrs.have.constvalue, &s->attrs.constvalue);
    174 			t->n++;
    175 		}
    176 		break;
    177 
    178 	case TagFormalParameter:
    179 	case TagVariable:
    180 		if(s->attrs.name==nil || s->attrs.type==0)
    181 			break;
    182 		addsymx(fn, s->attrs.name, typebynum(s->attrs.type, 0));
    183 		break;
    184 	}
    185 }