• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
set_image_base(uint64 base)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