// Copyright (c) 2011 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.

#ifndef COURGETTE_ENCODED_PROGRAM_H_
#define COURGETTE_ENCODED_PROGRAM_H_

#include <vector>

#include "base/basictypes.h"
#include "courgette/disassembler.h"
#include "courgette/memory_allocator.h"
#include "courgette/types_elf.h"

namespace courgette {

class SinkStream;
class SinkStreamSet;
class SourceStreamSet;

// An EncodedProgram is a set of tables that contain a simple 'binary assembly
// language' that can be assembled to produce a sequence of bytes, for example,
// a Windows 32-bit executable.
//
class EncodedProgram {
 public:
  EncodedProgram();
  ~EncodedProgram();

  // Generating an EncodedProgram:
  //
  // (1) The image base can be specified at any time.
  void set_image_base(uint64 base) { image_base_ = base; }

  // (2) Address tables and indexes defined first.
  CheckBool DefineRel32Label(int index, RVA address) WARN_UNUSED_RESULT;
  CheckBool DefineAbs32Label(int index, RVA address) WARN_UNUSED_RESULT;
  void EndLabels();

  // (3) Add instructions in the order needed to generate bytes of file.
  // NOTE: If any of these methods ever fail, the EncodedProgram instance
  // has failed and should be discarded.
  CheckBool AddOrigin(RVA rva) WARN_UNUSED_RESULT;
  CheckBool AddCopy(uint32 count, const void* bytes) WARN_UNUSED_RESULT;
  CheckBool AddRel32(int label_index) WARN_UNUSED_RESULT;
  CheckBool AddRel32ARM(uint16 op, int label_index) WARN_UNUSED_RESULT;
  CheckBool AddAbs32(int label_index) WARN_UNUSED_RESULT;
  CheckBool AddPeMakeRelocs(ExecutableType kind) WARN_UNUSED_RESULT;
  CheckBool AddElfMakeRelocs() WARN_UNUSED_RESULT;
  CheckBool AddElfARMMakeRelocs() WARN_UNUSED_RESULT;

  // (3) Serialize binary assembly language tables to a set of streams.
  CheckBool WriteTo(SinkStreamSet* streams) WARN_UNUSED_RESULT;

  // Using an EncodedProgram to generate a byte stream:
  //
  // (4) Deserializes a fresh EncodedProgram from a set of streams.
  bool ReadFrom(SourceStreamSet* streams);

  // (5) Assembles the 'binary assembly language' into final file.
  CheckBool AssembleTo(SinkStream* buffer) WARN_UNUSED_RESULT;

 private:
  // Binary assembly language operations.
  // These are part of the patch format. Reusing an existing value will
  // break backwards compatibility.
  enum OP {
    ORIGIN = 0,    // ORIGIN <rva> - set address for subsequent assembly.
    COPY = 1,      // COPY <count> <bytes> - copy bytes to output.
    COPY1 = 2,     // COPY1 <byte> - same as COPY 1 <byte>.
    REL32 = 3,     // REL32 <index> - emit rel32 encoded reference to address at
                   // address table offset <index>
    ABS32 = 4,     // ABS32 <index> - emit abs32 encoded reference to address at
                   // address table offset <index>
    MAKE_PE_RELOCATION_TABLE = 5,  // Emit PE base relocation table blocks.
    MAKE_ELF_RELOCATION_TABLE = 6, // Emit Elf relocation table for X86
    MAKE_ELF_ARM_RELOCATION_TABLE = 7, // Emit Elf relocation table for ARM
    MAKE_PE64_RELOCATION_TABLE = 8, // Emit PE64 base relocation table blocks.
    // ARM reserves 0x1000-LAST_ARM, bits 13-16 define the opcode
    // subset, and 1-12 are the compressed ARM op.
    REL32ARM8   = 0x1000,
    REL32ARM11  = 0x2000,
    REL32ARM24  = 0x3000,
    REL32ARM25  = 0x4000,
    REL32ARM21  = 0x5000,
    LAST_ARM    = 0x5FFF,
  };

  typedef NoThrowBuffer<RVA> RvaVector;
  typedef NoThrowBuffer<uint32> UInt32Vector;
  typedef NoThrowBuffer<uint8> UInt8Vector;
  typedef NoThrowBuffer<OP> OPVector;

  void DebuggingSummary();
  CheckBool GeneratePeRelocations(SinkStream *buffer,
                                  uint8 type) WARN_UNUSED_RESULT;
  CheckBool GenerateElfRelocations(Elf32_Word pending_elf_relocation_table,
                                   SinkStream *buffer) WARN_UNUSED_RESULT;
  CheckBool DefineLabelCommon(RvaVector*, int, RVA) WARN_UNUSED_RESULT;
  void FinishLabelsCommon(RvaVector* addresses);

  // Decodes and evaluates courgette ops for ARM rel32 addresses.
  CheckBool EvaluateRel32ARM(OP op, size_t& ix_rel32_ix, RVA& current_rva,
                             SinkStream* output);

  // Binary assembly language tables.
  uint64 image_base_;
  RvaVector rel32_rva_;
  RvaVector abs32_rva_;
  OPVector ops_;
  RvaVector origins_;
  UInt32Vector copy_counts_;
  UInt8Vector copy_bytes_;
  UInt32Vector rel32_ix_;
  UInt32Vector abs32_ix_;

  // Table of the addresses containing abs32 relocations; computed during
  // assembly, used to generate base relocation table.
  UInt32Vector abs32_relocs_;

  DISALLOW_COPY_AND_ASSIGN(EncodedProgram);
};

}  // namespace courgette
#endif  // COURGETTE_ENCODED_PROGRAM_H_
