Blame


1 a84cbb2a 2004-04-19 devnull /*
2 a84cbb2a 2004-04-19 devnull * Dwarf data format parsing routines.
3 a84cbb2a 2004-04-19 devnull */
4 a84cbb2a 2004-04-19 devnull
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"
10 a84cbb2a 2004-04-19 devnull
11 a84cbb2a 2004-04-19 devnull ulong
12 a84cbb2a 2004-04-19 devnull dwarfget1(DwarfBuf *b)
13 a84cbb2a 2004-04-19 devnull {
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;
17 a84cbb2a 2004-04-19 devnull }
18 a84cbb2a 2004-04-19 devnull return *b->p++;
19 a84cbb2a 2004-04-19 devnull }
20 a84cbb2a 2004-04-19 devnull
21 a84cbb2a 2004-04-19 devnull int
22 a84cbb2a 2004-04-19 devnull dwarfgetn(DwarfBuf *b, uchar *a, int n)
23 a84cbb2a 2004-04-19 devnull {
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;
28 a84cbb2a 2004-04-19 devnull }
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;
32 a84cbb2a 2004-04-19 devnull }
33 a84cbb2a 2004-04-19 devnull
34 a84cbb2a 2004-04-19 devnull uchar*
35 a84cbb2a 2004-04-19 devnull dwarfgetnref(DwarfBuf *b, ulong n)
36 a84cbb2a 2004-04-19 devnull {
37 a84cbb2a 2004-04-19 devnull uchar *p;
38 a84cbb2a 2004-04-19 devnull
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;
42 a84cbb2a 2004-04-19 devnull }
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;
46 a84cbb2a 2004-04-19 devnull }
47 a84cbb2a 2004-04-19 devnull
48 a84cbb2a 2004-04-19 devnull char*
49 a84cbb2a 2004-04-19 devnull dwarfgetstring(DwarfBuf *b)
50 a84cbb2a 2004-04-19 devnull {
51 a84cbb2a 2004-04-19 devnull char *s;
52 a84cbb2a 2004-04-19 devnull
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)
57 a84cbb2a 2004-04-19 devnull 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;
61 a84cbb2a 2004-04-19 devnull }
62 a84cbb2a 2004-04-19 devnull b->p++;
63 a84cbb2a 2004-04-19 devnull return s;
64 a84cbb2a 2004-04-19 devnull }
65 a84cbb2a 2004-04-19 devnull
66 a84cbb2a 2004-04-19 devnull void
67 a84cbb2a 2004-04-19 devnull dwarfskip(DwarfBuf *b, int n)
68 a84cbb2a 2004-04-19 devnull {
69 a84cbb2a 2004-04-19 devnull if(b->p==nil || b->p+n > b->ep)
70 a84cbb2a 2004-04-19 devnull b->p = nil;
71 a84cbb2a 2004-04-19 devnull else
72 a84cbb2a 2004-04-19 devnull b->p += n;
73 a84cbb2a 2004-04-19 devnull }
74 a84cbb2a 2004-04-19 devnull
75 a84cbb2a 2004-04-19 devnull ulong
76 a84cbb2a 2004-04-19 devnull dwarfget2(DwarfBuf *b)
77 a84cbb2a 2004-04-19 devnull {
78 a84cbb2a 2004-04-19 devnull ulong v;
79 a84cbb2a 2004-04-19 devnull
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;
83 a84cbb2a 2004-04-19 devnull }
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;
87 a84cbb2a 2004-04-19 devnull }
88 a84cbb2a 2004-04-19 devnull
89 a84cbb2a 2004-04-19 devnull ulong
90 a84cbb2a 2004-04-19 devnull dwarfget4(DwarfBuf *b)
91 a84cbb2a 2004-04-19 devnull {
92 a84cbb2a 2004-04-19 devnull ulong v;
93 a84cbb2a 2004-04-19 devnull
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;
97 a84cbb2a 2004-04-19 devnull }
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;
101 a84cbb2a 2004-04-19 devnull }
102 a84cbb2a 2004-04-19 devnull
103 a84cbb2a 2004-04-19 devnull uvlong
104 a84cbb2a 2004-04-19 devnull dwarfget8(DwarfBuf *b)
105 a84cbb2a 2004-04-19 devnull {
106 a84cbb2a 2004-04-19 devnull uvlong v;
107 a84cbb2a 2004-04-19 devnull
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;
111 a84cbb2a 2004-04-19 devnull }
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;
115 a84cbb2a 2004-04-19 devnull }
116 a84cbb2a 2004-04-19 devnull
117 a84cbb2a 2004-04-19 devnull ulong
118 a84cbb2a 2004-04-19 devnull dwarfgetaddr(DwarfBuf *b)
119 a84cbb2a 2004-04-19 devnull {
120 a84cbb2a 2004-04-19 devnull static int nbad;
121 a84cbb2a 2004-04-19 devnull
122 a84cbb2a 2004-04-19 devnull if(b->addrsize == 0)
123 a84cbb2a 2004-04-19 devnull b->addrsize = b->d->addrsize;
124 a84cbb2a 2004-04-19 devnull
125 a84cbb2a 2004-04-19 devnull switch(b->addrsize){
126 a84cbb2a 2004-04-19 devnull case 1:
127 a84cbb2a 2004-04-19 devnull return dwarfget1(b);
128 a84cbb2a 2004-04-19 devnull case 2:
129 a84cbb2a 2004-04-19 devnull return dwarfget2(b);
130 a84cbb2a 2004-04-19 devnull case 4:
131 a84cbb2a 2004-04-19 devnull return dwarfget4(b);
132 a84cbb2a 2004-04-19 devnull case 8:
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;
139 a84cbb2a 2004-04-19 devnull }
140 a84cbb2a 2004-04-19 devnull }
141 a84cbb2a 2004-04-19 devnull
142 a84cbb2a 2004-04-19 devnull int n1, n2, n3, n4, n5;
143 a84cbb2a 2004-04-19 devnull
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!). */
146 a84cbb2a 2004-04-19 devnull ulong
147 a84cbb2a 2004-04-19 devnull dwarfget128(DwarfBuf *b)
148 a84cbb2a 2004-04-19 devnull {
149 a84cbb2a 2004-04-19 devnull static int nbad;
150 a84cbb2a 2004-04-19 devnull ulong c, d;
151 a84cbb2a 2004-04-19 devnull
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))
156 a84cbb2a 2004-04-19 devnull {n1++;
157 a84cbb2a 2004-04-19 devnull return c;
158 a84cbb2a 2004-04-19 devnull }
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))
163 a84cbb2a 2004-04-19 devnull {n2++;
164 a84cbb2a 2004-04-19 devnull return c;
165 a84cbb2a 2004-04-19 devnull }
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))
169 a84cbb2a 2004-04-19 devnull {n3++;
170 a84cbb2a 2004-04-19 devnull return c;
171 a84cbb2a 2004-04-19 devnull }
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))
175 a84cbb2a 2004-04-19 devnull {n4++;
176 a84cbb2a 2004-04-19 devnull return c;
177 a84cbb2a 2004-04-19 devnull }
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))
181 a84cbb2a 2004-04-19 devnull {n5++;
182 a84cbb2a 2004-04-19 devnull return c;
183 a84cbb2a 2004-04-19 devnull }
184 a84cbb2a 2004-04-19 devnull while(b->p<b->ep && *b->p&0x80)
185 a84cbb2a 2004-04-19 devnull b->p++;
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;
189 a84cbb2a 2004-04-19 devnull }
190 a84cbb2a 2004-04-19 devnull
191 a84cbb2a 2004-04-19 devnull long
192 a84cbb2a 2004-04-19 devnull dwarfget128s(DwarfBuf *b)
193 a84cbb2a 2004-04-19 devnull {
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;
197 a84cbb2a 2004-04-19 devnull
198 a84cbb2a 2004-04-19 devnull v = 0;
199 a84cbb2a 2004-04-19 devnull nb = 0;
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))
207 a84cbb2a 2004-04-19 devnull break;
208 a84cbb2a 2004-04-19 devnull }
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)){
212 a84cbb2a 2004-04-19 devnull if(0)
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);
215 a84cbb2a 2004-04-19 devnull }
216 a84cbb2a 2004-04-19 devnull return v;
217 a84cbb2a 2004-04-19 devnull }