ReactOS  0.4.10-dev-479-g13a3cf0
dwarfinfo.c
Go to the documentation of this file.
1 /*
2  * Dwarf info parse and search.
3  */
4 
5 #include <precomp.h>
6 #define NDEBUG
7 #include <debug.h>
8 
9 enum
10 {
13  DwarfAttrName = 0x03,
65  DwarfAttrType = 0x49,
84 
85  FormAddr = 0x01,
88  FormData2 = 0x05,
89  FormData4 = 0x06,
90  FormData8 = 0x07,
91  FormString = 0x08,
94  FormData1 = 0x0B,
95  FormFlag = 0x0C,
96  FormSdata = 0x0D,
97  FormStrp = 0x0E,
98  FormUdata = 0x0F,
99  FormRefAddr = 0x10,
100  FormRef1 = 0x11,
101  FormRef2 = 0x12,
102  FormRef4 = 0x13,
103  FormRef8 = 0x14,
104  FormRefUdata = 0x15,
106 };
107 
109 static int getulong(DwarfBuf*, int, ulong, ulong*, int*);
110 static int getuchar(DwarfBuf*, int, uchar*);
111 static int getstring(Dwarf *d, DwarfBuf*, int, char**);
112 static int getblock(DwarfBuf*, int, DwarfBlock*);
113 static int skipform(Dwarf *d, DwarfBuf*, int);
114 
115 int
117 {
118  DwarfSym compunit = { };
119  if(dwarfenumunit(d, unit, &compunit) < 0)
120  return -1;
121  while(dwarfnextsymat(d, &compunit, s) == 0) {
122  werrstr("got %s looking for %s\n", s->attrs.name, name);
123  if(s->attrs.name && strcmp(s->attrs.name, name) == 0)
124  return 0;
125  }
126  werrstr("symbol '%s' not found", name);
127  return -1;
128 }
129 
130 int
132 {
133  *s = *parent;
134  while(dwarfnextsymat(d, parent, s))
135  if(s->attrs.name && strcmp(s->attrs.name, name) == 0)
136  return 0;
137  werrstr("symbol '%s' not found", name);
138  return -1;
139 }
140 
141 int
143 {
144  int rsym = dwarfnextsymat(d, parent, s);
145  while (rsym == 0 && s->attrs.tag != tag) {
146  if (s->attrs.haskids) {
147  DwarfSym p = *s;
148  int csym = dwarflookupchildtag(d, &p, tag, s);
149  if (csym == 0) {
150  return csym;
151  }
152  }
153  rsym = dwarfnextsym(d, s);
154  }
155  return rsym;
156 }
157 
158 int
160 {
161  DwarfSym compunit = { };
162  if (dwarfenumunit(d, unit, &compunit) < 0) {
163  return -1;
164  }
165  do {
166  if (compunit.attrs.tag == tag) {
167  *s = compunit;
168  return 0;
169  }
170  if (dwarflookupchildtag(d, &compunit, tag, s) == 0)
171  return 0;
172  } while(dwarfnextsym(d, &compunit) == 0);
173  werrstr("symbol with tag 0x%lux not found", tag);
174  return -1;
175 }
176 
177 int
179 {
180  DwarfSym compunit = { };
181  if(dwarfenumunit(d, unit, &compunit) < 0)
182  return -1;
183  werrstr("dwarfseeksym: unit %x off %x\n", unit, off);
184  s->b.d = d;
185  s->b.p = d->info.data + unit + off;
186  s->b.ep = compunit.b.ep;
187  if(dwarfnextsymat(d, &compunit, s) == -1)
188  return -1;
189  werrstr("dwarfseeksym: unit %x off %x, tag %x", unit, off, s->attrs.tag);
190  return 0;
191 }
192 
193 int
195 {
196  DwarfSym compunit = { };
197  if(dwarfenumunit(d, unit, &compunit) < 0)
198  return -1;
199  while(dwarfnextsymat(d, &compunit, s) == 0){
200  if(s->attrs.tag != TagSubprogram)
201  continue;
202  if(s->attrs.lowpc <= pc && pc < s->attrs.highpc)
203  return 0;
204  }
205  werrstr("fn containing pc 0x%lux not found", pc);
206  return -1;
207 }
208 
209 int
211 {
212  int i;
213  ulong aoff, len;
214 
215  if(unit >= d->info.len){
216  werrstr("dwarf unit address 0x%x >= 0x%x out of range", unit, d->info.len);
217  return -1;
218  }
219  memset(s, 0, sizeof *s);
220  memset(&s->b, 0, sizeof s->b);
221 
222  s->b.d = d;
223  s->b.p = d->info.data + unit;
224  s->b.ep = d->info.data + d->info.len;
225  len = dwarfget4(&s->b);
226  s->unit = unit;
227  s->nextunit = unit + 4 + len;
228  s->b.ep = d->info.data + s->nextunit;
229 
230  if(s->b.ep - s->b.p < len){
231  badheader:
232  werrstr("bad dwarf unit header at unit 0x%lux end %x start %x len %x", unit, s->b.ep - d->info.data, s->b.p - d->info.data, len);
233  return -1;
234  }
235  s->b.ep = s->b.p+len;
236  if((i=dwarfget2(&s->b)) > 4)
237  goto badheader;
238  aoff = dwarfget4(&s->b);
239  s->b.addrsize = dwarfget1(&s->b);
240  if(d->addrsize == 0)
241  d->addrsize = s->b.addrsize;
242  if(s->b.p == nil)
243  goto badheader;
244 
245  s->aoff = aoff;
246 
247  return dwarfnextsym(d, s);
248 }
249 
250 int
252 {
253  ulong num;
254  DwarfAbbrev *a;
255 
256  werrstr("sym at %x (left %x)\n", s->b.p - d->info.data, s->b.ep - s->b.p);
257 
258  num = dwarfget128(&s->b);
259  werrstr("abbrev num %x\n", num);
260  s->num = num;
261  if(num == 0){
262  return -1;
263  }
264 
265  a = dwarfgetabbrev(d, s->aoff, num);
266  werrstr("a %p\n", a);
267  if(a == nil){
268  werrstr("getabbrev %x %x for %x", s->aoff, num, s->unit);
269  return -1;
270  }
271 
272  if(parseattrs(d, &s->b, s->attrs.tag, s->unit, a, &s->attrs) < 0) {
273  return -1;
274  }
275 
276  if (s->attrs.haskids) {
277  DwarfSym childSkip = { };
278  s->childoff = s->b.p - d->info.data;
279  werrstr("Set childoff at %x\n", s->childoff);
280  int r = dwarfnextsymat(d, s, &childSkip);
281  while (r == 0) {
282  r = dwarfnextsym(d, &childSkip);
283  }
284  s->b = childSkip.b;
285  } else {
286  s->childoff = 0;
287  }
288  return 0;
289 }
290 
291 int
293 {
294  uint sib;
295 
296  if (!parent->attrs.haskids || !parent->childoff)
297  return -1;
298 
299  child->unit = parent->unit;
300  child->aoff = parent->aoff;
301  child->depth = parent->depth + 1;
302  if(child->attrs.have.sibling){
303  sib = child->attrs.sibling;
304  if(sib < d->info.len && d->info.data+sib > child->b.p)
305  child->b.p = d->info.data+sib;
306  else if (sib >= d->info.len) {
307  werrstr("sibling reported as out of bounds %d vs %d", sib, d->info.len);
308  return -1;
309  } else if (d->info.data+sib+parent->unit < child->b.p) {
310  werrstr("subsequent sibling is listed before prev %d vs %d", sib+parent->unit, child->b.p - d->info.data);
311  return -1;
312  }
313  }
314 
315  // Uninitialized
316  if (!child->b.d) {
317  child->b = parent->b;
318  child->b.p = parent->childoff + parent->b.d->info.data;
319  werrstr("Rewound to childoff %x\n", parent->childoff);
320  }
321 
322  return dwarfnextsym(d, child);
323 }
324 
325 typedef struct Parse Parse;
326 struct Parse {
327  const char *namestr;
328  int name;
329  int off;
330  int haveoff;
331  int type;
332 };
333 
334 #define ATTR(x) (#x)+9, x
335 #define OFFSET(x) offsetof(DwarfAttrs, x), offsetof(DwarfAttrs, have.x)
336 
337 static Parse plist[] = { /* Font Tab 4 */
338  { ATTR(DwarfAttrAbstractOrigin), OFFSET(abstractorigin), TReference },
339  { ATTR(DwarfAttrAccessibility), OFFSET(accessibility), TConstant },
340  { ATTR(DwarfAttrAddrClass), OFFSET(addrclass), TConstant },
341  { ATTR(DwarfAttrBaseTypes), OFFSET(basetypes), TReference },
342  { ATTR(DwarfAttrBitOffset), OFFSET(bitoffset), TConstant },
343  { ATTR(DwarfAttrBitSize), OFFSET(bitsize), TConstant },
345  { ATTR(DwarfAttrCalling), OFFSET(calling), TConstant },
346  { ATTR(DwarfAttrCommonRef), OFFSET(commonref), TReference },
347  { ATTR(DwarfAttrCompDir), OFFSET(compdir), TString },
349  { ATTR(DwarfAttrContainingType), OFFSET(containingtype), TReference },
352  { ATTR(DwarfAttrDeclColumn), OFFSET(declcolumn), TConstant },
353  { ATTR(DwarfAttrDeclFile), OFFSET(declfile), TConstant },
354  { ATTR(DwarfAttrDeclLine), OFFSET(declline), TConstant },
355  { ATTR(DwarfAttrDefaultValue), OFFSET(defaultvalue), TReference },
356  { ATTR(DwarfAttrDiscr), OFFSET(discr), TReference },
357  { ATTR(DwarfAttrDiscrList), OFFSET(discrlist), TBlock },
358  { ATTR(DwarfAttrDiscrValue), OFFSET(discrvalue), TConstant },
360  { ATTR(DwarfAttrFrameBase), OFFSET(framebase), TBlock|TConstant },
361  { ATTR(DwarfAttrFriend), OFFSET(friend), TReference },
362  { ATTR(DwarfAttrHighpc), OFFSET(highpc), TAddress },
363  { ATTR(DwarfAttrEntrypc), OFFSET(entrypc), TAddress },
364  { ATTR(DwarfAttrIdentifierCase), OFFSET(identifiercase), TConstant },
365  { ATTR(DwarfAttrImport), OFFSET(import), TReference },
366  { ATTR(DwarfAttrInline), OFFSET(inlined), TConstant },
367  { ATTR(DwarfAttrArtificial), OFFSET(isartificial), TFlag },
368  { ATTR(DwarfAttrDeclaration), OFFSET(isdeclaration), TFlag },
369  { ATTR(DwarfAttrExternal), OFFSET(isexternal), TFlag },
370  { ATTR(DwarfAttrIsOptional), OFFSET(isoptional), TFlag },
371  { ATTR(DwarfAttrPrototyped), OFFSET(isprototyped), TFlag },
372  { ATTR(DwarfAttrVarParam), OFFSET(isvarparam), TFlag },
373  { ATTR(DwarfAttrLanguage), OFFSET(language), TConstant },
376  { ATTR(DwarfAttrLowpc), OFFSET(lowpc), TAddress },
377  { ATTR(DwarfAttrMacroInfo), OFFSET(macroinfo), TConstant },
379  { ATTR(DwarfAttrNamelistItem), OFFSET(namelistitem), TBlock },
382  { ATTR(DwarfAttrProducer), OFFSET(producer), TString },
383  { ATTR(DwarfAttrRanges), OFFSET(ranges), TReference },
384  { ATTR(DwarfAttrReturnAddr), OFFSET(returnaddr), TBlock|TConstant },
386  { ATTR(DwarfAttrSibling), OFFSET(sibling), TReference },
387  { ATTR(DwarfAttrSpecification), OFFSET(specification), TReference },
388  { ATTR(DwarfAttrStartScope), OFFSET(startscope), TConstant },
389  { ATTR(DwarfAttrStaticLink), OFFSET(staticlink), TBlock|TConstant },
390  { ATTR(DwarfAttrStmtList), OFFSET(stmtlist), TConstant },
391  { ATTR(DwarfAttrStrideSize), OFFSET(stridesize), TConstant },
392  { ATTR(DwarfAttrStringLength), OFFSET(stringlength), TBlock|TConstant },
395  { ATTR(DwarfAttrUseLocation), OFFSET(uselocation), TBlock|TConstant },
396  { ATTR(DwarfAttrVirtuality), OFFSET(virtuality), TConstant },
397  { ATTR(DwarfAttrVisibility), OFFSET(visibility), TConstant },
398  { ATTR(DwarfAttrVtableElemLoc), OFFSET(vtableelemloc), TBlock|TReference },
399  { }
400 };
401 
403 
404 static int
406 {
407  int i, f, n, got;
408  static int nbad;
409  void *v;
410 
411  /* initialize ptab first time through for quick access */
412  if(ptab[DwarfAttrName].name != DwarfAttrName)
413  for(i=0; plist[i].name; i++)
414  ptab[plist[i].name] = plist[i];
415 
416  memset(attrs, 0, sizeof *attrs);
417  attrs->tag = a->tag;
418  attrs->haskids = a->haskids;
419 
420  for(i=0; i<a->nattr; i++){
421  n = a->attr[i].name;
422  f = a->attr[i].form;
423  werrstr("struct: (@%x) n %x f %x (%d %d)\n", b->p - d->info.data, n, f, ptab[n].haveoff, ptab[n].off);
424  if(n < 0 || n >= DwarfAttrMax || ptab[n].name==0) {
425  if (skipform(d, b, f) < 0) {
426  if(++nbad == 1)
427  werrstr("dwarf parse attrs: cannot skip form %d", f);
428  return -1;
429  }
430  continue;
431  }
432  v = (char*)attrs + ptab[n].off;
433  got = 0;
434  if(f == FormIndirect)
435  f = dwarfget128(b);
436  if((ptab[n].type&(TConstant|TReference|TAddress))
437  && getulong(b, f, unit, v, &got) >= 0)
438  ;
439  else if((ptab[n].type&TFlag) && getuchar(b, f, v) >= 0)
440  got = TFlag;
441  else if((ptab[n].type&TString) && getstring(d, b, f, v) >= 0)
442  got = TString;
443  else if((ptab[n].type&TBlock) && getblock(b, f, v) >= 0) {
444  got = TBlock;
445  } else {
446  werrstr("Skipping form %x\n", f);
447  if(skipform(d, b, f) < 0){
448  //if(++nbad == 1)
449  werrstr("dwarf parse attrs: cannot skip form %d", f);
450  return -1;
451  }
452  }
453 #if 0
454  if(got == TBlock && (ptab[n].type&TConstant))
455  got = constblock(b->d, v, v);
456 #endif
457  *((uchar*)attrs+ptab[n].haveoff) = got;
458  }
459 
460  if (attrs->have.name)
461  werrstr("%s: tag %x kids %d (last %x)\n", attrs->name, attrs->tag, attrs->haskids, b->p - b->d->info.data);
462 
463  return 0;
464 }
465 
466 static int
468 {
469  static int nbad;
470  uvlong uv;
471 
472  switch(form){
473  default:
474  return -1;
475 
476  /* addresses */
477  case FormAddr:
478  *type = TAddress;
479  *u = dwarfgetaddr(b);
480  return 0;
481 
482  /* references */
483  case FormRefAddr:
484  /* absolute ref in .debug_info */
485  *type = TReference;
486  *u = dwarfgetaddr(b);
487  return 0;
488  case FormRef1:
489  *u = dwarfget1(b);
490  goto relativeref;
491  case FormRef2:
492  *u = dwarfget2(b);
493  goto relativeref;
494  case FormRef4:
495  *u = dwarfget4(b);
496  goto relativeref;
497  case FormRef8:
498  *u = dwarfget8(b);
499  goto relativeref;
500  case FormRefUdata:
501  *u = dwarfget128(b);
502  relativeref:
503  *u += unit;
504  *type = TReference;
505  return 0;
506 
507  /* constants */
508  case FormData1:
509  *u = dwarfget1(b);
510  goto constant;
511  case FormData2:
512  *u = dwarfget2(b);
513  goto constant;
514  case FormData4:
515  *u = dwarfget4(b);
516  goto constant;
517  case FormData8:
518  uv = dwarfget8(b);
519  *u = uv;
520  if(uv != *u && ++nbad == 1)
521  werrstr("dwarf: truncating 64-bit attribute constants");
522  goto constant;
523  case FormSdata:
524  *u = dwarfget128s(b);
525  goto constant;
526  case FormUdata:
527  *u = dwarfget128(b);
528  constant:
529  *type = TConstant;
530  return 0;
531  }
532 }
533 
534 static int
536 {
537  switch(form){
538  default:
539  return -1;
540 
541  case FormFlag:
542  *u = dwarfget1(b);
543  return 0;
544  }
545 }
546 
547 static int
548 getstring(Dwarf *d, DwarfBuf *b, int form, char **s)
549 {
550  static int nbad;
551  ulong u, x;
552 
553  switch(form){
554  default:
555  return -1;
556 
557  case FormString:
558  x = b->p - d->info.data;
559  *s = dwarfgetstring(b);
560  for (u = 0; (*s)[u]; u++) {
561  assert(isprint((*s)[u]));
562  }
563  return 0;
564 
565  case FormStrp:
566  u = dwarfget4(b);
567  if(u >= b->d->str.len){
568  if(++nbad == 1)
569  werrstr("dwarf: bad string pointer 0x%lux in attribute", u);
570  /* don't return error - maybe can proceed */
571  *s = nil;
572  }else
573  *s = (char*)b->d->str.data + u;
574  return 0;
575 
576  }
577 }
578 
579 static int
581 {
582  ulong n;
583 
584  switch(form){
585  default:
586  return -1;
587  case FormDwarfBlock:
588  n = dwarfget128(b);
589  goto copyn;
590  case FormDwarfBlock1:
591  n = dwarfget1(b);
592  goto copyn;
593  case FormDwarfBlock2:
594  n = dwarfget2(b);
595  goto copyn;
596  case FormDwarfBlock4:
597  n = dwarfget4(b);
598  copyn:
599  bl->data = dwarfgetnref(b, n);
600  bl->len = n;
601  if(bl->data == nil)
602  return -1;
603  return 0;
604  }
605 }
606 
607 /* last resort */
608 static int
610 {
611  int type;
612  DwarfVal val;
613 
614  if(getulong(b, form, 0, &val.c, &type) < 0
615  && getuchar(b, form, (uchar*)&val) < 0
616  && getstring(d, b, form, &val.s) < 0
617  && getblock(b, form, &val.b) < 0)
618  return -1;
619  return 0;
620 }
621 
623 {
624  memset(stack, 0, sizeof(*stack));
625  stack->data = stack->storage;
626  stack->length = 0; stack->max = sizeof(stack->storage) / sizeof(stack->storage[0]);
627 }
628 
630 {
631  if (stack->length == stack->max) {
632  ulong *newstack = malloc(sizeof(ulong)*stack->max*2);
633  memcpy(newstack, stack->data, sizeof(ulong)*stack->length);
634  if (stack->data != stack->storage)
635  free(stack->data);
636  stack->data = newstack;
637  stack->max *= 2;
638  }
639  werrstr("stack[%d] = %x", stack->length, value);
640  stack->data[stack->length++] = value;
641 }
642 
644 {
645  ASSERT(stack->length > 0);
646  ulong val = stack->data[--stack->length];
647  werrstr("pop stack[%d] -> %x", stack->length, val);
648  return val;
649 }
650 
652 {
653  if (stack->data != stack->storage)
654  free(stack->data);
655 }
656 
657 // Returns -1 on failure
659 {
660  int ret = 0;
661  DwarfStack stack = { };
662  stackinit(&stack);
663  stackpush(&stack, cfa);
664  while (buf->p < buf->ep) {
665  int opcode = dwarfget1(buf);
666  werrstr("opcode %x", opcode);
667  switch (opcode) {
668  case 0:
669  buf->p = buf->ep;
670  break;
671  case OpAddr:
672  if (d->addrsize == 4) {
673  stackpush(&stack, dwarfget4(buf));
674  break;
675  } else {
676  werrstr("%s: we only support 4 byte addrs", name);
677  goto fatal;
678  }
679  case OpConst1s: {
680  signed char c = dwarfget1(buf);
681  stackpush(&stack, c);
682  } break;
683  case OpConst1u:
684  stackpush(&stack, dwarfget1(buf));
685  break;
686  case OpConst2s: {
687  signed short s = dwarfget2(buf);
688  stackpush(&stack, s);
689  } break;
690  case OpConst2u:
691  stackpush(&stack, dwarfget2(buf));
692  break;
693  case OpConst4s: {
694  signed int i = dwarfget4(buf);
695  stackpush(&stack, i);
696  } break;
697  case OpConst4u:
698  stackpush(&stack, dwarfget4(buf));
699  break;
700  case OpConst8s:
701  case OpConst8u:
702  werrstr("const 8 not yet supported");
703  goto fatal;
704  case OpConsts:
705  stackpush(&stack, dwarfget128s(buf));
706  break;
707  case OpConstu:
708  stackpush(&stack, dwarfget128(buf));
709  break;
710  case OpDup: {
711  ulong popped = stackpop(&stack);
712  stackpush(&stack, popped);
713  stackpush(&stack, popped);
714  } break;
715  case OpDrop:
716  stackpop(&stack);
717  break;
718  case OpOver: {
719  if (stack.length < 2) goto fatal;
720  stackpush(&stack, stack.data[stack.length-2]);
721  } break;
722  case OpPick: {
723  ulong arg = dwarfget1(buf);
724  if (arg >= stack.length) goto fatal;
725  arg = stack.data[stack.length-1-arg];
726  stackpush(&stack, arg);
727  } break;
728  case OpSwap: {
729  ulong a = stackpop(&stack), b = stackpop(&stack);
730  stackpush(&stack, b);
731  stackpush(&stack, a);
732  } break;
733  case OpRot: {
734  ulong a = stackpop(&stack), b = stackpop(&stack), c = stackpop(&stack);
735  stackpush(&stack, b);
736  stackpush(&stack, c);
737  stackpush(&stack, a);
738  } break;
739  case OpXderef:
740  case OpXderefSize:
741  werrstr("Xderef not yet supported");
742  goto fatal;
743  case OpAbs: {
744  long a = stackpop(&stack);
745  stackpush(&stack, a < 0 ? -a : a);
746  } break;
747  case OpAnd:
748  stackpush(&stack, stackpop(&stack) & stackpop(&stack));
749  break;
750  case OpDiv: {
751  ulong a = stackpop(&stack), b = stackpop(&stack);
752  stackpush(&stack, b / a);
753  } break;
754  case OpMinus: {
755  ulong a = stackpop(&stack), b = stackpop(&stack);
756  stackpush(&stack, b - a);
757  } break;
758  case OpMod: {
759  ulong a = stackpop(&stack), b = stackpop(&stack);
760  stackpush(&stack, b % a);
761  } break;
762  case OpMul:
763  stackpush(&stack, stackpop(&stack) * stackpop(&stack));
764  break;
765  case OpNeg:
766  stackpush(&stack, -stackpop(&stack));
767  break;
768  case OpNot:
769  stackpush(&stack, ~stackpop(&stack));
770  break;
771  case OpOr:
772  stackpush(&stack, stackpop(&stack) | stackpop(&stack));
773  break;
774  case OpPlus:
775  stackpush(&stack, stackpop(&stack) + stackpop(&stack));
776  break;
777  case OpPlusUconst:
778  stackpush(&stack, stackpop(&stack) + dwarfget128(buf));
779  break;
780  case OpShl: {
781  ulong a = stackpop(&stack), b = stackpop(&stack);
782  stackpush(&stack, b << a);
783  } break;
784  case OpShr: {
785  ulong a = stackpop(&stack), b = stackpop(&stack);
786  stackpush(&stack, b >> a);
787  } break;
788  case OpShra: {
789  ulong a = stackpop(&stack);
790  long b = stackpop(&stack);
791  if (b < 0)
792  b = -(-b >> a);
793  else
794  b = b >> a;
795  stackpush(&stack, b);
796  } break;
797  case OpXor:
798  stackpush(&stack, stackpop(&stack) ^ stackpop(&stack));
799  break;
800  case OpSkip:
801  buf->p += dwarfget2(buf);
802  break;
803  case OpBra: {
804  ulong a = dwarfget2(buf);
805  if (stackpop(&stack))
806  buf->p += a;
807  } break;
808  case OpEq:
809  stackpush(&stack, stackpop(&stack) == stackpop(&stack));
810  break;
811  case OpGe: {
812  ulong a = stackpop(&stack), b = stackpop(&stack);
813  stackpush(&stack, b >= a);
814  } break;
815  case OpGt: {
816  ulong a = stackpop(&stack), b = stackpop(&stack);
817  stackpush(&stack, b > a);
818  } break;
819  case OpLe: {
820  ulong a = stackpop(&stack), b = stackpop(&stack);
821  stackpush(&stack, b <= a);
822  } break;
823  case OpLt: {
824  ulong a = stackpop(&stack), b = stackpop(&stack);
825  stackpush(&stack, b < a);
826  } break;
827  case OpNe:
828  stackpush(&stack, stackpop(&stack) != stackpop(&stack));
829  break;
830  case OpNop:
831  break;
832  case OpDeref: {
833  ulong val;
834  void* addr = (void*)stackpop(&stack);
836  (d->pe->fd,
837  &val,
838  addr,
839  d->addrsize))
840  goto fatal;
841  stackpush(&stack, val);
842  } break;
843  case OpDerefSize: {
844  ulong val, size = dwarfget1(buf);
845  void* addr = (void*)stackpop(&stack);
847  (d->pe->fd,
848  &val,
849  addr,
850  size))
851  goto fatal;
852  stackpush(&stack, val);
853  } break;
854  case OpFbreg: {
855  ulong val, offset = dwarfget128s(buf);
856  void* addr = (void*)cfa;
857  werrstr("FBREG cfa %x offset %x", cfa, offset);
859  (d->pe->fd,
860  &val,
861  (PVOID)((ULONG_PTR)addr+offset),
862  d->addrsize))
863  goto fatal;
864  stackpush(&stack, val);
865  } break;
866  case OpPiece:
867  werrstr("OpPiece not supported");
868  goto fatal;
869  default:
870  if (opcode >= OpLit0 && opcode < OpReg0)
871  stackpush(&stack, opcode - OpLit0);
872  else if (opcode >= OpReg0 && opcode < OpBreg0) {
873  ulong reg = opcode - OpReg0;
874  werrstr("REG[%d] value %x", reg, (ulong)registers->Registers[reg]);
875  stackpush(&stack, registers->Registers[reg]);
876  } else if (opcode >= OpBreg0 && opcode < OpRegx) {
877  ulong val,
878  reg = opcode - OpBreg0,
879  offset = dwarfget128s(buf);
880  void* addr = (void*)(ULONG_PTR)registers->Registers[reg];
881  werrstr("BREG[%d] reg %x offset %x", reg, addr, offset);
883  ((PVOID)d->pe->fd,
884  &val,
885  (PVOID)((ULONG_PTR)addr + offset),
886  d->addrsize))
887  goto fatal;
888  stackpush(&stack, val);
889  } else {
890  werrstr("opcode %x not supported", opcode);
891  goto fatal;
892  }
893  break;
894  }
895  }
896  if (stack.length < 1) goto fatal;
897  *result = stackpop(&stack);
898  werrstr("%s: value %x", name, *result);
899  goto finish;
900 
901 fatal:
902  ret = -1;
903 
904 finish:
905  stackfree(&stack);
906  return ret;
907 }
908 
910 {
911  int gotarg;
912  DwarfSym unit = { };
913 
914  if (dwarfenumunit(d, proc->unit, &unit) == -1)
915  return -1;
916 
917  werrstr("lookup in unit %x-%x, pc %x", unit.attrs.lowpc, unit.attrs.highpc, pc);
918  pc -= unit.attrs.lowpc;
919 
920  werrstr("paramblock %s -> unit %x type %x fde %x len %d registers %x",
921  parameter->name,
922  parameter->unit,
923  parameter->type,
924  parameter->fde,
925  parameter->len,
926  registers);
927 
928  // Seek our range in loc
929  DwarfBuf locbuf;
930  DwarfBuf instream = { };
931 
932  locbuf.d = d;
933  locbuf.addrsize = d->addrsize;
934 
935  if (parameter->loctype == TConstant) {
936  locbuf.p = d->loc.data + parameter->fde;
937  locbuf.ep = d->loc.data + d->loc.len;
938  ulong start, end, len;
939  do {
940  len = 0;
941  start = dwarfget4(&locbuf);
942  end = dwarfget4(&locbuf);
943  if (start && end) {
944  len = dwarfget2(&locbuf);
945  instream = locbuf;
946  instream.ep = instream.p + len;
947  locbuf.p = instream.ep;
948  }
949  werrstr("ip %x s %x e %x (%x bytes)", pc, start, end, len);
950  } while (start && end && (start > pc || end <= pc));
951  } else if (parameter->loctype == TBlock) {
952  instream = locbuf;
953  instream.p = (void *)parameter->fde;
954  instream.ep = instream.p + parameter->len;
955  } else {
956  werrstr("Wrong block type for parameter %s", parameter->name);
957  return -1;
958  }
959 
960  gotarg = dwarfgetarg(d, parameter->name, &instream, cfa, registers, &parameter->value);
961  if (gotarg == -1)
962  return -1;
963 
964  return 0;
965 }
966 
967 void
969 {
970  int j;
971  werrstr("tag %x\n", s->attrs.tag);
972  for (j = 0; plist[j].name; j++) {
973  char *have = ((char*)&s->attrs) + plist[j].haveoff;
974  char *attr = ((char*)&s->attrs) + plist[j].off;
975  if (*have == TString) {
976  char *str = *((char **)attr);
977  werrstr("%s: %s\n", plist[j].namestr, str);
978  } else if (*have == TReference) {
979  DwarfVal *val = ((DwarfVal*)attr);
980  werrstr("%s: %x:%x\n", plist[j].namestr, val->b.data, val->b.len);
981  } else if (*have)
982  werrstr("%s: (%x)\n", plist[j].namestr, *have);
983  }
984 }
985 
986 int
987 dwarfgetparams(Dwarf *d, DwarfSym *s, ulong pc, int pnum, DwarfParam *paramblocks)
988 {
989  int ip = 0;
990  DwarfSym param = { };
991  int res = dwarfnextsymat(d, s, &param);
992  while (res == 0 && ip < pnum) {
993  if (param.attrs.tag == TagFormalParameter &&
994  param.attrs.have.name &&
995  param.attrs.have.location) {
996  paramblocks[ip].name = malloc(strlen(param.attrs.name)+1);
997  strcpy(paramblocks[ip].name, param.attrs.name);
998  paramblocks[ip].unit = param.unit;
999  paramblocks[ip].type = param.attrs.type;
1000  paramblocks[ip].loctype = param.attrs.have.location;
1001  paramblocks[ip].len = param.attrs.location.b.len;
1002  paramblocks[ip].fde = (ulong)param.attrs.location.b.data;
1003  werrstr("param[%d] block %s -> type %x loctype %x fde %x len %x",
1004  ip,
1005  paramblocks[ip].name,
1006  paramblocks[ip].type,
1007  paramblocks[ip].loctype,
1008  paramblocks[ip].fde,
1009  paramblocks[ip].len);
1010  ip++;
1011  }
1012  res = dwarfnextsymat(d, s, &param);
1013  }
1014  return ip;
1015 }
DWORD *typedef PVOID
Definition: winlogon.h:60
uchar lowpc
Definition: dwarf.h:268
static void segment(struct gl_context *ctx, struct LineInfo *line, plot_func plot, GLfloat t0, GLfloat t1)
Definition: s_aaline.c:326
uint addrsize
Definition: dwarf.h:212
Definition: dwarf.h:185
#define werrstr(str,...)
Definition: compat.h:34
uchar location
Definition: dwarf.h:266
int dwarfenumunit(Dwarf *d, ulong unit, DwarfSym *s)
Definition: dwarfinfo.c:202
Definition: dwarf.h:173
DwarfBlock info
Definition: dwarf.h:446
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint 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 GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
Definition: get.c:139
ulong storage[16]
Definition: dwarf.h:478
Definition: dwarf.h:165
Definition: dwarf.h:169
int dwarfargvalue(Dwarf *d, DwarfSym *proc, ulong pc, ulong cfa, PROSSYM_REGISTERS registers, DwarfParam *parameter)
Definition: dwarfinfo.c:909
Definition: dwarf.h:183
Definition: dwarf.h:161
Definition: dwarf.h:179
ulong name
Definition: dwarf.h:421
unsigned char uchar
Definition: Unfrag.h:59
int off
Definition: dwarfinfo.c:333
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
ulong value
Definition: dwarf.h:215
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
char * dwarfgetstring(DwarfBuf *)
Definition: dwarfget.c:55
ulong max
Definition: dwarf.h:480
Definition: dwarf.h:167
Dwarf * d
Definition: dwarf.h:209
const XML_Char const XML_Char * encoding
Definition: expat.h:187
#define free
Definition: debug_ros.c:5
int form
Definition: main.c:89
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint 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 GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint GLenum GLfloat GLenum GLint GLenum GLsizei GLenum GLboolean GLenum GLdouble GLenum GLfloat GLenum GLenum GLfloat GLenum GLenum GLdouble GLenum GLenum GLint GLenum GLenum GLint GLenum GLuint GLenum GLvoid const GLubyte GLenum GLenum GLenum GLint GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLvoid GLenum GLint GLenum GLint GLenum GLenum GLint GLuint GLdouble GLfloat GLint GLshort GLubyte GLenum GLuint GLenum const GLfloat GLenum const GLint GLenum GLenum const GLfloat GLenum GLenum const GLint GLfloat const GLfloat GLenum opcode
Definition: glfuncs.h:172
GLintptr offset
Definition: glext.h:5920
ulong dwarfget4(DwarfBuf *)
Definition: dwarfget.c:96
uchar * data
Definition: dwarf.h:202
Definition: dwarf.h:178
Definition: dwarf.h:174
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
ULONGLONG Registers[32]
Definition: rossym.h:62
#define assert(x)
Definition: debug.h:53
Definition: ecma_167.h:138
int dwarfnextsym(Dwarf *d, DwarfSym *s)
Definition: dwarfinfo.c:251
static int skipform(Dwarf *d, DwarfBuf *, int)
Definition: dwarfinfo.c:609
Definition: dwarf.h:186
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint 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 GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble * u
Definition: glfuncs.h:88
void * arg
Definition: msvc.h:12
r parent
Definition: btrfs.c:2624
GLuint GLuint end
Definition: gl.h:1545
static HANDLE proc()
Definition: pdb.c:31
Definition: dwarf.h:156
ulong fde
Definition: dwarf.h:214
Definition: dwarf.h:163
Definition: dwarf.h:172
Definition: dwarf.h:158
int dwarfseeksym(Dwarf *d, ulong unit, ulong off, DwarfSym *s)
Definition: dwarfinfo.c:171
static HWND child
Definition: cursoricon.c:298
int nattr
Definition: dwarf.h:431
Definition: dwarf.h:133
int name
Definition: dwarfinfo.c:332
DwarfBlock loc
Definition: dwarf.h:466
uint32_t ULONG_PTR
Definition: typedefs.h:63
Definition: dwarf.h:171
GLuint n
Definition: s_context.h:57
Definition: dwarf.h:137
uchar type
Definition: dwarf.h:285
void stackinit(DwarfStack *stack)
Definition: dwarfinfo.c:622
int bytesize
Definition: main.c:93
GLenum GLclampf GLint i
Definition: glfuncs.h:14
ROSSYM_CALLBACKS RosSymCallbacks
Definition: init.c:14
ulong tag
Definition: dwarf.h:225
ulong dwarfget1(DwarfBuf *)
Definition: dwarfget.c:18
Definition: dwarf.h:151
#define a
Definition: ke_i.h:78
Definition: dwarf.h:181
int ip[4]
Definition: rtl.c:1176
Definition: dwarf.h:157
png_const_structrp png_const_inforp int * unit
Definition: png.h:2192
static int getuchar(DwarfBuf *, int, uchar *)
Definition: dwarfinfo.c:535
const WCHAR * str
#define ATTR(x)
Definition: dwarfinfo.c:334
ulong unit
Definition: dwarf.h:379
Definition: dwarf.h:134
Definition: dwarf.h:177
ulong childoff
Definition: dwarf.h:393
char * name
Definition: dwarf.h:210
const char * namestr
Definition: dwarfinfo.c:327
ulong tag
Definition: dwarf.h:428
static IStream instream
Definition: saxreader.c:2084
static int constblock(Dwarf *, DwarfBlock *, ulong *)
Definition: dwarfinfo.c:596
GLuint GLfloat * val
Definition: glext.h:7180
static Parse plist[]
Definition: dwarfinfo.c:337
Definition: dwarf.h:153
Definition: _stack.h:47
Definition: dwarf.h:152
static int getstring(Dwarf *d, DwarfBuf *, int, char **)
Definition: dwarfinfo.c:548
Definition: dwarf.h:176
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
int registers[NUMREGS]
Definition: dwarf.h:138
uchar haskids
Definition: dwarf.h:226
GLsizeiptr size
Definition: glext.h:5919
ulong length
Definition: dwarf.h:480
#define d
Definition: ke_i.h:81
Definition: dhcpd.h:61
int addrsize
Definition: dwarf.h:442
static int parseattrs(Dwarf *d, DwarfBuf *, ulong, ulong, DwarfAbbrev *, DwarfAttrs *)
Definition: dwarfinfo.c:405
DwarfBlock b
Definition: dwarf.h:220
ulong len
Definition: dwarf.h:203
GLfloat param
Definition: glext.h:5796
const GLubyte * c
Definition: glext.h:8905
ulong len
Definition: dwarf.h:214
GLuint GLuint num
Definition: glext.h:9618
int dwarfnextsymat(Dwarf *d, DwarfSym *s, int depth)
Definition: dwarfinfo.c:293
GLuint GLuint GLsizei count
Definition: gl.h:1545
Definition: cookie.c:170
Definition: dwarf.h:164
int dwarflookupsubname(Dwarf *d, DwarfSym *parent, char *name, DwarfSym *s)
Definition: dwarfinfo.c:141
Definition: dwarf.h:131
uchar * p
Definition: dwarf.h:210
Definition: dwarf.h:154
int dwarflookuptag(Dwarf *d, ulong unit, ulong tag, DwarfSym *s)
Definition: dwarfinfo.c:152
long dwarfget128s(DwarfBuf *)
Definition: dwarfget.c:198
Definition: dwarf.h:159
ulong loctype
Definition: dwarf.h:213
ulong dwarfget2(DwarfBuf *)
Definition: dwarfget.c:82
Definition: dwarf.h:188
BOOLEAN(* MemGetProc)(PVOID FileContext, ULONG_PTR *Target, PVOID SourceMem, ULONG Size)
Definition: rossym.h:110
static int getulong(DwarfBuf *, int, ulong, ulong *, int *)
Definition: dwarfinfo.c:467
ulong c
Definition: dwarf.h:218
int ret
GLenum const GLvoid * addr
Definition: glext.h:9621
int dwarfgetparams(Dwarf *d, DwarfSym *s, ulong pc, int pnum, DwarfParam *paramblocks)
Definition: dwarfinfo.c:987
ulong nextunit
Definition: dwarf.h:384
Definition: dwarf.h:160
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
Definition: dwarf.h:168
GLdouble s
Definition: gl.h:2039
ulong unit
Definition: dwarf.h:211
GLenum GLsizei len
Definition: glext.h:6722
Definition: dwarf.h:191
GLsizei const GLfloat * value
Definition: glext.h:6069
Definition: dwarf.h:162
unsigned long ulong
Definition: linux.h:275
void fatal(const char *msg)
static int getblock(DwarfBuf *, int, DwarfBlock *)
Definition: dwarfinfo.c:580
Definition: dwarf.h:150
DwarfBuf b
Definition: dwarf.h:378
const GLdouble * v
Definition: gl.h:2040
ulong dwarfget128(DwarfBuf *)
Definition: dwarfget.c:153
int dwarflookupfn(Dwarf *d, ulong unit, ulong pc, DwarfSym *s)
Definition: dwarfinfo.c:182
GLuint start
Definition: gl.h:1545
#define f
Definition: ke_i.h:83
Definition: dwarf.h:436
Definition: dwarf.h:170
DwarfAttr * attr
Definition: dwarf.h:430
struct _Pe * pe
Definition: dwarf.h:438
ulong * data
Definition: dwarf.h:479
ulong type
Definition: dwarf.h:212
static int reg
Definition: i386-dis.c:1275
uchar highpc
Definition: dwarf.h:254
DwarfAbbrev * dwarfgetabbrev(Dwarf *, ulong, ulong)
Definition: dwarfabbrev.c:129
void stackfree(DwarfStack *stack)
Definition: dwarfinfo.c:651
#define nil
Definition: compat.h:23
#define isprint(c)
Definition: acclib.h:73
ulong stackpop(DwarfStack *stack)
Definition: dwarfinfo.c:643
uchar * ep
Definition: dwarf.h:211
int type
Definition: dwarfinfo.c:335
unsigned long long uvlong
Definition: compat.h:9
ulong form
Definition: dwarf.h:422
uchar * dwarfgetnref(DwarfBuf *, ulong)
Definition: dwarfget.c:41
#define OFFSET(x)
Definition: dwarfinfo.c:335
Definition: name.c:36
int dwarfgetarg(Dwarf *d, const char *name, DwarfBuf *buf, ulong cfa, PROSSYM_REGISTERS registers, ulong *result)
Definition: dwarfinfo.c:658
GLuint res
Definition: glext.h:9613
uvlong dwarfget8(DwarfBuf *)
Definition: dwarfget.c:110
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
int depth
Definition: dwarf.h:382
uchar haskids
Definition: dwarf.h:429
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
uchar name
Definition: dwarf.h:270
DwarfBlock str
Definition: dwarf.h:451
static int priority
Definition: timer.c:163
int haveoff
Definition: dwarfinfo.c:334
static Parse ptab[DwarfAttrMax]
Definition: dwarfinfo.c:402
#define malloc
Definition: debug_ros.c:4
ulong aoff
Definition: dwarf.h:381
uint num
Definition: dwarf.h:390
UINT32 uint
Definition: types.h:83
void stackpush(DwarfStack *stack, ulong value)
Definition: dwarfinfo.c:629
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLfloat GLfloat p
Definition: glext.h:8902
uchar sibling
Definition: dwarf.h:278
char * s
Definition: dwarf.h:217
GLuint64EXT * result
Definition: glext.h:11304
#define memset(x, y, z)
Definition: compat.h:39
struct DwarfAttrs::@3899 have
Definition: dwarf.h:175
int dwarflookupnameinunit(Dwarf *d, ulong unit, char *name, DwarfSym *s)
Definition: dwarfinfo.c:126
int dwarflookupchildtag(Dwarf *d, DwarfSym *parent, ulong tag, DwarfSym *s)
Definition: dwarfinfo.c:142
ulong dwarfgetaddr(DwarfBuf *)
Definition: dwarfget.c:124
DwarfAttrs attrs
Definition: dwarf.h:375
void dwarfdumpsym(Dwarf *d, DwarfSym *s)
Definition: dwarfinfo.c:968
const char const char ** ordering
Definition: cffdrivr.c:690
Definition: dwarf.h:149
INT x
Definition: msvc.h:62
off
Definition: i386-dis.c:3909