/* 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 implementation of a class DwarfCU, that encapsulates a compilation
 * unit in the .debug_info section of the mapped ELF file.
 */

#include "string.h"
#include "stdio.h"
#include "elf_file.h"
#include "dwarf_cu.h"
#include "dwarf_utils.h"

DwarfCU::DwarfCU(ElfFile* elf)
    : elf_file_(elf),
      cu_die_(NULL),
      prev_cu_(NULL) {
}

DwarfCU::~DwarfCU() {
  if (cu_die_ != NULL) {
    delete cu_die_;
  }
  abbrs_.empty();
}

DwarfCU* DwarfCU::create_instance(ElfFile* elf, const void* hdr) {
  DwarfCU* ret;

  /* 64-bit DWARF CU has first 4 bytes in its header set to 0xFFFFFFFF. */
  if (*reinterpret_cast<const Elf_Word*>(hdr) == 0xFFFFFFFF) {
    ret = new(elf) DwarfCUImpl<Dwarf64_CUHdr, Dwarf64_Off>
                      (elf, reinterpret_cast<const Dwarf64_CUHdr*>(hdr));
  } else {
    ret = new(elf) DwarfCUImpl<Dwarf32_CUHdr, Dwarf32_Off>
                      (elf, reinterpret_cast<const Dwarf32_CUHdr*>(hdr));
  }
  assert(ret != NULL);
  if (ret == NULL) {
    _set_errno(ENOMEM);
  }
  return ret;
}

const Elf_Byte* DwarfCU::process_attrib(const Elf_Byte* prop,
                                        Dwarf_Form form,
                                        Dwarf_Value* attr_value) const {
  assert(form != 0);
  Dwarf_Value tmp_val;
  Dwarf_Value leb128;

  attr_value->type = DWARF_VALUE_UNKNOWN;
  attr_value->encoded_size = 0;
  attr_value->u64 = 0;

  switch (form) {
    /* Property is a block of data, contained in .debug_info section. Block
     * size is encoded with 1 byte value, and block data immediately follows
     * block size. */
    case DW_FORM_block1:
      attr_value->type = DWARF_VALUE_BLOCK;
      attr_value->block.block_size = *prop;
      attr_value->block.block_ptr = prop + 1;
      attr_value->encoded_size =
          static_cast<Elf_Word>(attr_value->block.block_size + 1);
      break;

    /* Property is a block of data, contained in .debug_info section. Block
     * size is encoded with 2 bytes value, and block data immediately follows
     * block size. */
    case DW_FORM_block2:
      attr_value->type = DWARF_VALUE_BLOCK;
      attr_value->block.block_size =
          elf_file_->pull_val(reinterpret_cast<const Elf_Half*>(prop));
      attr_value->block.block_ptr = prop + 2;
      attr_value->encoded_size =
          static_cast<Elf_Word>(attr_value->block.block_size + 2);
      break;

    /* Property is a block of data, contained in .debug_info section. Block
     * size is encoded with 4 bytes value, and block data immediately follows
     * block size. */
    case DW_FORM_block4:
      attr_value->type = DWARF_VALUE_BLOCK;
      attr_value->block.block_size =
          elf_file_->pull_val(reinterpret_cast<const Elf_Word*>(prop));
      attr_value->block.block_ptr = prop + 4;
      attr_value->encoded_size =
          static_cast<Elf_Word>(attr_value->block.block_size + 4);
      break;

    /* Property is a block of data, contained in .debug_info section. Block
     * size is encoded with unsigned LEB128 value, and block data immediately
     * follows block size. */
    case DW_FORM_block:
      reinterpret_cast<const Dwarf_Leb128*>(prop)->process_unsigned(&leb128);
      attr_value->type = DWARF_VALUE_BLOCK;
      attr_value->block.block_size = leb128.u32;
      attr_value->block.block_ptr = prop + leb128.encoded_size;
      attr_value->encoded_size =
          static_cast<Elf_Word>(attr_value->block.block_size +
                                leb128.encoded_size);
      break;

    /* Property is unsigned 1 byte value. */
    case DW_FORM_flag:
    case DW_FORM_data1:
    case DW_FORM_ref1:
      attr_value->type = DWARF_VALUE_U8;
      attr_value->u8 = *prop;
      attr_value->encoded_size = 1;
      break;

    /* Property is unsigned 2 bytes value. */
    case DW_FORM_data2:
    case DW_FORM_ref2:
      attr_value->type = DWARF_VALUE_U16;
      attr_value->u16 =
          elf_file_->pull_val(reinterpret_cast<const Elf_Half*>(prop));
      attr_value->encoded_size = 2;
      break;

    /* Property is unsigned 4 bytes value. */
    case DW_FORM_data4:
    case DW_FORM_ref4:
      attr_value->type = DWARF_VALUE_U32;
      attr_value->u32 =
          elf_file_->pull_val(reinterpret_cast<const Elf_Word*>(prop));
      attr_value->encoded_size = 4;
      break;

    /* Property is unsigned 8 bytes value. */
    case DW_FORM_data8:
    case DW_FORM_ref8:
    case DW_FORM_ref_sig8:
      attr_value->type = DWARF_VALUE_U64;
      attr_value->u64 =
          elf_file_->pull_val(reinterpret_cast<const Elf_Xword*>(prop));
      attr_value->encoded_size = 8;
      break;

    /* Property is signed LEB128 value. */
    case DW_FORM_sdata:
      reinterpret_cast<const Dwarf_Leb128*>(prop)->process_signed(attr_value);
      break;

    /* Property is unsigned LEB128 value. */
    case DW_FORM_ref_udata:
    case DW_FORM_udata:
      reinterpret_cast<const Dwarf_Leb128*>(prop)->process_unsigned(attr_value);
      break;

    /* Property is a string contained directly in .debug_info section. */
    case DW_FORM_string:
      attr_value->type = DWARF_VALUE_STR;
      attr_value->str = reinterpret_cast<const char*>(prop);
      attr_value->encoded_size = strlen(attr_value->str) + 1;
      break;

    /* Property is an offset of a string contained in .debug_str section.
     * We will process the reference here, converting it into the actual
     * string value. */
    case DW_FORM_strp:
      attr_value->type = DWARF_VALUE_STR;
      if (elf_file_->is_DWARF_64()) {
        Elf_Xword str_offset =
            elf_file_->pull_val(reinterpret_cast<const Elf_Xword*>(prop));
        attr_value->str = elf_file_->get_debug_str(str_offset);
        attr_value->encoded_size = 8;
      } else {
        Elf_Word str_offset =
            elf_file_->pull_val(reinterpret_cast<const Elf_Word*>(prop));
        attr_value->str = elf_file_->get_debug_str(str_offset);
        attr_value->encoded_size = 4;
      }
      break;

    /* Property is an address. */
    case DW_FORM_addr:
      if (addr_sizeof_ == 4) {
        attr_value->type = DWARF_VALUE_PTR32;
        attr_value->u32 =
            elf_file_->pull_val(reinterpret_cast<const Elf_Word*>(prop));
      } else {
        attr_value->type = DWARF_VALUE_PTR64;
        attr_value->u64 =
            elf_file_->pull_val(reinterpret_cast<const Elf_Xword*>(prop));
      }
      attr_value->encoded_size = addr_sizeof_;
      break;

    /* Reference from the beginning of .debug_info section. */
    case DW_FORM_ref_addr:
      /* DWARF3+ requires that encoding size of this property must be 4 bytes
       * in 32-bit DWARF, and 8 bytes in 64-bit DWARF, while DWARF2- requires
       * encoding size to be equal to CU's pointer size. */
      if (is_DWARF3_or_higher()) {
        if (elf_file_->is_DWARF_64()) {
          attr_value->type = DWARF_VALUE_U64;
          attr_value->u64 =
              elf_file_->pull_val(reinterpret_cast<const Elf_Xword*>(prop));
          attr_value->encoded_size = 4;
        } else {
          attr_value->type = DWARF_VALUE_U32;
          attr_value->u32 =
              elf_file_->pull_val(reinterpret_cast<const Elf_Word*>(prop));
          attr_value->encoded_size = 8;
        }
      } else {
        if (addr_sizeof_ == 4) {
          attr_value->type = DWARF_VALUE_U32;
          attr_value->u32 =
              elf_file_->pull_val(reinterpret_cast<const Elf_Word*>(prop));
        } else {
          attr_value->type = DWARF_VALUE_U64;
          attr_value->u64 =
              elf_file_->pull_val(reinterpret_cast<const Elf_Xword*>(prop));
        }
        attr_value->encoded_size = addr_sizeof_;
      }
      break;

    /* Reference to a section, other than .debug_info, or .debug_str */
    case DW_FORM_sec_offset:
      if (elf_file_->is_DWARF_64()) {
        attr_value->type = DWARF_VALUE_U64;
        attr_value->u64 =
            elf_file_->pull_val(reinterpret_cast<const Elf_Xword*>(prop));
        attr_value->encoded_size = 4;
      } else {
        attr_value->type = DWARF_VALUE_U32;
        attr_value->u32 =
            elf_file_->pull_val(reinterpret_cast<const Elf_Word*>(prop));
        attr_value->encoded_size = 8;
      }
      break;

    /* This is a replacement for DW_FORM_flag, which doesn't consume memory
     * in .debug_info section, and only by the fact of its existence it is
     * equal to DW_FORM_flag with value set to 1. */
    case DW_FORM_flag_present:
      attr_value->type = DWARF_VALUE_U8;
      attr_value->u8 = 1;
      attr_value->encoded_size = 0;
      break;

    /* Encodes the actual form to be used. */
    case DW_FORM_indirect:
      // Starts with ULEB128
      prop = reinterpret_cast<const Elf_Byte*>
                (reinterpret_cast<const Dwarf_Leb128*>
                    (prop)->process_unsigned(&tmp_val));
      /* ULEB128 encodes the actual form to be used to process this entry. */
      process_attrib(prop, tmp_val.u16, attr_value);
      attr_value->encoded_size += tmp_val.encoded_size;
      break;

    /* This form is defined for DWARF4, and has no documentation whatsoever. */
    case DW_FORM_exprloc:
    default:
      attr_value->type = DWARF_VALUE_U32;
      attr_value->u32 =
          elf_file_->pull_val(reinterpret_cast<const Elf_Word*>(prop));
      attr_value->encoded_size = 4;
      break;
  }

  return prop + attr_value->encoded_size;
}

void DwarfCU::dump() const {
  printf("\n\n>>>>>>>>>>>>>>> CU %p (version %u, address size %u)\n",
         cu_die_->die(), static_cast<Elf_Word>(version_),
         static_cast<Elf_Word>(addr_sizeof_));
  printf(">>>>> Build dir path:  %s\n", comp_dir_path());
  printf(">>>>> Build file path: %s\n", rel_cu_path());
  if (cu_die_ != NULL) {
    cu_die_->dump(false);
  }
}

//=============================================================================
// DwarfCUImpl implementation
//=============================================================================

template <typename Dwarf_CUHdr, typename Dwarf_Off>
DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::DwarfCUImpl(ElfFile* elf,
                                                 const Dwarf_CUHdr* hdr)
    : DwarfCU(elf),
      cu_header_(hdr) {
  /* Cache CU's DIE abbreviation descriptor in the array. This MUST be done
   * BEFORE first call to array's cache_to() method. */
  const Dwarf_Abbr_DIE* cu_abbr_die = reinterpret_cast<const Dwarf_Abbr_DIE*>
                                 (INC_CPTR(elf->get_debug_abbrev_data(),
                                           elf->pull_val(hdr->abbrev_offset)));
  abbrs_.add(cu_abbr_die);

  cu_size_ = elf->pull_val(hdr->size_hdr.size);
  version_ = elf->pull_val(hdr->version);
  addr_sizeof_ = hdr->address_size;
  memset(&stmtl_header_, 0, sizeof(stmtl_header_));
}

template <typename Dwarf_CUHdr, typename Dwarf_Off>
bool DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::parse(
    const DwarfParseContext* parse_context,
    const void** next_cu_die) {
  /* Start parsing with the DIE for this CU. */
  if (process_DIE(parse_context, get_DIE(), NULL) == NULL) {
    return false;
  }

  /* CU area size (thus, next CU header offset) in .debug_info section equals
   * to CU size, plus number of bytes, required to encode CU size in CU header
   * (4 for 32-bit CU, and 12 for 64-bit CU. */
  *next_cu_die =
      INC_CPTR(cu_header_, cu_size_ + ELFF_FIELD_OFFSET(Dwarf_CUHdr, version));

  return true;
}

template <typename Dwarf_CUHdr, typename Dwarf_Off>
const Elf_Byte* DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::process_DIE(
    const DwarfParseContext* parse_context,
    const Dwarf_DIE* die,
    DIEObject* parent_obj) {
  while (is_attrib_ptr_valid(die) && !die->is_separator()) {
    Dwarf_AbbrNum abbr_num;
    Dwarf_Tag     die_tag;
    Elf_Word      sibling_off = 0;

    /* Get DIE's abbreviation number, and advance to DIE's properties. */
    const Elf_Byte* die_attr = die->process(&abbr_num);

    /* Get abbreviation for the current DIE. */
    const Dwarf_Abbr_DIE* die_abbr = abbrs_.cache_to(abbr_num);
    if (die_abbr == NULL) {
      return NULL;
    }

    /* Get base DIE properties, and advance to the DIE's
     * attribute descriptors. */
    const Dwarf_Abbr_AT* at_abbr = die_abbr->process(NULL, &die_tag);

    /* Instantiate DIE object for this DIE, and get list of properties,
     * that should be collected while processing that DIE. */
    DIEObject* die_obj =
      create_die_object(parse_context, die, parent_obj, die_tag);
    if (die_obj == NULL && errno != 0) {
      return NULL;
    }

    if (die_obj != NULL) {
      if (parent_obj != NULL) {
        /* Update list of parent's children. */
        die_obj->link_sibling(parent_obj->last_child());
        parent_obj->link_child(die_obj);
      } else {
        /* NULL parent object is allowed only for CU DIE itself. */
        assert(cu_die_ == NULL && die_tag == DW_TAG_compile_unit);
        if (cu_die_ == NULL && die_tag != DW_TAG_compile_unit) {
          _set_errno(EINVAL);
          return NULL;
        }
        cu_die_ = die_obj;
        /* This CU DIE object will be used as a parent for all DIE
         * objects, created in this method. */
        parent_obj = cu_die_;
      }
    }

    // Loop through all DIE properties.
    while (elf_file_->is_valid_abbr_ptr(at_abbr, sizeof(Dwarf_Abbr_AT)) &&
           !at_abbr->is_separator()) {
      Dwarf_At    at_value;
      Dwarf_Form  at_form;
      Dwarf_Value attr_value;

      // Obtain next property value.
      at_abbr = at_abbr->process(&at_value, &at_form);
      die_attr = process_attrib(die_attr, at_form, &attr_value);

      if (at_value == DW_AT_sibling) {
        /* DW_AT_sibling means that next DIE is a child of the one that's
         * being currently processed. We need to cache value of this property
         * in order to correctly calculate next sibling of this DIE after
         * child's DIE has been processed. */
        assert(sibling_off == 0);
        sibling_off = attr_value.u32;
      }
    }

    /* Next DIE immediately follows last property for the current DIE. */
    die = reinterpret_cast<const Dwarf_DIE*>(die_attr);
    if (sibling_off != 0) {
      // Process child DIE.
      process_DIE(parse_context, die, die_obj != NULL ? die_obj : parent_obj);
      // Next sibling DIE offset is relative to this CU's header beginning.
      die = INC_CPTR_T(Dwarf_DIE, cu_header_, sibling_off);
    }
  }

  return INC_CPTR_T(Elf_Byte, die, 1);
}

template <typename Dwarf_CUHdr, typename Dwarf_Off>
DIEObject* DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::create_die_object(
    const DwarfParseContext* parse_context,
    const Dwarf_DIE* die,
    DIEObject* parent,
    Dwarf_Tag tag) {
  DIEObject* ret = NULL;

  /* We will always create a DIE object for CU DIE. */
  if (tag == DW_TAG_compile_unit || collect_die(parse_context, tag)) {
    ret = new(elf_file_) DIEObject(die, this, parent);
    assert(ret != NULL);
    if (ret == NULL) {
      _set_errno(ENOMEM);
    }
  } else {
    _set_errno(0);
  }
  return ret;
}

template <typename Dwarf_CUHdr, typename Dwarf_Off>
bool DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::init_stmtl() {
  if (stmtl_header_.unit_length != 0) {
    return true;
  }

  assert(cu_die_ != NULL);
  if (cu_die_ == NULL) {
    _set_errno(EINVAL);
    return false;
  }

  DIEAttrib stmtl;
  if (!cu_die()->get_attrib(DW_AT_stmt_list, &stmtl)) {
    _set_errno(EINVAL);
    return false;
  }

  const void* stmtl_start =
      INC_CPTR(elf_file()->get_debug_line_data(), stmtl.value()->u32);
  if (*reinterpret_cast<const Elf_Word*>(stmtl_start) == 0xFFFFFFFF) {
    cache_stmtl<Dwarf64_STMTLHdr>(reinterpret_cast<const Dwarf64_STMTLHdr*>(stmtl_start));
  } else {
    cache_stmtl<Dwarf32_STMTLHdr>(reinterpret_cast<const Dwarf32_STMTLHdr*>(stmtl_start));
  }

  return true;
}

template <typename Dwarf_CUHdr, typename Dwarf_Off>
bool DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::get_pc_address_file_info(
    Elf_Xword address,
    Dwarf_AddressInfo* info) {
  /* Make sure STMTL header is cached. */
  if (!init_stmtl()) {
    return false;
  }
  /* Flags address match, that should trigger return next time
   * source line gets adjusted. */
  bool found = false;
  /* Create new state machine. */
  DwarfStateMachine state(stmtl_header_.default_is_stmt != 0);

  /* Start the "Line Number Program" */
  const Elf_Byte* go = stmtl_header_.start;
  while (go < stmtl_header_.end) {
    const Elf_Byte op = *go;
    go++;

    if (op == 0) {
      /* This is an extended opcode. */
      Dwarf_Value op_size;

      /* First ULEB128 contains opcode size, (excluding ULEB128 itself). */
      go = reinterpret_cast<const Elf_Byte*>
             (reinterpret_cast<const Dwarf_Leb128*>(go)->process_unsigned(&op_size));
      /* Next is the extended opcode. */
      const Elf_Byte* ex_op_ptr = go;
      switch (*ex_op_ptr) {
        case DW_LNE_end_sequence:
          state.end_sequence_ = true;
          state.reset(stmtl_header_.default_is_stmt != 0);
          found = false;
          break;

        case DW_LNE_set_address: {
          Elf_Xword prev_address = state.address_;
          if (is_CU_address_64()) {
            state.address_ =
              elf_file()->pull_val(reinterpret_cast<const Elf_Xword*>(ex_op_ptr + 1));
          } else {
            state.address_ =
              elf_file()->pull_val(reinterpret_cast<const Elf_Word*>(ex_op_ptr + 1));
          }
          if (prev_address != 0 &&
              address >= prev_address && address < state.address_) {
            return set_source_info(&state, info);
          } else if (address == state.address_) {
            found = true;
          }
          break;
        }

        case DW_LNE_define_file: {
          /* Parameters start with the directly encoded zero-terminated
           * file name. */
          state.set_file_info_ = INC_CPTR_T(Dwarf_STMTL_FileDesc, ex_op_ptr, 1);
          assert(state.set_file_info_ != NULL);
          if (state.set_file_info_ != NULL) {
            ex_op_ptr = reinterpret_cast<const Elf_Byte*>(state.set_file_info_->process(NULL));
          }
          break;
        }

        case DW_LNE_set_discriminator: {
          Dwarf_Value discr_val;
          /* One parameter: discriminator's ULEB128 value. */
          reinterpret_cast<const Dwarf_Leb128*>(ex_op_ptr + 1)->process_unsigned(&discr_val);
          state.discriminator_ = discr_val.u32;
          break;
        }

        default:
          assert(0);
          return false;
      }
      go += op_size.u32;
    } else if (op < stmtl_header_.opcode_base) {
      /* This is a standard opcode. */
      switch (op) {
        case DW_LNS_copy:
          /* No parameters. */
          state.basic_block_ = false;
          state.prologue_end_ = false;
          state.epilogue_begin_ = false;
          break;

        case DW_LNS_advance_pc: {
          /* One parameter: ULEB128 value to add to the current address value
           * in the state machine. */
          Dwarf_Value addr_add;
          go = reinterpret_cast<const Elf_Byte*>
              (reinterpret_cast<const Dwarf_Leb128*>(go)->process_unsigned(&addr_add));
          Elf_Xword prev_address = state.address_;
          state.address_ += addr_add.u64;
          if (prev_address != 0 &&
              address >= prev_address && address < state.address_) {
            return set_source_info(&state, info);
          } else if (address == state.address_) {
            found = true;
          }
          break;
        }

        case DW_LNS_advance_line: {
          /* One parameter: signed LEB128 value to add to the current line
           * number in the state machine. */
          Dwarf_Value line_add;
          go = reinterpret_cast<const Elf_Byte*>
              (reinterpret_cast<const Dwarf_Leb128*>(go)->process_signed(&line_add));
          state.line_ += line_add.s32;
          if (found) {
            return set_source_info(&state, info);
          }
          break;
        }

        case DW_LNS_set_file: {
          /* One parameter: ULEB128 value encoding current file number. */
          Dwarf_Value file_num;
          go = reinterpret_cast<const Elf_Byte*>
              (reinterpret_cast<const Dwarf_Leb128*>(go)->process_unsigned(&file_num));
          state.file_ = file_num.u32;
          /* This operation should discard previously saved file information. */
          state.set_file_info_ = NULL;
          break;
        }

        case DW_LNS_set_column: {
          /* One parameter: ULEB128 value encoding current column number. */
          Dwarf_Value column_num;
          go = reinterpret_cast<const Elf_Byte*>
              (reinterpret_cast<const Dwarf_Leb128*>(go)->process_unsigned(&column_num));
          state.column_ = column_num.u32;
          break;
        }

        case DW_LNS_negate_stmt:
          /* No parameters. */
          state.is_stmt_ = !state.is_stmt_;
          break;

        case DW_LNS_set_basic_block:
          /* No parameters. */
          state.basic_block_ = true;
          break;

        case DW_LNS_const_add_pc: {
          Elf_Xword prev_address = state.address_;
          /* No parameters. This operation does the same thing, as special
           * opcode 255 would do to the current address. */
          Elf_Word adjusted =
              static_cast<Elf_Word>(255) - stmtl_header_.opcode_base;
          state.address_ += (adjusted / stmtl_header_.line_range) *
                            stmtl_header_.min_instruction_len;
          if (prev_address != 0 &&
              address >= prev_address && address < state.address_) {
            return set_source_info(&state, info);
          } else if (address == state.address_) {
            found = true;
          }
          break;
        }

        case DW_LNS_fixed_advance_pc: {
          Elf_Xword prev_address = state.address_;
          /* One parameter: directly encoded 16-bit value to add to the
           * current address. */
          state.address_ +=
              elf_file()->pull_val(reinterpret_cast<const Elf_Half*>(go));
          if (prev_address != 0 &&
              address >= prev_address && address < state.address_) {
            return set_source_info(&state, info);
          } else if (address == state.address_) {
            found = true;
          }
          go += sizeof(Elf_Half);
          break;
        }

        case DW_LNS_set_prologue_end:
          /* No parameters. */
          state.prologue_end_ = true;
          break;

        case DW_LNS_set_epilogue_begin:
          /* No parameters. */
          state.epilogue_begin_ = true;
          break;

        case DW_LNS_set_isa: {
          /* One parameter: ISA value encoded as ULEB128. */
          Dwarf_Value isa_val;
          go = reinterpret_cast<const Elf_Byte*>
              (reinterpret_cast<const Dwarf_Leb128*>(go)->process_unsigned(&isa_val));
          state.isa_ = isa_val.u32;
          break;
        }

        default:
          /* Unknown opcode. Just skip it. */
          for (Elf_Byte uleb = 0;
               uleb < stmtl_header_.standard_opcode_lengths[op - 1]; uleb++) {
            Dwarf_Value tmp;
            go = reinterpret_cast<const Elf_Byte*>
              (reinterpret_cast<const Dwarf_Leb128*>(go)->process_unsigned(&tmp));
          }
          break;
      }
    } else {
      Elf_Xword prev_address = state.address_;
      /* This is a special opcode. */
      const Elf_Word adjusted = op - stmtl_header_.opcode_base;
      /* Advance address. */
      state.address_ += (adjusted / stmtl_header_.line_range) *
                        stmtl_header_.min_instruction_len;
      if (prev_address != 0 &&
          address >= prev_address && address < state.address_) {
        return set_source_info(&state, info);
      }
      /* Advance line. */
      state.line_ += stmtl_header_.line_base +
                     (adjusted % stmtl_header_.line_range);
      if (state.address_ == address) {
        return set_source_info(&state, info);
      }
      /* Do the woodoo. */
      state.basic_block_ = false;
      state.prologue_end_ = false;
      state.epilogue_begin_ = false;
    }
  }

  return false;
}

template <typename Dwarf_CUHdr, typename Dwarf_Off>
const Dwarf_STMTL_FileDesc* DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::get_stmt_file_info(
    Elf_Word index) {
  /* Index must be 1-based. */
  if (index == 0) {
    return NULL;
  }

  const Dwarf_STMTL_FileDesc* cur_desc = stmtl_header_.file_infos;
  while (index != 1 && !cur_desc->is_last_entry()) {
    cur_desc = cur_desc->process(NULL);
    index--;
  }
  assert(!cur_desc->is_last_entry());
  return cur_desc->is_last_entry() ? NULL : cur_desc;
}

template <typename Dwarf_CUHdr, typename Dwarf_Off>
const char* DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::get_stmt_dir_name(
    Elf_Word dir_index) {
  if (dir_index == 0) {
    /* Requested is current compilation directory. */
    return comp_dir_path();
  }
  if (dir_index > stmtl_header_.inc_dir_num) {
    return NULL;
  }

  const char* cur_dir = stmtl_header_.include_directories;
  while (dir_index != 1) {
    cur_dir += strlen(cur_dir) + 1;
    dir_index--;
  }
  return cur_dir;
}

template <typename Dwarf_CUHdr, typename Dwarf_Off>
bool DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::set_source_info(
    const DwarfStateMachine* state,
    Dwarf_AddressInfo* info) {
  info->line_number = state->line_;
  const Dwarf_STMTL_FileDesc* file_info = state->set_file_info_;
  if (file_info == NULL) {
    file_info = get_stmt_file_info(state->file_);
    if (file_info == NULL) {
      info->file_name = rel_cu_path();
      info->dir_name = comp_dir_path();
      return true;
    }
  }
  info->file_name = file_info->get_file_name();
  const Elf_Word dir_index = file_info->get_dir_index();
  info->dir_name = get_stmt_dir_name(dir_index);
  return true;
}

