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.
14 static int parseabbrevs(Dwarf
*, ulong
, DwarfAbbrev
*, DwarfAttr
*, int*, int*);
15 DwarfAbbrev
*dwarfgetabbrev(Dwarf
*, ulong
, ulong
);
18 loadabbrevs(Dwarf
*d
, ulong off
, DwarfAbbrev
**aa
)
24 if(d
->acache
.off
== off
&& d
->acache
.na
){
29 /* two passes - once to count, then allocate, then a second to copy */
30 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", 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 werrstr("abbrev: num %d tag %x @ %x", num
, tag
, b
.p
- d
->abbrev
.data
);
79 haskids
= dwarfget1(&b
);
81 name
= dwarfget128(&b
);
82 form
= dwarfget128(&b
);
83 assert(form
< 0x3000);
84 if(name
== 0 && form
== 0)
94 abbrev
->haskids
= haskids
;
111 findabbrev(DwarfAbbrev
*a
, int na
, ulong num
)
115 for(i
=0; i
<na
; i
++) {
116 if(a
[i
].num
== num
) {
120 werrstr("abbrev not found (%x)", na
);
125 dwarfgetabbrev(Dwarf
*d
, ulong off
, ulong num
)
129 werrstr("want num %d\n", num
);
130 if((na
= loadabbrevs(d
, off
, &a
)) < 0){
131 werrstr("loadabbrevs: %r");
134 return findabbrev(a
, na
, num
);