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 d = *b->p++;
160 c |= (d&0x7F)<<7;
161 if(!(d&0x80))
162 {n2++;
163 return c;
165 d = *b->p++;
166 c |= (d&0x7F)<<14;
167 if(!(d&0x80))
168 {n3++;
169 return c;
171 d = *b->p++;
172 c |= (d&0x7F)<<21;
173 if(!(d&0x80))
174 {n4++;
175 return c;
177 d = *b->p++;
178 c |= (d&0x7F)<<28;
179 if(!(d&0x80))
180 {n5++;
181 return c;
183 while(b->p<b->ep && *b->p&0x80)
184 b->p++;
185 if(++nbad == 1)
186 fprint(2, "dwarf: overflow during parsing of uleb128 integer\n");
187 return c;
190 long
191 dwarfget128s(DwarfBuf *b)
193 int nb, c;
194 ulong v;
195 static int nbad;
197 v = 0;
198 nb = 0;
199 if(b->p==nil)
200 return 0;
201 while(b->p<b->ep){
202 c = *b->p++;
203 v |= (c & 0x7F)<<nb;
204 nb += 7;
205 if(!(c&0x80))
206 break;
208 if(v&(1<<(nb-1)))
209 v |= ~(((ulong)1<<nb)-1);
210 if(nb > 8*sizeof(ulong)){
211 if(0)
212 if(++nbad == 1)
213 fprint(2, "dwarf: overflow during parsing of sleb128 integer: got %d bits\n", nb);
215 return v;