| 1 | // Copyright (c) 2013 Austin T. Clements. All rights reserved. |
| 2 | // Use of this source code is governed by an MIT license |
| 3 | // that can be found in the LICENSE file. |
| 4 | |
| 5 | #ifndef _DWARFPP_DW_HH_ |
| 6 | #define _DWARFPP_DW_HH_ |
| 7 | |
| 8 | #include <cstdint> |
| 9 | #include <string> |
| 10 | |
| 11 | DWARFPP_BEGIN_NAMESPACE |
| 12 | |
| 13 | // Integer representations (Section 7.26) |
| 14 | typedef std::int8_t sbyte; |
| 15 | typedef std::uint8_t ubyte; |
| 16 | typedef std::uint16_t uhalf; |
| 17 | typedef std::uint32_t uword; |
| 18 | |
| 19 | // Section offsets and lengths |
| 20 | typedef std::uint64_t section_offset; |
| 21 | typedef std::uint64_t section_length; |
| 22 | |
| 23 | // A target machine address. Targets may use smaller addresses; this |
| 24 | // represents the largest supported address type. |
| 25 | typedef std::uint64_t taddr; |
| 26 | |
| 27 | // DIE tags (Section 7, figure 18). typedef, friend, and namespace |
| 28 | // have a trailing underscore because they are reserved words. |
| 29 | enum class DW_TAG |
| 30 | { |
| 31 | array_type = 0x01, |
| 32 | class_type = 0x02, |
| 33 | entry_point = 0x03, |
| 34 | enumeration_type = 0x04, |
| 35 | formal_parameter = 0x05, |
| 36 | imported_declaration = 0x08, |
| 37 | label = 0x0a, |
| 38 | lexical_block = 0x0b, |
| 39 | member = 0x0d, |
| 40 | pointer_type = 0x0f, |
| 41 | reference_type = 0x10, |
| 42 | compile_unit = 0x11, |
| 43 | string_type = 0x12, |
| 44 | structure_type = 0x13, |
| 45 | subroutine_type = 0x15, |
| 46 | typedef_ = 0x16, |
| 47 | |
| 48 | union_type = 0x17, |
| 49 | unspecified_parameters = 0x18, |
| 50 | variant = 0x19, |
| 51 | common_block = 0x1a, |
| 52 | common_inclusion = 0x1b, |
| 53 | inheritance = 0x1c, |
| 54 | inlined_subroutine = 0x1d, |
| 55 | module = 0x1e, |
| 56 | ptr_to_member_type = 0x1f, |
| 57 | set_type = 0x20, |
| 58 | subrange_type = 0x21, |
| 59 | with_stmt = 0x22, |
| 60 | access_declaration = 0x23, |
| 61 | base_type = 0x24, |
| 62 | catch_block = 0x25, |
| 63 | const_type = 0x26, |
| 64 | constant = 0x27, |
| 65 | enumerator = 0x28, |
| 66 | file_type = 0x29, |
| 67 | friend_ = 0x2a, |
| 68 | |
| 69 | namelist = 0x2b, |
| 70 | namelist_item = 0x2c, |
| 71 | packed_type = 0x2d, |
| 72 | subprogram = 0x2e, |
| 73 | template_type_parameter = 0x2f, |
| 74 | template_value_parameter = 0x30, |
| 75 | thrown_type = 0x31, |
| 76 | try_block = 0x32, |
| 77 | variant_part = 0x33, |
| 78 | variable = 0x34, |
| 79 | volatile_type = 0x35, |
| 80 | dwarf_procedure = 0x36, |
| 81 | restrict_type = 0x37, |
| 82 | interface_type = 0x38, |
| 83 | namespace_ = 0x39, |
| 84 | imported_module = 0x3a, |
| 85 | unspecified_type = 0x3b, |
| 86 | partial_unit = 0x3c, |
| 87 | imported_unit = 0x3d, |
| 88 | condition = 0x3f, |
| 89 | |
| 90 | shared_type = 0x40, |
| 91 | type_unit = 0x41, |
| 92 | rvalue_reference_type = 0x42, |
| 93 | template_alias = 0x43, |
| 94 | lo_user = 0x4080, |
| 95 | hi_user = 0xffff, |
| 96 | }; |
| 97 | |
| 98 | std::string |
| 99 | to_string(DW_TAG v); |
| 100 | |
| 101 | // Child determination (Section 7, figure 19). |
| 102 | enum class DW_CHILDREN : ubyte |
| 103 | { |
| 104 | no = 0x00, |
| 105 | yes = 0x01, |
| 106 | }; |
| 107 | |
| 108 | std::string |
| 109 | to_string(DW_CHILDREN v); |
| 110 | |
| 111 | // Attribute names (Section 7, figure 20). inline, friend, mutable, |
| 112 | // and explicit have a trailing underscore because they are reserved |
| 113 | // words. |
| 114 | enum class DW_AT |
| 115 | { |
| 116 | sibling = 0x01, // reference |
| 117 | location = 0x02, // exprloc, loclistptr |
| 118 | name = 0x03, // string |
| 119 | ordering = 0x09, // constant |
| 120 | byte_size = 0x0b, // constant, exprloc, reference |
| 121 | bit_offset = 0x0c, // constant, exprloc, reference |
| 122 | bit_size = 0x0d, // constant, exprloc, reference |
| 123 | stmt_list = 0x10, // lineptr |
| 124 | low_pc = 0x11, // address |
| 125 | high_pc = 0x12, // address, constant |
| 126 | language = 0x13, // constant |
| 127 | discr = 0x15, // reference |
| 128 | discr_value = 0x16, // constant |
| 129 | visibility = 0x17, // constant |
| 130 | import = 0x18, // reference |
| 131 | string_length = 0x19, // exprloc, loclistptr |
| 132 | common_reference = 0x1a, // reference |
| 133 | comp_dir = 0x1b, // string |
| 134 | const_value = 0x1c, // block, constant, string |
| 135 | |
| 136 | containing_type = 0x1d, // reference |
| 137 | default_value = 0x1e, // reference |
| 138 | inline_ = 0x20, // constant |
| 139 | is_optional = 0x21, // flag |
| 140 | lower_bound = 0x22, // constant, exprloc, reference |
| 141 | producer = 0x25, // string |
| 142 | prototyped = 0x27, // flag |
| 143 | return_addr = 0x2a, // exprloc, loclistptr |
| 144 | start_scope = 0x2c, // constant, rangelistptr |
| 145 | bit_stride = 0x2e, // constant, exprloc, reference |
| 146 | upper_bound = 0x2f, // constant, exprloc, reference |
| 147 | abstract_origin = 0x31, // reference |
| 148 | accessibility = 0x32, // constant |
| 149 | address_class = 0x33, // constant |
| 150 | artificial = 0x34, // flag |
| 151 | base_types = 0x35, // reference |
| 152 | calling_convention = 0x36, // constant |
| 153 | count = 0x37, // constant, exprloc, reference |
| 154 | data_member_location = 0x38, // constant, exprloc, loclistptr |
| 155 | decl_column = 0x39, // constant |
| 156 | |
| 157 | decl_file = 0x3a, // constant |
| 158 | decl_line = 0x3b, // constant |
| 159 | declaration = 0x3c, // flag |
| 160 | discr_list = 0x3d, // block |
| 161 | encoding = 0x3e, // constant |
| 162 | external = 0x3f, // flag |
| 163 | frame_base = 0x40, // exprloc, loclistptr |
| 164 | friend_ = 0x41, // reference |
| 165 | identifier_case = 0x42, // constant |
| 166 | macro_info = 0x43, // macptr |
| 167 | namelist_item = 0x44, // reference |
| 168 | priority = 0x45, // reference |
| 169 | segment = 0x46, // exprloc, loclistptr |
| 170 | specification = 0x47, // reference |
| 171 | static_link = 0x48, // exprloc, loclistptr |
| 172 | type = 0x49, // reference |
| 173 | use_location = 0x4a, // exprloc, loclistptr |
| 174 | variable_parameter = 0x4b, // flag |
| 175 | virtuality = 0x4c, // constant |
| 176 | vtable_elem_location = 0x4d, // exprloc, loclistptr |
| 177 | |
| 178 | // DWARF 3 |
| 179 | allocated = 0x4e, // constant, exprloc, reference |
| 180 | associated = 0x4f, // constant, exprloc, reference |
| 181 | data_location = 0x50, // exprloc |
| 182 | byte_stride = 0x51, // constant, exprloc, reference |
| 183 | entry_pc = 0x52, // address |
| 184 | use_UTF8 = 0x53, // flag |
| 185 | extension = 0x54, // reference |
| 186 | ranges = 0x55, // rangelistptr |
| 187 | trampoline = 0x56, // address, flag, reference, string |
| 188 | call_column = 0x57, // constant |
| 189 | call_file = 0x58, // constant |
| 190 | call_line = 0x59, // constant |
| 191 | description = 0x5a, // string |
| 192 | binary_scale = 0x5b, // constant |
| 193 | decimal_scale = 0x5c, // constant |
| 194 | small = 0x5d, // reference |
| 195 | decimal_sign = 0x5e, // constant |
| 196 | digit_count = 0x5f, // constant |
| 197 | picture_string = 0x60, // string |
| 198 | mutable_ = 0x61, // flag |
| 199 | |
| 200 | threads_scaled = 0x62, // flag |
| 201 | explicit_ = 0x63, // flag |
| 202 | object_pointer = 0x64, // reference |
| 203 | endianity = 0x65, // constant |
| 204 | elemental = 0x66, // flag |
| 205 | pure = 0x67, // flag |
| 206 | recursive = 0x68, // flag |
| 207 | |
| 208 | // DWARF 4 |
| 209 | signature = 0x69, // reference |
| 210 | main_subprogram = 0x6a, // flag |
| 211 | data_bit_offset = 0x6b, // constant |
| 212 | const_expr = 0x6c, // flag |
| 213 | enum_class = 0x6d, // flag |
| 214 | linkage_name = 0x6e, // string |
| 215 | |
| 216 | lo_user = 0x2000, |
| 217 | hi_user = 0x3fff, |
| 218 | }; |
| 219 | |
| 220 | std::string |
| 221 | to_string(DW_AT v); |
| 222 | |
| 223 | // Attribute form encodings (Section 7, figure 21) |
| 224 | enum class DW_FORM |
| 225 | { |
| 226 | addr = 0x01, // address |
| 227 | block2 = 0x03, // block |
| 228 | block4 = 0x04, // block |
| 229 | data2 = 0x05, // constant |
| 230 | data4 = 0x06, // constant |
| 231 | data8 = 0x07, // constant |
| 232 | string = 0x08, // string |
| 233 | block = 0x09, // block |
| 234 | block1 = 0x0a, // block |
| 235 | data1 = 0x0b, // constant |
| 236 | flag = 0x0c, // flag |
| 237 | sdata = 0x0d, // constant |
| 238 | strp = 0x0e, // string |
| 239 | udata = 0x0f, // constant |
| 240 | ref_addr = 0x10, // reference |
| 241 | ref1 = 0x11, // reference |
| 242 | ref2 = 0x12, // reference |
| 243 | ref4 = 0x13, // reference |
| 244 | ref8 = 0x14, // reference |
| 245 | |
| 246 | ref_udata = 0x15, // reference |
| 247 | indirect = 0x16, // (Section 7.5.3) |
| 248 | |
| 249 | // DWARF 4 |
| 250 | sec_offset = 0x17, // lineptr, loclistptr, macptr, rangelistptr |
| 251 | exprloc = 0x18, // exprloc |
| 252 | flag_present = 0x19, // flag |
| 253 | ref_sig8 = 0x20, // reference |
| 254 | }; |
| 255 | |
| 256 | std::string |
| 257 | to_string(DW_FORM v); |
| 258 | |
| 259 | // DWARF operation encodings (Section 7.7.1 and figure 24) |
| 260 | enum class DW_OP : ubyte |
| 261 | { |
| 262 | addr = 0x03, // [constant address (size target specific)] |
| 263 | deref = 0x06, |
| 264 | |
| 265 | const1u = 0x08, // [1-byte constant] |
| 266 | const1s = 0x09, // [1-byte constant] |
| 267 | const2u = 0x0a, // [2-byte constant] |
| 268 | const2s = 0x0b, // [2-byte constant] |
| 269 | const4u = 0x0c, // [4-byte constant] |
| 270 | const4s = 0x0d, // [4-byte constant] |
| 271 | const8u = 0x0e, // [8-byte constant] |
| 272 | const8s = 0x0f, // [8-byte constant] |
| 273 | constu = 0x10, // [ULEB128 constant] |
| 274 | consts = 0x11, // [SLEB128 constant] |
| 275 | dup = 0x12, |
| 276 | drop = 0x13, |
| 277 | over = 0x14, |
| 278 | pick = 0x15, // [1-byte stack index] |
| 279 | swap = 0x16, |
| 280 | rot = 0x17, |
| 281 | xderef = 0x18, |
| 282 | abs = 0x19, |
| 283 | and_ = 0x1a, |
| 284 | div = 0x1b, |
| 285 | |
| 286 | minus = 0x1c, |
| 287 | mod = 0x1d, |
| 288 | mul = 0x1e, |
| 289 | neg = 0x1f, |
| 290 | not_ = 0x20, |
| 291 | or_ = 0x21, |
| 292 | plus = 0x22, |
| 293 | plus_uconst = 0x23, // [ULEB128 addend] |
| 294 | shl = 0x24, |
| 295 | shr = 0x25, |
| 296 | shra = 0x26, |
| 297 | xor_ = 0x27, |
| 298 | skip = 0x2f, // [signed 2-byte constant] |
| 299 | bra = 0x28, // [signed 2-byte constant] |
| 300 | eq = 0x29, |
| 301 | ge = 0x2a, |
| 302 | gt = 0x2b, |
| 303 | le = 0x2c, |
| 304 | lt = 0x2d, |
| 305 | ne = 0x2e, |
| 306 | |
| 307 | // Literals 0..31 = (lit0 + literal) |
| 308 | lit0 = 0x30, |
| 309 | lit31 = 0x4f, |
| 310 | |
| 311 | // Registers 0..31 = (reg0 + regnum) |
| 312 | reg0 = 0x50, |
| 313 | reg31 = 0x6f, |
| 314 | |
| 315 | // Base register 0..31 = (breg0 + regnum) |
| 316 | breg0 = 0x70, // [SLEB128 offset] |
| 317 | breg31 = 0x8f, // [SLEB128 offset] |
| 318 | |
| 319 | regx = 0x90, // [ULEB128 register] |
| 320 | fbreg = 0x91, // [SLEB128 offset] |
| 321 | bregx = 0x92, // [ULEB128 register, SLEB128 offset] |
| 322 | piece = 0x93, // [ULEB128 size of piece addressed] |
| 323 | deref_size = 0x94, // [1-byte size of data retrieved] |
| 324 | xderef_size = 0x95, // [1-byte size of data retrieved] |
| 325 | nop = 0x96, |
| 326 | |
| 327 | // DWARF 3 |
| 328 | push_object_address = 0x97, |
| 329 | call2 = 0x98, // [2-byte offset of DIE] |
| 330 | call4 = 0x99, // [4-byte offset of DIE] |
| 331 | call_ref = 0x9a, // [4- or 8-byte offset of DIE] |
| 332 | form_tls_address = 0x9b, |
| 333 | call_frame_cfa = 0x9c, |
| 334 | bit_piece = 0x9d, // [ULEB128 size, ULEB128 offset] |
| 335 | |
| 336 | // DWARF 4 |
| 337 | implicit_value = 0x9e, // [ULEB128 size, block of that size] |
| 338 | stack_value = 0x9f, |
| 339 | |
| 340 | lo_user = 0xe0, |
| 341 | hi_user = 0xff, |
| 342 | }; |
| 343 | |
| 344 | std::string |
| 345 | to_string(DW_OP v); |
| 346 | |
| 347 | // DW_AT::encoding constants (DWARF4 section 7.8 figure 25) |
| 348 | enum class DW_ATE |
| 349 | { |
| 350 | address = 0x01, |
| 351 | boolean = 0x02, |
| 352 | complex_float = 0x03, |
| 353 | float_ = 0x04, |
| 354 | signed_ = 0x05, |
| 355 | signed_char = 0x06, |
| 356 | unsigned_ = 0x07, |
| 357 | unsigned_char = 0x08, |
| 358 | imaginary_float = 0x09, |
| 359 | packed_decimal = 0x0a, |
| 360 | numeric_string = 0x0b, |
| 361 | edited = 0x0c, |
| 362 | signed_fixed = 0x0d, |
| 363 | unsigned_fixed = 0x0e, |
| 364 | decimal_float = 0x0f, |
| 365 | |
| 366 | // DWARF 4 |
| 367 | UTF = 0x10, |
| 368 | |
| 369 | lo_user = 0x80, |
| 370 | hi_user = 0xff, |
| 371 | }; |
| 372 | |
| 373 | std::string |
| 374 | to_string(DW_ATE v); |
| 375 | |
| 376 | // DW_AT::decimal_sign constants (DWARF4 section 7.8 figure 26) |
| 377 | enum class DW_DS |
| 378 | { |
| 379 | unsigned_ = 0x01, |
| 380 | leading_overpunch = 0x02, |
| 381 | trailing_overpunch = 0x03, |
| 382 | leading_separate = 0x04, |
| 383 | trailing_separate = 0x05, |
| 384 | }; |
| 385 | |
| 386 | std::string |
| 387 | to_string(DW_DS v); |
| 388 | |
| 389 | // DW_AT::endianity constants (DWARF4 section 7.8 figure 27) |
| 390 | enum class DW_END |
| 391 | { |
| 392 | default_ = 0x00, |
| 393 | big = 0x01, |
| 394 | little = 0x02, |
| 395 | lo_user = 0x40, |
| 396 | hi_user = 0xff, |
| 397 | }; |
| 398 | |
| 399 | std::string |
| 400 | to_string(DW_END v); |
| 401 | |
| 402 | // DW_AT::accessibility constants (DWARF4 section 7.9 figure 28) |
| 403 | enum class DW_ACCESS |
| 404 | { |
| 405 | public_ = 0x01, |
| 406 | protected_ = 0x02, |
| 407 | private_ = 0x03, |
| 408 | }; |
| 409 | |
| 410 | std::string |
| 411 | to_string(DW_ACCESS v); |
| 412 | |
| 413 | // DW_AT::visibility constants (DWARF4 section 7.10 figure 29) |
| 414 | enum class DW_VIS |
| 415 | { |
| 416 | local = 0x01, |
| 417 | exported = 0x02, |
| 418 | qualified = 0x03, |
| 419 | }; |
| 420 | |
| 421 | std::string |
| 422 | to_string(DW_VIS v); |
| 423 | |
| 424 | // DW_AT::virtuality constants (DWARF4 section 7.11 figure 30) |
| 425 | enum class DW_VIRTUALITY |
| 426 | { |
| 427 | none = 0x00, |
| 428 | virtual_ = 0x01, |
| 429 | pure_virtual = 0x02, |
| 430 | }; |
| 431 | |
| 432 | std::string |
| 433 | to_string(DW_VIRTUALITY v); |
| 434 | |
| 435 | // DW_AT::language constants (DWARF4 section 7.12 figure 31) |
| 436 | enum class DW_LANG |
| 437 | { |
| 438 | C89 = 0x0001, // Lower bound 0 |
| 439 | C = 0x0002, // Lower bound 0 |
| 440 | Ada83 = 0x0003, // Lower bound 1 |
| 441 | C_plus_plus = 0x0004, // Lower bound 0 |
| 442 | Cobol74 = 0x0005, // Lower bound 1 |
| 443 | Cobol85 = 0x0006, // Lower bound 1 |
| 444 | Fortran77 = 0x0007, // Lower bound 1 |
| 445 | Fortran90 = 0x0008, // Lower bound 1 |
| 446 | Pascal83 = 0x0009, // Lower bound 1 |
| 447 | Modula2 = 0x000a, // Lower bound 1 |
| 448 | Java = 0x000b, // Lower bound 0 |
| 449 | C99 = 0x000c, // Lower bound 0 |
| 450 | Ada95 = 0x000d, // Lower bound 1 |
| 451 | Fortran95 = 0x000e, // Lower bound 1 |
| 452 | PLI = 0x000f, // Lower bound 1 |
| 453 | |
| 454 | ObjC = 0x0010, // Lower bound 0 |
| 455 | ObjC_plus_plus = 0x0011, // Lower bound 0 |
| 456 | UPC = 0x0012, // Lower bound 0 |
| 457 | D = 0x0013, // Lower bound 0 |
| 458 | Python = 0x0014, // Lower bound 0 |
| 459 | lo_user = 0x8000, |
| 460 | hi_user = 0xffff, |
| 461 | }; |
| 462 | |
| 463 | std::string |
| 464 | to_string(DW_LANG v); |
| 465 | |
| 466 | // DW_AT::identifier_case constants (DWARF4 section 7.14 figure 32) |
| 467 | enum class DW_ID |
| 468 | { |
| 469 | case_sensitive = 0x00, |
| 470 | up_case = 0x01, |
| 471 | down_case = 0x02, |
| 472 | case_insensitive = 0x03, |
| 473 | }; |
| 474 | |
| 475 | std::string |
| 476 | to_string(DW_ID v); |
| 477 | |
| 478 | // DW_AT::calling_convention constants (DWARF4 section 7.15 figure 33) |
| 479 | enum class DW_CC |
| 480 | { |
| 481 | normal = 0x01, |
| 482 | program = 0x02, |
| 483 | nocall = 0x03, |
| 484 | lo_user = 0x40, |
| 485 | hi_user = 0xff, |
| 486 | }; |
| 487 | |
| 488 | std::string |
| 489 | to_string(DW_CC v); |
| 490 | |
| 491 | // DW_AT::inline constants (DWARF4 section 7.16 figure 34) |
| 492 | enum class DW_INL |
| 493 | { |
| 494 | not_inlined = 0x00, |
| 495 | inlined = 0x01, |
| 496 | declared_not_inlined = 0x02, |
| 497 | declared_inlined = 0x03, |
| 498 | }; |
| 499 | |
| 500 | std::string |
| 501 | to_string(DW_INL v); |
| 502 | |
| 503 | // DW_AT::ordering constants (DWARF4 section 7.17 figure 35) |
| 504 | enum class DW_ORD |
| 505 | { |
| 506 | row_major = 0x00, |
| 507 | col_major = 0x01, |
| 508 | }; |
| 509 | |
| 510 | std::string |
| 511 | to_string(DW_ORD v); |
| 512 | |
| 513 | // DW_AT::discr_list constants (DWARF4 section 7.18 figure 36) |
| 514 | enum class DW_DSC |
| 515 | { |
| 516 | label = 0x00, |
| 517 | range = 0x01, |
| 518 | }; |
| 519 | |
| 520 | std::string |
| 521 | to_string(DW_DSC v); |
| 522 | |
| 523 | // Line number standard opcodes (DWARF4 section 7.21 figure 37) |
| 524 | enum class DW_LNS |
| 525 | { |
| 526 | copy = 0x01, |
| 527 | advance_pc = 0x02, |
| 528 | advance_line = 0x03, |
| 529 | set_file = 0x04, |
| 530 | set_column = 0x05, |
| 531 | negate_stmt = 0x06, |
| 532 | set_basic_block = 0x07, |
| 533 | const_add_pc = 0x08, |
| 534 | fixed_advance_pc = 0x09, |
| 535 | |
| 536 | // DWARF 3 |
| 537 | set_prologue_end = 0x0a, |
| 538 | set_epilogue_begin = 0x0b, |
| 539 | set_isa = 0x0c, |
| 540 | }; |
| 541 | |
| 542 | std::string |
| 543 | to_string(DW_LNS v); |
| 544 | |
| 545 | // Line number extended opcodes (DWARF4 section 7.21 figure 38) |
| 546 | enum class DW_LNE |
| 547 | { |
| 548 | end_sequence = 0x01, |
| 549 | set_address = 0x02, |
| 550 | define_file = 0x03, |
| 551 | |
| 552 | // DWARF 4 |
| 553 | set_discriminator = 0x04, |
| 554 | |
| 555 | // DWARF 3 |
| 556 | lo_user = 0x80, |
| 557 | hi_user = 0xff, |
| 558 | }; |
| 559 | |
| 560 | std::string |
| 561 | to_string(DW_LNE v); |
| 562 | |
| 563 | DWARFPP_END_NAMESPACE |
| 564 | |
| 565 | #endif |
| 566 | |