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