ReactOS 0.4.15-dev-7942-gd23573b
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 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 16 of file dwarfcfa.c.

◆ trace

#define trace   0

Definition at line 21 of file dwarfcfa.c.

Typedef Documentation

◆ State

typedef struct State State

Definition at line 23 of file dwarfcfa.c.

Function Documentation

◆ checkreg()

static int checkreg ( State s,
long  r 
)
static

Definition at line 179 of file dwarfcfa.c.

180{
181 if(r < 0 || r >= s->nr){
182 werrstr("bad register number 0x%lux", r);
183 return -1;
184 }
185 return 0;
186}
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 189 of file dwarfcfa.c.

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

48{
49 int i, ret;
50 DwarfBuf fde, b;
51 DwarfExpr *initr;
52 State s;
53
54 initr = mallocz(nr*sizeof(initr[0]), 1);
55 if(initr == 0)
56 return -1;
57
58 memset(&s, 0, sizeof s);
59 s.loc = 0;
60 s.cfa = cfa;
61 s.ra = ra;
62 s.r = r;
63 s.nr = nr;
64
65 if(findfde(d, pc, &s, &fde) < 0){
66 free(initr);
67 return -1;
68 }
69
70 memset(r, 0, nr*sizeof(r[0]));
71 for(i=0; i<nr; i++)
72 r[i].type = RuleSame;
73 if(trace) werrstr("s.init %p-%p, fde %p-%p\n", s.init.p, s.init.ep, fde.p, fde.ep);
74 b = s.init;
75 if(dexec(&b, &s, 0) < 0)
76 goto err;
77
78 s.initr = initr;
79 memmove(initr, r, nr*sizeof(initr[0]));
80
81 if(trace) werrstr("s.loc 0x%lux pc 0x%lux\n", s.loc, pc);
82 while(s.loc < pc){
83 if(trace) werrstr("s.loc 0x%lux pc 0x%lux\n", s.loc, pc);
84 if(dexec(&fde, &s, 1) < 0)
85 goto err;
86 }
87 *ra = s.r[s.rareg];
88
89 ret = 0;
90 goto out;
91
92err:
93 ret = -1;
94out:
95 free(initr);
96 for(i=0; i<s.nstack; i++)
97 free(s.stack[i]);
98 free(s.stack);
99 return ret;
100}
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: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 dwarfregunwind().

◆ findfde()

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

Definition at line 109 of file dwarfcfa.c.

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

Referenced by dwarfunwind().