encoded_program.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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. #ifndef COURGETTE_ENCODED_PROGRAM_H_
  5. #define COURGETTE_ENCODED_PROGRAM_H_
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <memory>
  9. #include <vector>
  10. #include "courgette/courgette.h"
  11. #include "courgette/image_utils.h"
  12. #include "courgette/instruction_utils.h"
  13. #include "courgette/memory_allocator.h"
  14. #include "courgette/types_elf.h"
  15. namespace courgette {
  16. // Stream indexes.
  17. const int kStreamMisc = 0;
  18. const int kStreamOps = 1;
  19. const int kStreamBytes = 2;
  20. const int kStreamAbs32Indexes = 3;
  21. const int kStreamRel32Indexes = 4;
  22. const int kStreamAbs32Addresses = 5;
  23. const int kStreamRel32Addresses = 6;
  24. const int kStreamCopyCounts = 7;
  25. const int kStreamOriginAddresses = kStreamMisc;
  26. const int kStreamLimit = 9;
  27. class LabelManager;
  28. class SinkStream;
  29. class SinkStreamSet;
  30. class SourceStreamSet;
  31. // EncodedProgram encodes Courgette's simple "binary assembly language", which
  32. // can be assembled to produce a sequence of bytes (e.g., a Windows 32-bit
  33. // executable).
  34. class EncodedProgram {
  35. public:
  36. EncodedProgram();
  37. EncodedProgram(const EncodedProgram&) = delete;
  38. EncodedProgram& operator=(const EncodedProgram&) = delete;
  39. ~EncodedProgram();
  40. // Generating an EncodedProgram:
  41. //
  42. // (1) The image base can be specified at any time.
  43. void set_image_base(uint64_t base) { image_base_ = base; }
  44. // (2) Address tables and indexes imported first.
  45. [[nodiscard]] CheckBool ImportLabels(const LabelManager& abs32_label_manager,
  46. const LabelManager& rel32_label_manager);
  47. // (3) Add instructions in the order needed to generate bytes of file.
  48. // NOTE: If any of these methods ever fail, the EncodedProgram instance
  49. // has failed and should be discarded.
  50. [[nodiscard]] CheckBool AddOrigin(RVA rva);
  51. [[nodiscard]] CheckBool AddCopy(size_t count, const void* bytes);
  52. [[nodiscard]] CheckBool AddRel32(int label_index);
  53. [[nodiscard]] CheckBool AddAbs32(int label_index);
  54. [[nodiscard]] CheckBool AddAbs64(int label_index);
  55. [[nodiscard]] CheckBool AddPeMakeRelocs(ExecutableType kind);
  56. [[nodiscard]] CheckBool AddElfMakeRelocs();
  57. // (3) Serialize binary assembly language tables to a set of streams.
  58. [[nodiscard]] CheckBool WriteTo(SinkStreamSet* streams);
  59. // Using an EncodedProgram to generate a byte stream:
  60. //
  61. // (4) Deserializes a fresh EncodedProgram from a set of streams.
  62. bool ReadFrom(SourceStreamSet* streams);
  63. // (5) Assembles the 'binary assembly language' into final file.
  64. [[nodiscard]] CheckBool AssembleTo(SinkStream* buffer);
  65. // Calls |gen| to extract all instructions, which are then encoded and stored.
  66. CheckBool GenerateInstructions(ExecutableType exe_type,
  67. const InstructionGenerator& gen);
  68. private:
  69. // Binary assembly language operations.
  70. // These are part of the patch format. Reusing an existing value will
  71. // break backwards compatibility.
  72. enum OP {
  73. ORIGIN = 0, // ORIGIN <rva> - set address for subsequent assembly.
  74. COPY = 1, // COPY <count> <bytes> - copy bytes to output.
  75. COPY1 = 2, // COPY1 <byte> - same as COPY 1 <byte>.
  76. REL32 = 3, // REL32 <index> - emit rel32 encoded reference to address at
  77. // address table offset <index>.
  78. ABS32 = 4, // ABS32 <index> - emit abs32 encoded reference to address at
  79. // address table offset <index>.
  80. MAKE_PE_RELOCATION_TABLE = 5, // Emit PE base relocation table blocks.
  81. MAKE_ELF_RELOCATION_TABLE = 6, // Emit ELF relocation table for X86.
  82. // DEPCREATED: ELF relocation table for ARM.
  83. // MAKE_ELF_ARM_RELOCATION_TABLE_DEPRECATED = 7,
  84. MAKE_PE64_RELOCATION_TABLE = 8, // Emit PE64 base relocation table blocks.
  85. ABS64 = 9, // ABS64 <index> - emit abs64 encoded reference to address at
  86. // address table offset <index>.
  87. };
  88. typedef NoThrowBuffer<RVA> RvaVector;
  89. typedef NoThrowBuffer<size_t> SizeTVector;
  90. typedef NoThrowBuffer<uint32_t> UInt32Vector;
  91. typedef NoThrowBuffer<uint8_t> UInt8Vector;
  92. typedef NoThrowBuffer<OP> OPVector;
  93. void DebuggingSummary();
  94. // Helper for ImportLabels().
  95. static CheckBool WriteRvasToList(const LabelManager& label_manager,
  96. RvaVector* rvas);
  97. // Helper for ImportLabels().
  98. static void FillUnassignedRvaSlots(RvaVector* rvas);
  99. [[nodiscard]] CheckBool GeneratePeRelocations(SinkStream* buffer,
  100. uint8_t type);
  101. [[nodiscard]] CheckBool GenerateElfRelocations(
  102. Elf32_Word pending_elf_relocation_table,
  103. SinkStream* buffer);
  104. // Binary assembly language tables.
  105. uint64_t image_base_ = 0;
  106. RvaVector rel32_rva_;
  107. RvaVector abs32_rva_;
  108. OPVector ops_;
  109. RvaVector origins_;
  110. SizeTVector copy_counts_;
  111. UInt8Vector copy_bytes_;
  112. UInt32Vector rel32_ix_;
  113. UInt32Vector abs32_ix_;
  114. // Table of the addresses containing abs32 relocations; computed during
  115. // assembly, used to generate base relocation table.
  116. UInt32Vector abs32_relocs_;
  117. };
  118. // Deserializes program from a stream set to |*output|. Returns C_OK if
  119. // successful, otherwise assigns |*output| to null and returns an error status.
  120. Status ReadEncodedProgram(SourceStreamSet* source,
  121. std::unique_ptr<EncodedProgram>* output);
  122. } // namespace courgette
  123. #endif // COURGETTE_ENCODED_PROGRAM_H_