ReactOS 0.4.16-dev-136-g52192f1
dwarfcfa.c File Reference
#include <precomp.h>
#include <debug.h>
Include dependency graph for dwarfcfa.c:

Go to the source code of this file.

Classes

struct  State
 

Macros

#define NDEBUG
 
#define trace   1
 

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)
 
int dwarfcomputecfa (Dwarf *d, DwarfExpr *cfa, PROSSYM_REGISTERS registers, ulong *cfaLocation)
 
int dwarfregunwind (Dwarf *d, ulong pc, ulong fde, DwarfExpr *cfa, PROSSYM_REGISTERS registers)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file dwarfcfa.c.

◆ trace

#define trace   1

Definition at line 16 of file dwarfcfa.c.

Typedef Documentation

◆ State

typedef struct State State

Definition at line 18 of file dwarfcfa.c.

Function Documentation

◆ checkreg()

static int checkreg ( State s,
long  r 
)
static

Definition at line 176 of file dwarfcfa.c.

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

◆ dexec()

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

Definition at line 186 of file dwarfcfa.c.

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

◆ dwarfcomputecfa()

int dwarfcomputecfa ( Dwarf d,
DwarfExpr cfa,
PROSSYM_REGISTERS  registers,
ulong cfaLocation 
)

Definition at line 404 of file dwarfcfa.c.

405{
406 switch (cfa->type) {
407 case RuleRegOff:
408 *cfaLocation = registers->Registers[cfa->reg] + cfa->offset;
409 werrstr("cfa reg %d (%x) offset %x = %x", cfa->reg, (ulong)registers->Registers[cfa->reg], cfa->offset, cfaLocation);
410 break;
411 default:
412 werrstr("cfa->type %x", cfa->type);
413 return -1;
414 }
415
416 return 0;
417}
unsigned long ulong
Definition: linux.h:275
int registers[NUMREGS]
int type
Definition: dwarf.h:367
ulong reg
Definition: dwarf.h:369
long offset
Definition: dwarf.h:368

Referenced by dwarfregunwind(), and RosSymGetAddressInformation().

◆ dwarfregunwind()

int dwarfregunwind ( Dwarf d,
ulong  pc,
ulong  fde,
DwarfExpr cfa,
PROSSYM_REGISTERS  registers 
)

Definition at line 419 of file dwarfcfa.c.

420{
421 int i;
422 State s = { };
423 DwarfExpr initr[sizeof(registers->Registers) / sizeof(registers->Registers[0])] = { };
424 DwarfExpr r[sizeof(registers->Registers) / sizeof(registers->Registers[0])] = { };
425 DwarfExpr ra;
426
427 int nr = s.nr = sizeof(registers->Registers) / sizeof(registers->Registers[0]);
428 s.initr = initr;
429 s.r = r;
430 for (i = 0; i < sizeof(r) / sizeof(r[0]); i++) {
431 r[i].type = RuleRegister;
432 r[i].offset = registers->Registers[i];
433 r[i].reg = i;
434 }
435
436 int res = dwarfunwind(d, pc, cfa, &ra, initr, sizeof(initr) / sizeof(initr[0]));
437 if (res == -1) return -1;
438
439 ulong cfaLocation;
440
441 if (dwarfcomputecfa(d, cfa, registers, &cfaLocation) == -1)
442 return -1;
443
444 for (i = 0; i < nr; i++) {
445 switch (r[i].type) {
446 case RuleUndef:
447 werrstr("Undefined register slot %d", i);
448 assert(FALSE);
449 break;
450 case RuleSame:
451 break;
452 case RuleRegister:
453 registers->Registers[i] = registers->Registers[r[i].reg];
454 break;
455 case RuleRegOff: {
458 (d->pe->fd,
459 &registers->Registers[i],
460 r[i].offset + registers->Registers[r[i].reg],
461 d->addrsize);
462 if (!success) return -1;
463 } break;
464 case RuleCfaOffset:
465 {
468 (d->pe->fd,
469 &registers->Registers[i],
470 r[i].offset + cfaLocation,
471 d->addrsize);
472 werrstr("reg[%d] = %x: cfa offset (cfa %x, offset %x) -> @%x", i, (ulong)registers->Registers[i], cfaLocation, initr[i].offset, r[i].offset + cfaLocation);
473 if (!success) return -1;
474 } break;
475 default:
476 werrstr("We don't yet support cfa rule %d in slot %d", r[i].type, i);
477 assert(FALSE);
478 break;
479 }
480 }
481
482 ulong cfaSpace[4];
483 for (i = 0; i < sizeof(cfaSpace) / sizeof(cfaSpace[0]); i++) {
485 (d->pe->fd, &cfaSpace[i], cfaLocation + (i * 4), d->addrsize);
486 }
487 werrstr("CFA(%x) [%08x, %08x, %08x, %08x]",
488 cfaLocation, cfaSpace[0], cfaSpace[1], cfaSpace[2], cfaSpace[3]);
489
490 return 0;
491}
unsigned char BOOLEAN
#define FALSE
Definition: types.h:117
#define assert(x)
Definition: debug.h:53
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint res
Definition: glext.h:9613
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
ULONG nr
Definition: thread.c:7
int dwarfcomputecfa(Dwarf *d, DwarfExpr *cfa, PROSSYM_REGISTERS registers, ulong *cfaLocation)
Definition: dwarfcfa.c:404
int dwarfunwind(Dwarf *d, ulong pc, DwarfExpr *cfa, DwarfExpr *ra, DwarfExpr *r, int nr)
Definition: dwarfcfa.c:42
ROSSYM_CALLBACKS RosSymCallbacks
Definition: init.c:14
BOOLEAN(* MemGetProc)(PVOID FileContext, ULONG_PTR *Target, PVOID SourceMem, ULONG Size)
Definition: rossym.h:110
#define success(from, fromstr, to, tostr)

Referenced by RosSymGetAddressInformation().

◆ dwarfunwind()

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

Definition at line 42 of file dwarfcfa.c.

43{
44 int i, ret;
45 DwarfBuf fde, b;
46 DwarfExpr *initr;
47 State s;
48
49 initr = mallocz(nr*sizeof(initr[0]), 1);
50 if(initr == 0)
51 return -1;
52
53 memset(&s, 0, sizeof s);
54 s.loc = 0;
55 s.cfa = cfa;
56 s.ra = ra;
57 s.r = r;
58 s.nr = nr;
59
60 if(findfde(d, pc, &s, &fde) < 0){
61 free(initr);
62 return -1;
63 }
64
65 memset(r, 0, nr*sizeof(r[0]));
66 for(i=0; i<nr; i++)
67 r[i].type = RuleSame;
68 if(trace) werrstr("s.init %p-%p, fde %p-%p", s.init.p, s.init.ep, fde.p, fde.ep);
69 b = s.init;
70 if(dexec(&b, &s, 0) < 0)
71 goto err;
72
73 s.initr = initr;
74 memmove(initr, r, nr*sizeof(initr[0]));
75
76 if(trace) werrstr("s.loc 0x%lx pc 0x%lx", s.loc, pc);
77 while(s.loc < pc){
78 if(trace) werrstr("s.loc 0x%lx pc 0x%lx", s.loc, pc);
79 if(dexec(&fde, &s, 1) < 0)
80 goto err;
81 }
82 *ra = s.r[s.rareg];
83
84 ret = 0;
85 goto out;
86
87err:
88 ret = -1;
89out:
90 free(initr);
91 for(i=0; i<s.nstack; i++)
92 free(s.stack[i]);
93 free(s.stack);
94 return ret;
95}
#define b
Definition: ke_i.h:79
#define err(...)
static FILE * out
Definition: regtests2xml.c:44
static int findfde(Dwarf *, ulong, State *, DwarfBuf *)
Definition: dwarfcfa.c:109
static int dexec(DwarfBuf *, State *, int)
Definition: dwarfcfa.c:189
#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 printrules().

◆ findfde()

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

Definition at line 104 of file dwarfcfa.c.

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