encoded_program.h revision a36e5920737c6adbddd3e43b760e5de8431db6e0
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef COURGETTE_ENCODED_PROGRAM_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COURGETTE_ENCODED_PROGRAM_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "courgette/disassembler.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "courgette/memory_allocator.h"
13ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "courgette/types_elf.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace courgette {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SinkStream;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SinkStreamSet;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SourceStreamSet;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An EncodedProgram is a set of tables that contain a simple 'binary assembly
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// language' that can be assembled to produce a sequence of bytes, for example,
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a Windows 32-bit executable.
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EncodedProgram {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EncodedProgram();
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~EncodedProgram();
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generating an EncodedProgram:
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (1) The image base can be specified at any time.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_image_base(uint64 base) { image_base_ = base; }
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (2) Address tables and indexes defined first.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckBool DefineRel32Label(int index, RVA address) WARN_UNUSED_RESULT;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckBool DefineAbs32Label(int index, RVA address) WARN_UNUSED_RESULT;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void EndLabels();
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (3) Add instructions in the order needed to generate bytes of file.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: If any of these methods ever fail, the EncodedProgram instance
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // has failed and should be discarded.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckBool AddOrigin(RVA rva) WARN_UNUSED_RESULT;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckBool AddCopy(uint32 count, const void* bytes) WARN_UNUSED_RESULT;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckBool AddRel32(int label_index) WARN_UNUSED_RESULT;
46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CheckBool AddRel32ARM(uint16 op, int label_index) WARN_UNUSED_RESULT;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckBool AddAbs32(int label_index) WARN_UNUSED_RESULT;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckBool AddPeMakeRelocs() WARN_UNUSED_RESULT;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckBool AddElfMakeRelocs() WARN_UNUSED_RESULT;
50ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  CheckBool AddElfARMMakeRelocs() WARN_UNUSED_RESULT;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (3) Serialize binary assembly language tables to a set of streams.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckBool WriteTo(SinkStreamSet* streams) WARN_UNUSED_RESULT;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Using an EncodedProgram to generate a byte stream:
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (4) Deserializes a fresh EncodedProgram from a set of streams.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ReadFrom(SourceStreamSet* streams);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (5) Assembles the 'binary assembly language' into final file.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckBool AssembleTo(SinkStream* buffer) WARN_UNUSED_RESULT;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Binary assembly language operations.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These are part of the patch format. Reusing an existing value will
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // break backwards compatibility.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum OP {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ORIGIN = 0,    // ORIGIN <rva> - set address for subsequent assembly.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    COPY = 1,      // COPY <count> <bytes> - copy bytes to output.
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    COPY1 = 2,     // COPY1 <byte> - same as COPY 1 <byte>.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    REL32 = 3,     // REL32 <index> - emit rel32 encoded reference to address at
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   // address table offset <index>
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ABS32 = 4,     // ABS32 <index> - emit abs32 encoded reference to address at
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   // address table offset <index>
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MAKE_PE_RELOCATION_TABLE = 5,  // Emit PE base relocation table blocks.
76ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    MAKE_ELF_RELOCATION_TABLE = 6, // Emit Elf relocation table for X86
77ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    MAKE_ELF_ARM_RELOCATION_TABLE = 7, // Emit Elf relocation table for ARM
78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // ARM reserves 0x1000-LAST_ARM, bits 13-16 define the opcode
79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // subset, and 1-12 are the compressed ARM op.
80a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    REL32ARM8   = 0x1000,
81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    REL32ARM11  = 0x2000,
82a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    REL32ARM24  = 0x3000,
83a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    REL32ARM25  = 0x4000,
84a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    REL32ARM21  = 0x5000,
85a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    LAST_ARM    = 0x5FFF,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef NoThrowBuffer<RVA> RvaVector;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef NoThrowBuffer<uint32> UInt32Vector;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef NoThrowBuffer<uint8> UInt8Vector;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef NoThrowBuffer<OP> OPVector;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DebuggingSummary();
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckBool GeneratePeRelocations(SinkStream *buffer) WARN_UNUSED_RESULT;
95ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  CheckBool GenerateElfRelocations(Elf32_Word pending_elf_relocation_table,
96ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                   SinkStream *buffer) WARN_UNUSED_RESULT;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckBool DefineLabelCommon(RvaVector*, int, RVA) WARN_UNUSED_RESULT;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void FinishLabelsCommon(RvaVector* addresses);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Decodes and evaluates courgette ops for ARM rel32 addresses.
101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CheckBool EvaluateRel32ARM(OP op, size_t& ix_rel32_ix, RVA& current_rva,
102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                             SinkStream* output);
103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Binary assembly language tables.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint64 image_base_;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RvaVector rel32_rva_;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RvaVector abs32_rva_;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OPVector ops_;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RvaVector origins_;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UInt32Vector copy_counts_;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UInt8Vector copy_bytes_;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UInt32Vector rel32_ix_;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UInt32Vector abs32_ix_;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Table of the addresses containing abs32 relocations; computed during
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // assembly, used to generate base relocation table.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UInt32Vector abs32_relocs_;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(EncodedProgram);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace courgette
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // COURGETTE_ENCODED_PROGRAM_H_
124