1 // Copyright 2011 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef COURGETTE_ENCODED_PROGRAM_H_
6 #define COURGETTE_ENCODED_PROGRAM_H_
14 #include "courgette/courgette.h"
15 #include "courgette/image_utils.h"
16 #include "courgette/instruction_utils.h"
17 #include "courgette/memory_allocator.h"
18 #include "courgette/types_elf.h"
23 const int kStreamMisc = 0;
24 const int kStreamOps = 1;
25 const int kStreamBytes = 2;
26 const int kStreamAbs32Indexes = 3;
27 const int kStreamRel32Indexes = 4;
28 const int kStreamAbs32Addresses = 5;
29 const int kStreamRel32Addresses = 6;
30 const int kStreamCopyCounts = 7;
31 const int kStreamOriginAddresses = kStreamMisc;
33 const int kStreamLimit = 9;
38 class SourceStreamSet;
40 // EncodedProgram encodes Courgette's simple "binary assembly language", which
41 // can be assembled to produce a sequence of bytes (e.g., a Windows 32-bit
43 class EncodedProgram {
47 EncodedProgram(const EncodedProgram&) = delete;
48 EncodedProgram& operator=(const EncodedProgram&) = delete;
52 // Generating an EncodedProgram:
54 // (1) The image base can be specified at any time.
55 void set_image_base(uint64_t base) { image_base_ = base; }
57 // (2) Address tables and indexes imported first.
59 [[nodiscard]] CheckBool ImportLabels(const LabelManager& abs32_label_manager,
60 const LabelManager& rel32_label_manager);
62 // (3) Add instructions in the order needed to generate bytes of file.
63 // NOTE: If any of these methods ever fail, the EncodedProgram instance
64 // has failed and should be discarded.
65 [[nodiscard]] CheckBool AddOrigin(RVA rva);
66 [[nodiscard]] CheckBool AddCopy(size_t count, const void* bytes);
67 [[nodiscard]] CheckBool AddRel32(int label_index);
68 [[nodiscard]] CheckBool AddAbs32(int label_index);
69 [[nodiscard]] CheckBool AddAbs64(int label_index);
70 [[nodiscard]] CheckBool AddPeMakeRelocs(ExecutableType kind);
71 [[nodiscard]] CheckBool AddElfMakeRelocs();
73 // (3) Serialize binary assembly language tables to a set of streams.
74 [[nodiscard]] CheckBool WriteTo(SinkStreamSet* streams);
76 // Using an EncodedProgram to generate a byte stream:
78 // (4) Deserializes a fresh EncodedProgram from a set of streams.
79 bool ReadFrom(SourceStreamSet* streams);
81 // (5) Assembles the 'binary assembly language' into final file.
82 [[nodiscard]] CheckBool AssembleTo(SinkStream* buffer);
84 // Calls |gen| to extract all instructions, which are then encoded and stored.
85 CheckBool GenerateInstructions(ExecutableType exe_type,
86 const InstructionGenerator& gen);
89 // Binary assembly language operations.
90 // These are part of the patch format. Reusing an existing value will
91 // break backwards compatibility.
93 ORIGIN = 0, // ORIGIN <rva> - set address for subsequent assembly.
94 COPY = 1, // COPY <count> <bytes> - copy bytes to output.
95 COPY1 = 2, // COPY1 <byte> - same as COPY 1 <byte>.
96 REL32 = 3, // REL32 <index> - emit rel32 encoded reference to address at
97 // address table offset <index>.
98 ABS32 = 4, // ABS32 <index> - emit abs32 encoded reference to address at
99 // address table offset <index>.
100 MAKE_PE_RELOCATION_TABLE = 5, // Emit PE base relocation table blocks.
101 MAKE_ELF_RELOCATION_TABLE = 6, // Emit ELF relocation table for X86.
102 // DEPCREATED: ELF relocation table for ARM.
103 // MAKE_ELF_ARM_RELOCATION_TABLE_DEPRECATED = 7,
104 MAKE_PE64_RELOCATION_TABLE = 8, // Emit PE64 base relocation table blocks.
105 ABS64 = 9, // ABS64 <index> - emit abs64 encoded reference to address at
106 // address table offset <index>.
109 typedef NoThrowBuffer<RVA> RvaVector;
110 typedef NoThrowBuffer<size_t> SizeTVector;
111 typedef NoThrowBuffer<uint32_t> UInt32Vector;
112 typedef NoThrowBuffer<uint8_t> UInt8Vector;
113 typedef NoThrowBuffer<OP> OPVector;
115 void DebuggingSummary();
117 // Helper for ImportLabels().
118 static CheckBool WriteRvasToList(const LabelManager& label_manager,
121 // Helper for ImportLabels().
122 static void FillUnassignedRvaSlots(RvaVector* rvas);
124 [[nodiscard]] CheckBool GeneratePeRelocations(SinkStream* buffer,
126 [[nodiscard]] CheckBool GenerateElfRelocations(
127 Elf32_Word pending_elf_relocation_table,
130 // Binary assembly language tables.
131 uint64_t image_base_ = 0;
132 RvaVector rel32_rva_;
133 RvaVector abs32_rva_;
136 SizeTVector copy_counts_;
137 UInt8Vector copy_bytes_;
138 UInt32Vector rel32_ix_;
139 UInt32Vector abs32_ix_;
141 // Table of the addresses containing abs32 relocations; computed during
142 // assembly, used to generate base relocation table.
143 UInt32Vector abs32_relocs_;
146 // Deserializes program from a stream set to |*output|. Returns C_OK if
147 // successful, otherwise assigns |*output| to null and returns an error status.
148 Status ReadEncodedProgram(SourceStreamSet* source,
149 std::unique_ptr<EncodedProgram>* output);
151 } // namespace courgette
153 #endif // COURGETTE_ENCODED_PROGRAM_H_