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