// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/zucchini/disassembler_elf.h"

#include <stddef.h>

#include <utility>

#include "base/logging.h"
#include "base/numerics/checked_math.h"
#include "base/numerics/safe_conversions.h"
#include "components/zucchini/abs32_utils.h"
#include "components/zucchini/algorithm.h"
#include "components/zucchini/arm_utils.h"
#include "components/zucchini/buffer_source.h"

namespace zucchini {

namespace {

constexpr uint64_t kElfImageBase = 0;
constexpr size_t kSizeBound = 0x7FFF0000;

// Threshold value for heuristics to detect THUMB2 code.
constexpr double kAArch32BitCondAlwaysDensityThreshold = 0.4;

// Bit fields for JudgeSection() return value.
enum SectionJudgement : int {
  // Bit: Section does not invalidate ELF, but may or may not be useful.
  SECTION_BIT_SAFE = 1 << 0,
  // Bit: Section useful for AddressTranslator, to map between offsets and RVAs.
  SECTION_BIT_USEFUL_FOR_ADDRESS_TRANSLATOR = 1 << 1,
  // Bit: Section useful for |offset_bound|, to estimate ELF size.
  SECTION_BIT_USEFUL_FOR_OFFSET_BOUND = 1 << 2,
  // Bit: Section potentially useful for pointer extraction.
  SECTION_BIT_MAYBE_USEFUL_FOR_POINTERS = 1 << 3,

  // The following are verdicts from combining bits, to improve semantics.
  // Default value: A section is malformed and invalidates ELF.
  SECTION_IS_MALFORMED = 0,
  // Section does not invalidate ELF, but is also not used for anything.
  SECTION_IS_USELESS = SECTION_BIT_SAFE,
};

// Decides how a section affects ELF parsing, and returns a bit field composed
// from SectionJudgement values.
template <class TRAITS>
int JudgeSection(size_t image_size, const typename TRAITS::Elf_Shdr* section) {
  // BufferRegion uses |size_t| this can be 32-bit in some cases. For Elf64
  // |sh_addr|, |sh_offset| and |sh_size| are 64-bit this can result in
  // overflows in the subsequent validation steps.
  if (!base::IsValueInRangeForNumericType<size_t>(section->sh_addr) ||
      !base::IsValueInRangeForNumericType<size_t>(section->sh_offset) ||
      !base::IsValueInRangeForNumericType<size_t>(section->sh_size)) {
    return SECTION_IS_MALFORMED;
  }

  // Examine RVA range: Reject if numerical overflow may happen.
  if (!BufferRegion{static_cast<size_t>(section->sh_addr),
                    static_cast<size_t>(section->sh_size)}
           .FitsIn(kSizeBound))
    return SECTION_IS_MALFORMED;

  // Examine offset range: If section takes up |image| data then be stricter.
  size_t offset_bound =
      (section->sh_type == elf::SHT_NOBITS) ? kSizeBound : image_size;
  if (!BufferRegion{static_cast<size_t>(section->sh_offset),
                    static_cast<size_t>(section->sh_size)}
           .FitsIn(offset_bound))
    return SECTION_IS_MALFORMED;

  // Empty sections don't contribute to offset-RVA mapping. For consistency, it
  // should also not affect |offset_bounds|.
  if (section->sh_size == 0)
    return SECTION_IS_USELESS;

  // Sections with |sh_addr == 0| are ignored because these tend to duplicates
  // (can cause problems for lookup) and uninteresting. For consistency, it
  // should also not affect |offset_bounds|.
  if (section->sh_addr == 0)
    return SECTION_IS_USELESS;

  if (section->sh_type == elf::SHT_NOBITS) {
    // Special case for .tbss sections: These should be ignored because they may
    // have offset-RVA map that don't match other sections.
    if (section->sh_flags & elf::SHF_TLS)
      return SECTION_IS_USELESS;

    // Section is useful for offset-RVA translation, but does not affect
    // |offset_bounds| since it can have large virtual size (e.g., .bss).
    return SECTION_BIT_SAFE | SECTION_BIT_USEFUL_FOR_ADDRESS_TRANSLATOR;
  }

  return SECTION_BIT_SAFE | SECTION_BIT_USEFUL_FOR_ADDRESS_TRANSLATOR |
         SECTION_BIT_USEFUL_FOR_OFFSET_BOUND |
         SECTION_BIT_MAYBE_USEFUL_FOR_POINTERS;
}

// Determines whether |section| is a reloc section.
template <class TRAITS>
bool IsRelocSection(const typename TRAITS::Elf_Shdr& section) {
  DCHECK_GT(section.sh_size, 0U);
  if (section.sh_type == elf::SHT_REL) {
    // Also validate |section.sh_entsize|, which gets used later.
    return section.sh_entsize == sizeof(typename TRAITS::Elf_Rel);
  }
  if (section.sh_type == elf::SHT_RELA)
    return section.sh_entsize == sizeof(typename TRAITS::Elf_Rela);
  return false;
}

// Determines whether |section| is a section with executable code.
template <class TRAITS>
bool IsExecSection(const typename TRAITS::Elf_Shdr& section) {
  DCHECK_GT(section.sh_size, 0U);
  return section.sh_type == elf::SHT_PROGBITS &&
         (section.sh_flags & elf::SHF_EXECINSTR) != 0;
}

}  // namespace

/******** Elf32Traits ********/

// static
constexpr Bitness Elf32Traits::kBitness;
constexpr elf::FileClass Elf32Traits::kIdentificationClass;

/******** Elf32IntelTraits ********/

// static
constexpr ExecutableType Elf32IntelTraits::kExeType;
const char Elf32IntelTraits::kExeTypeString[] = "ELF x86";
constexpr elf::MachineArchitecture Elf32IntelTraits::kMachineValue;
constexpr uint32_t Elf32IntelTraits::kRelType;

/******** ElfAArch32Traits ********/

// static
constexpr ExecutableType ElfAArch32Traits::kExeType;
const char ElfAArch32Traits::kExeTypeString[] = "ELF ARM";
constexpr elf::MachineArchitecture ElfAArch32Traits::kMachineValue;
constexpr uint32_t ElfAArch32Traits::kRelType;

/******** Elf64Traits ********/

// static
constexpr Bitness Elf64Traits::kBitness;
constexpr elf::FileClass Elf64Traits::kIdentificationClass;

/******** Elf64IntelTraits ********/

// static
constexpr ExecutableType Elf64IntelTraits::kExeType;
const char Elf64IntelTraits::kExeTypeString[] = "ELF x64";
constexpr elf::MachineArchitecture Elf64IntelTraits::kMachineValue;
constexpr uint32_t Elf64IntelTraits::kRelType;

/******** ElfAArch64Traits ********/

// static
constexpr ExecutableType ElfAArch64Traits::kExeType;
const char ElfAArch64Traits::kExeTypeString[] = "ELF ARM64";
constexpr elf::MachineArchitecture ElfAArch64Traits::kMachineValue;
constexpr uint32_t ElfAArch64Traits::kRelType;

/******** DisassemblerElf ********/

// static.
template <class TRAITS>
bool DisassemblerElf<TRAITS>::QuickDetect(ConstBufferView image) {
  BufferSource source(image);

  // Do not consume the bytes for the magic value, as they are part of the
  // header.
  if (!source.CheckNextBytes({0x7F, 'E', 'L', 'F'}))
    return false;

  auto* header = source.GetPointer<typename Traits::Elf_Ehdr>();
  if (!header)
    return false;

  if (header->e_ident[elf::EI_CLASS] != Traits::kIdentificationClass)
    return false;

  if (header->e_ident[elf::EI_DATA] != 1)  // Only ELFDATA2LSB is supported.
    return false;

  if (header->e_type != elf::ET_EXEC && header->e_type != elf::ET_DYN)
    return false;

  if (header->e_version != 1 || header->e_ident[elf::EI_VERSION] != 1)
    return false;

  if (header->e_machine != supported_architecture())
    return false;

  if (header->e_shentsize != sizeof(typename Traits::Elf_Shdr))
    return false;

  return true;
}

template <class TRAITS>
DisassemblerElf<TRAITS>::~DisassemblerElf() = default;

template <class TRAITS>
ExecutableType DisassemblerElf<TRAITS>::GetExeType() const {
  return Traits::kExeType;
}

template <class TRAITS>
std::string DisassemblerElf<TRAITS>::GetExeTypeString() const {
  return Traits::kExeTypeString;
}

// |num_equivalence_iterations_| = 2 for reloc -> abs32.
template <class TRAITS>
DisassemblerElf<TRAITS>::DisassemblerElf() : Disassembler(2) {}

template <class TRAITS>
bool DisassemblerElf<TRAITS>::Parse(ConstBufferView image) {
  image_ = image;
  if (!ParseHeader())
    return false;
  ParseSections();
  return true;
}

template <class TRAITS>
std::unique_ptr<ReferenceReader> DisassemblerElf<TRAITS>::MakeReadRelocs(
    offset_t lo,
    offset_t hi) {
  DCHECK_LE(lo, hi);
  DCHECK_LE(hi, image_.size());

  if (reloc_section_dims_.empty())
    return std::make_unique<EmptyReferenceReader>();

  return std::make_unique<RelocReaderElf>(
      image_, Traits::kBitness, reloc_section_dims_,
      supported_relocation_type(), lo, hi, translator_);
}

template <class TRAITS>
std::unique_ptr<ReferenceWriter> DisassemblerElf<TRAITS>::MakeWriteRelocs(
    MutableBufferView image) {
  return std::make_unique<RelocWriterElf>(image, Traits::kBitness, translator_);
}

template <class TRAITS>
bool DisassemblerElf<TRAITS>::ParseHeader() {
  BufferSource source(image_);
  // Ensure any offsets will fit within the |image_|'s bounds.
  if (!base::IsValueInRangeForNumericType<offset_t>(image_.size()))
    return false;

  // Ensures |header_| is valid later on.
  if (!QuickDetect(image_))
    return false;

  header_ = source.GetPointer<typename Traits::Elf_Ehdr>();

  sections_count_ = header_->e_shnum;
  source = std::move(BufferSource(image_).Skip(header_->e_shoff));
  sections_ = source.GetArray<typename Traits::Elf_Shdr>(sections_count_);
  if (!sections_)
    return false;
  offset_t section_table_end =
      base::checked_cast<offset_t>(source.begin() - image_.begin());

  segments_count_ = header_->e_phnum;
  source = std::move(BufferSource(image_).Skip(header_->e_phoff));
  segments_ = source.GetArray<typename Traits::Elf_Phdr>(segments_count_);
  if (!segments_)
    return false;
  offset_t segment_table_end =
      base::checked_cast<offset_t>(source.begin() - image_.begin());

  // Check string section -- even though we've stopped using them.
  elf::Elf32_Half string_section_id = header_->e_shstrndx;
  if (string_section_id >= sections_count_)
    return false;
  size_t section_names_size = sections_[string_section_id].sh_size;
  if (section_names_size > 0) {
    // If nonempty, then last byte of string section must be null.
    const char* section_names = nullptr;
    source = std::move(
        BufferSource(image_).Skip(sections_[string_section_id].sh_offset));
    section_names = source.GetArray<char>(section_names_size);
    if (!section_names || section_names[section_names_size - 1] != '\0')
      return false;
  }

  // Establish bound on encountered offsets.
  offset_t offset_bound = std::max(section_table_end, segment_table_end);

  // Visits |segments_| to get estimate on |offset_bound|.
  for (const typename Traits::Elf_Phdr* segment = segments_;
       segment != segments_ + segments_count_; ++segment) {
    // |image_.covers()| is a sufficient check except when size_t is 32 bit and
    // parsing ELF64. In such cases a value-in-range check is needed on the
    // segment. This fixes crbug/1035603.
    offset_t segment_end;
    base::CheckedNumeric<offset_t> checked_segment_end = segment->p_offset;
    checked_segment_end += segment->p_filesz;
    if (!checked_segment_end.AssignIfValid(&segment_end) ||
        !image_.covers({static_cast<size_t>(segment->p_offset),
                        static_cast<size_t>(segment->p_filesz)})) {
      return false;
    }
    offset_bound = std::max(offset_bound, segment_end);
  }

  // Visit and validate each section; add address translation data to |units|.
  std::vector<AddressTranslator::Unit> units;
  units.reserve(sections_count_);
  section_judgements_.reserve(sections_count_);

  for (int i = 0; i < sections_count_; ++i) {
    const typename Traits::Elf_Shdr* section = &sections_[i];
    int judgement = JudgeSection<Traits>(image_.size(), section);
    section_judgements_.push_back(judgement);
    if ((judgement & SECTION_BIT_SAFE) == 0)
      return false;

    uint32_t sh_size = base::checked_cast<uint32_t>(section->sh_size);
    offset_t sh_offset = base::checked_cast<offset_t>(section->sh_offset);
    rva_t sh_addr = base::checked_cast<rva_t>(section->sh_addr);
    if ((judgement & SECTION_BIT_USEFUL_FOR_ADDRESS_TRANSLATOR) != 0) {
      // Store mappings between RVA and offset.
      units.push_back({sh_offset, sh_size, sh_addr, sh_size});
    }
    if ((judgement & SECTION_BIT_USEFUL_FOR_OFFSET_BOUND) != 0) {
      offset_t section_end = base::checked_cast<offset_t>(sh_offset + sh_size);
      offset_bound = std::max(offset_bound, section_end);
    }
  }

  // Initialize |translator_| for offset-RVA translations. Any inconsistency
  // (e.g., 2 offsets correspond to the same RVA) would invalidate the ELF file.
  if (translator_.Initialize(std::move(units)) != AddressTranslator::kSuccess)
    return false;

  DCHECK_LE(offset_bound, image_.size());
  image_.shrink(offset_bound);
  return true;
}

template <class TRAITS>
void DisassemblerElf<TRAITS>::ExtractInterestingSectionHeaders() {
  DCHECK(reloc_section_dims_.empty());
  DCHECK(exec_headers_.empty());
  for (elf::Elf32_Half i = 0; i < sections_count_; ++i) {
    const typename Traits::Elf_Shdr* section = sections_ + i;
    if ((section_judgements_[i] & SECTION_BIT_MAYBE_USEFUL_FOR_POINTERS) != 0) {
      if (IsRelocSection<Traits>(*section))
        reloc_section_dims_.emplace_back(*section);
      else if (IsExecSection<Traits>(*section))
        exec_headers_.push_back(section);
    }
  }
  auto comp = [](const typename Traits::Elf_Shdr* a,
                 const typename Traits::Elf_Shdr* b) {
    return a->sh_offset < b->sh_offset;
  };
  std::sort(reloc_section_dims_.begin(), reloc_section_dims_.end());
  std::sort(exec_headers_.begin(), exec_headers_.end(), comp);
}

template <class TRAITS>
void DisassemblerElf<TRAITS>::GetAbs32FromRelocSections() {
  constexpr int kAbs32Width = Traits::kVAWidth;
  DCHECK(abs32_locations_.empty());

  // Read reloc targets to get preliminary abs32 locations.
  std::unique_ptr<ReferenceReader> relocs = MakeReadRelocs(0, offset_t(size()));
  for (auto ref = relocs->GetNext(); ref.has_value(); ref = relocs->GetNext())
    abs32_locations_.push_back(ref->target);

  std::sort(abs32_locations_.begin(), abs32_locations_.end());

  // Abs32 references must have targets translatable to offsets. Remove those
  // that are unable to do so.
  size_t num_untranslatable =
      RemoveUntranslatableAbs32(image_, {Traits::kBitness, kElfImageBase},
                                translator_, &abs32_locations_);
  LOG_IF(WARNING, num_untranslatable) << "Removed " << num_untranslatable
                                      << " untranslatable abs32 references.";

  // Abs32 reference bodies must not overlap. If found, simply remove them.
  size_t num_overlapping =
      RemoveOverlappingAbs32Locations(kAbs32Width, &abs32_locations_);
  LOG_IF(WARNING, num_overlapping)
      << "Removed " << num_overlapping
      << " abs32 references with overlapping bodies.";

  abs32_locations_.shrink_to_fit();
}

template <class TRAITS>
void DisassemblerElf<TRAITS>::GetRel32FromCodeSections() {
  for (const typename Traits::Elf_Shdr* section : exec_headers_)
    ParseExecSection(*section);
  PostProcessRel32();
}

template <class TRAITS>
void DisassemblerElf<TRAITS>::ParseSections() {
  ExtractInterestingSectionHeaders();
  GetAbs32FromRelocSections();
  GetRel32FromCodeSections();
}

/******** DisassemblerElfIntel ********/

template <class TRAITS>
DisassemblerElfIntel<TRAITS>::DisassemblerElfIntel() = default;

template <class TRAITS>
DisassemblerElfIntel<TRAITS>::~DisassemblerElfIntel() = default;

template <class TRAITS>
std::vector<ReferenceGroup> DisassemblerElfIntel<TRAITS>::MakeReferenceGroups()
    const {
  return {
      {ReferenceTypeTraits{sizeof(TRAITS::Elf_Rel::r_offset), TypeTag(kReloc),
                           PoolTag(kReloc)},
       &DisassemblerElfIntel<TRAITS>::MakeReadRelocs,
       &DisassemblerElfIntel<TRAITS>::MakeWriteRelocs},
      {ReferenceTypeTraits{Traits::kVAWidth, TypeTag(kAbs32), PoolTag(kAbs32)},
       &DisassemblerElfIntel<TRAITS>::MakeReadAbs32,
       &DisassemblerElfIntel<TRAITS>::MakeWriteAbs32},
      // N.B.: Rel32 |width| is 4 bytes, even for x64.
      {ReferenceTypeTraits{4, TypeTag(kRel32), PoolTag(kRel32)},
       &DisassemblerElfIntel<TRAITS>::MakeReadRel32,
       &DisassemblerElfIntel<TRAITS>::MakeWriteRel32}};
}

template <class TRAITS>
void DisassemblerElfIntel<TRAITS>::ParseExecSection(
    const typename TRAITS::Elf_Shdr& section) {
  constexpr int kAbs32Width = Traits::kVAWidth;

  // |this->| is needed to access protected members of templated base class. To
  // reduce noise, use local references for these.
  ConstBufferView& image_ = this->image_;
  const AddressTranslator& translator_ = this->translator_;
  auto& abs32_locations_ = this->abs32_locations_;

  // Range of values was ensured in ParseHeader().
  rva_t start_rva = base::checked_cast<rva_t>(section.sh_addr);
  rva_t end_rva = base::checked_cast<rva_t>(start_rva + section.sh_size);

  AddressTranslator::RvaToOffsetCache target_rva_checker(translator_);

  ConstBufferView region(image_.begin() + section.sh_offset, section.sh_size);
  Abs32GapFinder gap_finder(image_, region, abs32_locations_, kAbs32Width);
  typename TRAITS::Rel32FinderUse rel_finder(image_, translator_);
  // Iterate over gaps between abs32 references, to avoid collision.
  while (gap_finder.FindNext()) {
    rel_finder.SetRegion(gap_finder.GetGap());
    while (rel_finder.FindNext()) {
      auto rel32 = rel_finder.GetRel32();
      if (target_rva_checker.IsValid(rel32.target_rva) &&
          (rel32.can_point_outside_section ||
           (start_rva <= rel32.target_rva && rel32.target_rva < end_rva))) {
        rel_finder.Accept();
        rel32_locations_.push_back(rel32.location);
      }
    }
  }
}

template <class TRAITS>
void DisassemblerElfIntel<TRAITS>::PostProcessRel32() {
  rel32_locations_.shrink_to_fit();
  std::sort(rel32_locations_.begin(), rel32_locations_.end());
}

template <class TRAITS>
std::unique_ptr<ReferenceReader> DisassemblerElfIntel<TRAITS>::MakeReadAbs32(
    offset_t lo,
    offset_t hi) {
  // TODO(huangs): Don't use Abs32RvaExtractorWin32 here; use new class that
  // caters to different ELF architectures.
  Abs32RvaExtractorWin32 abs_rva_extractor(
      this->image_, AbsoluteAddress(TRAITS::kBitness, kElfImageBase),
      this->abs32_locations_, lo, hi);
  return std::make_unique<Abs32ReaderWin32>(std::move(abs_rva_extractor),
                                            this->translator_);
}

template <class TRAITS>
std::unique_ptr<ReferenceWriter> DisassemblerElfIntel<TRAITS>::MakeWriteAbs32(
    MutableBufferView image) {
  return std::make_unique<Abs32WriterWin32>(
      image, AbsoluteAddress(TRAITS::kBitness, kElfImageBase),
      this->translator_);
}

template <class TRAITS>
std::unique_ptr<ReferenceReader> DisassemblerElfIntel<TRAITS>::MakeReadRel32(
    offset_t lo,
    offset_t hi) {
  return std::make_unique<Rel32ReaderX86>(this->image_, lo, hi,
                                          &rel32_locations_, this->translator_);
}

template <class TRAITS>
std::unique_ptr<ReferenceWriter> DisassemblerElfIntel<TRAITS>::MakeWriteRel32(
    MutableBufferView image) {
  return std::make_unique<Rel32WriterX86>(image, this->translator_);
}

// Explicit instantiation for supported classes.
template class DisassemblerElfIntel<Elf32IntelTraits>;
template class DisassemblerElfIntel<Elf64IntelTraits>;
template bool DisassemblerElf<Elf32IntelTraits>::QuickDetect(
    ConstBufferView image);
template bool DisassemblerElf<Elf64IntelTraits>::QuickDetect(
    ConstBufferView image);

/******** DisassemblerElfArm ********/

template <class Traits>
DisassemblerElfArm<Traits>::DisassemblerElfArm() = default;

template <class Traits>
DisassemblerElfArm<Traits>::~DisassemblerElfArm() = default;

template <class Traits>
bool DisassemblerElfArm<Traits>::IsTargetOffsetInExecSection(
    offset_t offset) const {
  // Executable sections can appear in large numbers in .o files and in
  // pathological cases. Since this function may be called for each reference
  // candidate, linear search may be too slow (so use binary search).
  return IsTargetOffsetInElfSectionList(this->exec_headers_, offset);
}

template <class Traits>
void DisassemblerElfArm<Traits>::ParseExecSection(
    const typename Traits::Elf_Shdr& section) {
  ConstBufferView& image_ = this->image_;
  const AddressTranslator& translator_ = this->translator_;
  auto& abs32_locations_ = this->abs32_locations_;

  ConstBufferView region(image_.begin() + section.sh_offset, section.sh_size);
  Abs32GapFinder gap_finder(image_, region, abs32_locations_, Traits::kVAWidth);
  std::unique_ptr<typename Traits::Rel32FinderUse> rel_finder =
      MakeRel32Finder(section);
  AddressTranslator::RvaToOffsetCache rva_to_offset(translator_);
  while (gap_finder.FindNext()) {
    rel_finder->SetRegion(gap_finder.GetGap());
    while (rel_finder->FindNext()) {
      auto rel32 = rel_finder->GetRel32();
      offset_t target_offset = rva_to_offset.Convert(rel32.target_rva);
      if (target_offset != kInvalidOffset) {
        // For robustness, reject illegal offsets, which can arise from, e.g.,
        // misidentify ARM vs. THUMB2 mode, or even misidentifying data as code!
        if (IsTargetOffsetInExecSection(target_offset)) {
          rel_finder->Accept();
          rel32_locations_table_[rel32.type].push_back(rel32.location);
        }
      }
    }
  }
}

template <class Traits>
void DisassemblerElfArm<Traits>::PostProcessRel32() {
  for (int type = 0; type < AArch32Rel32Translator::NUM_ADDR_TYPE; ++type) {
    std::sort(rel32_locations_table_[type].begin(),
              rel32_locations_table_[type].end());
    rel32_locations_table_[type].shrink_to_fit();
  }
}

template <class Traits>
std::unique_ptr<ReferenceReader> DisassemblerElfArm<Traits>::MakeReadAbs32(
    offset_t lo,
    offset_t hi) {
  // TODO(huangs): Reconcile the use of Win32-specific classes in ARM code!
  Abs32RvaExtractorWin32 abs_rva_extractor(this->image_,
                                           AbsoluteAddress(Traits::kBitness, 0),
                                           this->abs32_locations_, lo, hi);
  return std::make_unique<Abs32ReaderWin32>(std::move(abs_rva_extractor),
                                            this->translator_);
}

template <class Traits>
std::unique_ptr<ReferenceWriter> DisassemblerElfArm<Traits>::MakeWriteAbs32(
    MutableBufferView image) {
  return std::make_unique<Abs32WriterWin32>(
      image, AbsoluteAddress(Traits::kBitness, 0), this->translator_);
}

template <class TRAITS>
template <class ADDR_TRAITS>
std::unique_ptr<ReferenceReader> DisassemblerElfArm<TRAITS>::MakeReadRel32(
    offset_t lower,
    offset_t upper) {
  return std::make_unique<Rel32ReaderArm<ADDR_TRAITS>>(
      this->translator_, this->image_,
      this->rel32_locations_table_[ADDR_TRAITS::addr_type], lower, upper);
}

template <class TRAITS>
template <class ADDR_TRAITS>
std::unique_ptr<ReferenceWriter> DisassemblerElfArm<TRAITS>::MakeWriteRel32(
    MutableBufferView image) {
  return std::make_unique<Rel32WriterArm<ADDR_TRAITS>>(this->translator_,
                                                       image);
}

/******** DisassemblerElfAArch32 ********/

DisassemblerElfAArch32::DisassemblerElfAArch32() = default;
DisassemblerElfAArch32::~DisassemblerElfAArch32() = default;

std::vector<ReferenceGroup> DisassemblerElfAArch32::MakeReferenceGroups()
    const {
  return {
      {ReferenceTypeTraits{sizeof(Traits::Elf_Rel::r_offset),
                           TypeTag(AArch32ReferenceType::kReloc),
                           PoolTag(ArmReferencePool::kPoolReloc)},
       &DisassemblerElfAArch32::MakeReadRelocs,
       &DisassemblerElfAArch32::MakeWriteRelocs},
      {ReferenceTypeTraits{Traits::kVAWidth,
                           TypeTag(AArch32ReferenceType::kAbs32),
                           PoolTag(ArmReferencePool::kPoolAbs32)},
       &DisassemblerElfAArch32::MakeReadAbs32,
       &DisassemblerElfAArch32::MakeWriteAbs32},
      {ReferenceTypeTraits{4, TypeTag(AArch32ReferenceType::kRel32_A24),
                           PoolTag(ArmReferencePool::kPoolRel32)},
       &DisassemblerElfAArch32::MakeReadRel32<
           AArch32Rel32Translator::AddrTraits_A24>,
       &DisassemblerElfAArch32::MakeWriteRel32<
           AArch32Rel32Translator::AddrTraits_A24>},
      {ReferenceTypeTraits{2, TypeTag(AArch32ReferenceType::kRel32_T8),
                           PoolTag(ArmReferencePool::kPoolRel32)},
       &DisassemblerElfAArch32::MakeReadRel32<
           AArch32Rel32Translator::AddrTraits_T8>,
       &DisassemblerElfAArch32::MakeWriteRel32<
           AArch32Rel32Translator::AddrTraits_T8>},
      {ReferenceTypeTraits{2, TypeTag(AArch32ReferenceType::kRel32_T11),
                           PoolTag(ArmReferencePool::kPoolRel32)},
       &DisassemblerElfAArch32::MakeReadRel32<
           AArch32Rel32Translator::AddrTraits_T11>,
       &DisassemblerElfAArch32::MakeWriteRel32<
           AArch32Rel32Translator::AddrTraits_T11>},
      {ReferenceTypeTraits{4, TypeTag(AArch32ReferenceType::kRel32_T20),
                           PoolTag(ArmReferencePool::kPoolRel32)},
       &DisassemblerElfAArch32::MakeReadRel32<
           AArch32Rel32Translator::AddrTraits_T20>,
       &DisassemblerElfAArch32::MakeWriteRel32<
           AArch32Rel32Translator::AddrTraits_T20>},
      {ReferenceTypeTraits{4, TypeTag(AArch32ReferenceType::kRel32_T24),
                           PoolTag(ArmReferencePool::kPoolRel32)},
       &DisassemblerElfAArch32::MakeReadRel32<
           AArch32Rel32Translator::AddrTraits_T24>,
       &DisassemblerElfAArch32::MakeWriteRel32<
           AArch32Rel32Translator::AddrTraits_T24>},
  };
}

std::unique_ptr<DisassemblerElfAArch32::Traits::Rel32FinderUse>
DisassemblerElfAArch32::MakeRel32Finder(
    const typename Traits::Elf_Shdr& section) {
  return std::make_unique<Rel32FinderAArch32>(image_, translator_,
                                              IsExecSectionThumb2(section));
}

bool DisassemblerElfAArch32::IsExecSectionThumb2(
    const typename Traits::Elf_Shdr& section) const {
  // ARM mode requires 4-byte alignment.
  if (section.sh_addr % 4 != 0 || section.sh_size % 4 != 0)
    return true;
  const uint8_t* first = image_.begin() + section.sh_offset;
  const uint8_t* end = first + section.sh_size;
  // Each instruction in 32-bit ARM (little-endian) looks like
  //   ?? ?? ?? X?,
  // where X specifies conditional execution. X = 0xE represents AL = "ALways
  // execute", and tends to appear very often. We use this as our main indicator
  // to discern 32-bit ARM mode from THUMB2 mode.
  size_t num = 0;
  size_t den = 0;
  for (const uint8_t* cur = first; cur < end; cur += 4) {
    // |cur[3]| is within bounds because |end - cur| is a multiple of 4.
    uint8_t maybe_cond = cur[3] & 0xF0;
    if (maybe_cond == 0xE0)
      ++num;
    ++den;
  }

  if (den > 0) {
    LOG(INFO) << "Section scan: " << num << " / " << den << " => "
              << base::StringPrintf("%.2f", num * 100.0 / den) << "%";
  }
  return num < den * kAArch32BitCondAlwaysDensityThreshold;
}

/******** DisassemblerElfAArch64 ********/

DisassemblerElfAArch64::DisassemblerElfAArch64() = default;

DisassemblerElfAArch64::~DisassemblerElfAArch64() = default;

std::vector<ReferenceGroup> DisassemblerElfAArch64::MakeReferenceGroups()
    const {
  return {
      {ReferenceTypeTraits{sizeof(Traits::Elf_Rel::r_offset),
                           TypeTag(AArch64ReferenceType::kReloc),
                           PoolTag(ArmReferencePool::kPoolReloc)},
       &DisassemblerElfAArch64::MakeReadRelocs,
       &DisassemblerElfAArch64::MakeWriteRelocs},
      {ReferenceTypeTraits{Traits::kVAWidth,
                           TypeTag(AArch64ReferenceType::kAbs32),
                           PoolTag(ArmReferencePool::kPoolAbs32)},
       &DisassemblerElfAArch64::MakeReadAbs32,
       &DisassemblerElfAArch64::MakeWriteAbs32},
      {ReferenceTypeTraits{4, TypeTag(AArch64ReferenceType::kRel32_Immd14),
                           PoolTag(ArmReferencePool::kPoolRel32)},
       &DisassemblerElfAArch64::MakeReadRel32<
           AArch64Rel32Translator::AddrTraits_Immd14>,
       &DisassemblerElfAArch64::MakeWriteRel32<
           AArch64Rel32Translator::AddrTraits_Immd14>},
      {ReferenceTypeTraits{4, TypeTag(AArch64ReferenceType::kRel32_Immd19),
                           PoolTag(ArmReferencePool::kPoolRel32)},
       &DisassemblerElfAArch64::MakeReadRel32<
           AArch64Rel32Translator::AddrTraits_Immd19>,
       &DisassemblerElfAArch64::MakeWriteRel32<
           AArch64Rel32Translator::AddrTraits_Immd19>},
      {ReferenceTypeTraits{4, TypeTag(AArch64ReferenceType::kRel32_Immd26),
                           PoolTag(ArmReferencePool::kPoolRel32)},
       &DisassemblerElfAArch64::MakeReadRel32<
           AArch64Rel32Translator::AddrTraits_Immd26>,
       &DisassemblerElfAArch64::MakeWriteRel32<
           AArch64Rel32Translator::AddrTraits_Immd26>},
  };
}

std::unique_ptr<DisassemblerElfAArch64::Traits::Rel32FinderUse>
DisassemblerElfAArch64::MakeRel32Finder(
    const typename Traits::Elf_Shdr& section) {
  return std::make_unique<Rel32FinderAArch64>(image_, translator_);
}

// Explicit instantiation for supported classes.
template class DisassemblerElfArm<ElfAArch32Traits>;
template class DisassemblerElfArm<ElfAArch64Traits>;
template bool DisassemblerElf<ElfAArch32Traits>::QuickDetect(
    ConstBufferView image);
template bool DisassemblerElf<ElfAArch64Traits>::QuickDetect(
    ConstBufferView image);

}  // namespace zucchini
