2 * Dwarf abbreviation parsing code.
4 * The convention here is that calling dwarfgetabbrevs relinquishes
5 * access to any abbrevs returned previously. Will have to add
6 * explicit reference counting if this turns out not to be acceptable.
15 static int parseabbrevs(Dwarf*, ulong, DwarfAbbrev*, DwarfAttr*, int*, int*);
16 DwarfAbbrev *dwarfgetabbrev(Dwarf*, ulong, ulong);
19 loadabbrevs(Dwarf *d, ulong off, DwarfAbbrev **aa)
25 if(d->acache.off == off && d->acache.na){
30 /* two passes - once to count, then allocate, then a second to copy */
31 if(parseabbrevs(d, off, nil, nil, &nabbrev, &nattr) < 0)
34 abbrev = malloc(nabbrev*sizeof(DwarfAbbrev) + nattr*sizeof(DwarfAttr));
35 attr = (DwarfAttr*)(abbrev+nabbrev);
37 if(parseabbrevs(d, off, abbrev, attr, nil, nil) < 0){
44 d->acache.na = nabbrev;
52 parseabbrevs(Dwarf *d, ulong off, DwarfAbbrev *abbrev, DwarfAttr *attr, int *pnabbrev, int *pnattr)
54 int i, nabbrev, nattr, haskids;
55 ulong num, tag, name, form;
58 if(off >= d->abbrev.len){
59 werrstr("bad abbrev section offset 0x%lux >= 0x%lux\n", off, d->abbrev.len);
63 memset(&b, 0, sizeof b);
64 b.p = d->abbrev.data + off;
65 b.ep = d->abbrev.data + d->abbrev.len;
71 werrstr("malformed abbrev data");
74 num = dwarfget128(&b);
77 tag = dwarfget128(&b);
78 haskids = dwarfget1(&b);
80 name = dwarfget128(&b);
81 form = dwarfget128(&b);
82 if(name == 0 && form == 0)
92 abbrev->haskids = haskids;
109 findabbrev(DwarfAbbrev *a, int na, ulong num)
116 werrstr("abbrev not found");
121 dwarfgetabbrev(Dwarf *d, ulong off, ulong num)
126 if((na = loadabbrevs(d, off, &a)) < 0){
127 werrstr("loadabbrevs: %r");
130 return findabbrev(a, na, num);