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