URI:
       tdwarfinfo.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tdwarfinfo.c (15367B)
       ---
            1 /*
            2  * Dwarf info parse and search.
            3  */
            4 
            5 #include <u.h>
            6 #include <libc.h>
            7 #include <bio.h>
            8 #include "elf.h"
            9 #include "dwarf.h"
           10 
           11 enum
           12 {
           13         DwarfAttrSibling = 0x01,
           14         DwarfAttrLocation = 0x02,
           15         DwarfAttrName = 0x03,
           16         DwarfAttrOrdering = 0x09,
           17         DwarfAttrByteSize = 0x0B,
           18         DwarfAttrBitOffset = 0x0C,
           19         DwarfAttrBitSize = 0x0D,
           20         DwarfAttrStmtList = 0x10,
           21         DwarfAttrLowpc = 0x11,
           22         DwarfAttrHighpc = 0x12,
           23         DwarfAttrLanguage = 0x13,
           24         DwarfAttrDiscr = 0x15,
           25         DwarfAttrDiscrValue = 0x16,
           26         DwarfAttrVisibility = 0x17,
           27         DwarfAttrImport = 0x18,
           28         DwarfAttrStringLength = 0x19,
           29         DwarfAttrCommonRef = 0x1A,
           30         DwarfAttrCompDir = 0x1B,
           31         DwarfAttrConstValue = 0x1C,
           32         DwarfAttrContainingType = 0x1D,
           33         DwarfAttrDefaultValue = 0x1E,
           34         DwarfAttrInline = 0x20,
           35         DwarfAttrIsOptional = 0x21,
           36         DwarfAttrLowerBound = 0x22,
           37         DwarfAttrProducer = 0x25,
           38         DwarfAttrPrototyped = 0x27,
           39         DwarfAttrReturnAddr = 0x2A,
           40         DwarfAttrStartScope = 0x2C,
           41         DwarfAttrStrideSize = 0x2E,
           42         DwarfAttrUpperBound = 0x2F,
           43         DwarfAttrAbstractOrigin = 0x31,
           44         DwarfAttrAccessibility = 0x32,
           45         DwarfAttrAddrClass = 0x33,
           46         DwarfAttrArtificial = 0x34,
           47         DwarfAttrBaseTypes = 0x35,
           48         DwarfAttrCalling = 0x36,
           49         DwarfAttrCount = 0x37,
           50         DwarfAttrDataMemberLoc = 0x38,
           51         DwarfAttrDeclColumn = 0x39,
           52         DwarfAttrDeclFile = 0x3A,
           53         DwarfAttrDeclLine = 0x3B,
           54         DwarfAttrDeclaration = 0x3C,
           55         DwarfAttrDiscrList = 0x3D,
           56         DwarfAttrEncoding = 0x3E,
           57         DwarfAttrExternal = 0x3F,
           58         DwarfAttrFrameBase = 0x40,
           59         DwarfAttrFriend = 0x41,
           60         DwarfAttrIdentifierCase = 0x42,
           61         DwarfAttrMacroInfo = 0x43,
           62         DwarfAttrNamelistItem = 0x44,
           63         DwarfAttrPriority = 0x45,
           64         DwarfAttrSegment = 0x46,
           65         DwarfAttrSpecification = 0x47,
           66         DwarfAttrStaticLink = 0x48,
           67         DwarfAttrType = 0x49,
           68         DwarfAttrUseLocation = 0x4A,
           69         DwarfAttrVarParam = 0x4B,
           70         DwarfAttrVirtuality = 0x4C,
           71         DwarfAttrVtableElemLoc = 0x4D,
           72         DwarfAttrAllocated = 0x4E,
           73         DwarfAttrAssociated = 0x4F,
           74         DwarfAttrDataLocation = 0x50,
           75         DwarfAttrStride = 0x51,
           76         DwarfAttrEntrypc = 0x52,
           77         DwarfAttrUseUTF8 = 0x53,
           78         DwarfAttrExtension = 0x54,
           79         DwarfAttrRanges = 0x55,
           80         DwarfAttrTrampoline = 0x56,
           81         DwarfAttrCallColumn = 0x57,
           82         DwarfAttrCallFile = 0x58,
           83         DwarfAttrCallLine = 0x59,
           84         DwarfAttrDescription = 0x5A,
           85         DwarfAttrMax,
           86 
           87         FormAddr = 0x01,
           88         FormDwarfBlock2 = 0x03,
           89         FormDwarfBlock4 = 0x04,
           90         FormData2 = 0x05,
           91         FormData4 = 0x06,
           92         FormData8 = 0x07,
           93         FormString = 0x08,
           94         FormDwarfBlock = 0x09,
           95         FormDwarfBlock1 = 0x0A,
           96         FormData1 = 0x0B,
           97         FormFlag = 0x0C,
           98         FormSdata = 0x0D,
           99         FormStrp = 0x0E,
          100         FormUdata = 0x0F,
          101         FormRefAddr = 0x10,
          102         FormRef1 = 0x11,
          103         FormRef2 = 0x12,
          104         FormRef4 = 0x13,
          105         FormRef8 = 0x14,
          106         FormRefUdata = 0x15,
          107         FormIndirect = 0x16
          108 };
          109 
          110 static int parseattrs(DwarfBuf*, ulong, DwarfAbbrev*, DwarfAttrs*);
          111 static int getulong(DwarfBuf*, int, ulong, ulong*, int*);
          112 static int getuchar(DwarfBuf*, int, uchar*);
          113 static int getstring(DwarfBuf*, int, char**);
          114 static int getblock(DwarfBuf*, int, DwarfBlock*);
          115 static int skipform(DwarfBuf*, int);
          116 static int constblock(Dwarf*, DwarfBlock*, ulong*);
          117 
          118 int
          119 dwarflookupnameinunit(Dwarf *d, ulong unit, char *name, DwarfSym *s)
          120 {
          121         if(dwarfenumunit(d, unit, s) < 0)
          122                 return -1;
          123 
          124         dwarfnextsymat(d, s, 0);        /* s is now the CompileUnit */
          125         while(dwarfnextsymat(d, s, 1) == 1)
          126                 if(s->attrs.name && strcmp(s->attrs.name, name) == 0)
          127                         return 0;
          128         werrstr("symbol '%s' not found", name);
          129         return -1;
          130 }
          131 
          132 
          133 int
          134 dwarflookupsubname(Dwarf *d, DwarfSym *parent, char *name, DwarfSym *s)
          135 {
          136         *s = *parent;
          137         while(dwarfnextsymat(d, s, parent->depth+1))
          138                 if(s->attrs.name && strcmp(s->attrs.name, name) == 0)
          139                         return 0;
          140         werrstr("symbol '%s' not found", name);
          141         return -1;
          142 }
          143 
          144 int
          145 dwarflookuptag(Dwarf *d, ulong unit, ulong tag, DwarfSym *s)
          146 {
          147         if(dwarfenumunit(d, unit, s) < 0)
          148                 return -1;
          149 
          150         dwarfnextsymat(d, s, 0);        /* s is now the CompileUnit */
          151         if(s->attrs.tag == tag)
          152                 return 0;
          153         while(dwarfnextsymat(d, s, 1) == 1)
          154                 if(s->attrs.tag == tag)
          155                         return 0;
          156         werrstr("symbol with tag 0x%lux not found", tag);
          157         return -1;
          158 }
          159 
          160 int
          161 dwarfseeksym(Dwarf *d, ulong unit, ulong off, DwarfSym *s)
          162 {
          163         if(dwarfenumunit(d, unit, s) < 0)
          164                 return -1;
          165         s->b.p = d->info.data + unit + off;
          166         if(dwarfnextsymat(d, s, 0) != 1)
          167                 return -1;
          168         return 0;
          169 }
          170 
          171 int
          172 dwarflookupfn(Dwarf *d, ulong unit, ulong pc, DwarfSym *s)
          173 {
          174         if(dwarfenumunit(d, unit, s) < 0)
          175                 return -1;
          176 
          177         if(dwarfnextsymat(d, s, 0) != 1)
          178                 return -1;
          179         /* s is now the CompileUnit */
          180 
          181         while(dwarfnextsymat(d, s, 1) == 1){
          182                 if(s->attrs.tag != TagSubprogram)
          183                         continue;
          184                 if(s->attrs.lowpc <= pc && pc < s->attrs.highpc)
          185                         return 0;
          186         }
          187         werrstr("fn containing pc 0x%lux not found", pc);
          188         return -1;
          189 }
          190 
          191 int
          192 dwarfenumunit(Dwarf *d, ulong unit, DwarfSym *s)
          193 {
          194         int i;
          195         ulong aoff, len;
          196 
          197         if(unit >= d->info.len){
          198                 werrstr("dwarf unit address 0x%lux >= 0x%lux out of range", unit, d->info.len);
          199                 return -1;
          200         }
          201         memset(s, 0, sizeof *s);
          202         memset(&s->b, 0, sizeof s->b);
          203         s->b.d = d;
          204         s->b.p = d->info.data + unit;
          205         s->b.ep = d->info.data + d->info.len;
          206         len = dwarfget4(&s->b);
          207         s->nextunit = unit + 4 + len;
          208 
          209         if(s->b.ep - s->b.p < len){
          210         badheader:
          211                 werrstr("bad dwarf unit header at unit 0x%lux", unit);
          212                 return -1;
          213         }
          214         s->b.ep = s->b.p+len;
          215         if((i=dwarfget2(&s->b)) != 2)
          216                 goto badheader;
          217         aoff = dwarfget4(&s->b);
          218         s->b.addrsize = dwarfget1(&s->b);
          219         if(d->addrsize == 0)
          220                 d->addrsize = s->b.addrsize;
          221         if(s->b.p == nil)
          222                 goto badheader;
          223 
          224         s->aoff = aoff;
          225         s->unit = unit;
          226         s->depth = 0;
          227         return 0;
          228 }
          229 
          230 int
          231 dwarfenum(Dwarf *d, DwarfSym *s)
          232 {
          233         if(dwarfenumunit(d, 0, s) < 0)
          234                 return -1;
          235         s->allunits = 1;
          236         return 0;
          237 }
          238 
          239 int
          240 dwarfnextsym(Dwarf *d, DwarfSym *s)
          241 {
          242         ulong num;
          243         DwarfAbbrev *a;
          244 
          245         if(s->attrs.haskids)
          246                 s->depth++;
          247 top:
          248         if(s->b.p >= s->b.ep){
          249                 if(s->allunits && s->nextunit < d->info.len){
          250                         if(dwarfenumunit(d, s->nextunit, s) < 0)
          251                                 return -1;
          252                         s->allunits = 1;
          253                         goto top;
          254                 }
          255                 return 0;
          256         }
          257 
          258         s->uoff = s->b.p - (d->info.data+s->unit);
          259         num = dwarfget128(&s->b);
          260         if(num == 0){
          261                 if(s->depth == 0)
          262                         return 0;
          263                 if(s->depth > 0)
          264                         s->depth--;
          265                 goto top;
          266         }
          267 
          268         a = dwarfgetabbrev(d, s->aoff, num);
          269         if(a == nil){
          270                 fprint(2, "getabbrev %ud %ud for %ud,%ud: %r\n", s->aoff, num, s->unit, s->uoff);
          271                 abort();
          272                 return -1;
          273         }
          274         if(parseattrs(&s->b, s->unit, a, &s->attrs) < 0)
          275                 return -1;
          276         return 1;
          277 }
          278 
          279 int
          280 dwarfnextsymat(Dwarf *d, DwarfSym *s, int depth)
          281 {
          282         int r;
          283         DwarfSym t;
          284         uint sib;
          285 
          286         if(s->depth == depth && s->attrs.have.sibling){
          287                 sib = s->attrs.sibling;
          288                 if(sib < d->info.len && d->info.data+sib >= s->b.p)
          289                         s->b.p = d->info.data+sib;
          290                 s->attrs.haskids = 0;
          291         }
          292 
          293         /*
          294          * The funny game with t and s make sure that
          295          * if we get to the end of a run of a particular
          296          * depth, we leave s so that a call to nextsymat with depth-1
          297          * will actually produce the desired guy.  We could change
          298          * the interface to dwarfnextsym instead, but I'm scared
          299          * to touch it.
          300          */
          301         t = *s;
          302         for(;;){
          303                 if((r = dwarfnextsym(d, &t)) != 1)
          304                         return r;
          305                 if(t.depth < depth){
          306                         /* went too far - nothing to see */
          307                         return 0;
          308                 }
          309                 *s = t;
          310                 if(t.depth == depth)
          311                         return 1;
          312         }
          313 }
          314 
          315 typedef struct Parse Parse;
          316 struct Parse {
          317         int name;
          318         int off;
          319         int haveoff;
          320         int type;
          321 };
          322 
          323 #define OFFSET(x) offsetof(DwarfAttrs, x), offsetof(DwarfAttrs, have.x)
          324 
          325 static Parse plist[] = {        /* Font Tab 4 */
          326         DwarfAttrAbstractOrigin,        OFFSET(abstractorigin),                TReference,
          327         DwarfAttrAccessibility,        OFFSET(accessibility),                TConstant,
          328         DwarfAttrAddrClass,                 OFFSET(addrclass),                         TConstant,
          329         DwarfAttrArtificial,                OFFSET(isartificial),                 TFlag,
          330         DwarfAttrBaseTypes,                OFFSET(basetypes),                        TReference,
          331         DwarfAttrBitOffset,                OFFSET(bitoffset),                        TConstant,
          332         DwarfAttrBitSize,                OFFSET(bitsize),                        TConstant,
          333         DwarfAttrByteSize,                OFFSET(bytesize),                        TConstant,
          334         DwarfAttrCalling,                OFFSET(calling),                        TConstant,
          335         DwarfAttrCommonRef,                OFFSET(commonref),                        TReference,
          336         DwarfAttrCompDir,                OFFSET(compdir),                        TString,
          337         DwarfAttrConstValue,                OFFSET(constvalue),                        TString|TConstant|TBlock,
          338         DwarfAttrContainingType,        OFFSET(containingtype),                TReference,
          339         DwarfAttrCount,                        OFFSET(count),                                TConstant|TReference,
          340         DwarfAttrDataMemberLoc,        OFFSET(datamemberloc),                TBlock|TConstant|TReference,
          341         DwarfAttrDeclColumn,                OFFSET(declcolumn),                        TConstant,
          342         DwarfAttrDeclFile,                OFFSET(declfile),                        TConstant,
          343         DwarfAttrDeclLine,                OFFSET(declline),                        TConstant,
          344         DwarfAttrDeclaration,        OFFSET(isdeclaration),                TFlag,
          345         DwarfAttrDefaultValue,        OFFSET(defaultvalue),                TReference,
          346         DwarfAttrDiscr,                        OFFSET(discr),                                TReference,
          347         DwarfAttrDiscrList,                OFFSET(discrlist),                        TBlock,
          348         DwarfAttrDiscrValue,                OFFSET(discrvalue),                        TConstant,
          349         DwarfAttrEncoding,                OFFSET(encoding),                        TConstant,
          350         DwarfAttrExternal,                OFFSET(isexternal),                        TFlag,
          351         DwarfAttrFrameBase,                OFFSET(framebase),                        TBlock|TConstant,
          352         DwarfAttrFriend,                        OFFSET(friend),                                TReference,
          353         DwarfAttrHighpc,                        OFFSET(highpc),                                TAddress,
          354         DwarfAttrIdentifierCase,        OFFSET(identifiercase),                TConstant,
          355         DwarfAttrImport,                        OFFSET(import),                                TReference,
          356         DwarfAttrInline,                        OFFSET(inlined),                        TConstant,
          357         DwarfAttrIsOptional,                OFFSET(isoptional),                        TFlag,
          358         DwarfAttrLanguage,                OFFSET(language),                        TConstant,
          359         DwarfAttrLocation,                OFFSET(location),                        TBlock|TConstant,
          360         DwarfAttrLowerBound,                OFFSET(lowerbound),                        TConstant|TReference,
          361         DwarfAttrLowpc,                        OFFSET(lowpc),                                TAddress,
          362         DwarfAttrMacroInfo,                OFFSET(macroinfo),                        TConstant,
          363         DwarfAttrName,                        OFFSET(name),                                TString,
          364         DwarfAttrNamelistItem,        OFFSET(namelistitem),                TBlock,
          365         DwarfAttrOrdering,                 OFFSET(ordering),                        TConstant,
          366         DwarfAttrPriority,                OFFSET(priority),                        TReference,
          367         DwarfAttrProducer,                OFFSET(producer),                        TString,
          368         DwarfAttrPrototyped,                OFFSET(isprototyped),                TFlag,
          369         DwarfAttrRanges,                        OFFSET(ranges),                                TReference,
          370         DwarfAttrReturnAddr,                OFFSET(returnaddr),                        TBlock|TConstant,
          371         DwarfAttrSegment,                OFFSET(segment),                        TBlock|TConstant,
          372         DwarfAttrSibling,                OFFSET(sibling),                        TReference,
          373         DwarfAttrSpecification,        OFFSET(specification),                TReference,
          374         DwarfAttrStartScope,                OFFSET(startscope),                        TConstant,
          375         DwarfAttrStaticLink,                OFFSET(staticlink),                        TBlock|TConstant,
          376         DwarfAttrStmtList,                OFFSET(stmtlist),                        TConstant,
          377         DwarfAttrStrideSize,                OFFSET(stridesize),                        TConstant,
          378         DwarfAttrStringLength,        OFFSET(stringlength),                TBlock|TConstant,
          379         DwarfAttrType,                        OFFSET(type),                                TReference,
          380         DwarfAttrUpperBound,                OFFSET(upperbound),                        TConstant|TReference,
          381         DwarfAttrUseLocation,        OFFSET(uselocation),                TBlock|TConstant,
          382         DwarfAttrVarParam,                OFFSET(isvarparam),                        TFlag,
          383         DwarfAttrVirtuality,                OFFSET(virtuality),                        TConstant,
          384         DwarfAttrVisibility,                OFFSET(visibility),                        TConstant,
          385         DwarfAttrVtableElemLoc,        OFFSET(vtableelemloc),                TBlock|TReference,
          386 };
          387 
          388 static Parse ptab[DwarfAttrMax];
          389 
          390 static int
          391 parseattrs(DwarfBuf *b, ulong unit, DwarfAbbrev *a, DwarfAttrs *attrs)
          392 {
          393         int i, f, n, got;
          394         static int nbad;
          395         void *v;
          396 
          397         /* initialize ptab first time through for quick access */
          398         if(ptab[DwarfAttrName].name != DwarfAttrName)
          399                 for(i=0; i<nelem(plist); i++)
          400                         ptab[plist[i].name] = plist[i];
          401 
          402         memset(attrs, 0, sizeof *attrs);
          403         attrs->tag = a->tag;
          404         attrs->haskids = a->haskids;
          405 
          406         for(i=0; i<a->nattr; i++){
          407                 n = a->attr[i].name;
          408                 f = a->attr[i].form;
          409                 if(n < 0 || n >= nelem(ptab) || ptab[n].name==0){
          410                         if(++nbad == 1)
          411                                 fprint(2, "dwarf parse attrs: unexpected attribute name 0x%ux\n", n);
          412                         return -1;
          413                 }
          414                 v = (char*)attrs + ptab[n].off;
          415                 got = 0;
          416                 if(f == FormIndirect)
          417                         f = dwarfget128(b);
          418                 if((ptab[n].type&(TConstant|TReference|TAddress))
          419                 && getulong(b, f, unit, v, &got) >= 0)
          420                         ;
          421                 else if((ptab[n].type&TFlag) && getuchar(b, f, v) >= 0)
          422                         got = TFlag;
          423                 else if((ptab[n].type&TString) && getstring(b, f, v) >= 0)
          424                         got = TString;
          425                 else if((ptab[n].type&TBlock) && getblock(b, f, v) >= 0)
          426                         got = TBlock;
          427                 else{
          428                         if(skipform(b, f) < 0){
          429                                 if(++nbad == 1)
          430                                         fprint(2, "dwarf parse attrs: cannot skip form %d\n", f);
          431                                 return -1;
          432                         }
          433                 }
          434                 if(got == TBlock && (ptab[n].type&TConstant))
          435                         got = constblock(b->d, v, v);
          436                 *((uchar*)attrs+ptab[n].haveoff) = got;
          437         }
          438         return 0;
          439 }
          440 
          441 static int
          442 getulong(DwarfBuf *b, int form, ulong unit, ulong *u, int *type)
          443 {
          444         static int nbad;
          445         uvlong uv;
          446 
          447         switch(form){
          448         default:
          449                 return -1;
          450 
          451         /* addresses */
          452         case FormAddr:
          453                 *type = TAddress;
          454                 *u = dwarfgetaddr(b);
          455                 return 0;
          456 
          457         /* references */
          458         case FormRefAddr:
          459                 /* absolute ref in .debug_info */
          460                 *type = TReference;
          461                 *u = dwarfgetaddr(b);
          462                 return 0;
          463         case FormRef1:
          464                 *u = dwarfget1(b);
          465                 goto relativeref;
          466         case FormRef2:
          467                 *u = dwarfget2(b);
          468                 goto relativeref;
          469         case FormRef4:
          470                 *u = dwarfget4(b);
          471                 goto relativeref;
          472         case FormRef8:
          473                 *u = dwarfget8(b);
          474                 goto relativeref;
          475         case FormRefUdata:
          476                 *u = dwarfget128(b);
          477         relativeref:
          478                 *u += unit;
          479                 *type = TReference;
          480                 return 0;
          481 
          482         /* constants */
          483         case FormData1:
          484                 *u = dwarfget1(b);
          485                 goto constant;
          486         case FormData2:
          487                 *u = dwarfget2(b);
          488                 goto constant;
          489         case FormData4:
          490                 *u = dwarfget4(b);
          491                 goto constant;
          492         case FormData8:
          493                 uv = dwarfget8(b);
          494                 *u = uv;
          495                 if(uv != *u && ++nbad == 1)
          496                         fprint(2, "dwarf: truncating 64-bit attribute constants\n");
          497                 goto constant;
          498         case FormSdata:
          499                 *u = dwarfget128s(b);
          500                 goto constant;
          501         case FormUdata:
          502                 *u = dwarfget128(b);
          503         constant:
          504                 *type = TConstant;
          505                 return 0;
          506         }
          507 }
          508 
          509 static int
          510 getuchar(DwarfBuf *b, int form, uchar *u)
          511 {
          512         switch(form){
          513         default:
          514                 return -1;
          515 
          516         case FormFlag:
          517                 *u = dwarfget1(b);
          518                 return 0;
          519         }
          520 }
          521 
          522 static int
          523 getstring(DwarfBuf *b, int form, char **s)
          524 {
          525         static int nbad;
          526         ulong u;
          527 
          528         switch(form){
          529         default:
          530                 return -1;
          531 
          532         case FormString:
          533                 *s = dwarfgetstring(b);
          534                 return 0;
          535 
          536         case FormStrp:
          537                 u = dwarfget4(b);
          538                 if(u >= b->d->str.len){
          539                         if(++nbad == 1)
          540                                 fprint(2, "dwarf: bad string pointer 0x%lux in attribute\n", u);
          541                         /* don't return error - maybe can proceed */
          542                         *s = nil;
          543                 }else
          544                         *s = (char*)b->d->str.data + u;
          545                 return 0;
          546 
          547         }
          548 }
          549 
          550 static int
          551 getblock(DwarfBuf *b, int form, DwarfBlock *bl)
          552 {
          553         ulong n;
          554 
          555         switch(form){
          556         default:
          557                 return -1;
          558         case FormDwarfBlock:
          559                 n = dwarfget128(b);
          560                 goto copyn;
          561         case FormDwarfBlock1:
          562                 n = dwarfget1(b);
          563                 goto copyn;
          564         case FormDwarfBlock2:
          565                 n = dwarfget2(b);
          566                 goto copyn;
          567         case FormDwarfBlock4:
          568                 n = dwarfget4(b);
          569         copyn:
          570                 bl->data = dwarfgetnref(b, n);
          571                 bl->len = n;
          572                 if(bl->data == nil)
          573                         return -1;
          574                 return 0;
          575         }
          576 }
          577 
          578 static int
          579 constblock(Dwarf *d, DwarfBlock *bl, ulong *pval)
          580 {
          581         DwarfBuf b;
          582 
          583         memset(&b, 0, sizeof b);
          584         b.p = bl->data;
          585         b.ep = bl->data+bl->len;
          586         b.d = d;
          587 
          588         switch(dwarfget1(&b)){
          589         case OpAddr:
          590                 *pval = dwarfgetaddr(&b);
          591                 return TConstant;
          592         case OpConst1u:
          593                 *pval = dwarfget1(&b);
          594                 return TConstant;
          595         case OpConst1s:
          596                 *pval = (schar)dwarfget1(&b);
          597                 return TConstant;
          598         case OpConst2u:
          599                 *pval = dwarfget2(&b);
          600                 return TConstant;
          601         case OpConst2s:
          602                 *pval = (s16int)dwarfget2(&b);
          603                 return TConstant;
          604         case OpConst4u:
          605                 *pval = dwarfget4(&b);
          606                 return TConstant;
          607         case OpConst4s:
          608                 *pval = (s32int)dwarfget4(&b);
          609                 return TConstant;
          610         case OpConst8u:
          611                 *pval = (u64int)dwarfget8(&b);
          612                 return TConstant;
          613         case OpConst8s:
          614                 *pval = (s64int)dwarfget8(&b);
          615                 return TConstant;
          616         case OpConstu:
          617                 *pval = dwarfget128(&b);
          618                 return TConstant;
          619         case OpConsts:
          620                 *pval = dwarfget128s(&b);
          621                 return TConstant;
          622         case OpPlusUconst:
          623                 *pval = dwarfget128(&b);
          624                 return TConstant;
          625         default:
          626                 return TBlock;
          627         }
          628 }
          629 
          630 /* last resort */
          631 static int
          632 skipform(DwarfBuf *b, int form)
          633 {
          634         int type;
          635         DwarfVal val;
          636 
          637         if(getulong(b, form, 0, &val.c, &type) < 0
          638         && getuchar(b, form, (uchar*)&val) < 0
          639         && getstring(b, form, &val.s) < 0
          640         && getblock(b, form, &val.b) < 0)
          641                 return -1;
          642         return 0;
          643 }