123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- // 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 <stddef.h>
- #include <stdint.h>
- #include <memory>
- #include <vector>
- #include "courgette/courgette.h"
- #include "courgette/image_utils.h"
- #include "courgette/instruction_utils.h"
- #include "courgette/memory_allocator.h"
- #include "courgette/types_elf.h"
- namespace courgette {
- // Stream indexes.
- const int kStreamMisc = 0;
- const int kStreamOps = 1;
- const int kStreamBytes = 2;
- const int kStreamAbs32Indexes = 3;
- const int kStreamRel32Indexes = 4;
- const int kStreamAbs32Addresses = 5;
- const int kStreamRel32Addresses = 6;
- const int kStreamCopyCounts = 7;
- const int kStreamOriginAddresses = kStreamMisc;
- const int kStreamLimit = 9;
- class LabelManager;
- class SinkStream;
- class SinkStreamSet;
- class SourceStreamSet;
- // EncodedProgram encodes Courgette's simple "binary assembly language", which
- // can be assembled to produce a sequence of bytes (e.g., a Windows 32-bit
- // executable).
- class EncodedProgram {
- public:
- EncodedProgram();
- EncodedProgram(const EncodedProgram&) = delete;
- EncodedProgram& operator=(const EncodedProgram&) = delete;
- ~EncodedProgram();
- // Generating an EncodedProgram:
- //
- // (1) The image base can be specified at any time.
- void set_image_base(uint64_t base) { image_base_ = base; }
- // (2) Address tables and indexes imported first.
- [[nodiscard]] CheckBool ImportLabels(const LabelManager& abs32_label_manager,
- const LabelManager& rel32_label_manager);
- // (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.
- [[nodiscard]] CheckBool AddOrigin(RVA rva);
- [[nodiscard]] CheckBool AddCopy(size_t count, const void* bytes);
- [[nodiscard]] CheckBool AddRel32(int label_index);
- [[nodiscard]] CheckBool AddAbs32(int label_index);
- [[nodiscard]] CheckBool AddAbs64(int label_index);
- [[nodiscard]] CheckBool AddPeMakeRelocs(ExecutableType kind);
- [[nodiscard]] CheckBool AddElfMakeRelocs();
- // (3) Serialize binary assembly language tables to a set of streams.
- [[nodiscard]] CheckBool WriteTo(SinkStreamSet* streams);
- // 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.
- [[nodiscard]] CheckBool AssembleTo(SinkStream* buffer);
- // Calls |gen| to extract all instructions, which are then encoded and stored.
- CheckBool GenerateInstructions(ExecutableType exe_type,
- const InstructionGenerator& gen);
- 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.
- // DEPCREATED: ELF relocation table for ARM.
- // MAKE_ELF_ARM_RELOCATION_TABLE_DEPRECATED = 7,
- MAKE_PE64_RELOCATION_TABLE = 8, // Emit PE64 base relocation table blocks.
- ABS64 = 9, // ABS64 <index> - emit abs64 encoded reference to address at
- // address table offset <index>.
- };
- typedef NoThrowBuffer<RVA> RvaVector;
- typedef NoThrowBuffer<size_t> SizeTVector;
- typedef NoThrowBuffer<uint32_t> UInt32Vector;
- typedef NoThrowBuffer<uint8_t> UInt8Vector;
- typedef NoThrowBuffer<OP> OPVector;
- void DebuggingSummary();
- // Helper for ImportLabels().
- static CheckBool WriteRvasToList(const LabelManager& label_manager,
- RvaVector* rvas);
- // Helper for ImportLabels().
- static void FillUnassignedRvaSlots(RvaVector* rvas);
- [[nodiscard]] CheckBool GeneratePeRelocations(SinkStream* buffer,
- uint8_t type);
- [[nodiscard]] CheckBool GenerateElfRelocations(
- Elf32_Word pending_elf_relocation_table,
- SinkStream* buffer);
- // Binary assembly language tables.
- uint64_t image_base_ = 0;
- RvaVector rel32_rva_;
- RvaVector abs32_rva_;
- OPVector ops_;
- RvaVector origins_;
- SizeTVector 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_;
- };
- // Deserializes program from a stream set to |*output|. Returns C_OK if
- // successful, otherwise assigns |*output| to null and returns an error status.
- Status ReadEncodedProgram(SourceStreamSet* source,
- std::unique_ptr<EncodedProgram>* output);
- } // namespace courgette
- #endif // COURGETTE_ENCODED_PROGRAM_H_
|