xref: /reactos/sdk/lib/rossym_new/dwarfabbrev.c (revision 40462c92)
1 /*
2  * Dwarf abbreviation parsing code.
3  *
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.
7  */
8 
9 #include <precomp.h>
10 
11 #define NDEBUG
12 #include <debug.h>
13 
14 static int parseabbrevs(Dwarf*, ulong, DwarfAbbrev*, DwarfAttr*, int*, int*);
15 DwarfAbbrev *dwarfgetabbrev(Dwarf*, ulong, ulong);
16 
17 static int
18 loadabbrevs(Dwarf *d, ulong off, DwarfAbbrev **aa)
19 {
20     int nattr, nabbrev;
21     DwarfAbbrev *abbrev;
22     DwarfAttr *attr;
23 
24     if(d->acache.off == off && d->acache.na){
25         *aa = d->acache.a;
26         return d->acache.na;
27     }
28 
29     /* two passes - once to count, then allocate, then a second to copy */
30     if(parseabbrevs(d, off, nil, nil, &nabbrev, &nattr) < 0) {
31         return -1;
32     }
33 
34     abbrev = malloc(nabbrev*sizeof(DwarfAbbrev) + nattr*sizeof(DwarfAttr));
35     attr = (DwarfAttr*)(abbrev+nabbrev);
36 
37     if(parseabbrevs(d, off, abbrev, attr, nil, nil) < 0){
38         free(abbrev);
39         return -1;
40     }
41 
42     free(d->acache.a);
43     d->acache.a = abbrev;
44     d->acache.na = nabbrev;
45     d->acache.off = off;
46 
47     *aa = abbrev;
48     return nabbrev;
49 }
50 
51 static int
52 parseabbrevs(Dwarf *d, ulong off, DwarfAbbrev *abbrev, DwarfAttr *attr, int *pnabbrev, int *pnattr)
53 {
54     int i, nabbrev, nattr, haskids;
55     ulong num, tag, name, form;
56     DwarfBuf b;
57 
58     if(off >= d->abbrev.len){
59         werrstr("bad abbrev section offset 0x%lux >= 0x%lux", off, d->abbrev.len);
60         return -1;
61     }
62 
63     memset(&b, 0, sizeof b);
64     b.p = d->abbrev.data + off;
65     b.ep = d->abbrev.data + d->abbrev.len;
66 
67     nabbrev = 0;
68     nattr = 0;
69     for(;;){
70         if(b.p == nil){
71             werrstr("malformed abbrev data");
72             return -1;
73         }
74         num = dwarfget128(&b);
75         if(num == 0)
76             break;
77         tag = dwarfget128(&b);
78         werrstr("abbrev: num %d tag %x @ %x", num, tag, b.p - d->abbrev.data);
79         haskids = dwarfget1(&b);
80         for(i=0;; i++){
81             name = dwarfget128(&b);
82             form = dwarfget128(&b);
83             assert(form < 0x3000);
84             if(name == 0 && form == 0)
85                 break;
86             if(attr){
87                 attr[i].name = name;
88                 attr[i].form = form;
89             }
90         }
91         if(abbrev){
92             abbrev->num = num;
93             abbrev->tag = tag;
94             abbrev->haskids = haskids;
95             abbrev->attr = attr;
96             abbrev->nattr = i;
97             abbrev++;
98             attr += i;
99         }
100         nabbrev++;
101         nattr += i;
102     }
103     if(pnabbrev)
104         *pnabbrev = nabbrev;
105     if(pnattr)
106         *pnattr = nattr;
107     return 0;
108 }
109 
110 static DwarfAbbrev*
111 findabbrev(DwarfAbbrev *a, int na, ulong num)
112 {
113     int i;
114 
115     for(i=0; i<na; i++) {
116         if(a[i].num == num) {
117             return &a[i];
118         }
119     }
120     werrstr("abbrev not found (%x)", na);
121     return nil;
122 }
123 
124 DwarfAbbrev*
125 dwarfgetabbrev(Dwarf *d, ulong off, ulong num)
126 {
127     DwarfAbbrev *a;
128     int na;
129     werrstr("want num %d\n", num);
130     if((na = loadabbrevs(d, off, &a)) < 0){
131         werrstr("loadabbrevs: %r");
132         return nil;
133     }
134     return findabbrev(a, na, num);
135 }
136 
137