ReactOS  0.4.14-dev-297-g23e575c
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 }
#define werrstr(str,...)
Definition: compat.h:34
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble s
Definition: gl.h:2039

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);
387  arg2 = dwarfget128s(b);
388  goto offset;
389 
390  case 0x12: /* cfa sf */
391  arg1 = dwarfget128(b);
392  arg2 = dwarfget128s(b);
393  goto defcfa;
394 
395  case 0x13: /* cfa offset sf */
396  arg1 = dwarfget128s(b);
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 }
#define werrstr(str,...)
Definition: compat.h:34
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define free
Definition: debug_ros.c:5
GLintptr offset
Definition: glext.h:5920
ulong dwarfget4(DwarfBuf *)
Definition: dwarfget.c:96
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glext.h:9514
static int checkreg(State *s, long r)
Definition: dwarfcfa.c:180
ulong dwarfget1(DwarfBuf *)
Definition: dwarfget.c:18
#define e
Definition: ke_i.h:82
GLuint GLuint GLuint GLuint arg1
Definition: glext.h:9513
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
const GLubyte * c
Definition: glext.h:8905
long dwarfget128s(DwarfBuf *)
Definition: dwarfget.c:198
ulong dwarfget2(DwarfBuf *)
Definition: dwarfget.c:82
GLdouble s
Definition: gl.h:2039
_STLP_MOVE_TO_STD_NAMESPACE void _STLP_CALL advance(_InputIterator &__i, _Distance __n)
ulong dwarfget128(DwarfBuf *)
Definition: dwarfget.c:153
#define trace
Definition: dwarfcfa.c:22
#define nil
Definition: compat.h:23
uchar * dwarfgetnref(DwarfBuf *, ulong)
Definition: dwarfget.c:41
#define c
Definition: ke_i.h:80
#define malloc
Definition: debug_ros.c:4
ulong dwarfgetaddr(DwarfBuf *)
Definition: dwarfget.c:124

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 
93 err:
94  ret = -1;
95 out:
96  free(initr);
97  for(i=0; i<s.nstack; i++)
98  free(s.stack[i]);
99  free(s.stack);
100  return ret;
101 }
#define werrstr(str,...)
Definition: compat.h:34
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
ULONG nr
Definition: thread.c:7
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define free
Definition: debug_ros.c:5
#define mallocz(x, y)
Definition: compat.h:36
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
static int dexec(DwarfBuf *, State *, int)
Definition: dwarfcfa.c:190
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 b
Definition: ke_i.h:79
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define d
Definition: ke_i.h:81
static FILE * out
Definition: regtests2xml.c:44
uchar * p
Definition: dwarf.h:210
int ret
static int findfde(Dwarf *, ulong, State *, DwarfBuf *)
Definition: dwarfcfa.c:110
GLdouble s
Definition: gl.h:2039
#define err(...)
#define trace
Definition: dwarfcfa.c:22
uchar * ep
Definition: dwarf.h:211
#define memset(x, y, z)
Definition: compat.h:39

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 }
#define werrstr(str,...)
Definition: compat.h:34
unsigned char uchar
Definition: Unfrag.h:59
char * dwarfgetstring(DwarfBuf *)
Definition: dwarfget.c:55
ulong dwarfget4(DwarfBuf *)
Definition: dwarfget.c:96
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
ulong dwarfget1(DwarfBuf *)
Definition: dwarfget.c:18
GLuint base
Definition: 3dtext.c:35
#define b
Definition: ke_i.h:79
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLsizeiptr size
Definition: glext.h:5919
#define d
Definition: ke_i.h:81
uchar * p
Definition: dwarf.h:210
long dwarfget128s(DwarfBuf *)
Definition: dwarfget.c:198
GLenum GLsizei len
Definition: glext.h:6722
GLdouble s
Definition: gl.h:2039
unsigned long ulong
Definition: linux.h:275
static unsigned __int64 next
Definition: rand_nt.c:6
ulong dwarfget128(DwarfBuf *)
Definition: dwarfget.c:153
#define nil
Definition: compat.h:23
uchar * ep
Definition: dwarf.h:211
GLenum GLuint id
Definition: glext.h:5579
ulong dwarfgetaddr(DwarfBuf *)
Definition: dwarfget.c:124

Referenced by dwarfunwind().