// Copyright 2013 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 "courgette/disassembler_elf_32_arm.h"

#include <algorithm>
#include <string>
#include <vector>

#include "base/basictypes.h"
#include "base/logging.h"

#include "courgette/assembly_program.h"
#include "courgette/courgette.h"
#include "courgette/encoded_program.h"

namespace courgette {

CheckBool DisassemblerElf32ARM::Compress(ARM_RVA type, uint32 arm_op, RVA rva,
                                         uint16* c_op, uint32* addr) {
  // This method takes an ARM or thumb opcode, extracts the relative
  // target address from it (addr), and creates a corresponding
  // Courgette opcode (c_op).
  //
  // Details on ARM the opcodes, and how the relative targets are
  // computed were taken from the "ARM Architecture Reference Manual",
  // section A4.1.5 and the "Thumb-2 supplement", section 4.6.12.
  // ARM_OFF24 is for the ARM opcode.  The rest are for thumb opcodes.
  switch (type) {
    case ARM_OFF8: {
      // The offset is given by lower 8 bits of the op.  It is a 9-bit
      // offset, shifted right one bit and signed extended.
      uint32 temp = (arm_op & 0x00FF) << 1;
      if (temp & 0x0100)
        temp |= 0xFFFFFE00;
      temp += 4;  // Offset from _next_ PC.
      fflush(stdout);

      (*addr) = temp;
      (*c_op) = static_cast<uint16>(arm_op >> 8) | 0x1000;
      break;
    }
    case ARM_OFF11: {
      // The offset is given by lower 11 bits of the op, and is a
      // 12-bit offset, shifted right one bit and sign extended.
      uint32 temp = (arm_op & 0x07FF) << 1;
      if (temp & 0x00000800)
        temp |= 0xFFFFF000;
      temp += 4;  // Offset from _next_ PC.

      (*addr) = temp;
      (*c_op) = static_cast<uint16>(arm_op >> 11) | 0x2000;
      break;
    }
    case ARM_OFF24: {
      // The offset is given by the lower 24-bits of the op, shifted
      // left 2 bits, and sign extended.
      uint32 temp = (arm_op & 0x00FFFFFF) << 2;
      if (temp & 0x02000000)
        temp |= 0xFC000000;
      temp += 8;

      (*addr) = temp;
      (*c_op) = (arm_op >> 24) | 0x3000;
      break;
    }
    case ARM_OFF25: {
      uint32 temp = 0;
      temp |= (arm_op & 0x000007FF) << 1;  // imm11
      temp |= (arm_op & 0x03FF0000) >> 4;  // imm10

      uint32 S   = (arm_op & (1 << 26)) >> 26;
      uint32 j2  = (arm_op & (1 << 11)) >> 11;
      uint32 j1  = (arm_op & (1 << 13)) >> 13;
      bool bit12 = ((arm_op & (1 << 12)) >> 12) != 0;
      bool bit14 = ((arm_op & (1 << 14)) >> 14) != 0;

      uint32 i2  = ~(j2 ^ S) & 1;
      uint32 i1  = ~(j1 ^ S) & 1;
      bool toARM =  bit14 && !bit12;

      temp |= (S << 24) | (i1 << 23) | (i2 << 22);

      if (temp & 0x01000000) // sign extension
        temp |= 0xFE000000;
      uint32 prefetch;
      if (toARM) {
        // Align PC on 4-byte boundary
        uint32 align4byte = (rva % 4) ? 2 : 4;
        prefetch = align4byte;
      } else {
        prefetch = 4;
      }
      temp += prefetch;
      (*addr) = temp;

      uint32 temp2 = 0x4000;
      temp2 |= (arm_op & (1 << 12)) >> 12;
      temp2 |= (arm_op & (1 << 14)) >> 13;
      temp2 |= (arm_op & (1 << 15)) >> 13;
      temp2 |= (arm_op & 0xF8000000) >> 24;
      temp2 |= (prefetch & 0x0000000F) << 8;
      (*c_op) = static_cast<uint16>(temp2);
      break;
    }
    case ARM_OFF21: {
      uint32 temp = 0;
      temp |= (arm_op & 0x000007FF) << 1;  // imm11
      temp |= (arm_op & 0x003F0000) >> 4;  // imm6

      uint32 S   = (arm_op & (1 << 26)) >> 26;
      uint32 j2  = (arm_op & (1 << 11)) >> 11;
      uint32 j1  = (arm_op & (1 << 13)) >> 13;

      temp |= (S << 20) | (j1 << 19) | (j2 << 18);

      if (temp & 0x00100000)  // sign extension
        temp |= 0xFFE00000;
      temp += 4;
      (*addr) = temp;

      uint32 temp2 = 0x5000;
      temp2 |= (arm_op & 0x03C00000) >> 22;  // just save the cond
      (*c_op) = static_cast<uint16>(temp2);
      break;
    }
    default:
      return false;
  }
  return true;
}

CheckBool DisassemblerElf32ARM::Decompress(ARM_RVA type, uint16 c_op,
                                           uint32 addr, uint32* arm_op) {
  // Reverses the process in the compress() method.  Takes the
  // Courgette op and relative address and reconstructs the original
  // ARM or thumb op.
  switch (type) {
    case ARM_OFF8:
      (*arm_op) = ((c_op & 0x0FFF) << 8) | (((addr - 4) >> 1) & 0x000000FF);
      break;
    case ARM_OFF11:
      (*arm_op) = ((c_op & 0x0FFF) << 11) | (((addr - 4) >> 1) & 0x000007FF);
      break;
    case ARM_OFF24:
      (*arm_op) = ((c_op & 0x0FFF) << 24) | (((addr - 8) >> 2) & 0x00FFFFFF);
      break;
    case ARM_OFF25: {
      uint32 temp = 0;
      temp |= (c_op & (1 << 0)) << 12;
      temp |= (c_op & (1 << 1)) << 13;
      temp |= (c_op & (1 << 2)) << 13;
      temp |= (c_op & (0xF8000000 >> 24)) << 24;

      uint32 prefetch = (c_op & 0x0F00) >> 8;
      addr -= prefetch;

      addr &= 0x01FFFFFF;

      uint32 S  = (addr & (1 << 24)) >> 24;
      uint32 i1 = (addr & (1 << 23)) >> 23;
      uint32 i2 = (addr & (1 << 22)) >> 22;

      uint32 j1 = ((~i1) ^ S) & 1;
      uint32 j2 = ((~i2) ^ S) & 1;

      temp |= S << 26;
      temp |= j2 << 11;
      temp |= j1 << 13;

      temp |= (addr & (0x000007FF << 1)) >> 1;
      temp |= (addr & (0x03FF0000 >> 4)) << 4;

      (*arm_op) = temp;
      break;
    }
    case ARM_OFF21: {
      uint32 temp = 0xF0008000;
      temp |= (c_op & (0x03C00000 >> 22)) << 22;

      addr -= 4;
      addr &= 0x001FFFFF;

      uint32 S  = (addr & (1 << 20)) >> 20;
      uint32 j1 = (addr & (1 << 19)) >> 19;
      uint32 j2 = (addr & (1 << 18)) >> 18;

      temp |= S << 26;
      temp |= j2 << 11;
      temp |= j1 << 13;

      temp |= (addr & (0x000007FF << 1)) >> 1;
      temp |= (addr & (0x003F0000 >> 4)) << 4;

      (*arm_op) = temp;
      break;
    }
    default:
      return false;
  }
  return true;
}

uint16 DisassemblerElf32ARM::TypedRVAARM::op_size() const {
  switch (type_) {
    case ARM_OFF8:
      return 2;
    case ARM_OFF11:
      return 2;
    case ARM_OFF24:
      return 4;
    case ARM_OFF25:
      return 4;
    case ARM_OFF21:
      return 4;
    default:
      return 0xFFFF;
  }
}

CheckBool DisassemblerElf32ARM::TypedRVAARM::ComputeRelativeTarget(
    const uint8* op_pointer) {
  arm_op_ = op_pointer;
  switch (type_) {
    case ARM_OFF8:
      // Fall through
    case ARM_OFF11: {
      RVA relative_target;
      CheckBool ret = Compress(type_, Read16LittleEndian(op_pointer), rva(),
                               &c_op_, &relative_target);
      set_relative_target(relative_target);
      return ret;
    }
    case ARM_OFF24: {
      RVA relative_target;
      CheckBool ret = Compress(type_, Read32LittleEndian(op_pointer), rva(),
                               &c_op_, &relative_target);
      set_relative_target(relative_target);
      return ret;
    }
    case ARM_OFF25:
      // Fall through
    case ARM_OFF21: {
      // A thumb-2 op is 32 bits stored as two 16-bit words
      uint32 pval = (Read16LittleEndian(op_pointer) << 16)
        | Read16LittleEndian(op_pointer + 2);
      RVA relative_target;
      CheckBool ret = Compress(type_, pval, rva(), &c_op_, &relative_target);
      set_relative_target(relative_target);
      return ret;
    }
   default:
     return false;
  }
}

CheckBool DisassemblerElf32ARM::TypedRVAARM::EmitInstruction(
    AssemblyProgram* program,
    RVA target_rva) {
  return program->EmitRel32ARM(c_op(),
                               program->FindOrMakeRel32Label(target_rva),
                               arm_op_,
                               op_size());
}

DisassemblerElf32ARM::DisassemblerElf32ARM(const void* start, size_t length)
  : DisassemblerElf32(start, length) {
}

// Convert an ELF relocation struction into an RVA
CheckBool DisassemblerElf32ARM::RelToRVA(Elf32_Rel rel, RVA* result) const {

  // The rightmost byte of r_info is the type...
  elf32_rel_arm_type_values type =
      (elf32_rel_arm_type_values)(unsigned char)rel.r_info;

  // The other 3 bytes of r_info are the symbol
  uint32 symbol =  rel.r_info >> 8;

  switch(type)
  {
    case R_ARM_RELATIVE:
      if (symbol != 0)
        return false;

      // This is a basic ABS32 relocation address
      *result = rel.r_offset;
      return true;

    default:
      return false;
  }
}

CheckBool DisassemblerElf32ARM::ParseRelocationSection(
    const Elf32_Shdr *section_header,
      AssemblyProgram* program) {
  // This method compresses a contiguous stretch of R_ARM_RELATIVE
  // entries in the relocation table with a Courgette relocation table
  // instruction.  It skips any entries at the beginning that appear
  // in a section that Courgette doesn't support, e.g. INIT.
  // Specifically, the entries should be
  //   (1) In the same relocation table
  //   (2) Are consecutive
  //   (3) Are sorted in memory address order
  //
  // Happily, this is normally the case, but it's not required by spec
  // so we check, and just don't do it if we don't match up.
  //
  // The expectation is that one relocation section will contain
  // all of our R_ARM_RELATIVE entries in the expected order followed
  // by assorted other entries we can't use special handling for.

  bool match = true;

  // Walk all the bytes in the section, matching relocation table or not
  size_t file_offset = section_header->sh_offset;
  size_t section_end = section_header->sh_offset + section_header->sh_size;

  Elf32_Rel *section_relocs_iter =
      (Elf32_Rel *)OffsetToPointer(section_header->sh_offset);

  uint32 section_relocs_count = section_header->sh_size /
                                section_header->sh_entsize;

  if (abs32_locations_.size() > section_relocs_count)
    match = false;

  if (!abs32_locations_.empty()) {
    std::vector<RVA>::iterator reloc_iter = abs32_locations_.begin();

    for (uint32 i = 0; i < section_relocs_count; i++) {
      if (section_relocs_iter->r_offset == *reloc_iter)
        break;

      if (!ParseSimpleRegion(file_offset, file_offset + sizeof(Elf32_Rel),
                             program))
        return false;

      file_offset += sizeof(Elf32_Rel);
      ++section_relocs_iter;
    }

    while (match && (reloc_iter != abs32_locations_.end())) {
      if (section_relocs_iter->r_info != R_ARM_RELATIVE ||
          section_relocs_iter->r_offset != *reloc_iter)
        match = false;

      section_relocs_iter++;
      reloc_iter++;
      file_offset += sizeof(Elf32_Rel);
    }

    if (match) {
      // Skip over relocation tables
      if (!program->EmitElfARMRelocationInstruction())
        return false;
    }
  }

  return ParseSimpleRegion(file_offset, section_end, program);
}

CheckBool DisassemblerElf32ARM::ParseRel32RelocsFromSection(
    const Elf32_Shdr* section_header) {

  uint32 start_file_offset = section_header->sh_offset;
  uint32 end_file_offset = start_file_offset + section_header->sh_size;

  const uint8* start_pointer = OffsetToPointer(start_file_offset);
  const uint8* end_pointer = OffsetToPointer(end_file_offset);

  // Quick way to convert from Pointer to RVA within a single Section is to
  // subtract 'pointer_to_rva'.
  const uint8* const adjust_pointer_to_rva = start_pointer -
                                             section_header->sh_addr;

  // Find the rel32 relocations.
  const uint8* p = start_pointer;
  bool on_32bit = 1; // 32-bit ARM ops appear on 32-bit boundaries, so track it
  while (p < end_pointer) {
    // Heuristic discovery of rel32 locations in instruction stream: are the
    // next few bytes the start of an instruction containing a rel32
    // addressing mode?

    TypedRVAARM* rel32_rva = NULL;
    RVA target_rva = 0;
    bool found = false;

    // 16-bit thumb ops
    if (!found && (p + 3) <= end_pointer) {
      uint16 pval = Read16LittleEndian(p);
      if ((pval & 0xF000) == 0xD000) {
        RVA rva = static_cast<RVA>(p - adjust_pointer_to_rva);

        rel32_rva = new TypedRVAARM(ARM_OFF8, rva);
        if (!rel32_rva->ComputeRelativeTarget((uint8*) p)) {
          return false;
        }
        target_rva = rel32_rva->rva() + rel32_rva->relative_target();
        found = true;
      } else if ((pval & 0xF800) == 0xE000) {
        RVA rva = static_cast<RVA>(p - adjust_pointer_to_rva);

        rel32_rva = new TypedRVAARM(ARM_OFF11, rva);
        if (!rel32_rva->ComputeRelativeTarget((uint8*) p)) {
          return false;
        }
        target_rva = rel32_rva->rva() + rel32_rva->relative_target();
        found = true;
      }
    }

    // thumb-2 ops comprised of two 16-bit words
    if (!found && (p + 5) <= end_pointer) {
      // This is really two 16-bit words, not one 32-bit word.
      uint32 pval = (Read16LittleEndian(p) << 16) | Read16LittleEndian(p + 2);
      if ((pval & 0xF8008000) == 0xF0008000) {
        // Covers thumb-2's 32-bit conditional/unconditional branches

        if ( (pval & (1 << 14)) || (pval & (1 << 12)) ) {
          // A branch, with link, or with link and exchange.
          RVA rva = static_cast<RVA>(p - adjust_pointer_to_rva);

          rel32_rva = new TypedRVAARM(ARM_OFF25, rva);
          if (!rel32_rva->ComputeRelativeTarget((uint8*) p)) {
            return false;
          }
          target_rva = rel32_rva->rva() + rel32_rva->relative_target();
          found = true;
        } else {
          // TODO(paulgazz) make sure cond is not 111
          // A conditional branch instruction
          RVA rva = static_cast<RVA>(p - adjust_pointer_to_rva);

          rel32_rva = new TypedRVAARM(ARM_OFF21, rva);
          if (!rel32_rva->ComputeRelativeTarget((uint8*) p)) {
            return false;
          }
          target_rva = rel32_rva->rva() + rel32_rva->relative_target();
          found = true;
        }
      }
    }

    // 32-bit ARM ops
    if (!found && on_32bit && (p + 5) <= end_pointer) {
      uint32 pval = Read32LittleEndian(p);
      if ((pval & 0x0E000000) == 0x0A000000) {
        // Covers both 0x0A 0x0B ARM relative branches
        RVA rva = static_cast<RVA>(p - adjust_pointer_to_rva);

        rel32_rva = new TypedRVAARM(ARM_OFF24, rva);
        if (!rel32_rva->ComputeRelativeTarget((uint8*) p)) {
          return false;
        }
        target_rva = rel32_rva->rva() + rel32_rva->relative_target();
        found = true;
      }
    }

    if (found && IsValidRVA(target_rva)) {
      rel32_locations_.push_back(rel32_rva);
#if COURGETTE_HISTOGRAM_TARGETS
      ++rel32_target_rvas_[target_rva];
#endif
      p += rel32_rva->op_size();

      // A tricky way to update the on_32bit flag.  Here is the truth table:
      // on_32bit | on_32bit   size is 4
      // ---------+---------------------
      // 1        | 0          0
      // 0        | 0          1
      // 0        | 1          0
      // 1        | 1          1
      on_32bit = (~(on_32bit ^ (rel32_rva->op_size() == 4))) != 0;
    } else {
      // Move 2 bytes at a time, but track 32-bit boundaries
      p += 2;
      on_32bit = ((on_32bit + 1) % 2) != 0;
    }
  }

  return true;
}

}  // namespace courgette
