ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

dwarfinfo.c
Go to the documentation of this file.
00001 /*
00002  * Dwarf info parse and search.
00003  */
00004 
00005 #include <precomp.h>
00006 #define NDEBUG
00007 #include <debug.h>
00008 
00009 enum
00010 {
00011     DwarfAttrSibling = 0x01,
00012     DwarfAttrLocation = 0x02,
00013     DwarfAttrName = 0x03,
00014     DwarfAttrOrdering = 0x09,
00015     DwarfAttrByteSize = 0x0B,
00016     DwarfAttrBitOffset = 0x0C,
00017     DwarfAttrBitSize = 0x0D,
00018     DwarfAttrStmtList = 0x10,
00019     DwarfAttrLowpc = 0x11,
00020     DwarfAttrHighpc = 0x12,
00021     DwarfAttrLanguage = 0x13,
00022     DwarfAttrDiscr = 0x15,
00023     DwarfAttrDiscrValue = 0x16,
00024     DwarfAttrVisibility = 0x17,
00025     DwarfAttrImport = 0x18,
00026     DwarfAttrStringLength = 0x19,
00027     DwarfAttrCommonRef = 0x1A,
00028     DwarfAttrCompDir = 0x1B,
00029     DwarfAttrConstValue = 0x1C,
00030     DwarfAttrContainingType = 0x1D,
00031     DwarfAttrDefaultValue = 0x1E,
00032     DwarfAttrInline = 0x20,
00033     DwarfAttrIsOptional = 0x21,
00034     DwarfAttrLowerBound = 0x22,
00035     DwarfAttrProducer = 0x25,
00036     DwarfAttrPrototyped = 0x27,
00037     DwarfAttrReturnAddr = 0x2A,
00038     DwarfAttrStartScope = 0x2C,
00039     DwarfAttrStrideSize = 0x2E,
00040     DwarfAttrUpperBound = 0x2F,
00041     DwarfAttrAbstractOrigin = 0x31,
00042     DwarfAttrAccessibility = 0x32,
00043     DwarfAttrAddrClass = 0x33,
00044     DwarfAttrArtificial = 0x34,
00045     DwarfAttrBaseTypes = 0x35,
00046     DwarfAttrCalling = 0x36,
00047     DwarfAttrCount = 0x37,
00048     DwarfAttrDataMemberLoc = 0x38,
00049     DwarfAttrDeclColumn = 0x39,
00050     DwarfAttrDeclFile = 0x3A,
00051     DwarfAttrDeclLine = 0x3B,
00052     DwarfAttrDeclaration = 0x3C,
00053     DwarfAttrDiscrList = 0x3D,
00054     DwarfAttrEncoding = 0x3E,
00055     DwarfAttrExternal = 0x3F,
00056     DwarfAttrFrameBase = 0x40,
00057     DwarfAttrFriend = 0x41,
00058     DwarfAttrIdentifierCase = 0x42,
00059     DwarfAttrMacroInfo = 0x43,
00060     DwarfAttrNamelistItem = 0x44,
00061     DwarfAttrPriority = 0x45,
00062     DwarfAttrSegment = 0x46,
00063     DwarfAttrSpecification = 0x47,
00064     DwarfAttrStaticLink = 0x48,
00065     DwarfAttrType = 0x49,
00066     DwarfAttrUseLocation = 0x4A,
00067     DwarfAttrVarParam = 0x4B,
00068     DwarfAttrVirtuality = 0x4C,
00069     DwarfAttrVtableElemLoc = 0x4D,
00070     DwarfAttrAllocated = 0x4E,
00071     DwarfAttrAssociated = 0x4F,
00072     DwarfAttrDataLocation = 0x50,
00073     DwarfAttrStride = 0x51,
00074     DwarfAttrEntrypc = 0x52,
00075     DwarfAttrUseUTF8 = 0x53,
00076     DwarfAttrExtension = 0x54,
00077     DwarfAttrRanges = 0x55,
00078     DwarfAttrTrampoline = 0x56,
00079     DwarfAttrCallColumn = 0x57,
00080     DwarfAttrCallFile = 0x58,
00081     DwarfAttrCallLine = 0x59,
00082     DwarfAttrDescription = 0x5A,
00083     DwarfAttrMax,
00084 
00085     FormAddr = 0x01,
00086     FormDwarfBlock2 = 0x03,
00087     FormDwarfBlock4 = 0x04,
00088     FormData2 = 0x05,
00089     FormData4 = 0x06,
00090     FormData8 = 0x07,
00091     FormString = 0x08,
00092     FormDwarfBlock = 0x09,
00093     FormDwarfBlock1 = 0x0A,
00094     FormData1 = 0x0B,
00095     FormFlag = 0x0C,
00096     FormSdata = 0x0D,
00097     FormStrp = 0x0E,
00098     FormUdata = 0x0F,
00099     FormRefAddr = 0x10,
00100     FormRef1 = 0x11,
00101     FormRef2 = 0x12,
00102     FormRef4 = 0x13,
00103     FormRef8 = 0x14,
00104     FormRefUdata = 0x15,
00105     FormIndirect = 0x16
00106 };
00107 
00108 static int parseattrs(Dwarf *d, DwarfBuf*, ulong, ulong, DwarfAbbrev*, DwarfAttrs*);
00109 static int getulong(DwarfBuf*, int, ulong, ulong*, int*);
00110 static int getuchar(DwarfBuf*, int, uchar*);
00111 static int getstring(Dwarf *d, DwarfBuf*, int, char**);
00112 static int getblock(DwarfBuf*, int, DwarfBlock*);
00113 static int skipform(Dwarf *d, DwarfBuf*, int);
00114 
00115 int
00116 dwarflookupnameinunit(Dwarf *d, ulong unit, char *name, DwarfSym *s)
00117 {
00118     DwarfSym compunit = { };
00119     if(dwarfenumunit(d, unit, &compunit) < 0)
00120         return -1;
00121     while(dwarfnextsymat(d, &compunit, s) == 0) {
00122         werrstr("got %s looking for %s\n", s->attrs.name, name);
00123         if(s->attrs.name && strcmp(s->attrs.name, name) == 0)
00124             return 0;
00125     }
00126     werrstr("symbol '%s' not found", name);
00127     return -1;
00128 }
00129 
00130 int
00131 dwarflookupsubname(Dwarf *d, DwarfSym *parent, char *name, DwarfSym *s)
00132 {
00133     *s = *parent;
00134     while(dwarfnextsymat(d, parent, s))
00135         if(s->attrs.name && strcmp(s->attrs.name, name) == 0)
00136             return 0;
00137     werrstr("symbol '%s' not found", name);
00138     return -1;
00139 }
00140 
00141 int
00142 dwarflookupchildtag(Dwarf *d, DwarfSym *parent, ulong tag, DwarfSym *s)
00143 {
00144     int rsym = dwarfnextsymat(d, parent, s);
00145     while (rsym == 0 && s->attrs.tag != tag) {
00146         if (s->attrs.haskids) {
00147             DwarfSym p = *s;
00148             int csym = dwarflookupchildtag(d, &p, tag, s);
00149             if (csym == 0) {
00150                 return csym;
00151             }
00152         }
00153         rsym = dwarfnextsym(d, s);
00154     }
00155     return rsym;
00156 }
00157 
00158 int
00159 dwarflookuptag(Dwarf *d, ulong unit, ulong tag, DwarfSym *s)
00160 {
00161     DwarfSym compunit = { };
00162     if (dwarfenumunit(d, unit, &compunit) < 0) {
00163         return -1;
00164     }
00165     do {
00166         if (compunit.attrs.tag == tag) {
00167             *s = compunit;
00168             return 0;
00169         }
00170         if (dwarflookupchildtag(d, &compunit, tag, s) == 0)
00171             return 0;
00172     } while(dwarfnextsym(d, &compunit) == 0);
00173     werrstr("symbol with tag 0x%lux not found", tag);
00174     return -1;
00175 }
00176 
00177 int
00178 dwarfseeksym(Dwarf *d, ulong unit, ulong off, DwarfSym *s)
00179 {
00180     DwarfSym compunit = { };
00181     if(dwarfenumunit(d, unit, &compunit) < 0)
00182         return -1;
00183     werrstr("dwarfseeksym: unit %x off %x\n", unit, off);
00184     s->b.d = d;
00185     s->b.p = d->info.data + unit + off;
00186     s->b.ep = compunit.b.ep;
00187     if(dwarfnextsymat(d, &compunit, s) == -1)
00188         return -1;
00189     werrstr("dwarfseeksym: unit %x off %x, tag %x", unit, off, s->attrs.tag);
00190     return 0;
00191 }
00192 
00193 int
00194 dwarflookupfn(Dwarf *d, ulong unit, ulong pc, DwarfSym *s)
00195 {
00196     DwarfSym compunit = { };
00197     if(dwarfenumunit(d, unit, &compunit) < 0)
00198         return -1;
00199     while(dwarfnextsymat(d, &compunit, s) == 0){
00200         if(s->attrs.tag != TagSubprogram)
00201             continue;
00202         if(s->attrs.lowpc <= pc && pc < s->attrs.highpc)
00203             return 0;
00204     }
00205     werrstr("fn containing pc 0x%lux not found", pc);
00206     return -1;
00207 }
00208 
00209 int
00210 dwarfenumunit(Dwarf *d, ulong unit, DwarfSym *s)
00211 {
00212     int i;
00213     ulong aoff, len;
00214 
00215     if(unit >= d->info.len){
00216         werrstr("dwarf unit address 0x%x >= 0x%x out of range", unit, d->info.len);
00217         return -1;
00218     }
00219     memset(s, 0, sizeof *s);
00220     memset(&s->b, 0, sizeof s->b);
00221 
00222     s->b.d = d;
00223     s->b.p = d->info.data + unit;
00224     s->b.ep = d->info.data + d->info.len;
00225     len = dwarfget4(&s->b);
00226     s->unit = unit;
00227     s->nextunit = unit + 4 + len;
00228     s->b.ep = d->info.data + s->nextunit;
00229 
00230     if(s->b.ep - s->b.p < len){
00231     badheader:
00232         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);
00233         return -1;
00234     }
00235     s->b.ep = s->b.p+len;
00236     if((i=dwarfget2(&s->b)) > 4)
00237         goto badheader;
00238     aoff = dwarfget4(&s->b);
00239     s->b.addrsize = dwarfget1(&s->b);
00240     if(d->addrsize == 0)
00241         d->addrsize = s->b.addrsize;
00242     if(s->b.p == nil)
00243         goto badheader;
00244 
00245     s->aoff = aoff;
00246 
00247     return dwarfnextsym(d, s);
00248 }
00249 
00250 int
00251 dwarfnextsym(Dwarf *d, DwarfSym *s)
00252 {
00253     ulong num;
00254     DwarfAbbrev *a;
00255 
00256     werrstr("sym at %x (left %x)\n", s->b.p - d->info.data, s->b.ep - s->b.p);
00257 
00258     num = dwarfget128(&s->b);
00259     werrstr("abbrev num %x\n", num);
00260     s->num = num;
00261     if(num == 0){
00262         return -1;
00263     }
00264 
00265     a = dwarfgetabbrev(d, s->aoff, num);
00266     werrstr("a %p\n", a);
00267     if(a == nil){
00268         werrstr("getabbrev %x %x for %x", s->aoff, num, s->unit);
00269         return -1;
00270     }
00271 
00272     if(parseattrs(d, &s->b, s->attrs.tag, s->unit, a, &s->attrs) < 0) {
00273         return -1;
00274     }
00275 
00276     if (s->attrs.haskids) {
00277         DwarfSym childSkip = { };
00278         s->childoff = s->b.p - d->info.data;
00279         werrstr("Set childoff at %x\n", s->childoff);
00280         int r = dwarfnextsymat(d, s, &childSkip);
00281         while (r == 0) {
00282             r = dwarfnextsym(d, &childSkip);
00283         }
00284         s->b = childSkip.b;
00285     } else {
00286         s->childoff = 0;
00287     }
00288     return 0;
00289 }
00290 
00291 int
00292 dwarfnextsymat(Dwarf *d, DwarfSym *parent, DwarfSym *child)
00293 {
00294     uint sib;
00295 
00296     if (!parent->attrs.haskids || !parent->childoff)
00297         return -1;
00298 
00299     child->unit = parent->unit;
00300     child->aoff = parent->aoff;
00301     child->depth = parent->depth + 1;
00302     if(child->attrs.have.sibling){
00303         sib = child->attrs.sibling;
00304         if(sib < d->info.len && d->info.data+sib > child->b.p)
00305             child->b.p = d->info.data+sib;
00306         else if (sib >= d->info.len) {
00307             werrstr("sibling reported as out of bounds %d vs %d", sib, d->info.len);
00308             return -1;
00309         } else if (d->info.data+sib+parent->unit < child->b.p) {
00310             werrstr("subsequent sibling is listed before prev %d vs %d", sib+parent->unit, child->b.p - d->info.data);
00311             return -1;
00312         }
00313     }
00314 
00315     // Uninitialized
00316     if (!child->b.d) {
00317         child->b = parent->b;
00318         child->b.p = parent->childoff + parent->b.d->info.data;
00319         werrstr("Rewound to childoff %x\n", parent->childoff);
00320     }
00321 
00322     return dwarfnextsym(d, child);
00323 }
00324 
00325 typedef struct Parse Parse;
00326 struct Parse {
00327     const char *namestr;
00328     int name;
00329     int off;
00330     int haveoff;
00331     int type;
00332 };
00333 
00334 #define ATTR(x) (#x)+9, x
00335 #define OFFSET(x) offsetof(DwarfAttrs, x), offsetof(DwarfAttrs, have.x)
00336 
00337 static Parse plist[] = {    /* Font Tab 4 */
00338     { ATTR(DwarfAttrAbstractOrigin),    OFFSET(abstractorigin),     TReference },
00339     { ATTR(DwarfAttrAccessibility), OFFSET(accessibility),      TConstant },
00340     { ATTR(DwarfAttrAddrClass),         OFFSET(addrclass),          TConstant },
00341     { ATTR(DwarfAttrBaseTypes),     OFFSET(basetypes),          TReference },
00342     { ATTR(DwarfAttrBitOffset),     OFFSET(bitoffset),          TConstant },
00343     { ATTR(DwarfAttrBitSize),       OFFSET(bitsize),            TConstant },
00344     { ATTR(DwarfAttrByteSize),      OFFSET(bytesize),           TConstant },
00345     { ATTR(DwarfAttrCalling),       OFFSET(calling),            TConstant },
00346     { ATTR(DwarfAttrCommonRef),     OFFSET(commonref),          TReference },
00347     { ATTR(DwarfAttrCompDir),       OFFSET(compdir),            TString },
00348     { ATTR(DwarfAttrConstValue),        OFFSET(constvalue),         TString|TConstant|TBlock },
00349     { ATTR(DwarfAttrContainingType),    OFFSET(containingtype),     TReference },
00350     { ATTR(DwarfAttrCount),         OFFSET(count),              TConstant|TReference },
00351     { ATTR(DwarfAttrDataMemberLoc), OFFSET(datamemberloc),      TBlock|TConstant|TReference },
00352     { ATTR(DwarfAttrDeclColumn),        OFFSET(declcolumn),         TConstant },
00353     { ATTR(DwarfAttrDeclFile),      OFFSET(declfile),           TConstant },
00354     { ATTR(DwarfAttrDeclLine),      OFFSET(declline),           TConstant },
00355     { ATTR(DwarfAttrDefaultValue),  OFFSET(defaultvalue),       TReference },
00356     { ATTR(DwarfAttrDiscr),         OFFSET(discr),              TReference },
00357     { ATTR(DwarfAttrDiscrList),     OFFSET(discrlist),          TBlock },
00358     { ATTR(DwarfAttrDiscrValue),        OFFSET(discrvalue),         TConstant },
00359     { ATTR(DwarfAttrEncoding),      OFFSET(encoding),           TConstant },
00360     { ATTR(DwarfAttrFrameBase),     OFFSET(framebase),          TBlock|TConstant },
00361     { ATTR(DwarfAttrFriend),            OFFSET(friend),             TReference },
00362     { ATTR(DwarfAttrHighpc),            OFFSET(highpc),             TAddress },
00363     { ATTR(DwarfAttrEntrypc),         OFFSET(entrypc),            TAddress },
00364     { ATTR(DwarfAttrIdentifierCase),    OFFSET(identifiercase),     TConstant },
00365     { ATTR(DwarfAttrImport),            OFFSET(import),             TReference },
00366     { ATTR(DwarfAttrInline),            OFFSET(inlined),            TConstant },
00367     { ATTR(DwarfAttrArtificial),        OFFSET(isartificial),       TFlag },
00368     { ATTR(DwarfAttrDeclaration),       OFFSET(isdeclaration),      TFlag },
00369     { ATTR(DwarfAttrExternal),      OFFSET(isexternal),         TFlag },
00370     { ATTR(DwarfAttrIsOptional),        OFFSET(isoptional),         TFlag },
00371     { ATTR(DwarfAttrPrototyped),        OFFSET(isprototyped),       TFlag },
00372     { ATTR(DwarfAttrVarParam),      OFFSET(isvarparam),         TFlag },
00373     { ATTR(DwarfAttrLanguage),      OFFSET(language),           TConstant },
00374     { ATTR(DwarfAttrLocation),      OFFSET(location),           TReference|TBlock },
00375     { ATTR(DwarfAttrLowerBound),        OFFSET(lowerbound),         TConstant|TReference },
00376     { ATTR(DwarfAttrLowpc),         OFFSET(lowpc),              TAddress },
00377     { ATTR(DwarfAttrMacroInfo),     OFFSET(macroinfo),          TConstant },
00378     { ATTR(DwarfAttrName),          OFFSET(name),               TString },
00379     { ATTR(DwarfAttrNamelistItem),  OFFSET(namelistitem),       TBlock },
00380     { ATTR(DwarfAttrOrdering),      OFFSET(ordering),           TConstant },
00381     { ATTR(DwarfAttrPriority),      OFFSET(priority),           TReference },
00382     { ATTR(DwarfAttrProducer),      OFFSET(producer),           TString },
00383     { ATTR(DwarfAttrRanges),            OFFSET(ranges),             TReference },
00384     { ATTR(DwarfAttrReturnAddr),        OFFSET(returnaddr),         TBlock|TConstant },
00385     { ATTR(DwarfAttrSegment),       OFFSET(segment),            TBlock|TConstant },
00386     { ATTR(DwarfAttrSibling),       OFFSET(sibling),            TReference },
00387     { ATTR(DwarfAttrSpecification), OFFSET(specification),      TReference },
00388     { ATTR(DwarfAttrStartScope),        OFFSET(startscope),         TConstant },
00389     { ATTR(DwarfAttrStaticLink),        OFFSET(staticlink),         TBlock|TConstant },
00390     { ATTR(DwarfAttrStmtList),      OFFSET(stmtlist),           TConstant },
00391     { ATTR(DwarfAttrStrideSize),        OFFSET(stridesize),         TConstant },
00392     { ATTR(DwarfAttrStringLength),  OFFSET(stringlength),       TBlock|TConstant },
00393     { ATTR(DwarfAttrType),          OFFSET(type),               TReference },
00394     { ATTR(DwarfAttrUpperBound),        OFFSET(upperbound),         TConstant|TReference },
00395     { ATTR(DwarfAttrUseLocation),   OFFSET(uselocation),        TBlock|TConstant },
00396     { ATTR(DwarfAttrVirtuality),        OFFSET(virtuality),         TConstant },
00397     { ATTR(DwarfAttrVisibility),        OFFSET(visibility),         TConstant },
00398     { ATTR(DwarfAttrVtableElemLoc), OFFSET(vtableelemloc),      TBlock|TReference },
00399     { }
00400 };
00401 
00402 static Parse ptab[DwarfAttrMax];
00403 
00404 static int
00405 parseattrs(Dwarf *d, DwarfBuf *b, ulong tag, ulong unit, DwarfAbbrev *a, DwarfAttrs *attrs)
00406 {
00407     int i, f, n, got;
00408     static int nbad;
00409     void *v;
00410 
00411     /* initialize ptab first time through for quick access */
00412     if(ptab[DwarfAttrName].name != DwarfAttrName)
00413         for(i=0; plist[i].name; i++)
00414             ptab[plist[i].name] = plist[i];
00415 
00416     memset(attrs, 0, sizeof *attrs);
00417     attrs->tag = a->tag;
00418     attrs->haskids = a->haskids;
00419 
00420     for(i=0; i<a->nattr; i++){
00421         n = a->attr[i].name;
00422         f = a->attr[i].form;
00423         werrstr("struct: (@%x) n %x f %x (%d %d)\n", b->p - d->info.data, n, f, ptab[n].haveoff, ptab[n].off);
00424         if(n < 0 || n >= DwarfAttrMax || ptab[n].name==0) {
00425             if (skipform(d, b, f) < 0) {
00426                 if(++nbad == 1)
00427                     werrstr("dwarf parse attrs: cannot skip form %d", f);
00428                 return -1;
00429             }
00430             continue;
00431         }
00432         v = (char*)attrs + ptab[n].off;
00433         got = 0;
00434         if(f == FormIndirect)
00435             f = dwarfget128(b);
00436         if((ptab[n].type&(TConstant|TReference|TAddress))
00437            && getulong(b, f, unit, v, &got) >= 0)
00438             ;
00439         else if((ptab[n].type&TFlag) && getuchar(b, f, v) >= 0)
00440             got = TFlag;
00441         else if((ptab[n].type&TString) && getstring(d, b, f, v) >= 0)
00442             got = TString;
00443         else if((ptab[n].type&TBlock) && getblock(b, f, v) >= 0) {
00444             got = TBlock;
00445         } else {
00446             werrstr("Skipping form %x\n", f);
00447             if(skipform(d, b, f) < 0){
00448                 //if(++nbad == 1)
00449                     werrstr("dwarf parse attrs: cannot skip form %d", f);
00450                 return -1;
00451             }
00452         }
00453 #if 0
00454         if(got == TBlock && (ptab[n].type&TConstant))
00455             got = constblock(b->d, v, v);
00456 #endif
00457         *((uchar*)attrs+ptab[n].haveoff) = got;
00458     }
00459 
00460     if (attrs->have.name)
00461         werrstr("%s: tag %x kids %d (last %x)\n", attrs->name, attrs->tag, attrs->haskids, b->p - b->d->info.data);
00462 
00463     return 0;
00464 }
00465 
00466 static int
00467 getulong(DwarfBuf *b, int form, ulong unit, ulong *u, int *type)
00468 {
00469     static int nbad;
00470     uvlong uv;
00471 
00472     switch(form){
00473     default:
00474         return -1;
00475 
00476     /* addresses */
00477     case FormAddr:
00478         *type = TAddress;
00479         *u = dwarfgetaddr(b);
00480         return 0;
00481 
00482     /* references */
00483     case FormRefAddr:
00484         /* absolute ref in .debug_info */
00485         *type = TReference;
00486         *u = dwarfgetaddr(b);
00487         return 0;
00488     case FormRef1:
00489         *u = dwarfget1(b);
00490         goto relativeref;
00491     case FormRef2:
00492         *u = dwarfget2(b);
00493         goto relativeref;
00494     case FormRef4:
00495         *u = dwarfget4(b);
00496         goto relativeref;
00497     case FormRef8:
00498         *u = dwarfget8(b);
00499         goto relativeref;
00500     case FormRefUdata:
00501         *u = dwarfget128(b);
00502     relativeref:
00503         *u += unit;
00504         *type = TReference;
00505         return 0;
00506 
00507     /* constants */
00508     case FormData1:
00509         *u = dwarfget1(b);
00510         goto constant;
00511     case FormData2:
00512         *u = dwarfget2(b);
00513         goto constant;
00514     case FormData4:
00515         *u = dwarfget4(b);
00516         goto constant;
00517     case FormData8:
00518         uv = dwarfget8(b);
00519         *u = uv;
00520         if(uv != *u && ++nbad == 1)
00521             werrstr("dwarf: truncating 64-bit attribute constants");
00522         goto constant;
00523     case FormSdata:
00524         *u = dwarfget128s(b);
00525         goto constant;
00526     case FormUdata:
00527         *u = dwarfget128(b);
00528     constant:
00529         *type = TConstant;
00530         return 0;
00531     }
00532 }
00533 
00534 static int
00535 getuchar(DwarfBuf *b, int form, uchar *u)
00536 {
00537     switch(form){
00538     default:
00539         return -1;
00540 
00541     case FormFlag:
00542         *u = dwarfget1(b);
00543         return 0;
00544     }
00545 }
00546 
00547 static int
00548 getstring(Dwarf *d, DwarfBuf *b, int form, char **s)
00549 {
00550     static int nbad;
00551     ulong u, x;
00552 
00553     switch(form){
00554     default:
00555         return -1;
00556 
00557     case FormString:
00558         x = b->p - d->info.data;
00559         *s = dwarfgetstring(b);
00560         for (u = 0; (*s)[u]; u++) {
00561             assert(isprint((*s)[u]));
00562         }
00563         return 0;
00564 
00565     case FormStrp:
00566         u = dwarfget4(b);
00567         if(u >= b->d->str.len){
00568             if(++nbad == 1)
00569                 werrstr("dwarf: bad string pointer 0x%lux in attribute", u);
00570             /* don't return error - maybe can proceed */
00571             *s = nil;
00572         }else
00573             *s = (char*)b->d->str.data + u;
00574         return 0;
00575 
00576     }
00577 }
00578 
00579 static int
00580 getblock(DwarfBuf *b, int form, DwarfBlock *bl)
00581 {
00582     ulong n;
00583 
00584     switch(form){
00585     default:
00586         return -1;
00587     case FormDwarfBlock:
00588         n = dwarfget128(b);
00589         goto copyn;
00590     case FormDwarfBlock1:
00591         n = dwarfget1(b);
00592         goto copyn;
00593     case FormDwarfBlock2:
00594         n = dwarfget2(b);
00595         goto copyn;
00596     case FormDwarfBlock4:
00597         n = dwarfget4(b);
00598     copyn:
00599         bl->data = dwarfgetnref(b, n);
00600         bl->len = n;
00601         if(bl->data == nil)
00602             return -1;
00603         return 0;
00604     }
00605 }
00606 
00607 /* last resort */
00608 static int
00609 skipform(Dwarf *d, DwarfBuf *b, int form)
00610 {
00611     int type;
00612     DwarfVal val;
00613 
00614     if(getulong(b, form, 0, &val.c, &type) < 0
00615        && getuchar(b, form, (uchar*)&val) < 0
00616        && getstring(d, b, form, &val.s) < 0
00617        && getblock(b, form, &val.b) < 0)
00618         return -1;
00619     return 0;
00620 }
00621 
00622 void stackinit(DwarfStack *stack)
00623 {
00624     memset(stack, 0, sizeof(*stack));
00625     stack->data = stack->storage;
00626     stack->length = 0; stack->max = sizeof(stack->storage) / sizeof(stack->storage[0]);
00627 }
00628 
00629 void stackpush(DwarfStack *stack, ulong value)
00630 {
00631     if (stack->length == stack->max) {
00632         ulong *newstack = malloc(sizeof(ulong)*stack->max*2);
00633         memcpy(newstack, stack->data, sizeof(ulong)*stack->length);
00634         if (stack->data != stack->storage)
00635             free(stack->data);
00636         stack->data = newstack;
00637         stack->max *= 2;
00638     }
00639     werrstr("stack[%d] = %x", stack->length, value);
00640     stack->data[stack->length++] = value;
00641 }
00642 
00643 ulong stackpop(DwarfStack *stack) 
00644 {
00645     ASSERT(stack->length > 0);
00646     ulong val = stack->data[--stack->length];
00647     werrstr("pop stack[%d] -> %x", stack->length, val);
00648     return val;
00649 }
00650 
00651 void stackfree(DwarfStack *stack)
00652 {
00653     if (stack->data != stack->storage)
00654         free(stack->data);
00655 }
00656 
00657 // Returns -1 on failure
00658 int dwarfgetarg(Dwarf *d, const char *name, DwarfBuf *buf, ulong cfa, PROSSYM_REGISTERS registers, ulong *result)
00659 {
00660     int ret = 0;
00661     DwarfStack stack = { };
00662     stackinit(&stack);
00663     stackpush(&stack, cfa);
00664     while (buf->p < buf->ep) {
00665         int opcode = dwarfget1(buf);
00666         werrstr("opcode %x", opcode);
00667         switch (opcode) {
00668         case 0:
00669             buf->p = buf->ep;
00670             break;
00671         case OpAddr:
00672             if (d->addrsize == 4) {
00673                 stackpush(&stack, dwarfget4(buf));
00674                 break;
00675             } else {
00676                 werrstr("%s: we only support 4 byte addrs", name);
00677                 goto fatal;
00678             }
00679         case OpConst1s: {
00680             signed char c = dwarfget1(buf);
00681             stackpush(&stack, c);
00682         } break;
00683         case OpConst1u:
00684             stackpush(&stack, dwarfget1(buf));
00685             break;
00686         case OpConst2s: {
00687             signed short s = dwarfget2(buf);
00688             stackpush(&stack, s);
00689         } break;
00690         case OpConst2u:
00691             stackpush(&stack, dwarfget2(buf));
00692             break;
00693         case OpConst4s: {
00694             signed int i = dwarfget4(buf);
00695             stackpush(&stack, i);
00696         } break;
00697         case OpConst4u:
00698             stackpush(&stack, dwarfget4(buf));
00699             break;
00700         case OpConst8s:
00701         case OpConst8u:
00702             werrstr("const 8 not yet supported");
00703             goto fatal;
00704         case OpConsts:
00705             stackpush(&stack, dwarfget128s(buf));
00706             break;
00707         case OpConstu:
00708             stackpush(&stack, dwarfget128(buf));
00709             break;
00710         case OpDup: {
00711             ulong popped = stackpop(&stack);
00712             stackpush(&stack, popped);
00713             stackpush(&stack, popped);
00714         } break;
00715         case OpDrop:
00716             stackpop(&stack);
00717             break;
00718         case OpOver: {
00719             if (stack.length < 2) goto fatal;
00720             stackpush(&stack, stack.data[stack.length-2]);
00721         } break;
00722         case OpPick: {
00723             ulong arg = dwarfget1(buf);
00724             if (arg >= stack.length) goto fatal;
00725             arg = stack.data[stack.length-1-arg];
00726             stackpush(&stack, arg);
00727         } break;
00728         case OpSwap: {
00729             ulong a = stackpop(&stack), b = stackpop(&stack);
00730             stackpush(&stack, b);
00731             stackpush(&stack, a);
00732         } break;
00733         case OpRot: {
00734             ulong a = stackpop(&stack), b = stackpop(&stack), c = stackpop(&stack);
00735             stackpush(&stack, b);
00736             stackpush(&stack, c);
00737             stackpush(&stack, a);
00738         } break;
00739         case OpXderef:
00740         case OpXderefSize:
00741             werrstr("Xderef not yet supported");
00742             goto fatal;
00743         case OpAbs: {
00744             long a = stackpop(&stack);
00745             stackpush(&stack, a < 0 ? -a : a);
00746         } break;
00747         case OpAnd:
00748             stackpush(&stack, stackpop(&stack) & stackpop(&stack));
00749             break;
00750         case OpDiv: {
00751             ulong a = stackpop(&stack), b = stackpop(&stack);
00752             stackpush(&stack, b / a);
00753         } break;
00754         case OpMinus: {
00755             ulong a = stackpop(&stack), b = stackpop(&stack);
00756             stackpush(&stack, b - a);
00757         } break;
00758         case OpMod: {
00759             ulong a = stackpop(&stack), b = stackpop(&stack);
00760             stackpush(&stack, b % a);
00761         } break;
00762         case OpMul:
00763             stackpush(&stack, stackpop(&stack) * stackpop(&stack));
00764             break;
00765         case OpNeg:
00766             stackpush(&stack, -stackpop(&stack));
00767             break;
00768         case OpNot:
00769             stackpush(&stack, ~stackpop(&stack));
00770             break;
00771         case OpOr:
00772             stackpush(&stack, stackpop(&stack) | stackpop(&stack));
00773             break;
00774         case OpPlus:
00775             stackpush(&stack, stackpop(&stack) + stackpop(&stack));
00776             break;
00777         case OpPlusUconst:
00778             stackpush(&stack, stackpop(&stack) + dwarfget128(buf));
00779             break;
00780         case OpShl: {
00781             ulong a = stackpop(&stack), b = stackpop(&stack);
00782             stackpush(&stack, b << a);
00783         } break;
00784         case OpShr: {
00785             ulong a = stackpop(&stack), b = stackpop(&stack);
00786             stackpush(&stack, b >> a);
00787         } break;
00788         case OpShra: {
00789             ulong a = stackpop(&stack);
00790             long b = stackpop(&stack);
00791             if (b < 0)
00792                 b = -(-b >> a);
00793             else
00794                 b = b >> a;
00795             stackpush(&stack, b);
00796         } break;
00797         case OpXor:
00798             stackpush(&stack, stackpop(&stack) ^ stackpop(&stack));
00799             break;
00800         case OpSkip:
00801             buf->p += dwarfget2(buf);
00802             break;
00803         case OpBra: {
00804             ulong a = dwarfget2(buf);
00805             if (stackpop(&stack))
00806                 buf->p += a;
00807         } break;
00808         case OpEq:
00809             stackpush(&stack, stackpop(&stack) == stackpop(&stack));
00810             break;
00811         case OpGe: {
00812             ulong a = stackpop(&stack), b = stackpop(&stack);
00813             stackpush(&stack, b >= a);
00814         } break;
00815         case OpGt: {
00816             ulong a = stackpop(&stack), b = stackpop(&stack);
00817             stackpush(&stack, b > a);
00818         } break;
00819         case OpLe: {
00820             ulong a = stackpop(&stack), b = stackpop(&stack);
00821             stackpush(&stack, b <= a);
00822         } break;
00823         case OpLt: {
00824             ulong a = stackpop(&stack), b = stackpop(&stack);
00825             stackpush(&stack, b < a);
00826         } break;
00827         case OpNe:
00828             stackpush(&stack, stackpop(&stack) != stackpop(&stack));
00829             break;
00830         case OpNop:
00831             break;
00832         case OpDeref: {
00833             ulong val;
00834             void* addr = (void*)stackpop(&stack);
00835             if (!RosSymCallbacks.MemGetProc
00836                 (d->pe->fd,
00837                  &val,
00838                  addr,
00839                  d->addrsize))
00840                 goto fatal;
00841             stackpush(&stack, val);
00842         } break;
00843         case OpDerefSize: {
00844             ulong val, size = dwarfget1(buf);
00845             void* addr = (void*)stackpop(&stack);
00846             if (!RosSymCallbacks.MemGetProc
00847                 (d->pe->fd,
00848                  &val,
00849                  addr,
00850                  size))
00851                 goto fatal;
00852             stackpush(&stack, val);
00853         } break;
00854         case OpFbreg: {
00855             ulong val, offset = dwarfget128s(buf);;
00856             void* addr = (void*)cfa;
00857             werrstr("FBREG cfa %x offset %x", cfa, offset);
00858             if (!RosSymCallbacks.MemGetProc
00859                 (d->pe->fd,
00860                  &val,
00861                  (PVOID)((ULONG_PTR)addr+offset),
00862                  d->addrsize))
00863                 goto fatal;
00864             stackpush(&stack, val);
00865         } break;
00866         case OpPiece:
00867             werrstr("OpPiece not supported");
00868             goto fatal;
00869         default:
00870             if (opcode >= OpLit0 && opcode < OpReg0)
00871                 stackpush(&stack, opcode - OpLit0);
00872             else if (opcode >= OpReg0 && opcode < OpBreg0) {
00873                 ulong reg = opcode - OpReg0;
00874                 werrstr("REG[%d] value %x", reg, (ulong)registers->Registers[reg]);
00875                 stackpush(&stack, registers->Registers[reg]);
00876             } else if (opcode >= OpBreg0 && opcode < OpRegx) {
00877                 ulong val, 
00878                     reg = opcode - OpBreg0, 
00879                     offset = dwarfget128s(buf);
00880                 void* addr = (void*)(ULONG_PTR)registers->Registers[reg];
00881                 werrstr("BREG[%d] reg %x offset %x", reg, addr, offset);
00882                 if (!RosSymCallbacks.MemGetProc
00883                     ((PVOID)d->pe->fd,
00884                      &val,
00885                      (PVOID)((ULONG_PTR)addr + offset),
00886                      d->addrsize))
00887                     goto fatal;
00888                 stackpush(&stack, val);
00889             } else {
00890                 werrstr("opcode %x not supported", opcode);
00891                 goto fatal;
00892             }
00893             break;
00894         }
00895     }
00896     if (stack.length < 1) goto fatal;
00897     *result = stackpop(&stack);
00898     werrstr("%s: value %x", name, *result);
00899     goto finish;
00900 
00901 fatal:
00902     ret = -1;
00903 
00904 finish:
00905     stackfree(&stack);
00906     return ret;
00907 }
00908 
00909 int dwarfargvalue(Dwarf *d, DwarfSym *proc, ulong pc, ulong cfa, PROSSYM_REGISTERS registers, DwarfParam *parameter)
00910 {
00911     int gotarg;
00912     DwarfSym unit = { };
00913 
00914     if (dwarfenumunit(d, proc->unit, &unit) == -1)
00915         return -1;
00916 
00917     werrstr("lookup in unit %x-%x, pc %x", unit.attrs.lowpc, unit.attrs.highpc, pc);
00918     pc -= unit.attrs.lowpc;
00919     
00920     werrstr("paramblock %s -> unit %x type %x fde %x len %d registers %x", 
00921             parameter->name, 
00922             parameter->unit, 
00923             parameter->type, 
00924             parameter->fde, 
00925             parameter->len, 
00926             registers);
00927 
00928     // Seek our range in loc
00929     DwarfBuf locbuf;
00930     DwarfBuf instream = { };
00931 
00932     locbuf.d = d;
00933     locbuf.addrsize = d->addrsize;
00934     
00935     if (parameter->loctype == TConstant) {
00936         locbuf.p = d->loc.data + parameter->fde;
00937         locbuf.ep = d->loc.data + d->loc.len;
00938         ulong start, end, len;
00939         do {
00940             len = 0;
00941             start = dwarfget4(&locbuf);
00942             end = dwarfget4(&locbuf);
00943             if (start && end) {
00944                 len = dwarfget2(&locbuf);
00945                 instream = locbuf;
00946                 instream.ep = instream.p + len;
00947                 locbuf.p = instream.ep;
00948             }
00949             werrstr("ip %x s %x e %x (%x bytes)", pc, start, end, len);
00950         } while (start && end && (start > pc || end <= pc));
00951     } else if (parameter->loctype == TBlock) {
00952         instream = locbuf;
00953         instream.p = (void *)parameter->fde;
00954         instream.ep = instream.p + parameter->len;
00955     } else {
00956         werrstr("Wrong block type for parameter %s", parameter->name);
00957         return -1;
00958     }
00959 
00960     gotarg = dwarfgetarg(d, parameter->name, &instream, cfa, registers, &parameter->value);
00961     if (gotarg == -1)
00962         return -1;
00963     
00964     return 0;
00965 }
00966 
00967 void
00968 dwarfdumpsym(Dwarf *d, DwarfSym *s)
00969 {
00970     int j;
00971     werrstr("tag %x\n", s->attrs.tag);
00972     for (j = 0; plist[j].name; j++) {
00973         char *have = ((char*)&s->attrs) + plist[j].haveoff;
00974         char *attr = ((char*)&s->attrs) + plist[j].off;
00975         if (*have == TString) {
00976             char *str = *((char **)attr);
00977             werrstr("%s: %s\n", plist[j].namestr, str);
00978         } else if (*have == TReference) {
00979             DwarfVal *val = ((DwarfVal*)attr);
00980             werrstr("%s: %x:%x\n", plist[j].namestr, val->b.data, val->b.len);
00981         } else if (*have)
00982             werrstr("%s: (%x)\n", plist[j].namestr, *have);
00983     }
00984 }
00985 
00986 int
00987 dwarfgetparams(Dwarf *d, DwarfSym *s, ulong pc, int pnum, DwarfParam *paramblocks)
00988 {
00989     int ip = 0;
00990     DwarfSym param = { };
00991     int res = dwarfnextsymat(d, s, &param);
00992     while (res == 0 && ip < pnum) {
00993         if (param.attrs.tag == TagFormalParameter &&
00994             param.attrs.have.name && 
00995             param.attrs.have.location) {
00996             paramblocks[ip].name = malloc(strlen(param.attrs.name)+1);
00997             strcpy(paramblocks[ip].name, param.attrs.name);
00998             paramblocks[ip].unit = param.unit;
00999             paramblocks[ip].type = param.attrs.type;
01000             paramblocks[ip].loctype = param.attrs.have.location;
01001             paramblocks[ip].len = param.attrs.location.b.len;
01002             paramblocks[ip].fde = (ulong)param.attrs.location.b.data;
01003             werrstr("param[%d] block %s -> type %x loctype %x fde %x len %x", 
01004                    ip, 
01005                    paramblocks[ip].name, 
01006                    paramblocks[ip].type,
01007                    paramblocks[ip].loctype, 
01008                    paramblocks[ip].fde,
01009                    paramblocks[ip].len);
01010             ip++;
01011         }
01012         res = dwarfnextsymat(d, s, &param);
01013     }
01014     return ip;
01015 }

Generated on Mon May 28 2012 04:36:11 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.