/* Copyright (C) 2007-2010 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/

/*
 * Contains declarations of types, constants and structures
 * describing DWARF format.
 */

#ifndef ELFF_DWARF_DEFS_H_
#define ELFF_DWARF_DEFS_H_

#include "dwarf.h"
#include "elf_defs.h"

/* DWARF structures are packed to 1 byte. */
#define ELFF_PACKED __attribute__ ((packed))

/*
 * Helper types for misc. DWARF variables.
 */

/* Type for DWARF abbreviation number. */
typedef uint32_t  Dwarf_AbbrNum;

/* Type for DWARF tag ID. */
typedef uint16_t  Dwarf_Tag;

/* Type for DWARF attribute ID. */
typedef uint16_t  Dwarf_At;

/* Type for DWARF form ID. */
typedef uint16_t  Dwarf_Form;

/* Type for offset in 32-bit DWARF. */
typedef uint32_t  Dwarf32_Off;

/* Type for offset in 64-bit DWARF. */
typedef uint64_t  Dwarf64_Off;

/* Enumerates types of values, obtained during DWARF attribute decoding. */
typedef enum DwarfValueType {
  /* Undefined */
  DWARF_VALUE_UNKNOWN = 1,

  /* uint8_t */
  DWARF_VALUE_U8,

  /* int8_t */
  DWARF_VALUE_S8,

  /* uint16_t */
  DWARF_VALUE_U16,

  /* int16_t */
  DWARF_VALUE_S16,

  /* uint32_t */
  DWARF_VALUE_U32,

  /* int32_t */
  DWARF_VALUE_S32,

  /* uint64_t */
  DWARF_VALUE_U64,

  /* int64_t */
  DWARF_VALUE_S64,

  /* const char* */
  DWARF_VALUE_STR,

  /* 32-bit address */
  DWARF_VALUE_PTR32,

  /* 64-bit address */
  DWARF_VALUE_PTR64,

  /* Dwarf_Block */
  DWARF_VALUE_BLOCK,
} DwarfValueType;

/* Describes block of data, stored directly in the mapped .debug_info
 * section. This type is used to represent an attribute encoded with
 * DW_FORM_block# form.
 */
typedef struct Dwarf_Block {
  /* Pointer to the block data inside mapped .debug_info section. */
  const void*   block_ptr;

  /* Byte size of the block data. */
  Elf_Word      block_size;
} Dwarf_Block;

/* Describes a value, obtained from the mapped .debug_info section
 * during DWARF attribute decoding.
 */
typedef struct Dwarf_Value {
  /* Unites all possible data types for the value.
   * See DwarfValueType for the list of types.
   */
  union {
    Elf_Byte      u8;
    Elf_Sbyte     s8;
    Elf_Half      u16;
    Elf_Shalf     s16;
    Elf_Word      u32;
    Elf_Sword     s32;
    Elf_Xword     u64;
    Elf_Sxword    s64;
    Elf_Word      ptr32;
    Elf_Xword     ptr64;
    const char*   str;
    Dwarf_Block   block;
  };

  /* Value type (defines which variable in the union abowe
   * contains the value).
   */
  DwarfValueType  type;

  /* Number of bytes that encode this value in .debug_info section
   * of ELF file.
   */
  Elf_Word        encoded_size;
} Dwarf_Value;

/* DWARF's LEB128 data type. LEB128 is defined as:
 * Variable Length Data. "Little Endian Base 128" (LEB128) numbers. LEB128 is
 * a scheme for encoding integers densely that exploits the assumption that
 * most integers are small in magnitude. (This encoding is equally suitable
 * whether the target machine architecture represents data in big-endian or
 * littleendian order. It is "little endian" only in the sense that it avoids
 * using space to represent the "big" end of an unsigned integer, when the big
 * end is all zeroes or sign extension bits).
 *
 * Unsigned LEB128 numbers are encoded as follows: start at the low order end
 * of an unsigned integer and chop it into 7-bit chunks. Place each chunk into
 * the low order 7 bits of a byte. Typically, several of the high order bytes
 * will be zero; discard them. Emit the remaining bytes in a stream, starting
 * with the low order byte; set the high order bit on each byte except the last
 * emitted byte. The high bit of zero on the last byte indicates to the decoder
 * that it has encountered the last byte. The integer zero is a special case,
 * consisting of a single zero byte.
 *
 * The encoding for signed LEB128 numbers is similar, except that the criterion
 * for discarding high order bytes is not whether they are zero, but whether
 * they consist entirely of sign extension bits. Consider the 32-bit integer
 * -2. The three high level bytes of the number are sign extension, thus LEB128
 * would represent it as a single byte containing the low order 7 bits, with
 * the high order bit cleared to indicate the end of the byte stream. Note that
 * there is nothing within the LEB128 representation that indicates whether an
 * encoded number is signed or unsigned. The decoder must know what type of
 * number to expect.
 *
 * NOTE: It's assumed that LEB128 will not contain encodings for integers,
 * larger than 64 bit.
*/
typedef struct ELFF_PACKED Dwarf_Leb128 {
  /* Beginning of the LEB128 block. */
  Elf_Byte  val;

  /* Pulls actual value, encoded with this LEB128 block.
   * Param:
   *  value - Upon return will contain value, encoded with this LEB128 block.
   *  sign - If true, the caller expects the LEB128 to contain a signed
   *    integer, otherwise, caller expects an unsigned integer value to be
   *    encoded with this LEB128 block.
   */
  void get_common(Dwarf_Value* value, bool sign) const {
    value->u64 = 0;
    /* Integer zero is a special case. */
    if (val == 0) {
      value->type = sign ? DWARF_VALUE_S32 : DWARF_VALUE_U32;
      value->encoded_size = 1;
      return;
    }

    /* We've got to reconstruct the integer. */
    value->type = DWARF_VALUE_UNKNOWN;
    value->encoded_size = 0;

    /* Byte by byte loop though the LEB128, reconstructing the integer from
     * 7-bits chunks. Byte with 8-th bit set to zero indicates the end
     * of the LEB128 block. For signed integers, 7-th bit of the last LEB128
     * byte controls the sign. If 7-th bit of the last LEB128 byte is set,
     * the integer is negative. If 7-th bit of the last LEB128 byte is not
     * set, the integer is positive.
     */
    const Elf_Byte* cur = &val;
    Elf_Word shift = 0;
    while ((*cur & 0x80) != 0) {
      value->u64 |= (static_cast<Elf_Xword>(*cur) & 0x7F) << shift;
      shift += 7;
      value->encoded_size++;
      cur++;
    }
    value->u64 |= (static_cast<Elf_Xword>(*cur) & 0x7F) << shift;
    value->encoded_size++;

    /* LEB128 format doesn't carry any info of the sizeof of the integer it
     * represents. We well guess it, judging by the highest bit set in the
     * reconstucted integer.
     */
    if ((value->u64 & 0xFFFFFFFF00000000LL) == 0) {
      /* 32-bit integer. */
      if (sign) {
        value->type = DWARF_VALUE_S32;
        if (((*cur) & 0x40) != 0) {
          // Value is negative.
          value->u64 |= - (1 << (shift + 7));
        } else if ((value->u32 & 0x80000000) != 0) {
          // Make sure we don't report negative value in this case.
          value->type = DWARF_VALUE_S64;
        }
      } else {
        value->type = DWARF_VALUE_U32;
      }
    } else {
      /* 64-bit integer. */
      if (sign) {
        value->type = DWARF_VALUE_S64;
        if (((*cur) & 0x40) != 0) {
          // Value is negative.
          value->u64 |= - (1 << (shift + 7));
        }
      } else {
        value->type = DWARF_VALUE_U64;
      }
    }
  }

  /* Pulls actual unsigned value, encoded with this LEB128 block.
   * See get_common() for more info.
   * Param:
   *  value - Upon return will contain unsigned value, encoded with
   *  this LEB128 block.
   */
  void get_unsigned(Dwarf_Value* value) const {
    get_common(value, false);
  }

  /* Pulls actual signed value, encoded with this LEB128 block.
   * See get_common() for more info.
   * Param:
   *  value - Upon return will contain signed value, encoded with
   *  this LEB128 block.
   */
  void get_signed(Dwarf_Value* value) const {
    get_common(value, true);
  }

  /* Pulls LEB128 value, advancing past this LEB128 block.
   * See get_common() for more info.
   * Return:
   *  Pointer to the byte past this LEB128 block.
   */
  const void* process(Dwarf_Value* value, bool sign) const {
    get_common(value, sign);
    return INC_CPTR(&val, value->encoded_size);
  }

  /* Pulls LEB128 unsigned value, advancing past this LEB128 block.
   * See process() for more info.
   */
  const void* process_unsigned(Dwarf_Value* value) const {
    return process(value, false);
  }

  /* Pulls LEB128 signed value, advancing past this LEB128 block.
   * See process() for more info.
   */
  const void* process_signed(Dwarf_Value* value) const {
    return process(value, true);
  }
} Dwarf_Leb128;

/* DIE attribute descriptor in the .debug_abbrev section.
 * Attribute descriptor contains two LEB128 values. First one provides
 * attribute ID (one of DW_AT_XXX values), and the second one provides
 * format (one of DW_FORMAT_XXX values), in which attribute value is
 * encoded in the .debug_info section of the ELF file.
 */
typedef struct ELFF_PACKED Dwarf_Abbr_AT {
  /* Attribute ID (DW_AT_XXX).
   * Attribute format (DW_FORMAT_XXX) follows immediately.
   */
  Dwarf_Leb128  at;

  /* Checks if this is a separator descriptor.
   * Zero is an invalid attribute ID, indicating the end of attribute
   * list for the current DIE.
   */
  bool is_separator() const {
    return at.val == 0;
  }

  /* Pulls attribute data, advancing past this descriptor.
   * Param:
   *  at_value - Upon return contains attribute value of this descriptor.
   *  form - Upon return contains form value of this descriptor.
   * Return:
   *  Pointer to the byte past this descriptor block (usually, next
   *  attribute decriptor).
   */
  const Dwarf_Abbr_AT* process(Dwarf_At* at_value, Dwarf_Form* form) const {
    if (is_separator()) {
      /* Size of separator descriptor is always 2 bytes. */
      *at_value = 0;
      *form = 0;
      return INC_CPTR_T(Dwarf_Abbr_AT, &at.val, 2);
    }

    Dwarf_Value val;

    /* Process attribute ID. */
    const Dwarf_Leb128* next =
        reinterpret_cast<const Dwarf_Leb128*>(at.process_unsigned(&val));
    *at_value = val.u16;

    /* Follow with processing the form. */
    next = reinterpret_cast<const Dwarf_Leb128*>(next->process_unsigned(&val));
    *form = val.u16;
    return reinterpret_cast<const Dwarf_Abbr_AT*>(next);
  }
} Dwarf_Abbr_AT;

/* DIE abbreviation descriptor in the .debug_abbrev section.
 * DIE abbreviation descriptor contains three parameters. The first one is a
 * LEB128 value, that encodes 1 - based abbreviation descriptor number.
 * Abbreviation descriptor numbers seems to be always in sequential order, and
 * are counted on per-compilation unit basis. I.e. abbreviation number for the
 * first DIE abbreviation descriptor of each compilation unit is always 1.
 *
 * Besides abbreviation number, DIE abbreviation descriptor contains two more
 * values. The first one (after abbr_num) is a LEB128 value containing DIE's
 * tag value, and the second one is one byte flag specifying whether or not
 * the DIE contains any cildren.
 *
 * This descriptor is immediately followed by a list of attribute descriptors
 * (see Dwarf_Abbr_AT) for the DIE represented by this abbreviation descriptor.
 */
typedef struct ELFF_PACKED Dwarf_Abbr_DIE {
  /* 1 - based abbreviation number for the DIE. */
  Dwarf_Leb128  abbr_num;

  /* Gets abbreviation number for this descriptor. */
  Dwarf_AbbrNum get_abbr_num() const {
    Dwarf_Value val;
    abbr_num.get_unsigned(&val);
    return val.u16;
  }

  /* Gets DIE tag for this descriptor. */
  Dwarf_Tag get_tag() const {
    Dwarf_Tag tag;
    process(NULL, &tag);
    return tag;
  }

  /* Pulls DIE abbreviation descriptor data, advancing past this descriptor.
   * Param:
   *  abbr_index - Upon return contains abbreviation number for this
   *    descriptor. This parameter can be NULL, if the caller is not interested
   *    in this value.
   *  tag - Upon return contains tag of the DIE for this descriptor. This
   *    parameter can be NULL, if the caller is not interested in this value.
   *  form - Upon return contains form of the DIE for this descriptor.
   * Return:
   *  Pointer to the list of attribute descriptors for the DIE.
   */
  const Dwarf_Abbr_AT* process(Dwarf_AbbrNum* abbr_index,
                               Dwarf_Tag* tag) const {
    Dwarf_Value val;
    const Dwarf_Leb128* next =
        reinterpret_cast<const Dwarf_Leb128*>(abbr_num.process_unsigned(&val));
    if (abbr_index != NULL) {
      *abbr_index = val.u32;
    }

    /* Next one is a "tag". */
    next = reinterpret_cast<const Dwarf_Leb128*>(next->process_unsigned(&val));
    if (tag != NULL) {
      *tag = val.u16;
    }

    /* Next one is a "has children" one byte flag. We're not interested in it,
     * so jump to the list of attribute descriptors that immediately follows
     * this DIE descriptor. */
    return INC_CPTR_T(Dwarf_Abbr_AT, next, 1);
  }
} Dwarf_Abbr_DIE;

/* DIE descriptor in the .debug_info section.
 * DIE descriptor contains one LEB128-encoded value, containing DIE's
 * abbreviation descriptor number in the .debug_abbrev section.
 *
 * DIE descriptor is immediately followed by the list of DIE attribute values,
 * format of wich is defined by the list of attribute descriptors in the
 * .debug_abbrev section, that immediately follow the DIE attribute descriptor,
 * addressed by this descriptor's abbr_num LEB128.
 */
typedef struct ELFF_PACKED Dwarf_DIE {
  /* 1 - based index of DIE abbreviation descriptor (Dwarf_Abbr_DIE) for this
   * DIE in the .debug_abbrev section.
   *
   * NOTE: DIE abbreviation descriptor indexes are tied to the compilation
   * unit. In other words, each compilation unit restarts counting DIE
   * abbreviation descriptors from 1.
   *
   * NOTE: Zero is invalid value for this field, indicating that this DIE is a
   * separator (usually it ends a list of "child" DIEs)
   */
  Dwarf_Leb128  abbr_num;

  /* Checks if this is a separator DIE. */
  bool is_separator() const {
    return abbr_num.val == 0;
  }

  /* Gets (1 - based) abbreviation number for this DIE. */
  Dwarf_AbbrNum get_abbr_num() const {
    Dwarf_Value val;
    abbr_num.get_unsigned(&val);
    return val.u16;
  }

  /* Pulls DIE information, advancing past this descriptor to DIE attributes.
   * Param:
   *  abbr_num - Upon return contains abbreviation number for this DIE. This
   *    parameter can be NULL, if the caller is not interested in this value.
   * Return:
   *  Pointer to the byte past this descriptor (the list of DIE attributes).
   */
  const Elf_Byte* process(Dwarf_AbbrNum* abbr_number) const {
    if (is_separator()) {
      if (abbr_number != NULL) {
        *abbr_number = 0;
      }
      // Size of a separator DIE is 1 byte.
      return INC_CPTR_T(Elf_Byte, &abbr_num.val, 1);
    }
    Dwarf_Value val;
    const void* ret = abbr_num.process_unsigned(&val);
    if (abbr_number != NULL) {
      *abbr_number = val.u32;
    }
    return reinterpret_cast<const Elf_Byte*>(ret);
  }
} Dwarf_DIE;

/*
 * Variable size headers.
 * When encoding size value in DWARF, the first 32 bits of a "size" header
 * define header type. If first 32 bits of the header contain 0xFFFFFFFF
 * value, this is 64-bit size header with the following 64 bits encoding
 * the size. Otherwise, if first 32 bits are not 0xFFFFFFFF, they contain
 * 32-bit size value.
 */

/* Size header for 32-bit DWARF. */
typedef struct ELFF_PACKED Dwarf32_SizeHdr {
  /* Size value. */
  Elf_Word  size;
} Dwarf32_SizeHdr;

/* Size header for 64-bit DWARF. */
typedef struct ELFF_PACKED Dwarf64_SizeHdr {
  /* Size selector. For 64-bit DWARF this field is set to 0xFFFFFFFF */
  Elf_Word  size_selector;

  /* Actual size value. */
  Elf_Xword   size;
} Dwarf64_SizeHdr;

/* Compilation unit header in the .debug_info section.
 * Template param:
 *  Dwarf_SizeHdr - Type for the header's size field. Must be Dwarf32_SizeHdr
 *    for 32-bit DWARF, or Dwarf64_SizeHdr for 64-bit DWARF.
 *  Elf_Off - Type for abbrev_offset field. Must be Elf_Word for for 32-bit
 *    DWARF, or Elf_Xword for 64-bit DWARF.
 */
template <typename Dwarf_SizeHdr, typename Elf_Off>
struct ELFF_PACKED Dwarf_CUHdr {
  /* Size of the compilation unit data in .debug_info section. */
  Dwarf_SizeHdr   size_hdr;

  /* Compilation unit's DWARF version stamp. */
  Elf_Half        version;

  /* Relative (to the beginning of .debug_abbrev section data) offset of the
   * beginning of abbreviation sequence for this compilation unit.
   */
  Elf_Off         abbrev_offset;

  /* Pointer size for this compilation unit (should be 4, or 8). */
  Elf_Byte        address_size;
};
/* Compilation unit header in the .debug_info section for 32-bit DWARF. */
typedef Dwarf_CUHdr<Dwarf32_SizeHdr, Elf_Word> Dwarf32_CUHdr;
/* Compilation unit header in the .debug_info section for 64-bit DWARF. */
typedef Dwarf_CUHdr<Dwarf64_SizeHdr, Elf_Xword> Dwarf64_CUHdr;

/* CU STMTL header in the .debug_line section.
 * Template param:
 *  Dwarf_SizeHdr - Type for the header's size field. Must be Dwarf32_SizeHdr
 *    for 32-bit DWARF, or Dwarf64_SizeHdr for 64-bit DWARF.
 *  Elf_Size - Type for header_length field. Must be Elf_Word for for 32-bit
 *    DWARF, or Elf_Xword for 64-bit DWARF.
 */
template <typename Dwarf_SizeHdr, typename Elf_Size>
struct ELFF_PACKED Dwarf_STMTLHdr {
  /* The size in bytes of the line number information for this compilation
   * unit, not including the unit_length field itself. */
  Dwarf_SizeHdr unit_length;

  /* A version number. This number is specific to the line number information
   * and is independent of the DWARF version number. */
  Elf_Half      version;

  /* The number of bytes following the header_length field to the beginning of
   * the first byte of the line number program itself. In the 32-bit DWARF
   * format, this is a 4-byte unsigned length; in the 64-bit DWARF format,
   * this field is an 8-byte unsigned length. */
  Elf_Size      header_length;

  /* The size in bytes of the smallest target machine instruction. Line number
   * program opcodes that alter the address register first multiply their
   * operands by this value. */
  Elf_Byte      min_instruction_len;

  /* The initial value of the is_stmt register. */
  Elf_Byte      default_is_stmt;

  /* This parameter affects the meaning of the special opcodes. */
  Elf_Sbyte     line_base;

  /* This parameter affects the meaning of the special opcodes. */
  Elf_Byte      line_range;

  /* The number assigned to the first special opcode. */
  Elf_Byte      opcode_base;

  /* This is first opcode in an array specifying the number of LEB128 operands
   * for each of the standard opcodes. The first element of the array
   * corresponds to the opcode whose value is 1, and the last element
   * corresponds to the opcode whose value is opcode_base - 1. By increasing
   * opcode_base, and adding elements to this array, new standard opcodes can
   * be added, while allowing consumers who do not know about these new opcodes
   * to be able to skip them. NOTE: this array points to the mapped
   * .debug_line section. */
  Elf_Byte      standard_opcode_lengths;
};
/* CU STMTL header in the .debug_line section for 32-bit DWARF. */
typedef Dwarf_STMTLHdr<Dwarf32_SizeHdr, Elf_Word> Dwarf32_STMTLHdr;
/* CU STMTL header in the .debug_line section for 64-bit DWARF. */
typedef Dwarf_STMTLHdr<Dwarf64_SizeHdr, Elf_Xword> Dwarf64_STMTLHdr;

/* Source file descriptor in the .debug_line section.
 * Descriptor begins with zero-terminated file name, followed by an ULEB128,
 * encoding directory index in the list of included directories, followed by
 * an ULEB12, encoding file modification time, followed by an ULEB12, encoding
 * file size.
 */
typedef struct ELFF_PACKED Dwarf_STMTL_FileDesc {
  /* Zero-terminated file name. */
  char  file_name[1];

  /* Checks of this descriptor ends the list. */
  bool is_last_entry() const {
    return file_name[0] == '\0';
  }

  /* Gets file name. */
  const char* get_file_name() const {
    return file_name;
  }

  /* Processes this descriptor, advancing to the next one.
   * Param:
   *  dir_index - Upon return contains index of the parent directory in the
   *    list of included directories. Can be NULL if caller is not interested
   *    in this value.
   * Return:
   *  Pointer to the next source file descriptor in the list.
   */
  const Dwarf_STMTL_FileDesc* process(Elf_Word* dir_index) const {
    if (is_last_entry()) {
      return this;
    }

    /* First parameter: include directory index. */
    Dwarf_Value tmp;
    const Dwarf_Leb128* leb =
        INC_CPTR_T(Dwarf_Leb128, file_name, strlen(file_name) + 1);
    leb = reinterpret_cast<const Dwarf_Leb128*>(leb->process_unsigned(&tmp));
    if (dir_index != NULL) {
      *dir_index = tmp.u32;
    }
    /* Process file time. */
    leb = reinterpret_cast<const Dwarf_Leb128*>(leb->process_unsigned(&tmp));
    /* Process file size. */
    return reinterpret_cast<const Dwarf_STMTL_FileDesc*>(leb->process_unsigned(&tmp));
  }

  /* Gets directory index for this descriptor. */
  Elf_Word get_dir_index() const {
    assert(!is_last_entry());
    if (is_last_entry()) {
      return 0;
    }
    /* Get directory index. */
    Dwarf_Value ret;
    const Dwarf_Leb128* leb =
      INC_CPTR_T(Dwarf_Leb128, file_name, strlen(file_name) + 1);
    leb->process_unsigned(&ret);
    return ret.u32;
  }
} Dwarf_STMTL_FileDesc;

/* Encapsulates a DIE attribute, collected during ELF file parsing.
 */
class DIEAttrib {
 public:
  /* Constructs DIEAttrib intance. */
  DIEAttrib()
      : at_(0),
        form_(0) {
    value_.type = DWARF_VALUE_UNKNOWN;
  }

  /* Destructs DIEAttrib intance. */
  ~DIEAttrib() {
  }

  /* Gets DWARF attribute ID (DW_AT_Xxx) for this property. */
  Dwarf_At at() const {
    return at_;
  }

  /* Gets DWARF form ID (DW_FORM_Xxx) for this property. */
  Dwarf_Form form() const {
    return form_;
  }

  /* Gets value of this property. */
  const Dwarf_Value* value() const {
    return &value_;
  }

  /* Value of this property. */
  Dwarf_Value   value_;

  /* DWARF attribute ID (DW_AT_Xxx) for this property. */
  Dwarf_At      at_;

  /* DWARF form ID (DW_FORM_Xxx) for this property. */
  Dwarf_Form    form_;
};

/* Parse tag context.
 * This structure is used as an ELF file parsing parameter, limiting collected
 * DIEs by the list of tags.
 */
typedef struct DwarfParseContext {
  /* Zero-terminated list of tags to collect DIEs for. If this field is NULL,
   * DIEs for all tags will be collected during the parsing. */
  const Dwarf_Tag*  tags;
} DwarfParseContext;

/* Checks if a DIE with the given tag should be collected during the parsing.
 * Param:
 *  parse_context - Parse context to check the tag against. This parameter can
 *  be NULL, indicating that all tags should be collected.
 *  tag - Tag to check.
 * Return:
 *  true if a DIE with the given tag should be collected during the parsing,
 *  or false, if the DIE should not be collected.
 */
static inline bool
collect_die(const DwarfParseContext* parse_context, Dwarf_Tag tag) {
  if (parse_context == NULL || parse_context->tags == NULL) {
    return true;
  }
  for (const Dwarf_Tag* tags = parse_context->tags; *tags != 0; tags++) {
    if (*tags == tag) {
      return true;
    }
  }
  return false;
}

/* Encapsulates an array of Dwarf_Abbr_DIE pointers, cached for a compilation
 * unit. Although Dwarf_Abbr_DIE descriptors in the .debug_abbrev section of
 * the ELF file seems to be always in sequential order, DIE descriptors may
 * reference them randomly. So, to provide better performance, we will cache
 * all Dwarf_Abbr_DIE pointers, that were found for each DIE. Since all of the
 * Dwarf_Abbr_DIE are sequential, an array is the best way to cache them.
 *
 * NOTE: Objects of this class are instantiated one per each CU, as all DIE
 * abbreviation numberation is restarted from 1 for each new CU.
 */
class DwarfAbbrDieArray {
 public:
  /* Constructs DwarfAbbrDieArray instance.
   * Most of the CUs don't have too many unique Dwarf_Abbr_DIEs, so, in order
   * to decrease the amount of memory allocation calls, we will preallocate
   * a relatively small array for them along with the instance of this class,
   * hopping, that all Dwarf_Abbr_DIEs for the CU will fit into it.
   */
  DwarfAbbrDieArray()
      : array_(&small_array_[0]),
        array_size_(ELFF_ARRAY_SIZE(small_array_)),
        count_(0) {
  }

  /* Destructs DwarfAbbrDieArray instance. */
  ~DwarfAbbrDieArray() {
    if (array_ != &small_array_[0]) {
      delete[] array_;
    }
  }

  /* Adds new entry to the array
   * Param:
   *  abbr - New entry to add.
   *  num - Abbreviation number for the adding entry.
   *    NOTE: before adding, this method will verify that descriptor for the
   *    given abbreviation number has not been cached yet.
   *    NOTE: due to the nature of this array, entries MUST be added strictly
   *    in sequential order.
   * Return:
   *  true on success, false on failure.
   */
  bool add(const Dwarf_Abbr_DIE* abbr, Dwarf_AbbrNum num) {
    assert(num != 0);
    if (num == 0) {
      // Zero is illegal DIE abbreviation number.
      _set_errno(EINVAL);
      return false;
    }

    if (num <= count_) {
      // Already cached.
      return true;
    }

    // Enforce strict sequential order.
    assert(num == (count_ + 1));
    if (num != (count_ + 1)) {
      _set_errno(EINVAL);
      return false;
    }

    if (num >= array_size_) {
      /* Expand the array. Make it 64 entries bigger than adding entry number.
       * NOTE: that we don't check for an overflow here, since we secured
       * ourselves from that by enforcing strict sequential order. So, an
       * overflow may happen iff number of entries cached in this array is
       * close to 4G, which is a) totally unreasonable, and b) we would die
       * long before this amount of entries is cached.
       */
      Dwarf_AbbrNum new_size = num + 64;

      // Reallocate.
      const Dwarf_Abbr_DIE** new_array = new const Dwarf_Abbr_DIE*[new_size];
      assert(new_array != NULL);
      if (new_array == NULL) {
        _set_errno(ENOMEM);
        return false;
      }
      memcpy(new_array, array_, count_ * sizeof(const Dwarf_Abbr_DIE*));
      if (array_ != &small_array_[0]) {
        delete[] array_;
      }
      array_ = new_array;
      array_size_ = new_size;
    }

    // Abbreviation numbers are 1-based.
    array_[num - 1] = abbr;
    count_++;
    return true;
  }

  /* Adds new entry to the array
   * Param:
   *  abbr - New entry to add.
   * Return:
   *  true on success, false on failure.
   */
  bool add(const Dwarf_Abbr_DIE* abbr) {
    return add(abbr, abbr->get_abbr_num());
  }

  /* Gets an entry from the array
   * Param:
   *  num - 1-based index of an entry to get.
   * Return:
   *  Entry on success, or NULL if num exceeds the number of entries
   *  contained in the array.
   */
  const Dwarf_Abbr_DIE* get(Dwarf_AbbrNum num) const {
    assert(num != 0 && num <= count_);
    if (num != 0 && num <= count_) {
      return array_[num - 1];
    } else {
      _set_errno(EINVAL);
      return NULL;
    }
  }

  /* Caches Dwarf_Abbr_DIEs into this array up to the requested number.
   * NOTE: This method cannot be called on an empty array. Usually, first
   * entry is inserted into this array when CU object is initialized.
   * Param:
   *  num - Entry number to cache entries up to.
   * Return:
   *  Last cached entry (actually, an entry for the 'num' index).
   */
  const Dwarf_Abbr_DIE* cache_to(Dwarf_AbbrNum num) {
    /* Last cached DIE abbreviation. We always should have cached at least one
     * abbreviation for the CU DIE itself, added via "add" method when CU
     * object was initialized. */
    const Dwarf_Abbr_DIE* cur_abbr = get(count_);
    assert(cur_abbr != NULL);
    if (cur_abbr == NULL) {
      return NULL;
    }

    /* Starting with the last cached DIE abbreviation, loop through the
     * remaining DIE abbreviations in the .debug_abbrev section of the
     * mapped ELF file, caching them until we reach the requested
     * abbreviation descriptor number. Normally, the very next DIE
     * abbreviation will stop the loop. */
    while (num > count_) {
      Dwarf_AbbrNum abbr_num;
      Dwarf_Tag tmp2;
      Dwarf_Form tmp3;
      Dwarf_At tmp4;

      /* Process all AT abbreviations for the current DIE entry, reaching next
       * DIE abbreviation. */
      const Dwarf_Abbr_AT* abbr_at = cur_abbr->process(&abbr_num, &tmp2);
      while (!abbr_at->is_separator()) {
        abbr_at = abbr_at->process(&tmp4, &tmp3);
      }

      // Next DIE abbreviation is right after the separator AT abbreviation.
      cur_abbr = reinterpret_cast<const Dwarf_Abbr_DIE*>
                                              (abbr_at->process(&tmp4, &tmp3));
      if (!add(cur_abbr)) {
        return NULL;
      }
    }

    return array_[num - 1];
  }

  /* Empties array and frees allocations. */
  void empty() {
    if (array_ != &small_array_[0]) {
      delete[] array_;
      array_ = &small_array_[0];
      array_size_ = sizeof(small_array_) / sizeof(small_array_[0]);
    }
    count_ = 0;
  }

 protected:
  /* Array, preallocated in anticipation of relatively small number of
   * DIE abbreviations in compilation unit. */
  const Dwarf_Abbr_DIE*   small_array_[64];

  /* Array of Dwarf_Abbr_DIE pointers, cached for a compilation unit. */
  const Dwarf_Abbr_DIE**  array_;

  /* Current size of the array. */
  Dwarf_AbbrNum           array_size_;

  /* Number of entries, cached in the array. */
  Dwarf_AbbrNum           count_;
};

/* Encapsulates a state machine for the "Line Number Program", that is run
 * on data conained in the mapped .debug_line section.
 */
class DwarfStateMachine {
 public:
  /* Constructs DwarfStateMachine instance.
   * Param:
   *  set_is_stmt - Matches value of default_is_stmt field in the STMTL header.
   *    see Dwarf_STMTL_HdrXX.
   */
  explicit DwarfStateMachine(bool set_is_stmt)
    : address_(0),
      file_(1),
      line_(1),
      column_(0),
      discriminator_(0),
      is_stmt_(set_is_stmt),
      basic_block_(false),
      end_sequence_(false),
      prologue_end_(false),
      epilogue_begin_(false),
      isa_(0),
      set_file_info_(NULL) {
  }

  /* Destructs DwarfStateMachine instance. */
  ~DwarfStateMachine() {
  }

  /* Resets the state to default.
   * Param:
   *  set_is_stmt - Matches value of default_is_stmt field in the STMTL header.
   *    see Dwarf_STMTL_HdrXX.
  */
  void reset(bool set_is_stmt) {
    address_ = 0;
    file_ = 1;
    line_ = 1;
    column_ = 0;
    discriminator_ = 0;
    is_stmt_ = set_is_stmt;
    basic_block_ = false;
    end_sequence_ = false;
    prologue_end_ = false;
    epilogue_begin_ = false;
    isa_ = 0;
    set_file_info_ = NULL;
  }

  /*
   * Machine state.
   */

  /* Current address (current PC value). */
  Elf_Xword                   address_;

  /* Current index of source file descriptor. */
  Elf_Word                    file_;

  /* Current line in the current source file. */
  Elf_Word                    line_;

  /* Current column. */
  Elf_Word                    column_;

  /* Current discriminator value. */
  Elf_Word                    discriminator_;

  /* Current STMT flag. */
  bool                        is_stmt_;

  /* Current basic block flag. */
  bool                        basic_block_;

  /* Current end of sequence flag. */
  bool                        end_sequence_;

  /* Current end of prologue flag. */
  bool                        prologue_end_;

  /* Current epilogue begin flag. */
  bool                        epilogue_begin_;

  /* Current ISA value. */
  Elf_Word                    isa_;

  /* Current value for explicitly set current source file descriptor.
   * If not NULL, this descriptor has priority over the descriptor, addressed
   * by the file_ member of this class. */
  const Dwarf_STMTL_FileDesc* set_file_info_;
};

/* Checks if given tag belongs to a routine. */
static inline bool
dwarf_tag_is_routine(Dwarf_Tag tag) {
  return tag == DW_TAG_inlined_subroutine ||
         tag == DW_TAG_subprogram ||
         tag == DW_AT_main_subprogram;
}

/* Checks if given tag belongs to a compilation unit. */
static inline bool
dwarf_tag_is_cu(Dwarf_Tag tag) {
  return tag == DW_TAG_compile_unit ||
         tag == DW_TAG_partial_unit;
}

#endif  // ELFF_DWARF_DEFS_H_
