2 a84cbb2a 2004-04-19 devnull * Dwarf abbreviation parsing code.
4 a84cbb2a 2004-04-19 devnull * The convention here is that calling dwarfgetabbrevs relinquishes
5 a84cbb2a 2004-04-19 devnull * access to any abbrevs returned previously. Will have to add
6 a84cbb2a 2004-04-19 devnull * explicit reference counting if this turns out not to be acceptable.
9 a84cbb2a 2004-04-19 devnull #include <u.h>
10 a84cbb2a 2004-04-19 devnull #include <libc.h>
11 a84cbb2a 2004-04-19 devnull #include <bio.h>
12 a84cbb2a 2004-04-19 devnull #include "elf.h"
13 a84cbb2a 2004-04-19 devnull #include "dwarf.h"
15 a84cbb2a 2004-04-19 devnull static int parseabbrevs(Dwarf*, ulong, DwarfAbbrev*, DwarfAttr*, int*, int*);
16 a84cbb2a 2004-04-19 devnull DwarfAbbrev *dwarfgetabbrev(Dwarf*, ulong, ulong);
18 a84cbb2a 2004-04-19 devnull static int
19 a84cbb2a 2004-04-19 devnull loadabbrevs(Dwarf *d, ulong off, DwarfAbbrev **aa)
21 a84cbb2a 2004-04-19 devnull int nattr, nabbrev;
22 a84cbb2a 2004-04-19 devnull DwarfAbbrev *abbrev;
23 a84cbb2a 2004-04-19 devnull DwarfAttr *attr;
25 a84cbb2a 2004-04-19 devnull if(d->acache.off == off && d->acache.na){
26 a84cbb2a 2004-04-19 devnull *aa = d->acache.a;
27 a84cbb2a 2004-04-19 devnull return d->acache.na;
30 a84cbb2a 2004-04-19 devnull /* two passes - once to count, then allocate, then a second to copy */
31 a84cbb2a 2004-04-19 devnull if(parseabbrevs(d, off, nil, nil, &nabbrev, &nattr) < 0)
32 a84cbb2a 2004-04-19 devnull return -1;
34 a84cbb2a 2004-04-19 devnull abbrev = malloc(nabbrev*sizeof(DwarfAbbrev) + nattr*sizeof(DwarfAttr));
35 a84cbb2a 2004-04-19 devnull attr = (DwarfAttr*)(abbrev+nabbrev);
37 a84cbb2a 2004-04-19 devnull if(parseabbrevs(d, off, abbrev, attr, nil, nil) < 0){
38 a84cbb2a 2004-04-19 devnull free(abbrev);
39 a84cbb2a 2004-04-19 devnull return -1;
42 a84cbb2a 2004-04-19 devnull free(d->acache.a);
43 a84cbb2a 2004-04-19 devnull d->acache.a = abbrev;
44 a84cbb2a 2004-04-19 devnull d->acache.na = nabbrev;
45 a84cbb2a 2004-04-19 devnull d->acache.off = off;
47 a84cbb2a 2004-04-19 devnull *aa = abbrev;
48 a84cbb2a 2004-04-19 devnull return nabbrev;
51 a84cbb2a 2004-04-19 devnull static int
52 a84cbb2a 2004-04-19 devnull parseabbrevs(Dwarf *d, ulong off, DwarfAbbrev *abbrev, DwarfAttr *attr, int *pnabbrev, int *pnattr)
54 a84cbb2a 2004-04-19 devnull int i, nabbrev, nattr, haskids;
55 a84cbb2a 2004-04-19 devnull ulong num, tag, name, form;
56 a84cbb2a 2004-04-19 devnull DwarfBuf b;
58 a84cbb2a 2004-04-19 devnull if(off >= d->abbrev.len){
59 a84cbb2a 2004-04-19 devnull werrstr("bad abbrev section offset 0x%lux >= 0x%lux\n", off, d->abbrev.len);
60 a84cbb2a 2004-04-19 devnull return -1;
63 a84cbb2a 2004-04-19 devnull memset(&b, 0, sizeof b);
64 a84cbb2a 2004-04-19 devnull b.p = d->abbrev.data + off;
65 a84cbb2a 2004-04-19 devnull b.ep = d->abbrev.data + d->abbrev.len;
67 a84cbb2a 2004-04-19 devnull nabbrev = 0;
68 a84cbb2a 2004-04-19 devnull nattr = 0;
70 a84cbb2a 2004-04-19 devnull if(b.p == nil){
71 a84cbb2a 2004-04-19 devnull werrstr("malformed abbrev data");
72 a84cbb2a 2004-04-19 devnull return -1;
74 a84cbb2a 2004-04-19 devnull num = dwarfget128(&b);
75 a84cbb2a 2004-04-19 devnull if(num == 0)
77 a84cbb2a 2004-04-19 devnull tag = dwarfget128(&b);
78 a84cbb2a 2004-04-19 devnull haskids = dwarfget1(&b);
79 a84cbb2a 2004-04-19 devnull for(i=0;; i++){
80 a84cbb2a 2004-04-19 devnull name = dwarfget128(&b);
81 a84cbb2a 2004-04-19 devnull form = dwarfget128(&b);
82 a84cbb2a 2004-04-19 devnull if(name == 0 && form == 0)
84 a84cbb2a 2004-04-19 devnull if(attr){
85 a84cbb2a 2004-04-19 devnull attr[i].name = name;
86 a84cbb2a 2004-04-19 devnull attr[i].form = form;
89 a84cbb2a 2004-04-19 devnull if(abbrev){
90 a84cbb2a 2004-04-19 devnull abbrev->num = num;
91 a84cbb2a 2004-04-19 devnull abbrev->tag = tag;
92 a84cbb2a 2004-04-19 devnull abbrev->haskids = haskids;
93 a84cbb2a 2004-04-19 devnull abbrev->attr = attr;
94 a84cbb2a 2004-04-19 devnull abbrev->nattr = i;
95 a84cbb2a 2004-04-19 devnull abbrev++;
96 a84cbb2a 2004-04-19 devnull attr += i;
98 a84cbb2a 2004-04-19 devnull nabbrev++;
99 a84cbb2a 2004-04-19 devnull nattr += i;
101 a84cbb2a 2004-04-19 devnull if(pnabbrev)
102 a84cbb2a 2004-04-19 devnull *pnabbrev = nabbrev;
103 a84cbb2a 2004-04-19 devnull if(pnattr)
104 a84cbb2a 2004-04-19 devnull *pnattr = nattr;
105 a84cbb2a 2004-04-19 devnull return 0;
108 a84cbb2a 2004-04-19 devnull static DwarfAbbrev*
109 a84cbb2a 2004-04-19 devnull findabbrev(DwarfAbbrev *a, int na, ulong num)
113 a84cbb2a 2004-04-19 devnull for(i=0; i<na; i++)
114 a84cbb2a 2004-04-19 devnull if(a[i].num == num)
115 a84cbb2a 2004-04-19 devnull return &a[i];
116 eaf56db5 2004-04-21 devnull werrstr("abbrev not found");
117 a84cbb2a 2004-04-19 devnull return nil;
120 a84cbb2a 2004-04-19 devnull DwarfAbbrev*
121 a84cbb2a 2004-04-19 devnull dwarfgetabbrev(Dwarf *d, ulong off, ulong num)
123 a84cbb2a 2004-04-19 devnull DwarfAbbrev *a;
126 eaf56db5 2004-04-21 devnull if((na = loadabbrevs(d, off, &a)) < 0){
127 eaf56db5 2004-04-21 devnull werrstr("loadabbrevs: %r");
128 a84cbb2a 2004-04-19 devnull return nil;
130 a84cbb2a 2004-04-19 devnull return findabbrev(a, na, num);