User interface of Apps Developer Tool:
[chromium-blink-merge.git] / courgette / assembly_program.h
blobbb2d34c165353a46e0faea272c7a1d274ea117ce
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.
5 #ifndef COURGETTE_ASSEMBLY_PROGRAM_H_
6 #define COURGETTE_ASSEMBLY_PROGRAM_H_
8 #include <map>
9 #include <set>
10 #include <vector>
12 #include "base/basictypes.h"
13 #include "base/memory/scoped_ptr.h"
15 #include "courgette/disassembler.h"
16 #include "courgette/memory_allocator.h"
18 namespace courgette {
20 class EncodedProgram;
21 class Instruction;
23 typedef NoThrowBuffer<Instruction*> InstructionVector;
25 // A Label is a symbolic reference to an address. Unlike a conventional
26 // assembly language, we always know the address. The address will later be
27 // stored in a table and the Label will be replaced with the index into the
28 // table.
30 // TODO(sra): Make fields private and add setters and getters.
31 class Label {
32 public:
33 static const int kNoIndex = -1;
34 Label() : rva_(0), index_(kNoIndex) {}
35 explicit Label(RVA rva) : rva_(rva), index_(kNoIndex) {}
37 RVA rva_; // Address referred to by the label.
38 int index_; // Index of address in address table, kNoIndex until assigned.
41 typedef std::map<RVA, Label*> RVAToLabel;
43 // An AssemblyProgram is the result of disassembling an executable file.
45 // * The disassembler creates labels in the AssemblyProgram and emits
46 // 'Instructions'.
47 // * The disassembler then calls DefaultAssignIndexes to assign
48 // addresses to positions in the address tables.
49 // * [Optional step]
50 // * At this point the AssemblyProgram can be converted into an
51 // EncodedProgram and serialized to an output stream.
52 // * Later, the EncodedProgram can be deserialized and assembled into
53 // the original file.
55 // The optional step is to modify the AssemblyProgram. One form of modification
56 // is to assign indexes in such a way as to make the EncodedProgram for this
57 // AssemblyProgram look more like the EncodedProgram for some other
58 // AssemblyProgram. The modification process should call UnassignIndexes, do
59 // its own assignment, and then call AssignRemainingIndexes to ensure all
60 // indexes are assigned.
62 class AssemblyProgram {
63 public:
64 AssemblyProgram();
65 ~AssemblyProgram();
67 void set_image_base(uint64 image_base) { image_base_ = image_base; }
69 // Instructions will be assembled in the order they are emitted.
71 // Generates an entire base relocation table.
72 CheckBool EmitPeRelocsInstruction() WARN_UNUSED_RESULT;
74 // Generates an ELF style relocation table for X86.
75 CheckBool EmitElfRelocationInstruction() WARN_UNUSED_RESULT;
77 // Generates an ELF style relocation table for ARM.
78 CheckBool EmitElfARMRelocationInstruction() WARN_UNUSED_RESULT;
80 // Following instruction will be assembled at address 'rva'.
81 CheckBool EmitOriginInstruction(RVA rva) WARN_UNUSED_RESULT;
83 // Generates a single byte of data or machine instruction.
84 CheckBool EmitByteInstruction(uint8 byte) WARN_UNUSED_RESULT;
86 // Generates 4-byte relative reference to address of 'label'.
87 CheckBool EmitRel32(Label* label) WARN_UNUSED_RESULT;
89 // Generates 4-byte absolute reference to address of 'label'.
90 CheckBool EmitAbs32(Label* label) WARN_UNUSED_RESULT;
92 // Looks up a label or creates a new one. Might return NULL.
93 Label* FindOrMakeAbs32Label(RVA rva);
95 // Looks up a label or creates a new one. Might return NULL.
96 Label* FindOrMakeRel32Label(RVA rva);
98 void DefaultAssignIndexes();
99 void UnassignIndexes();
100 void AssignRemainingIndexes();
102 EncodedProgram* Encode() const;
104 // Accessor for instruction list.
105 const InstructionVector& instructions() const {
106 return instructions_;
109 // Returns the label if the instruction contains and absolute address,
110 // otherwise returns NULL.
111 Label* InstructionAbs32Label(const Instruction* instruction) const;
113 // Returns the label if the instruction contains and rel32 offset,
114 // otherwise returns NULL.
115 Label* InstructionRel32Label(const Instruction* instruction) const;
117 private:
118 CheckBool Emit(Instruction* instruction) WARN_UNUSED_RESULT;
120 // Looks up a label or creates a new one. Might return NULL.
121 Label* FindLabel(RVA rva, RVAToLabel* labels);
123 // Helper methods for the public versions.
124 static void UnassignIndexes(RVAToLabel* labels);
125 static void DefaultAssignIndexes(RVAToLabel* labels);
126 static void AssignRemainingIndexes(RVAToLabel* labels);
128 // Sharing instructions that emit a single byte saves a lot of space.
129 Instruction* GetByteInstruction(uint8 byte);
130 scoped_ptr<Instruction*[]> byte_instruction_cache_;
132 uint64 image_base_; // Desired or mandated base address of image.
134 InstructionVector instructions_; // All the instructions in program.
136 // These are lookup maps to find the label associated with a given address.
137 // We have separate label spaces for addresses referenced by rel32 labels and
138 // abs32 labels. This is somewhat arbitrary.
139 RVAToLabel rel32_labels_;
140 RVAToLabel abs32_labels_;
142 DISALLOW_COPY_AND_ASSIGN(AssemblyProgram);
145 } // namespace courgette
146 #endif // COURGETTE_ASSEMBLY_PROGRAM_H_