1 #include "compat.h" 2 3 typedef struct Dwarf Dwarf; 4 typedef struct DwarfAttrs DwarfAttrs; 5 typedef struct DwarfBlock DwarfBlock; 6 typedef struct DwarfBuf DwarfBuf; 7 typedef struct DwarfExpr DwarfExpr; 8 typedef struct DwarfSym DwarfSym; 9 typedef struct DwarfStack DwarfStack; 10 typedef struct DwarfParam DwarfParam; 11 typedef union DwarfVal DwarfVal; 12 13 enum 14 { 15 TagArrayType = 0x01, 16 TagClassType = 0x02, 17 TagEntryPoint = 0x03, 18 TagEnumerationType = 0x04, 19 TagFormalParameter = 0x05, 20 TagImportedDeclaration = 0x08, 21 TagLabel = 0x0A, 22 TagLexDwarfBlock = 0x0B, 23 TagMember = 0x0D, 24 TagPointerType = 0x0F, 25 TagReferenceType = 0x10, 26 TagCompileUnit = 0x11, 27 TagStringType = 0x12, 28 TagStructType = 0x13, 29 TagSubroutineType = 0x15, 30 TagTypedef = 0x16, 31 TagUnionType = 0x17, 32 TagUnspecifiedParameters = 0x18, 33 TagVariant = 0x19, 34 TagCommonDwarfBlock = 0x1A, 35 TagCommonInclusion = 0x1B, 36 TagInheritance = 0x1C, 37 TagInlinedSubroutine = 0x1D, 38 TagModule = 0x1E, 39 TagPtrToMemberType = 0x1F, 40 TagSetType = 0x20, 41 TagSubrangeType = 0x21, 42 TagWithStmt = 0x22, 43 TagAccessDeclaration = 0x23, 44 TagBaseType = 0x24, 45 TagCatchDwarfBlock = 0x25, 46 TagConstType = 0x26, 47 TagConstant = 0x27, 48 TagEnumerator = 0x28, 49 TagFileType = 0x29, 50 TagFriend = 0x2A, 51 TagNamelist = 0x2B, 52 TagNamelistItem = 0x2C, 53 TagPackedType = 0x2D, 54 TagSubprogram = 0x2E, 55 TagTemplateTypeParameter = 0x2F, 56 TagTemplateValueParameter = 0x30, 57 TagThrownType = 0x31, 58 TagTryDwarfBlock = 0x32, 59 TagVariantPart = 0x33, 60 TagVariable = 0x34, 61 TagVolatileType = 0x35, 62 TagDwarfProcedure = 0x36, 63 TagRestrictType = 0x37, 64 TagInterfaceType = 0x38, 65 TagNamespace = 0x39, 66 TagImportedModule = 0x3A, 67 TagUnspecifiedType = 0x3B, 68 TagPartialUnit = 0x3C, 69 TagImportedUnit = 0x3D, 70 TagMutableType = 0x3E, 71 72 TypeAddress = 0x01, 73 TypeBoolean = 0x02, 74 TypeComplexFloat = 0x03, 75 TypeFloat = 0x04, 76 TypeSigned = 0x05, 77 TypeSignedChar = 0x06, 78 TypeUnsigned = 0x07, 79 TypeUnsignedChar = 0x08, 80 TypeImaginaryFloat = 0x09, 81 82 AccessPublic = 0x01, 83 AccessProtected = 0x02, 84 AccessPrivate = 0x03, 85 86 VisLocal = 0x01, 87 VisExported = 0x02, 88 VisQualified = 0x03, 89 90 VirtNone = 0x00, 91 VirtVirtual = 0x01, 92 VirtPureVirtual = 0x02, 93 94 LangC89 = 0x0001, 95 LangC = 0x0002, 96 LangAda83 = 0x0003, 97 LangCplusplus = 0x0004, 98 LangCobol74 = 0x0005, 99 LangCobol85 = 0x0006, 100 LangFortran77 = 0x0007, 101 LangFortran90 = 0x0008, 102 LangPascal83 = 0x0009, 103 LangModula2 = 0x000A, 104 LangJava = 0x000B, 105 LangC99 = 0x000C, 106 LangAda95 = 0x000D, 107 LangFortran95 = 0x000E, 108 LangPLI = 0x000F, 109 /* 0x8000-0xFFFF reserved */ 110 111 IdCaseSensitive = 0x00, 112 IdCaseUpper = 0x01, 113 IdCaseLower = 0x02, 114 IdCaseInsensitive = 0x03, 115 116 CallingNormal = 0x01, 117 CallingProgram = 0x02, 118 CallingNocall = 0x03, 119 /* 0x40-0xFF reserved */ 120 121 InNone = 0x00, 122 InInlined = 0x01, 123 InDeclaredNotInlined = 0x02, 124 InDeclaredInlined = 0x03, 125 126 OrderRowMajor = 0x00, 127 OrderColumnMajor = 0x01, 128 129 DiscLabel = 0x00, 130 DiscRange = 0x01, 131 132 TReference = 1<<0, 133 TBlock = 1<<1, 134 TConstant = 1<<2, 135 TString = 1<<3, 136 TFlag = 1<<4, 137 TAddress = 1<<5, 138 139 OpAddr = 0x03, /* 1 op, const addr */ 140 OpDeref = 0x06, 141 OpConst1u = 0x08, /* 1 op, 1 byte const */ 142 OpConst1s = 0x09, /* " signed */ 143 OpConst2u = 0x0A, /* 1 op, 2 byte const */ 144 OpConst2s = 0x0B, /* " signed */ 145 OpConst4u = 0x0C, /* 1 op, 4 byte const */ 146 OpConst4s = 0x0D, /* " signed */ 147 OpConst8u = 0x0E, /* 1 op, 8 byte const */ 148 OpConst8s = 0x0F, /* " signed */ 149 OpConstu = 0x10, /* 1 op, LEB128 const */ 150 OpConsts = 0x11, /* " signed */ 151 OpDup = 0x12, 152 OpDrop = 0x13, 153 OpOver = 0x14, 154 OpPick = 0x15, /* 1 op, 1 byte stack index */ 155 OpSwap = 0x16, 156 OpRot = 0x17, 157 OpXderef = 0x18, 158 OpAbs = 0x19, 159 OpAnd = 0x1A, 160 OpDiv = 0x1B, 161 OpMinus = 0x1C, 162 OpMod = 0x1D, 163 OpMul = 0x1E, 164 OpNeg = 0x1F, 165 OpNot = 0x20, 166 OpOr = 0x21, 167 OpPlus = 0x22, 168 OpPlusUconst = 0x23, /* 1 op, ULEB128 addend */ 169 OpShl = 0x24, 170 OpShr = 0x25, 171 OpShra = 0x26, 172 OpXor = 0x27, 173 OpSkip = 0x2F, /* 1 op, signed 2-byte constant */ 174 OpBra = 0x28, /* 1 op, signed 2-byte constant */ 175 OpEq = 0x29, 176 OpGe = 0x2A, 177 OpGt = 0x2B, 178 OpLe = 0x2C, 179 OpLt = 0x2D, 180 OpNe = 0x2E, 181 OpLit0 = 0x30, 182 /* OpLitN = OpLit0 + N for N = 0..31 */ 183 OpReg0 = 0x50, 184 /* OpRegN = OpReg0 + N for N = 0..31 */ 185 OpBreg0 = 0x70, /* 1 op, signed LEB128 constant */ 186 /* OpBregN = OpBreg0 + N for N = 0..31 */ 187 OpRegx = 0x90, /* 1 op, ULEB128 register */ 188 OpFbreg = 0x91, /* 1 op, SLEB128 offset */ 189 OpBregx = 0x92, /* 2 op, ULEB128 reg, SLEB128 off */ 190 OpPiece = 0x93, /* 1 op, ULEB128 size of piece */ 191 OpDerefSize = 0x94, /* 1-byte size of data retrieved */ 192 OpXderefSize = 0x95, /* 1-byte size of data retrieved */ 193 OpNop = 0x96, 194 /* next four new in Dwarf v3 */ 195 OpPushObjAddr = 0x97, 196 OpCall2 = 0x98, /* 2-byte offset of DIE */ 197 OpCall4 = 0x99, /* 4-byte offset of DIE */ 198 OpCallRef = 0x9A /* 4- or 8- byte offset of DIE */ 199 /* 0xE0-0xFF reserved for user-specific */ 200 }; 201 202 struct DwarfBlock 203 { 204 uchar *data; 205 ulong len; 206 }; 207 208 struct DwarfParam 209 { 210 char *name; 211 ulong unit; 212 ulong type; 213 ulong loctype; 214 ulong fde, len; 215 ulong value; 216 }; 217 218 /* not for consumer use */ 219 struct DwarfBuf 220 { 221 Dwarf *d; 222 uchar *p; 223 uchar *ep; 224 uint addrsize; 225 }; 226 227 union DwarfVal 228 { 229 char *s; 230 ulong c; 231 ulong r; 232 DwarfBlock b; 233 }; 234 235 struct DwarfAttrs 236 { 237 ulong tag; 238 uchar haskids; 239 240 /* whether we have it, along with type */ 241 struct { 242 uchar abstractorigin; 243 uchar accessibility; 244 uchar addrclass; 245 uchar basetypes; 246 uchar bitoffset; 247 uchar bitsize; 248 uchar bytesize; 249 uchar calling; 250 uchar commonref; 251 uchar compdir; 252 uchar constvalue; 253 uchar containingtype; 254 uchar count; 255 uchar datamemberloc; 256 uchar declcolumn; 257 uchar declfile; 258 uchar declline; 259 uchar defaultvalue; 260 uchar discr; 261 uchar discrlist; 262 uchar discrvalue; 263 uchar encoding; 264 uchar framebase; 265 uchar friend; 266 uchar highpc; 267 uchar entrypc; 268 uchar identifiercase; 269 uchar import; 270 uchar inlined; 271 uchar isartificial; 272 uchar isdeclaration; 273 uchar isexternal; 274 uchar isoptional; 275 uchar isprototyped; 276 uchar isvarparam; 277 uchar language; 278 uchar location; 279 uchar lowerbound; 280 uchar lowpc; 281 uchar macroinfo; 282 uchar name; 283 uchar namelistitem; 284 uchar ordering; 285 uchar priority; 286 uchar producer; 287 uchar ranges; 288 uchar returnaddr; 289 uchar segment; 290 uchar sibling; 291 uchar specification; 292 uchar startscope; 293 uchar staticlink; 294 uchar stmtlist; 295 uchar stridesize; 296 uchar stringlength; 297 uchar type; 298 uchar upperbound; 299 uchar uselocation; 300 uchar virtuality; 301 uchar visibility; 302 uchar vtableelemloc; 303 } have; 304 305 ulong abstractorigin; 306 ulong accessibility; 307 ulong addrclass; 308 ulong basetypes; 309 ulong bitoffset; 310 ulong bitsize; 311 ulong bytesize; 312 ulong calling; 313 ulong commonref; 314 char* compdir; 315 DwarfVal constvalue; 316 ulong containingtype; 317 ulong count; 318 DwarfVal datamemberloc; 319 ulong declcolumn; 320 ulong declfile; 321 ulong declline; 322 ulong defaultvalue; 323 ulong discr; 324 DwarfBlock discrlist; 325 ulong discrvalue; 326 ulong encoding; 327 DwarfVal framebase; 328 ulong friend; 329 ulong highpc; 330 ulong entrypc; 331 ulong identifiercase; 332 ulong import; 333 ulong inlined; 334 uchar isartificial; 335 uchar isdeclaration; 336 uchar isexternal; 337 uchar isoptional; 338 uchar isprototyped; 339 uchar isvarparam; 340 ulong language; 341 DwarfVal location; 342 ulong lowerbound; 343 ulong lowpc; 344 ulong macroinfo; 345 char* name; 346 DwarfBlock namelistitem; 347 ulong ordering; 348 ulong priority; 349 char* producer; 350 ulong ranges; 351 DwarfVal returnaddr; 352 DwarfVal segment; 353 ulong sibling; 354 ulong specification; 355 ulong startscope; 356 DwarfVal staticlink; 357 ulong stmtlist; 358 ulong stridesize; 359 DwarfVal stringlength; 360 ulong type; 361 ulong upperbound; 362 DwarfVal uselocation; 363 ulong virtuality; 364 ulong visibility; 365 DwarfVal vtableelemloc; 366 }; 367 368 enum 369 { 370 RuleUndef, 371 RuleSame, 372 RuleCfaOffset, 373 RuleRegister, 374 RuleRegOff, 375 RuleLocation 376 }; 377 struct DwarfExpr 378 { 379 int type; 380 long offset; 381 ulong reg; 382 DwarfBlock loc; 383 }; 384 385 struct DwarfSym 386 { 387 DwarfAttrs attrs; 388 389 /* not for consumer use... */ 390 uint num; 391 DwarfBuf b; 392 int depth; 393 ulong unit, childoff, nextunit; 394 ulong aoff; 395 }; 396 397 struct _Pe; 398 Dwarf *dwarfopen(struct _Pe *elf); 399 void dwarfclose(Dwarf*); 400 int dwarfaddrtounit(Dwarf*, ulong, ulong*); 401 int dwarflookupfn(Dwarf*, ulong, ulong, DwarfSym*); 402 int dwarflookupname(Dwarf*, char*, DwarfSym*); 403 int dwarflookupnameinunit(Dwarf*, ulong, char*, DwarfSym*); 404 int dwarflookupsubname(Dwarf*, DwarfSym*, char*, DwarfSym*); 405 int dwarflookuptag(Dwarf*, ulong, ulong, DwarfSym*); 406 int dwarfenumunit(Dwarf*, ulong, DwarfSym*); 407 int dwarfseeksym(Dwarf*, ulong, ulong, DwarfSym*); 408 int dwarfenum(Dwarf*, DwarfSym*); 409 int dwarfnextsym(Dwarf*, DwarfSym*); 410 int dwarfnextsymat(Dwarf*, DwarfSym *parent, DwarfSym *child); 411 int dwarfpctoline(Dwarf*, DwarfSym *proc, ulong, char**, char**, ulong *); 412 int dwarfgetarg(Dwarf *d, const char *name, DwarfBuf *locbuf, ulong cfa, PROSSYM_REGISTERS registers, ulong *value); 413 int dwarfgettype(Dwarf *d, DwarfSym *param, DwarfSym *type); 414 415 ulong dwarfget1(DwarfBuf*); 416 ulong dwarfget2(DwarfBuf*); 417 ulong dwarfget4(DwarfBuf*); 418 uvlong dwarfget8(DwarfBuf*); 419 ulong dwarfget128(DwarfBuf*); 420 long dwarfget128s(DwarfBuf*); 421 ulong dwarfgetaddr(DwarfBuf*); 422 int dwarfgetn(DwarfBuf*, uchar*, int); 423 uchar *dwarfgetnref(DwarfBuf*, ulong); 424 char *dwarfgetstring(DwarfBuf*); 425 int dwarfcomputecfa(Dwarf *d, DwarfExpr *cfa, PROSSYM_REGISTERS registers, ulong *cfaLocation); 426 int dwarfregunwind(Dwarf *d, ulong pc, ulong fde, DwarfExpr *cfa, PROSSYM_REGISTERS registers); 427 int dwarfargvalue(Dwarf *d, DwarfSym *proc, ulong pc, ulong cfa, PROSSYM_REGISTERS registers, DwarfParam *parameters); 428 int dwarfgetparams(Dwarf *d, DwarfSym *s, ulong pc, int pnum, DwarfParam *paramblocks); 429 430 typedef struct DwarfAbbrev DwarfAbbrev; 431 typedef struct DwarfAttr DwarfAttr; 432 433 struct DwarfAttr 434 { 435 ulong name; 436 ulong form; 437 }; 438 439 struct DwarfAbbrev 440 { 441 ulong num; 442 ulong tag; 443 uchar haskids; 444 DwarfAttr *attr; 445 int nattr; 446 }; 447 448 struct _Pe; 449 450 struct Dwarf 451 { 452 struct _Pe *pe; 453 454 char **reg; 455 int nreg; 456 int addrsize; 457 DwarfBlock abbrev; 458 DwarfBlock aranges; 459 DwarfBlock frame; 460 DwarfBlock info; 461 DwarfBlock line; 462 DwarfBlock pubnames; 463 DwarfBlock pubtypes; 464 DwarfBlock ranges; 465 DwarfBlock str; 466 DwarfBlock loc; 467 468 /* little cache */ 469 struct { 470 DwarfAbbrev *a; 471 int na; 472 ulong off; 473 } acache; 474 }; 475 476 struct DwarfStack 477 { 478 ulong storage[16]; // own storage 479 ulong *data; 480 ulong length, max; 481 }; 482 483 DwarfAbbrev *dwarfgetabbrev(Dwarf*, ulong, ulong); 484 485 int dwarfgetinfounit(Dwarf*, ulong, DwarfBlock*); 486 void dwarfdumpsym(Dwarf *d, DwarfSym *s); 487 488 #define MAXIMUM_DWARF_NAME_SIZE 64 489