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