Home | History | Annotate | Download | only in courgette
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef COURGETTE_ENCODED_PROGRAM_H_
      6 #define COURGETTE_ENCODED_PROGRAM_H_
      7 
      8 #include <vector>
      9 
     10 #include "base/basictypes.h"
     11 #include "courgette/disassembler.h"
     12 #include "courgette/memory_allocator.h"
     13 #include "courgette/types_elf.h"
     14 
     15 namespace courgette {
     16 
     17 class SinkStream;
     18 class SinkStreamSet;
     19 class SourceStreamSet;
     20 
     21 // An EncodedProgram is a set of tables that contain a simple 'binary assembly
     22 // language' that can be assembled to produce a sequence of bytes, for example,
     23 // a Windows 32-bit executable.
     24 //
     25 class EncodedProgram {
     26  public:
     27   EncodedProgram();
     28   ~EncodedProgram();
     29 
     30   // Generating an EncodedProgram:
     31   //
     32   // (1) The image base can be specified at any time.
     33   void set_image_base(uint64 base) { image_base_ = base; }
     34 
     35   // (2) Address tables and indexes defined first.
     36   CheckBool DefineRel32Label(int index, RVA address) WARN_UNUSED_RESULT;
     37   CheckBool DefineAbs32Label(int index, RVA address) WARN_UNUSED_RESULT;
     38   void EndLabels();
     39 
     40   // (3) Add instructions in the order needed to generate bytes of file.
     41   // NOTE: If any of these methods ever fail, the EncodedProgram instance
     42   // has failed and should be discarded.
     43   CheckBool AddOrigin(RVA rva) WARN_UNUSED_RESULT;
     44   CheckBool AddCopy(uint32 count, const void* bytes) WARN_UNUSED_RESULT;
     45   CheckBool AddRel32(int label_index) WARN_UNUSED_RESULT;
     46   CheckBool AddRel32ARM(uint16 op, int label_index) WARN_UNUSED_RESULT;
     47   CheckBool AddAbs32(int label_index) WARN_UNUSED_RESULT;
     48   CheckBool AddPeMakeRelocs(ExecutableType kind) WARN_UNUSED_RESULT;
     49   CheckBool AddElfMakeRelocs() WARN_UNUSED_RESULT;
     50   CheckBool AddElfARMMakeRelocs() WARN_UNUSED_RESULT;
     51 
     52   // (3) Serialize binary assembly language tables to a set of streams.
     53   CheckBool WriteTo(SinkStreamSet* streams) WARN_UNUSED_RESULT;
     54 
     55   // Using an EncodedProgram to generate a byte stream:
     56   //
     57   // (4) Deserializes a fresh EncodedProgram from a set of streams.
     58   bool ReadFrom(SourceStreamSet* streams);
     59 
     60   // (5) Assembles the 'binary assembly language' into final file.
     61   CheckBool AssembleTo(SinkStream* buffer) WARN_UNUSED_RESULT;
     62 
     63  private:
     64   // Binary assembly language operations.
     65   // These are part of the patch format. Reusing an existing value will
     66   // break backwards compatibility.
     67   enum OP {
     68     ORIGIN = 0,    // ORIGIN <rva> - set address for subsequent assembly.
     69     COPY = 1,      // COPY <count> <bytes> - copy bytes to output.
     70     COPY1 = 2,     // COPY1 <byte> - same as COPY 1 <byte>.
     71     REL32 = 3,     // REL32 <index> - emit rel32 encoded reference to address at
     72                    // address table offset <index>
     73     ABS32 = 4,     // ABS32 <index> - emit abs32 encoded reference to address at
     74                    // address table offset <index>
     75     MAKE_PE_RELOCATION_TABLE = 5,  // Emit PE base relocation table blocks.
     76     MAKE_ELF_RELOCATION_TABLE = 6, // Emit Elf relocation table for X86
     77     MAKE_ELF_ARM_RELOCATION_TABLE = 7, // Emit Elf relocation table for ARM
     78     MAKE_PE64_RELOCATION_TABLE = 8, // Emit PE64 base relocation table blocks.
     79     // ARM reserves 0x1000-LAST_ARM, bits 13-16 define the opcode
     80     // subset, and 1-12 are the compressed ARM op.
     81     REL32ARM8   = 0x1000,
     82     REL32ARM11  = 0x2000,
     83     REL32ARM24  = 0x3000,
     84     REL32ARM25  = 0x4000,
     85     REL32ARM21  = 0x5000,
     86     LAST_ARM    = 0x5FFF,
     87   };
     88 
     89   typedef NoThrowBuffer<RVA> RvaVector;
     90   typedef NoThrowBuffer<uint32> UInt32Vector;
     91   typedef NoThrowBuffer<uint8> UInt8Vector;
     92   typedef NoThrowBuffer<OP> OPVector;
     93 
     94   void DebuggingSummary();
     95   CheckBool GeneratePeRelocations(SinkStream *buffer,
     96                                   uint8 type) WARN_UNUSED_RESULT;
     97   CheckBool GenerateElfRelocations(Elf32_Word pending_elf_relocation_table,
     98                                    SinkStream *buffer) WARN_UNUSED_RESULT;
     99   CheckBool DefineLabelCommon(RvaVector*, int, RVA) WARN_UNUSED_RESULT;
    100   void FinishLabelsCommon(RvaVector* addresses);
    101 
    102   // Decodes and evaluates courgette ops for ARM rel32 addresses.
    103   CheckBool EvaluateRel32ARM(OP op, size_t& ix_rel32_ix, RVA& current_rva,
    104                              SinkStream* output);
    105 
    106   // Binary assembly language tables.
    107   uint64 image_base_;
    108   RvaVector rel32_rva_;
    109   RvaVector abs32_rva_;
    110   OPVector ops_;
    111   RvaVector origins_;
    112   UInt32Vector copy_counts_;
    113   UInt8Vector copy_bytes_;
    114   UInt32Vector rel32_ix_;
    115   UInt32Vector abs32_ix_;
    116 
    117   // Table of the addresses containing abs32 relocations; computed during
    118   // assembly, used to generate base relocation table.
    119   UInt32Vector abs32_relocs_;
    120 
    121   DISALLOW_COPY_AND_ASSIGN(EncodedProgram);
    122 };
    123 
    124 }  // namespace courgette
    125 #endif  // COURGETTE_ENCODED_PROGRAM_H_
    126