17ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Copyright (C) 2007-2010 The Android Open Source Project 27ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine** 37ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine** This software is licensed under the terms of the GNU General Public 47ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine** License version 2, as published by the Free Software Foundation, and 57ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine** may be copied, distributed, and modified under those terms. 67ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine** 77ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine** This program is distributed in the hope that it will be useful, 87ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine** but WITHOUT ANY WARRANTY; without even the implied warranty of 97ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 107ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine** GNU General Public License for more details. 117ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine*/ 127ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 137ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* 147ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Contains declarations of types, constants and structures 157ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * describing DWARF format. 167ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 177ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 187ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine#ifndef ELFF_DWARF_DEFS_H_ 197ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine#define ELFF_DWARF_DEFS_H_ 207ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 217ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine#include "dwarf.h" 227ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine#include "elf_defs.h" 237ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 247ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* DWARF structures are packed to 1 byte. */ 257ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine#define ELFF_PACKED __attribute__ ((packed)) 267ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 277ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* 287ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Helper types for misc. DWARF variables. 297ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 307ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 317ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Type for DWARF abbreviation number. */ 327ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinetypedef uint32_t Dwarf_AbbrNum; 337ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 347ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Type for DWARF tag ID. */ 357ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinetypedef uint16_t Dwarf_Tag; 367ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 377ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Type for DWARF attribute ID. */ 387ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinetypedef uint16_t Dwarf_At; 397ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 407ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Type for DWARF form ID. */ 417ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinetypedef uint16_t Dwarf_Form; 427ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 437ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Type for offset in 32-bit DWARF. */ 447ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinetypedef uint32_t Dwarf32_Off; 457ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 467ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Type for offset in 64-bit DWARF. */ 477ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinetypedef uint64_t Dwarf64_Off; 487ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 497ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Enumerates types of values, obtained during DWARF attribute decoding. */ 507ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinetypedef enum DwarfValueType { 517ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Undefined */ 527ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine DWARF_VALUE_UNKNOWN = 1, 537ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 547ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* uint8_t */ 557ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine DWARF_VALUE_U8, 567ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 577ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* int8_t */ 587ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine DWARF_VALUE_S8, 597ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 607ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* uint16_t */ 617ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine DWARF_VALUE_U16, 627ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 637ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* int16_t */ 647ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine DWARF_VALUE_S16, 657ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 667ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* uint32_t */ 677ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine DWARF_VALUE_U32, 687ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 697ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* int32_t */ 707ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine DWARF_VALUE_S32, 717ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 727ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* uint64_t */ 737ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine DWARF_VALUE_U64, 747ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 757ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* int64_t */ 767ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine DWARF_VALUE_S64, 777ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 787ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* const char* */ 797ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine DWARF_VALUE_STR, 807ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 817ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* 32-bit address */ 827ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine DWARF_VALUE_PTR32, 837ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 847ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* 64-bit address */ 857ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine DWARF_VALUE_PTR64, 867ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 877ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Dwarf_Block */ 887ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine DWARF_VALUE_BLOCK, 897ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine} DwarfValueType; 907ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 917ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Describes block of data, stored directly in the mapped .debug_info 927ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * section. This type is used to represent an attribute encoded with 937ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * DW_FORM_block# form. 947ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 957ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinetypedef struct Dwarf_Block { 967ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Pointer to the block data inside mapped .debug_info section. */ 977ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const void* block_ptr; 987ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 997ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Byte size of the block data. */ 1007ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Word block_size; 1017ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine} Dwarf_Block; 1027ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 1037ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Describes a value, obtained from the mapped .debug_info section 1047ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * during DWARF attribute decoding. 1057ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 1067ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinetypedef struct Dwarf_Value { 1077ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Unites all possible data types for the value. 1087ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * See DwarfValueType for the list of types. 1097ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 1107ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine union { 1117ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Byte u8; 1127ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Sbyte s8; 1137ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Half u16; 1147ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Shalf s16; 1157ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Word u32; 1167ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Sword s32; 1177ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Xword u64; 1187ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Sxword s64; 1197ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Word ptr32; 1207ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Xword ptr64; 1217ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const char* str; 1227ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_Block block; 1237ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine }; 1247ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 1257ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Value type (defines which variable in the union abowe 1267ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * contains the value). 1277ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 1287ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine DwarfValueType type; 1297ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 1307ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Number of bytes that encode this value in .debug_info section 1317ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * of ELF file. 1327ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 1337ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Word encoded_size; 1347ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine} Dwarf_Value; 1357ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 1367ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* DWARF's LEB128 data type. LEB128 is defined as: 1377ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Variable Length Data. "Little Endian Base 128" (LEB128) numbers. LEB128 is 1387ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * a scheme for encoding integers densely that exploits the assumption that 1397ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * most integers are small in magnitude. (This encoding is equally suitable 1407ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * whether the target machine architecture represents data in big-endian or 1417ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * littleendian order. It is "little endian" only in the sense that it avoids 1427ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * using space to represent the "big" end of an unsigned integer, when the big 1437ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * end is all zeroes or sign extension bits). 1447ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * 1457ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Unsigned LEB128 numbers are encoded as follows: start at the low order end 1467ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * of an unsigned integer and chop it into 7-bit chunks. Place each chunk into 1477ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * the low order 7 bits of a byte. Typically, several of the high order bytes 1487ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * will be zero; discard them. Emit the remaining bytes in a stream, starting 1497ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * with the low order byte; set the high order bit on each byte except the last 1507ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * emitted byte. The high bit of zero on the last byte indicates to the decoder 1517ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * that it has encountered the last byte. The integer zero is a special case, 1527ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * consisting of a single zero byte. 1537ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * 1547ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * The encoding for signed LEB128 numbers is similar, except that the criterion 1557ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * for discarding high order bytes is not whether they are zero, but whether 1567ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * they consist entirely of sign extension bits. Consider the 32-bit integer 1577ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * -2. The three high level bytes of the number are sign extension, thus LEB128 1587ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * would represent it as a single byte containing the low order 7 bits, with 1597ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * the high order bit cleared to indicate the end of the byte stream. Note that 1607ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * there is nothing within the LEB128 representation that indicates whether an 1617ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * encoded number is signed or unsigned. The decoder must know what type of 1627ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * number to expect. 1637ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * 1647ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * NOTE: It's assumed that LEB128 will not contain encodings for integers, 1657ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * larger than 64 bit. 1667ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine*/ 1677ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinetypedef struct ELFF_PACKED Dwarf_Leb128 { 1687ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Beginning of the LEB128 block. */ 1697ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Byte val; 1707ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 1717ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Pulls actual value, encoded with this LEB128 block. 1727ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Param: 1737ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * value - Upon return will contain value, encoded with this LEB128 block. 1747ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * sign - If true, the caller expects the LEB128 to contain a signed 1757ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * integer, otherwise, caller expects an unsigned integer value to be 1767ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * encoded with this LEB128 block. 1777ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 1787ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine void get_common(Dwarf_Value* value, bool sign) const { 1797ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine value->u64 = 0; 1807ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Integer zero is a special case. */ 1817ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (val == 0) { 1827ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine value->type = sign ? DWARF_VALUE_S32 : DWARF_VALUE_U32; 1837ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine value->encoded_size = 1; 1847ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return; 1857ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 1867ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 1877ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* We've got to reconstruct the integer. */ 1887ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine value->type = DWARF_VALUE_UNKNOWN; 1897ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine value->encoded_size = 0; 1907ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 1917ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Byte by byte loop though the LEB128, reconstructing the integer from 1927ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * 7-bits chunks. Byte with 8-th bit set to zero indicates the end 1937ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * of the LEB128 block. For signed integers, 7-th bit of the last LEB128 1947ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * byte controls the sign. If 7-th bit of the last LEB128 byte is set, 1957ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * the integer is negative. If 7-th bit of the last LEB128 byte is not 1967ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * set, the integer is positive. 1977ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 1987ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const Elf_Byte* cur = &val; 1997ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Word shift = 0; 2007ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine while ((*cur & 0x80) != 0) { 2017ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine value->u64 |= (static_cast<Elf_Xword>(*cur) & 0x7F) << shift; 2027ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine shift += 7; 2037ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine value->encoded_size++; 2047ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine cur++; 2057ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 2067ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine value->u64 |= (static_cast<Elf_Xword>(*cur) & 0x7F) << shift; 2077ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine value->encoded_size++; 2087ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 2097ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* LEB128 format doesn't carry any info of the sizeof of the integer it 2107ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * represents. We well guess it, judging by the highest bit set in the 2117ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * reconstucted integer. 2127ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 2137ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if ((value->u64 & 0xFFFFFFFF00000000LL) == 0) { 2147ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* 32-bit integer. */ 2157ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (sign) { 2167ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine value->type = DWARF_VALUE_S32; 2177ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (((*cur) & 0x40) != 0) { 2187ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine // Value is negative. 2197ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine value->u64 |= - (1 << (shift + 7)); 2207ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } else if ((value->u32 & 0x80000000) != 0) { 2217ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine // Make sure we don't report negative value in this case. 2227ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine value->type = DWARF_VALUE_S64; 2237ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 2247ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } else { 2257ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine value->type = DWARF_VALUE_U32; 2267ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 2277ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } else { 2287ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* 64-bit integer. */ 2297ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (sign) { 2307ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine value->type = DWARF_VALUE_S64; 2317ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (((*cur) & 0x40) != 0) { 2327ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine // Value is negative. 2337ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine value->u64 |= - (1 << (shift + 7)); 2347ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 2357ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } else { 2367ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine value->type = DWARF_VALUE_U64; 2377ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 2387ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 2397ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 2407ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 2417ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Pulls actual unsigned value, encoded with this LEB128 block. 2427ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * See get_common() for more info. 2437ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Param: 2447ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * value - Upon return will contain unsigned value, encoded with 2457ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * this LEB128 block. 2467ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 2477ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine void get_unsigned(Dwarf_Value* value) const { 2487ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine get_common(value, false); 2497ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 2507ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 2517ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Pulls actual signed value, encoded with this LEB128 block. 2527ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * See get_common() for more info. 2537ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Param: 2547ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * value - Upon return will contain signed value, encoded with 2557ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * this LEB128 block. 2567ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 2577ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine void get_signed(Dwarf_Value* value) const { 2587ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine get_common(value, true); 2597ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 2607ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 2617ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Pulls LEB128 value, advancing past this LEB128 block. 2627ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * See get_common() for more info. 2637ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Return: 2647ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Pointer to the byte past this LEB128 block. 2657ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 2667ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const void* process(Dwarf_Value* value, bool sign) const { 2677ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine get_common(value, sign); 2687ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return INC_CPTR(&val, value->encoded_size); 2697ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 2707ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 2717ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Pulls LEB128 unsigned value, advancing past this LEB128 block. 2727ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * See process() for more info. 2737ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 2747ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const void* process_unsigned(Dwarf_Value* value) const { 2757ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return process(value, false); 2767ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 2777ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 2787ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Pulls LEB128 signed value, advancing past this LEB128 block. 2797ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * See process() for more info. 2807ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 2817ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const void* process_signed(Dwarf_Value* value) const { 2827ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return process(value, true); 2837ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 2847ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine} Dwarf_Leb128; 2857ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 2867ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* DIE attribute descriptor in the .debug_abbrev section. 2877ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Attribute descriptor contains two LEB128 values. First one provides 2887ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * attribute ID (one of DW_AT_XXX values), and the second one provides 2897ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * format (one of DW_FORMAT_XXX values), in which attribute value is 2907ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * encoded in the .debug_info section of the ELF file. 2917ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 2927ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinetypedef struct ELFF_PACKED Dwarf_Abbr_AT { 2937ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Attribute ID (DW_AT_XXX). 2947ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Attribute format (DW_FORMAT_XXX) follows immediately. 2957ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 2967ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_Leb128 at; 2977ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 2987ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Checks if this is a separator descriptor. 2997ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Zero is an invalid attribute ID, indicating the end of attribute 3007ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * list for the current DIE. 3017ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 3027ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine bool is_separator() const { 3037ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return at.val == 0; 3047ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 3057ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 3067ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Pulls attribute data, advancing past this descriptor. 3077ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Param: 3087ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * at_value - Upon return contains attribute value of this descriptor. 3097ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * form - Upon return contains form value of this descriptor. 3107ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Return: 3117ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Pointer to the byte past this descriptor block (usually, next 3127ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * attribute decriptor). 3137ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 3147ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const Dwarf_Abbr_AT* process(Dwarf_At* at_value, Dwarf_Form* form) const { 3157ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (is_separator()) { 3167ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Size of separator descriptor is always 2 bytes. */ 3177ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine *at_value = 0; 3187ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine *form = 0; 3197ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return INC_CPTR_T(Dwarf_Abbr_AT, &at.val, 2); 3207ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 3217ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 3227ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_Value val; 3237ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 3247ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Process attribute ID. */ 3257ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const Dwarf_Leb128* next = 3267ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine reinterpret_cast<const Dwarf_Leb128*>(at.process_unsigned(&val)); 3277ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine *at_value = val.u16; 3287ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 3297ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Follow with processing the form. */ 3307ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine next = reinterpret_cast<const Dwarf_Leb128*>(next->process_unsigned(&val)); 3317ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine *form = val.u16; 3327ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return reinterpret_cast<const Dwarf_Abbr_AT*>(next); 3337ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 3347ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine} Dwarf_Abbr_AT; 3357ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 3367ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* DIE abbreviation descriptor in the .debug_abbrev section. 3377ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * DIE abbreviation descriptor contains three parameters. The first one is a 3387ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * LEB128 value, that encodes 1 - based abbreviation descriptor number. 3397ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Abbreviation descriptor numbers seems to be always in sequential order, and 3407ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * are counted on per-compilation unit basis. I.e. abbreviation number for the 3417ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * first DIE abbreviation descriptor of each compilation unit is always 1. 3427ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * 3437ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Besides abbreviation number, DIE abbreviation descriptor contains two more 3447ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * values. The first one (after abbr_num) is a LEB128 value containing DIE's 3457ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * tag value, and the second one is one byte flag specifying whether or not 3467ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * the DIE contains any cildren. 3477ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * 3487ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * This descriptor is immediately followed by a list of attribute descriptors 3497ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * (see Dwarf_Abbr_AT) for the DIE represented by this abbreviation descriptor. 3507ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 3517ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinetypedef struct ELFF_PACKED Dwarf_Abbr_DIE { 3527ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* 1 - based abbreviation number for the DIE. */ 3537ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_Leb128 abbr_num; 3547ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 3557ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Gets abbreviation number for this descriptor. */ 3567ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_AbbrNum get_abbr_num() const { 3577ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_Value val; 3587ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine abbr_num.get_unsigned(&val); 3597ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return val.u16; 3607ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 3617ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 3627ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Gets DIE tag for this descriptor. */ 3637ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_Tag get_tag() const { 3647ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_Tag tag; 3657ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine process(NULL, &tag); 3667ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return tag; 3677ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 3687ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 3697ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Pulls DIE abbreviation descriptor data, advancing past this descriptor. 3707ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Param: 3717ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * abbr_index - Upon return contains abbreviation number for this 3727ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * descriptor. This parameter can be NULL, if the caller is not interested 3737ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * in this value. 3747ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * tag - Upon return contains tag of the DIE for this descriptor. This 3757ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * parameter can be NULL, if the caller is not interested in this value. 3767ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * form - Upon return contains form of the DIE for this descriptor. 3777ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Return: 3787ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Pointer to the list of attribute descriptors for the DIE. 3797ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 3807ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const Dwarf_Abbr_AT* process(Dwarf_AbbrNum* abbr_index, 3817ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_Tag* tag) const { 3827ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_Value val; 3837ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const Dwarf_Leb128* next = 3847ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine reinterpret_cast<const Dwarf_Leb128*>(abbr_num.process_unsigned(&val)); 3857ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (abbr_index != NULL) { 3867ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine *abbr_index = val.u32; 3877ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 3887ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 3897ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Next one is a "tag". */ 3907ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine next = reinterpret_cast<const Dwarf_Leb128*>(next->process_unsigned(&val)); 3917ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (tag != NULL) { 3927ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine *tag = val.u16; 3937ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 3947ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 3957ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Next one is a "has children" one byte flag. We're not interested in it, 3967ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * so jump to the list of attribute descriptors that immediately follows 3977ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * this DIE descriptor. */ 3987ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return INC_CPTR_T(Dwarf_Abbr_AT, next, 1); 3997ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 4007ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine} Dwarf_Abbr_DIE; 4017ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 4027ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* DIE descriptor in the .debug_info section. 4037ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * DIE descriptor contains one LEB128-encoded value, containing DIE's 4047ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * abbreviation descriptor number in the .debug_abbrev section. 4057ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * 4067ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * DIE descriptor is immediately followed by the list of DIE attribute values, 4077ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * format of wich is defined by the list of attribute descriptors in the 4087ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * .debug_abbrev section, that immediately follow the DIE attribute descriptor, 4097ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * addressed by this descriptor's abbr_num LEB128. 4107ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 4117ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinetypedef struct ELFF_PACKED Dwarf_DIE { 4127ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* 1 - based index of DIE abbreviation descriptor (Dwarf_Abbr_DIE) for this 4137ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * DIE in the .debug_abbrev section. 4147ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * 4157ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * NOTE: DIE abbreviation descriptor indexes are tied to the compilation 4167ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * unit. In other words, each compilation unit restarts counting DIE 4177ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * abbreviation descriptors from 1. 4187ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * 4197ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * NOTE: Zero is invalid value for this field, indicating that this DIE is a 4207ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * separator (usually it ends a list of "child" DIEs) 4217ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 4227ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_Leb128 abbr_num; 4237ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 4247ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Checks if this is a separator DIE. */ 4257ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine bool is_separator() const { 4267ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return abbr_num.val == 0; 4277ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 4287ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 4297ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Gets (1 - based) abbreviation number for this DIE. */ 4307ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_AbbrNum get_abbr_num() const { 4317ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_Value val; 4327ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine abbr_num.get_unsigned(&val); 4337ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return val.u16; 4347ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 4357ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 4367ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Pulls DIE information, advancing past this descriptor to DIE attributes. 4377ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Param: 4387ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * abbr_num - Upon return contains abbreviation number for this DIE. This 4397ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * parameter can be NULL, if the caller is not interested in this value. 4407ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Return: 4417ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Pointer to the byte past this descriptor (the list of DIE attributes). 4427ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 4437ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const Elf_Byte* process(Dwarf_AbbrNum* abbr_number) const { 4447ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (is_separator()) { 4457ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (abbr_number != NULL) { 4467ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine *abbr_number = 0; 4477ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 4487ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine // Size of a separator DIE is 1 byte. 4497ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return INC_CPTR_T(Elf_Byte, &abbr_num.val, 1); 4507ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 4517ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_Value val; 4527ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const void* ret = abbr_num.process_unsigned(&val); 4537ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (abbr_number != NULL) { 4547ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine *abbr_number = val.u32; 4557ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 4567ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return reinterpret_cast<const Elf_Byte*>(ret); 4577ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 4587ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine} Dwarf_DIE; 4597ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 4607ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* 4617ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Variable size headers. 4627ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * When encoding size value in DWARF, the first 32 bits of a "size" header 4637ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * define header type. If first 32 bits of the header contain 0xFFFFFFFF 4647ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * value, this is 64-bit size header with the following 64 bits encoding 4657ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * the size. Otherwise, if first 32 bits are not 0xFFFFFFFF, they contain 4667ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * 32-bit size value. 4677ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 4687ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 4697ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Size header for 32-bit DWARF. */ 4707ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinetypedef struct ELFF_PACKED Dwarf32_SizeHdr { 4717ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Size value. */ 4727ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Word size; 4737ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine} Dwarf32_SizeHdr; 4747ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 4757ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Size header for 64-bit DWARF. */ 4767ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinetypedef struct ELFF_PACKED Dwarf64_SizeHdr { 4777ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Size selector. For 64-bit DWARF this field is set to 0xFFFFFFFF */ 4787ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Word size_selector; 4797ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 4807ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Actual size value. */ 4817ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Xword size; 4827ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine} Dwarf64_SizeHdr; 4837ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 4847ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Compilation unit header in the .debug_info section. 4857ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Template param: 4867ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Dwarf_SizeHdr - Type for the header's size field. Must be Dwarf32_SizeHdr 4877ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * for 32-bit DWARF, or Dwarf64_SizeHdr for 64-bit DWARF. 4887ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Elf_Off - Type for abbrev_offset field. Must be Elf_Word for for 32-bit 4897ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * DWARF, or Elf_Xword for 64-bit DWARF. 4907ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 4917ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinetemplate <typename Dwarf_SizeHdr, typename Elf_Off> 4927ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinestruct ELFF_PACKED Dwarf_CUHdr { 4937ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Size of the compilation unit data in .debug_info section. */ 4947ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_SizeHdr size_hdr; 4957ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 4967ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Compilation unit's DWARF version stamp. */ 4977ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Half version; 4987ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 4997ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Relative (to the beginning of .debug_abbrev section data) offset of the 5007ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * beginning of abbreviation sequence for this compilation unit. 5017ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 5027ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Off abbrev_offset; 5037ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 5047ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Pointer size for this compilation unit (should be 4, or 8). */ 5057ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Byte address_size; 5067ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine}; 5077ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Compilation unit header in the .debug_info section for 32-bit DWARF. */ 5087ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinetypedef Dwarf_CUHdr<Dwarf32_SizeHdr, Elf_Word> Dwarf32_CUHdr; 5097ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Compilation unit header in the .debug_info section for 64-bit DWARF. */ 5107ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinetypedef Dwarf_CUHdr<Dwarf64_SizeHdr, Elf_Xword> Dwarf64_CUHdr; 5117ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 5127ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* CU STMTL header in the .debug_line section. 5137ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Template param: 5147ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Dwarf_SizeHdr - Type for the header's size field. Must be Dwarf32_SizeHdr 5157ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * for 32-bit DWARF, or Dwarf64_SizeHdr for 64-bit DWARF. 5167ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Elf_Size - Type for header_length field. Must be Elf_Word for for 32-bit 5177ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * DWARF, or Elf_Xword for 64-bit DWARF. 5187ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 5197ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinetemplate <typename Dwarf_SizeHdr, typename Elf_Size> 5207ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinestruct ELFF_PACKED Dwarf_STMTLHdr { 5217ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* The size in bytes of the line number information for this compilation 5227ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * unit, not including the unit_length field itself. */ 5237ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_SizeHdr unit_length; 5247ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 5257ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* A version number. This number is specific to the line number information 5267ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * and is independent of the DWARF version number. */ 5277ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Half version; 5287ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 5297ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* The number of bytes following the header_length field to the beginning of 5307ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * the first byte of the line number program itself. In the 32-bit DWARF 5317ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * format, this is a 4-byte unsigned length; in the 64-bit DWARF format, 5327ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * this field is an 8-byte unsigned length. */ 5337ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Size header_length; 5347ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 5357ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* The size in bytes of the smallest target machine instruction. Line number 5367ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * program opcodes that alter the address register first multiply their 5377ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * operands by this value. */ 5387ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Byte min_instruction_len; 5397ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 5407ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* The initial value of the is_stmt register. */ 5417ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Byte default_is_stmt; 5427ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 5437ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* This parameter affects the meaning of the special opcodes. */ 5447ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Sbyte line_base; 5457ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 5467ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* This parameter affects the meaning of the special opcodes. */ 5477ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Byte line_range; 5487ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 5497ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* The number assigned to the first special opcode. */ 5507ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Byte opcode_base; 5517ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 5527ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* This is first opcode in an array specifying the number of LEB128 operands 5537ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * for each of the standard opcodes. The first element of the array 5547ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * corresponds to the opcode whose value is 1, and the last element 5557ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * corresponds to the opcode whose value is opcode_base - 1. By increasing 5567ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * opcode_base, and adding elements to this array, new standard opcodes can 5577ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * be added, while allowing consumers who do not know about these new opcodes 5587ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * to be able to skip them. NOTE: this array points to the mapped 5597ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * .debug_line section. */ 5607ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Byte standard_opcode_lengths; 5617ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine}; 5627ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* CU STMTL header in the .debug_line section for 32-bit DWARF. */ 5637ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinetypedef Dwarf_STMTLHdr<Dwarf32_SizeHdr, Elf_Word> Dwarf32_STMTLHdr; 5647ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* CU STMTL header in the .debug_line section for 64-bit DWARF. */ 5657ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinetypedef Dwarf_STMTLHdr<Dwarf64_SizeHdr, Elf_Xword> Dwarf64_STMTLHdr; 5667ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 5677ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Source file descriptor in the .debug_line section. 5687ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Descriptor begins with zero-terminated file name, followed by an ULEB128, 5697ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * encoding directory index in the list of included directories, followed by 5707ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * an ULEB12, encoding file modification time, followed by an ULEB12, encoding 5717ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * file size. 5727ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 5737ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinetypedef struct ELFF_PACKED Dwarf_STMTL_FileDesc { 5747ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Zero-terminated file name. */ 5757ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine char file_name[1]; 5767ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 5777ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Checks of this descriptor ends the list. */ 5787ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine bool is_last_entry() const { 5797ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return file_name[0] == '\0'; 5807ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 5817ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 5827ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Gets file name. */ 5837ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const char* get_file_name() const { 5847ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return file_name; 5857ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 5867ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 5877ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Processes this descriptor, advancing to the next one. 5887ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Param: 5897ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * dir_index - Upon return contains index of the parent directory in the 5907ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * list of included directories. Can be NULL if caller is not interested 5917ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * in this value. 5927ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Return: 5937ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Pointer to the next source file descriptor in the list. 5947ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 5957ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const Dwarf_STMTL_FileDesc* process(Elf_Word* dir_index) const { 5967ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (is_last_entry()) { 5977ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return this; 5987ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 5997ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 6007ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* First parameter: include directory index. */ 6017ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_Value tmp; 6027ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const Dwarf_Leb128* leb = 6037ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine INC_CPTR_T(Dwarf_Leb128, file_name, strlen(file_name) + 1); 6047ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine leb = reinterpret_cast<const Dwarf_Leb128*>(leb->process_unsigned(&tmp)); 6057ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (dir_index != NULL) { 6067ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine *dir_index = tmp.u32; 6077ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 6087ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Process file time. */ 6097ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine leb = reinterpret_cast<const Dwarf_Leb128*>(leb->process_unsigned(&tmp)); 6107ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Process file size. */ 6117ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return reinterpret_cast<const Dwarf_STMTL_FileDesc*>(leb->process_unsigned(&tmp)); 6127ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 6137ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 6147ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Gets directory index for this descriptor. */ 6157ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Word get_dir_index() const { 6167ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine assert(!is_last_entry()); 6177ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (is_last_entry()) { 6187ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return 0; 6197ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 6207ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Get directory index. */ 6217ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_Value ret; 6227ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const Dwarf_Leb128* leb = 6237ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine INC_CPTR_T(Dwarf_Leb128, file_name, strlen(file_name) + 1); 6247ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine leb->process_unsigned(&ret); 6257ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return ret.u32; 6267ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 6277ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine} Dwarf_STMTL_FileDesc; 6287ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 6297ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Encapsulates a DIE attribute, collected during ELF file parsing. 6307ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 6317ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkineclass DIEAttrib { 6327ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine public: 6337ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Constructs DIEAttrib intance. */ 6347ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine DIEAttrib() 6357ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine : at_(0), 6367ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine form_(0) { 6377ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine value_.type = DWARF_VALUE_UNKNOWN; 6387ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 6397ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 6407ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Destructs DIEAttrib intance. */ 6417ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine ~DIEAttrib() { 6427ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 6437ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 6447ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Gets DWARF attribute ID (DW_AT_Xxx) for this property. */ 6457ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_At at() const { 6467ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return at_; 6477ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 6487ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 6497ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Gets DWARF form ID (DW_FORM_Xxx) for this property. */ 6507ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_Form form() const { 6517ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return form_; 6527ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 6537ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 6547ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Gets value of this property. */ 6557ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const Dwarf_Value* value() const { 6567ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return &value_; 6577ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 6587ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 6597ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Value of this property. */ 6607ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_Value value_; 6617ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 6627ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* DWARF attribute ID (DW_AT_Xxx) for this property. */ 6637ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_At at_; 6647ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 6657ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* DWARF form ID (DW_FORM_Xxx) for this property. */ 6667ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_Form form_; 6677ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine}; 6687ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 6697ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Parse tag context. 6707ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * This structure is used as an ELF file parsing parameter, limiting collected 6717ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * DIEs by the list of tags. 6727ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 6737ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinetypedef struct DwarfParseContext { 6747ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Zero-terminated list of tags to collect DIEs for. If this field is NULL, 6757ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * DIEs for all tags will be collected during the parsing. */ 6767ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const Dwarf_Tag* tags; 6777ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine} DwarfParseContext; 6787ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 6797ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Checks if a DIE with the given tag should be collected during the parsing. 6807ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Param: 6817ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * parse_context - Parse context to check the tag against. This parameter can 6827ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * be NULL, indicating that all tags should be collected. 6837ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * tag - Tag to check. 6847ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Return: 6857ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * true if a DIE with the given tag should be collected during the parsing, 6867ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * or false, if the DIE should not be collected. 6877ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 6887ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinestatic inline bool 6897ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinecollect_die(const DwarfParseContext* parse_context, Dwarf_Tag tag) { 6907ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (parse_context == NULL || parse_context->tags == NULL) { 6917ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return true; 6927ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 6937ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine for (const Dwarf_Tag* tags = parse_context->tags; *tags != 0; tags++) { 6947ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (*tags == tag) { 6957ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return true; 6967ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 6977ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 6987ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return false; 6997ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine} 7007ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 7017ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Encapsulates an array of Dwarf_Abbr_DIE pointers, cached for a compilation 7027ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * unit. Although Dwarf_Abbr_DIE descriptors in the .debug_abbrev section of 7037ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * the ELF file seems to be always in sequential order, DIE descriptors may 7047ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * reference them randomly. So, to provide better performance, we will cache 7057ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * all Dwarf_Abbr_DIE pointers, that were found for each DIE. Since all of the 7067ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Dwarf_Abbr_DIE are sequential, an array is the best way to cache them. 7077ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * 7087ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * NOTE: Objects of this class are instantiated one per each CU, as all DIE 7097ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * abbreviation numberation is restarted from 1 for each new CU. 7107ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 7117ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkineclass DwarfAbbrDieArray { 7127ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine public: 7137ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Constructs DwarfAbbrDieArray instance. 7147ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Most of the CUs don't have too many unique Dwarf_Abbr_DIEs, so, in order 7157ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * to decrease the amount of memory allocation calls, we will preallocate 7167ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * a relatively small array for them along with the instance of this class, 7177ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * hopping, that all Dwarf_Abbr_DIEs for the CU will fit into it. 7187ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 7197ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine DwarfAbbrDieArray() 7207ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine : array_(&small_array_[0]), 7217ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine array_size_(ELFF_ARRAY_SIZE(small_array_)), 7227ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine count_(0) { 7237ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 7247ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 7257ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Destructs DwarfAbbrDieArray instance. */ 7267ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine ~DwarfAbbrDieArray() { 7277ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (array_ != &small_array_[0]) { 7287ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine delete[] array_; 7297ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 7307ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 7317ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 7327ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Adds new entry to the array 7337ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Param: 7347ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * abbr - New entry to add. 7357ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * num - Abbreviation number for the adding entry. 7367ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * NOTE: before adding, this method will verify that descriptor for the 7377ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * given abbreviation number has not been cached yet. 7387ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * NOTE: due to the nature of this array, entries MUST be added strictly 7397ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * in sequential order. 7407ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Return: 7417ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * true on success, false on failure. 7427ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 7437ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine bool add(const Dwarf_Abbr_DIE* abbr, Dwarf_AbbrNum num) { 7447ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine assert(num != 0); 7457ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (num == 0) { 7467ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine // Zero is illegal DIE abbreviation number. 7477ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine _set_errno(EINVAL); 7487ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return false; 7497ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 7507ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 7517ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (num <= count_) { 7527ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine // Already cached. 7537ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return true; 7547ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 7557ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 7567ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine // Enforce strict sequential order. 7577ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine assert(num == (count_ + 1)); 7587ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (num != (count_ + 1)) { 7597ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine _set_errno(EINVAL); 7607ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return false; 7617ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 7627ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 7637ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (num >= array_size_) { 7647ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Expand the array. Make it 64 entries bigger than adding entry number. 7657ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * NOTE: that we don't check for an overflow here, since we secured 7667ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * ourselves from that by enforcing strict sequential order. So, an 7677ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * overflow may happen iff number of entries cached in this array is 7687ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * close to 4G, which is a) totally unreasonable, and b) we would die 7697ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * long before this amount of entries is cached. 7707ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 7717ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_AbbrNum new_size = num + 64; 7727ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 7737ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine // Reallocate. 7747ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const Dwarf_Abbr_DIE** new_array = new const Dwarf_Abbr_DIE*[new_size]; 7757ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine assert(new_array != NULL); 7767ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (new_array == NULL) { 7777ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine _set_errno(ENOMEM); 7787ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return false; 7797ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 7807ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine memcpy(new_array, array_, count_ * sizeof(const Dwarf_Abbr_DIE*)); 7817ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (array_ != &small_array_[0]) { 7827ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine delete[] array_; 7837ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 7847ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine array_ = new_array; 7857ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine array_size_ = new_size; 7867ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 7877ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 7887ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine // Abbreviation numbers are 1-based. 7897ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine array_[num - 1] = abbr; 7907ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine count_++; 7917ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return true; 7927ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 7937ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 7947ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Adds new entry to the array 7957ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Param: 7967ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * abbr - New entry to add. 7977ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Return: 7987ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * true on success, false on failure. 7997ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 8007ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine bool add(const Dwarf_Abbr_DIE* abbr) { 8017ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return add(abbr, abbr->get_abbr_num()); 8027ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 8037ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 8047ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Gets an entry from the array 8057ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Param: 8067ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * num - 1-based index of an entry to get. 8077ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Return: 8087ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Entry on success, or NULL if num exceeds the number of entries 8097ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * contained in the array. 8107ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 8117ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const Dwarf_Abbr_DIE* get(Dwarf_AbbrNum num) const { 8127ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine assert(num != 0 && num <= count_); 8137ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (num != 0 && num <= count_) { 8147ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return array_[num - 1]; 8157ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } else { 8167ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine _set_errno(EINVAL); 8177ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return NULL; 8187ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 8197ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 8207ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 8217ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Caches Dwarf_Abbr_DIEs into this array up to the requested number. 8227ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * NOTE: This method cannot be called on an empty array. Usually, first 8237ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * entry is inserted into this array when CU object is initialized. 8247ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Param: 8257ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * num - Entry number to cache entries up to. 8267ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Return: 8277ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Last cached entry (actually, an entry for the 'num' index). 8287ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 8297ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const Dwarf_Abbr_DIE* cache_to(Dwarf_AbbrNum num) { 8307ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Last cached DIE abbreviation. We always should have cached at least one 8317ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * abbreviation for the CU DIE itself, added via "add" method when CU 8327ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * object was initialized. */ 8337ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const Dwarf_Abbr_DIE* cur_abbr = get(count_); 8347ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine assert(cur_abbr != NULL); 8357ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (cur_abbr == NULL) { 8367ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return NULL; 8377ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 8387ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 8397ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Starting with the last cached DIE abbreviation, loop through the 8407ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * remaining DIE abbreviations in the .debug_abbrev section of the 8417ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * mapped ELF file, caching them until we reach the requested 8427ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * abbreviation descriptor number. Normally, the very next DIE 8437ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * abbreviation will stop the loop. */ 8447ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine while (num > count_) { 8457ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_AbbrNum abbr_num; 8467ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_Tag tmp2; 8477ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_Form tmp3; 8487ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_At tmp4; 8497ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 8507ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Process all AT abbreviations for the current DIE entry, reaching next 8517ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * DIE abbreviation. */ 8527ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const Dwarf_Abbr_AT* abbr_at = cur_abbr->process(&abbr_num, &tmp2); 8537ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine while (!abbr_at->is_separator()) { 8547ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine abbr_at = abbr_at->process(&tmp4, &tmp3); 8557ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 8567ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 8577ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine // Next DIE abbreviation is right after the separator AT abbreviation. 8587ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine cur_abbr = reinterpret_cast<const Dwarf_Abbr_DIE*> 8597ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine (abbr_at->process(&tmp4, &tmp3)); 8607ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (!add(cur_abbr)) { 8617ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return NULL; 8627ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 8637ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 8647ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 8657ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return array_[num - 1]; 8667ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 8677ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 8687ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Empties array and frees allocations. */ 8697ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine void empty() { 8707ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine if (array_ != &small_array_[0]) { 8717ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine delete[] array_; 8727ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine array_ = &small_array_[0]; 8737ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine array_size_ = sizeof(small_array_) / sizeof(small_array_[0]); 8747ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 8757ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine count_ = 0; 8767ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 8777ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 8787ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine protected: 8797ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Array, preallocated in anticipation of relatively small number of 8807ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * DIE abbreviations in compilation unit. */ 8817ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const Dwarf_Abbr_DIE* small_array_[64]; 8827ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 8837ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Array of Dwarf_Abbr_DIE pointers, cached for a compilation unit. */ 8847ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const Dwarf_Abbr_DIE** array_; 8857ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 8867ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Current size of the array. */ 8877ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_AbbrNum array_size_; 8887ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 8897ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Number of entries, cached in the array. */ 8907ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Dwarf_AbbrNum count_; 8917ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine}; 8927ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 8937ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Encapsulates a state machine for the "Line Number Program", that is run 8947ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * on data conained in the mapped .debug_line section. 8957ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 8967ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkineclass DwarfStateMachine { 8977ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine public: 8987ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Constructs DwarfStateMachine instance. 8997ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Param: 9007ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * set_is_stmt - Matches value of default_is_stmt field in the STMTL header. 9017ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * see Dwarf_STMTL_HdrXX. 9027ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 9037ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine explicit DwarfStateMachine(bool set_is_stmt) 9047ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine : address_(0), 9057ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine file_(1), 9067ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine line_(1), 9077ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine column_(0), 9087ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine discriminator_(0), 9097ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine is_stmt_(set_is_stmt), 9107ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine basic_block_(false), 9117ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine end_sequence_(false), 9127ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine prologue_end_(false), 9137ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine epilogue_begin_(false), 9147ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine isa_(0), 9157ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine set_file_info_(NULL) { 9167ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 9177ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 9187ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Destructs DwarfStateMachine instance. */ 9197ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine ~DwarfStateMachine() { 9207ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 9217ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 9227ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Resets the state to default. 9237ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Param: 9247ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * set_is_stmt - Matches value of default_is_stmt field in the STMTL header. 9257ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * see Dwarf_STMTL_HdrXX. 9267ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 9277ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine void reset(bool set_is_stmt) { 9287ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine address_ = 0; 9297ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine file_ = 1; 9307ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine line_ = 1; 9317ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine column_ = 0; 9327ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine discriminator_ = 0; 9337ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine is_stmt_ = set_is_stmt; 9347ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine basic_block_ = false; 9357ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine end_sequence_ = false; 9367ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine prologue_end_ = false; 9377ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine epilogue_begin_ = false; 9387ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine isa_ = 0; 9397ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine set_file_info_ = NULL; 9407ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine } 9417ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 9427ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* 9437ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Machine state. 9447ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */ 9457ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 9467ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Current address (current PC value). */ 9477ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Xword address_; 9487ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 9497ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Current index of source file descriptor. */ 9507ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Word file_; 9517ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 9527ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Current line in the current source file. */ 9537ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Word line_; 9547ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 9557ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Current column. */ 9567ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Word column_; 9577ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 9587ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Current discriminator value. */ 9597ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Word discriminator_; 9607ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 9617ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Current STMT flag. */ 9627ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine bool is_stmt_; 9637ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 9647ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Current basic block flag. */ 9657ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine bool basic_block_; 9667ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 9677ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Current end of sequence flag. */ 9687ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine bool end_sequence_; 9697ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 9707ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Current end of prologue flag. */ 9717ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine bool prologue_end_; 9727ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 9737ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Current epilogue begin flag. */ 9747ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine bool epilogue_begin_; 9757ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 9767ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Current ISA value. */ 9777ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine Elf_Word isa_; 9787ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 9797ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine /* Current value for explicitly set current source file descriptor. 9807ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * If not NULL, this descriptor has priority over the descriptor, addressed 9817ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * by the file_ member of this class. */ 9827ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine const Dwarf_STMTL_FileDesc* set_file_info_; 9837ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine}; 9847ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 9857ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Checks if given tag belongs to a routine. */ 9867ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinestatic inline bool 9877ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinedwarf_tag_is_routine(Dwarf_Tag tag) { 9887ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return tag == DW_TAG_inlined_subroutine || 9897ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine tag == DW_TAG_subprogram || 9907ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine tag == DW_AT_main_subprogram; 9917ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine} 9927ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 9937ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Checks if given tag belongs to a compilation unit. */ 9947ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinestatic inline bool 9957ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinedwarf_tag_is_cu(Dwarf_Tag tag) { 9967ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine return tag == DW_TAG_compile_unit || 9977ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine tag == DW_TAG_partial_unit; 9987ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine} 9997ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine 10007ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine#endif // ELFF_DWARF_DEFS_H_ 1001