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