// 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) = (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) = (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) = 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) = 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
