2 a84cbb2a 2004-04-19 devnull * Dwarf data format parsing routines.
5 a84cbb2a 2004-04-19 devnull #include <u.h>
6 a84cbb2a 2004-04-19 devnull #include <libc.h>
7 a84cbb2a 2004-04-19 devnull #include <bio.h>
8 a84cbb2a 2004-04-19 devnull #include "elf.h"
9 a84cbb2a 2004-04-19 devnull #include "dwarf.h"
12 a84cbb2a 2004-04-19 devnull dwarfget1(DwarfBuf *b)
14 a84cbb2a 2004-04-19 devnull if(b->p==nil || b->p+1 > b->ep){
15 a84cbb2a 2004-04-19 devnull b->p = nil;
16 a84cbb2a 2004-04-19 devnull return 0;
18 a84cbb2a 2004-04-19 devnull return *b->p++;
22 a84cbb2a 2004-04-19 devnull dwarfgetn(DwarfBuf *b, uchar *a, int n)
24 a84cbb2a 2004-04-19 devnull if(b->p==nil || b->p+n > b->ep){
25 a84cbb2a 2004-04-19 devnull b->p = nil;
26 a84cbb2a 2004-04-19 devnull memset(a, 0, n);
27 a84cbb2a 2004-04-19 devnull return -1;
29 a84cbb2a 2004-04-19 devnull memmove(a, b->p, n);
30 a84cbb2a 2004-04-19 devnull b->p += n;
31 a84cbb2a 2004-04-19 devnull return 0;
35 a84cbb2a 2004-04-19 devnull dwarfgetnref(DwarfBuf *b, ulong n)
37 a84cbb2a 2004-04-19 devnull uchar *p;
39 a84cbb2a 2004-04-19 devnull if(b->p==nil || b->p+n > b->ep){
40 a84cbb2a 2004-04-19 devnull b->p = nil;
41 a84cbb2a 2004-04-19 devnull return nil;
43 a84cbb2a 2004-04-19 devnull p = b->p;
44 a84cbb2a 2004-04-19 devnull b->p += n;
45 a84cbb2a 2004-04-19 devnull return p;
49 a84cbb2a 2004-04-19 devnull dwarfgetstring(DwarfBuf *b)
53 a84cbb2a 2004-04-19 devnull if(b->p == nil)
54 a84cbb2a 2004-04-19 devnull return nil;
55 a84cbb2a 2004-04-19 devnull s = (char*)b->p;
56 a84cbb2a 2004-04-19 devnull while(b->p < b->ep && *b->p)
58 a84cbb2a 2004-04-19 devnull if(b->p >= b->ep){
59 a84cbb2a 2004-04-19 devnull b->p = nil;
60 a84cbb2a 2004-04-19 devnull return nil;
63 a84cbb2a 2004-04-19 devnull return s;
67 a84cbb2a 2004-04-19 devnull dwarfskip(DwarfBuf *b, int n)
69 a84cbb2a 2004-04-19 devnull if(b->p==nil || b->p+n > b->ep)
70 a84cbb2a 2004-04-19 devnull b->p = nil;
72 a84cbb2a 2004-04-19 devnull b->p += n;
76 a84cbb2a 2004-04-19 devnull dwarfget2(DwarfBuf *b)
80 a84cbb2a 2004-04-19 devnull if(b->p==nil || b->p+2 > b->ep){
81 a84cbb2a 2004-04-19 devnull b->p = nil;
82 a84cbb2a 2004-04-19 devnull return 0;
84 a84cbb2a 2004-04-19 devnull v = b->d->elf->hdr.e2(b->p);
85 a84cbb2a 2004-04-19 devnull b->p += 2;
86 a84cbb2a 2004-04-19 devnull return v;
90 a84cbb2a 2004-04-19 devnull dwarfget4(DwarfBuf *b)
94 a84cbb2a 2004-04-19 devnull if(b->p==nil || b->p+4 > b->ep){
95 a84cbb2a 2004-04-19 devnull b->p = nil;
96 a84cbb2a 2004-04-19 devnull return 0;
98 a84cbb2a 2004-04-19 devnull v = b->d->elf->hdr.e4(b->p);
99 a84cbb2a 2004-04-19 devnull b->p += 4;
100 a84cbb2a 2004-04-19 devnull return v;
104 a84cbb2a 2004-04-19 devnull dwarfget8(DwarfBuf *b)
106 a84cbb2a 2004-04-19 devnull uvlong v;
108 a84cbb2a 2004-04-19 devnull if(b->p==nil || b->p+8 > b->ep){
109 a84cbb2a 2004-04-19 devnull b->p = nil;
110 a84cbb2a 2004-04-19 devnull return 0;
112 a84cbb2a 2004-04-19 devnull v = b->d->elf->hdr.e8(b->p);
113 a84cbb2a 2004-04-19 devnull b->p += 8;
114 a84cbb2a 2004-04-19 devnull return v;
118 a84cbb2a 2004-04-19 devnull dwarfgetaddr(DwarfBuf *b)
120 a84cbb2a 2004-04-19 devnull static int nbad;
122 a84cbb2a 2004-04-19 devnull if(b->addrsize == 0)
123 a84cbb2a 2004-04-19 devnull b->addrsize = b->d->addrsize;
125 a84cbb2a 2004-04-19 devnull switch(b->addrsize){
127 a84cbb2a 2004-04-19 devnull return dwarfget1(b);
129 a84cbb2a 2004-04-19 devnull return dwarfget2(b);
131 a84cbb2a 2004-04-19 devnull return dwarfget4(b);
133 a84cbb2a 2004-04-19 devnull return dwarfget8(b);
134 a84cbb2a 2004-04-19 devnull default:
135 a84cbb2a 2004-04-19 devnull if(++nbad == 1)
136 a84cbb2a 2004-04-19 devnull fprint(2, "dwarf: unexpected address size %lud in dwarfgetaddr\n", b->addrsize);
137 a84cbb2a 2004-04-19 devnull b->p = nil;
138 a84cbb2a 2004-04-19 devnull return 0;
142 a84cbb2a 2004-04-19 devnull int n1, n2, n3, n4, n5;
144 a84cbb2a 2004-04-19 devnull /* An inline function picks off the calls to dwarfget128 for 1-byte encodings,
145 a84cbb2a 2004-04-19 devnull * more than by far the common case (99.999% on most binaries!). */
147 a84cbb2a 2004-04-19 devnull dwarfget128(DwarfBuf *b)
149 a84cbb2a 2004-04-19 devnull static int nbad;
150 a84cbb2a 2004-04-19 devnull ulong c, d;
152 a84cbb2a 2004-04-19 devnull if(b->p == nil)
153 a84cbb2a 2004-04-19 devnull return 0;
154 a84cbb2a 2004-04-19 devnull c = *b->p++;
155 a84cbb2a 2004-04-19 devnull if(!(c&0x80))
157 a84cbb2a 2004-04-19 devnull return c;
159 be36ff68 2004-04-29 devnull c &= ~0x80;
160 a84cbb2a 2004-04-19 devnull d = *b->p++;
161 a84cbb2a 2004-04-19 devnull c |= (d&0x7F)<<7;
162 a84cbb2a 2004-04-19 devnull if(!(d&0x80))
164 a84cbb2a 2004-04-19 devnull return c;
166 a84cbb2a 2004-04-19 devnull d = *b->p++;
167 a84cbb2a 2004-04-19 devnull c |= (d&0x7F)<<14;
168 a84cbb2a 2004-04-19 devnull if(!(d&0x80))
170 a84cbb2a 2004-04-19 devnull return c;
172 a84cbb2a 2004-04-19 devnull d = *b->p++;
173 a84cbb2a 2004-04-19 devnull c |= (d&0x7F)<<21;
174 a84cbb2a 2004-04-19 devnull if(!(d&0x80))
176 a84cbb2a 2004-04-19 devnull return c;
178 a84cbb2a 2004-04-19 devnull d = *b->p++;
179 a84cbb2a 2004-04-19 devnull c |= (d&0x7F)<<28;
180 a84cbb2a 2004-04-19 devnull if(!(d&0x80))
182 a84cbb2a 2004-04-19 devnull return c;
184 a84cbb2a 2004-04-19 devnull while(b->p<b->ep && *b->p&0x80)
186 a84cbb2a 2004-04-19 devnull if(++nbad == 1)
187 a84cbb2a 2004-04-19 devnull fprint(2, "dwarf: overflow during parsing of uleb128 integer\n");
188 a84cbb2a 2004-04-19 devnull return c;
192 a84cbb2a 2004-04-19 devnull dwarfget128s(DwarfBuf *b)
194 a84cbb2a 2004-04-19 devnull int nb, c;
195 a84cbb2a 2004-04-19 devnull ulong v;
196 a84cbb2a 2004-04-19 devnull static int nbad;
200 a84cbb2a 2004-04-19 devnull if(b->p==nil)
201 a84cbb2a 2004-04-19 devnull return 0;
202 a84cbb2a 2004-04-19 devnull while(b->p<b->ep){
203 a84cbb2a 2004-04-19 devnull c = *b->p++;
204 a84cbb2a 2004-04-19 devnull v |= (c & 0x7F)<<nb;
205 a84cbb2a 2004-04-19 devnull nb += 7;
206 a84cbb2a 2004-04-19 devnull if(!(c&0x80))
209 a84cbb2a 2004-04-19 devnull if(v&(1<<(nb-1)))
210 a84cbb2a 2004-04-19 devnull v |= ~(((ulong)1<<nb)-1);
211 a84cbb2a 2004-04-19 devnull if(nb > 8*sizeof(ulong)){
213 a84cbb2a 2004-04-19 devnull if(++nbad == 1)
214 a84cbb2a 2004-04-19 devnull fprint(2, "dwarf: overflow during parsing of sleb128 integer: got %d bits\n", nb);
216 a84cbb2a 2004-04-19 devnull return v;