ReactOS 0.4.15-dev-7108-g1cf6ce6
dwarfcfa.c File Reference
#include <ntddk.h>
#include <reactos/rossym.h>
#include "rossympriv.h"
#include <ntimage.h>
#include <debug.h>
#include "dwarf.h"
Include dependency graph for dwarfcfa.c:

Go to the source code of this file.

Classes

struct  State
 

Macros

#define NTOSAPI
 
#define NDEBUG
 
#define trace   0
 

Typedefs

typedef struct State State
 

Functions

static int findfde (Dwarf *, ulong, State *, DwarfBuf *)
 
static int dexec (DwarfBuf *, State *, int)
 
int dwarfunwind (Dwarf *d, ulong pc, DwarfExpr *cfa, DwarfExpr *ra, DwarfExpr *r, int nr)
 
static int checkreg (State *s, long r)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 17 of file dwarfcfa.c.

◆ NTOSAPI

#define NTOSAPI

Definition at line 11 of file dwarfcfa.c.

◆ trace

#define trace   0

Definition at line 22 of file dwarfcfa.c.

Typedef Documentation

◆ State

typedef struct State State

Definition at line 24 of file dwarfcfa.c.

Function Documentation

◆ checkreg()

static int checkreg ( State s,
long  r 
)
static

Definition at line 180 of file dwarfcfa.c.

181{
182 if(r < 0 || r >= s->nr){
183 werrstr("bad register number 0x%lux", r);
184 return -1;
185 }
186 return 0;
187}
GLdouble s
Definition: gl.h:2039
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define werrstr(str,...)
Definition: compat.h:34

Referenced by dexec().

◆ dexec()

static int dexec ( DwarfBuf b,
State s,
int  locstop 
)
static

Definition at line 190 of file dwarfcfa.c.

191{
192 int c;
193 long arg1, arg2;
194 DwarfExpr *e;
195
196 for(;;){
197 if(b->p == b->ep){
198 if(s->initr)
199 s->loc = s->endloc;
200 return 0;
201 }
202 c = dwarfget1(b);
203 if(b->p == nil){
204 werrstr("ran out of instructions during cfa program");
205 if(trace) werrstr("%r\n");
206 return -1;
207 }
208 if(trace) werrstr("+ loc=0x%lux op 0x%ux ", s->loc, c);
209 switch(c>>6){
210 case 1: /* advance location */
211 arg1 = c&0x3F;
212 advance:
213 if(trace) werrstr("loc += %ld\n", arg1*s->iquantum);
214 s->loc += arg1 * s->iquantum;
215 if(locstop)
216 return 0;
217 continue;
218
219 case 2: /* offset rule */
220 arg1 = c&0x3F;
221 arg2 = dwarfget128(b);
222 offset:
223 if(trace) werrstr("r%ld += %ld\n", arg1, arg2*s->dquantum);
224 if(checkreg(s, arg1) < 0)
225 return -1;
226 s->r[arg1].type = RuleCfaOffset;
227 s->r[arg1].offset = arg2 * s->dquantum;
228 continue;
229
230 case 3: /* restore initial setting */
231 arg1 = c&0x3F;
232 restore:
233 if(trace) werrstr("r%ld = init\n", arg1);
234 if(checkreg(s, arg1) < 0)
235 return -1;
236 s->r[arg1] = s->initr[arg1];
237 continue;
238 }
239
240 switch(c){
241 case 0: /* nop */
242 if(trace) werrstr("nop\n");
243 continue;
244
245 case 0x01: /* set location */
246 s->loc = dwarfgetaddr(b);
247 if(trace) werrstr("loc = 0x%lux\n", s->loc);
248 if(locstop)
249 return 0;
250 continue;
251
252 case 0x02: /* advance loc1 */
253 arg1 = dwarfget1(b);
254 goto advance;
255
256 case 0x03: /* advance loc2 */
257 arg1 = dwarfget2(b);
258 goto advance;
259
260 case 0x04: /* advance loc4 */
261 arg1 = dwarfget4(b);
262 goto advance;
263
264 case 0x05: /* offset extended */
265 arg1 = dwarfget128(b);
266 arg2 = dwarfget128(b);
267 goto offset;
268
269 case 0x06: /* restore extended */
270 arg1 = dwarfget128(b);
271 goto restore;
272
273 case 0x07: /* undefined */
274 arg1 = dwarfget128(b);
275 if(trace) werrstr("r%ld = undef\n", arg1);
276 if(checkreg(s, arg1) < 0)
277 return -1;
278 s->r[arg1].type = RuleUndef;
279 continue;
280
281 case 0x08: /* same value */
282 arg1 = dwarfget128(b);
283 if(trace) werrstr("r%ld = same\n", arg1);
284 if(checkreg(s, arg1) < 0)
285 return -1;
286 s->r[arg1].type = RuleSame;
287 continue;
288
289 case 0x09: /* register */
290 arg1 = dwarfget128(b);
291 arg2 = dwarfget128(b);
292 if(trace) werrstr("r%ld = r%ld\n", arg1, arg2);
293 if(checkreg(s, arg1) < 0 || checkreg(s, arg2) < 0)
294 return -1;
295 s->r[arg1].type = RuleRegister;
296 s->r[arg1].reg = arg2;
297 continue;
298
299 case 0x0A: /* remember state */
300 e = malloc(s->nr*sizeof(e[0]));
301 if(trace) werrstr("push\n");
302 if(e == nil)
303 return -1;
304 void *newstack = malloc(s->nstack*sizeof(s->stack[0]));
305 RtlMoveMemory(newstack, s->stack, s->nstack*sizeof(s->stack[0]));
306 if (newstack) {
307 free(s->stack);
308 s->stack = newstack;
309 } else {
310 free(e);
311 return -1;
312 }
313 if(b->p == nil){
314 free(e);
315 return -1;
316 }
317 s->stack[s->nstack++] = e;
318 memmove(e, s->r, s->nr*sizeof(e[0]));
319 continue;
320
321 case 0x0B: /* restore state */
322 if(trace) werrstr("pop\n");
323 if(s->nstack == 0){
324 werrstr("restore state underflow");
325 return -1;
326 }
327 e = s->stack[s->nstack-1];
328 memmove(s->r, e, s->nr*sizeof(e[0]));
329 free(e);
330 s->nstack--;
331 continue;
332
333 case 0x0C: /* def cfa */
334 arg1 = dwarfget128(b);
335 arg2 = dwarfget128(b);
336 defcfa:
337 if(trace) werrstr("cfa %ld(r%ld)\n", arg2, arg1);
338 if(checkreg(s, arg1) < 0)
339 return -1;
340 s->cfa->type = RuleRegOff;
341 s->cfa->reg = arg1;
342 s->cfa->offset = arg2;
343 continue;
344
345 case 0x0D: /* def cfa register */
346 arg1 = dwarfget128(b);
347 if(trace) werrstr("cfa reg r%ld\n", arg1);
348 if(s->cfa->type != RuleRegOff){
349 werrstr("change CFA register but CFA not in register+offset form");
350 return -1;
351 }
352 if(checkreg(s, arg1) < 0)
353 return -1;
354 s->cfa->reg = arg1;
355 continue;
356
357 case 0x0E: /* def cfa offset */
358 arg1 = dwarfget128(b);
359 cfaoffset:
360 if(trace) werrstr("cfa off %ld\n", arg1);
361 if(s->cfa->type != RuleRegOff){
362 werrstr("change CFA offset but CFA not in register+offset form");
363 return -1;
364 }
365 s->cfa->offset = arg1;
366 continue;
367
368 case 0x0F: /* def cfa expression */
369 if(trace) werrstr("cfa expr\n");
370 s->cfa->type = RuleLocation;
371 s->cfa->loc.len = dwarfget128(b);
372 s->cfa->loc.data = dwarfgetnref(b, s->cfa->loc.len);
373 continue;
374
375 case 0x10: /* def reg expression */
376 arg1 = dwarfget128(b);
377 if(trace) werrstr("reg expr r%ld\n", arg1);
378 if(checkreg(s, arg1) < 0)
379 return -1;
380 s->r[arg1].type = RuleLocation;
381 s->r[arg1].loc.len = dwarfget128(b);
382 s->r[arg1].loc.data = dwarfgetnref(b, s->r[arg1].loc.len);
383 continue;
384
385 case 0x11: /* offset extended */
386 arg1 = dwarfget128(b);
388 goto offset;
389
390 case 0x12: /* cfa sf */
391 arg1 = dwarfget128(b);
393 goto defcfa;
394
395 case 0x13: /* cfa offset sf */
397 goto cfaoffset;
398
399 default: /* unknown */
400 werrstr("unknown opcode 0x%ux in cfa program", c);
401 return -1;
402 }
403 }
404 /* not reached */
405}
_STLP_MOVE_TO_STD_NAMESPACE void _STLP_CALL advance(_InputIterator &__i, _Distance __n)
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
GLuint GLuint GLuint GLuint arg1
Definition: glext.h:9513
const GLubyte * c
Definition: glext.h:8905
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glext.h:9514
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLintptr offset
Definition: glext.h:5920
#define e
Definition: ke_i.h:82
#define c
Definition: ke_i.h:80
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define trace
Definition: dwarfcfa.c:22
static int checkreg(State *s, long r)
Definition: dwarfcfa.c:180
#define nil
Definition: compat.h:23
ulong dwarfget128(DwarfBuf *)
Definition: dwarfget.c:153
ulong dwarfget2(DwarfBuf *)
Definition: dwarfget.c:82
@ RuleLocation
Definition: dwarf.h:363
@ RuleRegOff
Definition: dwarf.h:362
@ RuleRegister
Definition: dwarf.h:361
@ RuleSame
Definition: dwarf.h:359
@ RuleCfaOffset
Definition: dwarf.h:360
@ RuleUndef
Definition: dwarf.h:358
ulong dwarfget1(DwarfBuf *)
Definition: dwarfget.c:18
long dwarfget128s(DwarfBuf *)
Definition: dwarfget.c:198
ulong dwarfgetaddr(DwarfBuf *)
Definition: dwarfget.c:124
uchar * dwarfgetnref(DwarfBuf *, ulong)
Definition: dwarfget.c:41
ulong dwarfget4(DwarfBuf *)
Definition: dwarfget.c:96
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264

Referenced by dwarfunwind().

◆ dwarfunwind()

int dwarfunwind ( Dwarf d,
ulong  pc,
DwarfExpr cfa,
DwarfExpr ra,
DwarfExpr r,
int  nr 
)

Definition at line 48 of file dwarfcfa.c.

49{
50 int i, ret;
51 DwarfBuf fde, b;
52 DwarfExpr *initr;
53 State s;
54
55 initr = mallocz(nr*sizeof(initr[0]), 1);
56 if(initr == 0)
57 return -1;
58
59 memset(&s, 0, sizeof s);
60 s.loc = 0;
61 s.cfa = cfa;
62 s.ra = ra;
63 s.r = r;
64 s.nr = nr;
65
66 if(findfde(d, pc, &s, &fde) < 0){
67 free(initr);
68 return -1;
69 }
70
71 memset(r, 0, nr*sizeof(r[0]));
72 for(i=0; i<nr; i++)
73 r[i].type = RuleSame;
74 if(trace) werrstr("s.init %p-%p, fde %p-%p\n", s.init.p, s.init.ep, fde.p, fde.ep);
75 b = s.init;
76 if(dexec(&b, &s, 0) < 0)
77 goto err;
78
79 s.initr = initr;
80 memmove(initr, r, nr*sizeof(initr[0]));
81
82 if(trace) werrstr("s.loc 0x%lux pc 0x%lux\n", s.loc, pc);
83 while(s.loc < pc){
84 if(trace) werrstr("s.loc 0x%lux pc 0x%lux\n", s.loc, pc);
85 if(dexec(&fde, &s, 1) < 0)
86 goto err;
87 }
88 *ra = s.r[s.rareg];
89
90 ret = 0;
91 goto out;
92
93err:
94 ret = -1;
95out:
96 free(initr);
97 for(i=0; i<s.nstack; i++)
98 free(s.stack[i]);
99 free(s.stack);
100 return ret;
101}
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define d
Definition: ke_i.h:81
#define b
Definition: ke_i.h:79
ULONG nr
Definition: thread.c:7
#define err(...)
static FILE * out
Definition: regtests2xml.c:44
static int findfde(Dwarf *, ulong, State *, DwarfBuf *)
Definition: dwarfcfa.c:110
static int dexec(DwarfBuf *, State *, int)
Definition: dwarfcfa.c:190
#define mallocz(x, y)
Definition: compat.h:36
#define memset(x, y, z)
Definition: compat.h:39
uchar * p
Definition: dwarf.h:210
uchar * ep
Definition: dwarf.h:211
int ret

Referenced by dwarfregunwind().

◆ findfde()

static int findfde ( Dwarf d,
ulong  pc,
State s,
DwarfBuf fde 
)
static

Definition at line 110 of file dwarfcfa.c.

111{
112 static int nbad;
113 char *aug;
114 uchar *next;
115 int i, vers;
116 ulong len, id, base, size;
117 DwarfBuf b;
118
119 if(d->frame.data == nil){
120 werrstr("no frame debugging information");
121 return -1;
122 }
123 b.d = d;
124 b.p = d->frame.data;
125 b.ep = b.p + d->frame.len;
126 b.addrsize = d->addrsize;
127 if(b.addrsize == 0)
128 b.addrsize = 4; /* where should i find this? */
129
130 for(; b.p < b.ep; b.p = next){
131 if((i = (b.p - d->frame.data) % b.addrsize))
132 b.p += b.addrsize - i;
133 len = dwarfget4(&b);
134 if(len > b.ep-b.p){
135 werrstr("bad length in cie/fde header");
136 return -1;
137 }
138 next = b.p+len;
139 id = dwarfget4(&b);
140 if(id == 0xFFFFFFFF){ /* CIE */
141 vers = dwarfget1(&b);
142 if(vers != 1 && vers != 2 && vers != 3){
143 if(++nbad == 1)
144 werrstr("unknown cie version %d (wanted 1-3)\n", vers);
145 continue;
146 }
147 aug = dwarfgetstring(&b);
148 if(aug && *aug){
149 if(++nbad == 1)
150 werrstr("unknown augmentation: %s\n", aug);
151 continue;
152 }
153 s->iquantum = dwarfget128(&b);
154 s->dquantum = dwarfget128s(&b);
155 s->rareg = dwarfget128(&b);
156 if(s->rareg > s->nr){
157 werrstr("return address is register %d but only have %d registers",
158 s->rareg, s->nr);
159 return -1;
160 }
161 s->init.p = b.p;
162 s->init.ep = next;
163 }else{ /* FDE */
164 base = dwarfgetaddr(&b);
165 size = dwarfgetaddr(&b);
166 fde->p = b.p;
167 fde->ep = next;
168 s->loc = base;
169 s->endloc = base+size;
170 if(base <= pc && pc < base+size)
171 return 0;
172 }
173 }
174 werrstr("cannot find call frame information for pc 0x%lux", pc);
175 return -1;
176
177}
unsigned char uchar
Definition: Unfrag.h:59
unsigned long ulong
Definition: linux.h:275
GLsizeiptr size
Definition: glext.h:5919
GLenum GLsizei len
Definition: glext.h:6722
GLuint id
Definition: glext.h:5910
static unsigned __int64 next
Definition: rand_nt.c:6
char * dwarfgetstring(DwarfBuf *)
Definition: dwarfget.c:55

Referenced by dwarfunwind().