Blob


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