Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(311)

Side by Side Diff: courgette/assembly_program.h

Issue 2462993003: [Courgette] Refactor: Add and use Instruction*Receptor classes; call ParseFile() in 2 passes. (Closed)
Patch Set: Fix comments. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « courgette/adjustment_method_unittest.cc ('k') | courgette/assembly_program.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef COURGETTE_ASSEMBLY_PROGRAM_H_ 5 #ifndef COURGETTE_ASSEMBLY_PROGRAM_H_
6 #define COURGETTE_ASSEMBLY_PROGRAM_H_ 6 #define COURGETTE_ASSEMBLY_PROGRAM_H_
7 7
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 10
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 explicit Instruction(OP op) : op_(op), info_(0) {} 50 explicit Instruction(OP op) : op_(op), info_(0) {}
51 Instruction(OP op, unsigned int info) : op_(op), info_(info) {} 51 Instruction(OP op, unsigned int info) : op_(op), info_(info) {}
52 52
53 uint32_t op_ : 4; // A few bits to store the OP code. 53 uint32_t op_ : 4; // A few bits to store the OP code.
54 uint32_t info_ : 28; // Remaining bits in first word available to subclass. 54 uint32_t info_ : 28; // Remaining bits in first word available to subclass.
55 55
56 private: 56 private:
57 DISALLOW_COPY_AND_ASSIGN(Instruction); 57 DISALLOW_COPY_AND_ASSIGN(Instruction);
58 }; 58 };
59 59
60 typedef NoThrowBuffer<Instruction*> InstructionVector; 60 // An interface to receive emitted instructions parsed from an executable.
61 class InstructionReceptor {
62 public:
63 InstructionReceptor() = default;
64 virtual ~InstructionReceptor() = default;
65
66 // Generates an entire base relocation table.
67 virtual CheckBool EmitPeRelocs() = 0;
68
69 // Generates an ELF style relocation table for X86.
70 virtual CheckBool EmitElfRelocation() = 0;
71
72 // Generates an ELF style relocation table for ARM.
73 virtual CheckBool EmitElfARMRelocation() = 0;
74
75 // Following instruction will be assembled at address 'rva'.
76 virtual CheckBool EmitOrigin(RVA rva) = 0;
77
78 // Generates a single byte of data or machine instruction.
79 virtual CheckBool EmitSingleByte(uint8_t byte) = 0;
80
81 // Generates multiple bytes of data or machine instructions.
82 virtual CheckBool EmitMultipleBytes(const uint8_t* bytes, size_t len) = 0;
83
84 // Generates a 4-byte relative reference to address of 'label'.
85 virtual CheckBool EmitRel32(Label* label) = 0;
86
87 // Generates a 4-byte relative reference to address of 'label' for ARM.
88 virtual CheckBool EmitRel32ARM(uint16_t op,
89 Label* label,
90 const uint8_t* arm_op,
91 uint16_t op_size) = 0;
92
93 // Generates a 4-byte absolute reference to address of 'label'.
94 virtual CheckBool EmitAbs32(Label* label) = 0;
95
96 // Generates an 8-byte absolute reference to address of 'label'.
97 virtual CheckBool EmitAbs64(Label* label) = 0;
98
99 private:
100 DISALLOW_COPY_AND_ASSIGN(InstructionReceptor);
101 };
61 102
62 // An AssemblyProgram is the result of disassembling an executable file. 103 // An AssemblyProgram is the result of disassembling an executable file.
63 // 104 //
64 // * The disassembler creates labels in the AssemblyProgram and emits 105 // * The disassembler creates labels in the AssemblyProgram and emits
65 // 'Instructions'. 106 // 'Instructions'.
66 // * The disassembler then calls DefaultAssignIndexes to assign 107 // * The disassembler then calls DefaultAssignIndexes to assign
67 // addresses to positions in the address tables. 108 // addresses to positions in the address tables.
68 // * [Optional step] 109 // * [Optional step]
69 // * At this point the AssemblyProgram can be converted into an 110 // * At this point the AssemblyProgram can be converted into an
70 // EncodedProgram and serialized to an output stream. 111 // EncodedProgram and serialized to an output stream.
71 // * Later, the EncodedProgram can be deserialized and assembled into 112 // * Later, the EncodedProgram can be deserialized and assembled into
72 // the original file. 113 // the original file.
73 // 114 //
74 // The optional step is to modify the AssemblyProgram. One form of modification 115 // The optional step is to modify the AssemblyProgram. One form of modification
75 // is to assign indexes in such a way as to make the EncodedProgram for this 116 // is to assign indexes in such a way as to make the EncodedProgram for this
76 // AssemblyProgram look more like the EncodedProgram for some other 117 // AssemblyProgram look more like the EncodedProgram for some other
77 // AssemblyProgram. The modification process should call UnassignIndexes, do 118 // AssemblyProgram. The modification process should call UnassignIndexes, do
78 // its own assignment, and then call AssignRemainingIndexes to ensure all 119 // its own assignment, and then call AssignRemainingIndexes to ensure all
79 // indexes are assigned. 120 // indexes are assigned.
80 // 121
81 class AssemblyProgram { 122 class AssemblyProgram {
82 public: 123 public:
83 using LabelHandler = base::Callback<void(Label*)>; 124 using LabelHandler = base::Callback<void(Label*)>;
84 using LabelHandlerMap = std::map<OP, LabelHandler>; 125 using LabelHandlerMap = std::map<OP, LabelHandler>;
85 126
127 // A callback for GenerateInstructions() to emit instructions. The first
128 // argument (AssemblyProgram*) is provided for Label-related feature access.
129 // The second argument (InstructionReceptor*) is a receptor for instructions.
130 // The callback (which gets called in 2 passes) should return true on success,
131 // and false otherwise.
132 using InstructionGenerator =
133 base::Callback<CheckBool(AssemblyProgram*, InstructionReceptor*)>;
134
86 explicit AssemblyProgram(ExecutableType kind); 135 explicit AssemblyProgram(ExecutableType kind);
87 ~AssemblyProgram(); 136 ~AssemblyProgram();
88 137
89 ExecutableType kind() const { return kind_; } 138 ExecutableType kind() const { return kind_; }
90 139
91 void set_image_base(uint64_t image_base) { image_base_ = image_base; } 140 void set_image_base(uint64_t image_base) { image_base_ = image_base; }
92 141
93 // Instructions will be assembled in the order they are emitted.
94
95 // Generates an entire base relocation table.
96 CheckBool EmitPeRelocsInstruction() WARN_UNUSED_RESULT;
97
98 // Generates an ELF style relocation table for X86.
99 CheckBool EmitElfRelocationInstruction() WARN_UNUSED_RESULT;
100
101 // Generates an ELF style relocation table for ARM.
102 CheckBool EmitElfARMRelocationInstruction() WARN_UNUSED_RESULT;
103
104 // Following instruction will be assembled at address 'rva'.
105 CheckBool EmitOriginInstruction(RVA rva) WARN_UNUSED_RESULT;
106
107 // Generates a single byte of data or machine instruction.
108 CheckBool EmitByteInstruction(uint8_t byte) WARN_UNUSED_RESULT;
109
110 // Generates multiple bytes of data or machine instructions.
111 CheckBool EmitBytesInstruction(const uint8_t* value,
112 size_t len) WARN_UNUSED_RESULT;
113
114 // Generates 4-byte relative reference to address of 'label'.
115 CheckBool EmitRel32(Label* label) WARN_UNUSED_RESULT;
116
117 // Generates 4-byte relative reference to address of 'label' for
118 // ARM.
119 CheckBool EmitRel32ARM(uint16_t op,
120 Label* label,
121 const uint8_t* arm_op,
122 uint16_t op_size) WARN_UNUSED_RESULT;
123
124 // Generates 4-byte absolute reference to address of 'label'.
125 CheckBool EmitAbs32(Label* label) WARN_UNUSED_RESULT;
126
127 // Generates 8-byte absolute reference to address of 'label'.
128 CheckBool EmitAbs64(Label* label) WARN_UNUSED_RESULT;
129
130 // Traverses RVAs in |abs32_visitor| and |rel32_visitor| to precompute Labels. 142 // Traverses RVAs in |abs32_visitor| and |rel32_visitor| to precompute Labels.
131 void PrecomputeLabels(RvaVisitor* abs32_visitor, RvaVisitor* rel32_visitor); 143 void PrecomputeLabels(RvaVisitor* abs32_visitor, RvaVisitor* rel32_visitor);
132 144
133 // Removes underused Labels. Thresholds used (0 = no trimming) is 145 // Removes underused Labels. Thresholds used (0 = no trimming) is
134 // architecture-dependent. 146 // architecture-dependent.
135 void TrimLabels(); 147 void TrimLabels();
136 148
137 void UnassignIndexes(); 149 void UnassignIndexes();
138 void DefaultAssignIndexes(); 150 void DefaultAssignIndexes();
139 void AssignRemainingIndexes(); 151 void AssignRemainingIndexes();
140 152
141 // Looks up abs32 label. Returns null if none found. 153 // Looks up abs32 label. Returns null if none found.
142 Label* FindAbs32Label(RVA rva); 154 Label* FindAbs32Label(RVA rva);
143 155
144 // Looks up rel32 label. Returns null if none found. 156 // Looks up rel32 label. Returns null if none found.
145 Label* FindRel32Label(RVA rva); 157 Label* FindRel32Label(RVA rva);
146 158
147 std::unique_ptr<EncodedProgram> Encode() const; 159 std::unique_ptr<EncodedProgram> Encode() const;
148 160
149 // For each |instruction| in |instructions_|, looks up its opcode from 161 // For each |instruction| in |instructions_|, looks up its opcode from
150 // |handler_map| for a handler. If a handler exists, invoke it by passing the 162 // |handler_map| for a handler. If a handler exists, invoke it by passing the
151 // |instruction|'s label. We assume that |handler_map| has correct keys, i.e., 163 // |instruction|'s label. We assume that |handler_map| has correct keys, i.e.,
152 // opcodes for an instruction that have label. 164 // opcodes for an instruction that have label.
153 void HandleInstructionLabels(const LabelHandlerMap& handler_map) const; 165 void HandleInstructionLabels(const LabelHandlerMap& handler_map) const;
154 166
167 // Calls |gen| in 2 passes to emit instructions. In pass 1 we provide a
168 // receptor to count space requirement. In pass 2 we provide a receptor to
169 // store instructions.
170 CheckBool GenerateInstructions(const InstructionGenerator& gen);
171
172 // TODO(huangs): Implement these in InstructionStoreReceptor.
173 // Instructions will be assembled in the order they are emitted.
174
175 // Generates an entire base relocation table.
176 CheckBool EmitPeRelocs() WARN_UNUSED_RESULT;
177
178 // Generates an ELF style relocation table for X86.
179 CheckBool EmitElfRelocation() WARN_UNUSED_RESULT;
180
181 // Generates an ELF style relocation table for ARM.
182 CheckBool EmitElfARMRelocation() WARN_UNUSED_RESULT;
183
184 // Following instruction will be assembled at address 'rva'.
185 CheckBool EmitOrigin(RVA rva) WARN_UNUSED_RESULT;
186
187 // Generates a single byte of data or machine instruction.
188 CheckBool EmitSingleByte(uint8_t byte) WARN_UNUSED_RESULT;
189
190 // Generates multiple bytes of data or machine instructions.
191 CheckBool EmitMultipleBytes(const uint8_t* bytes,
192 size_t len) WARN_UNUSED_RESULT;
193
194 // Generates a 4-byte relative reference to address of 'label'.
195 CheckBool EmitRel32(Label* label) WARN_UNUSED_RESULT;
196
197 // Generates a 4-byte relative reference to address of 'label' for ARM.
198 CheckBool EmitRel32ARM(uint16_t op,
199 Label* label,
200 const uint8_t* arm_op,
201 uint16_t op_size) WARN_UNUSED_RESULT;
202
203 // Generates a 4-byte absolute reference to address of 'label'.
204 CheckBool EmitAbs32(Label* label) WARN_UNUSED_RESULT;
205
206 // Generates an 8-byte absolute reference to address of 'label'.
207 CheckBool EmitAbs64(Label* label) WARN_UNUSED_RESULT;
208
155 private: 209 private:
210 using InstructionVector = NoThrowBuffer<Instruction*>;
211
156 using ScopedInstruction = 212 using ScopedInstruction =
157 std::unique_ptr<Instruction, UncheckedDeleter<Instruction>>; 213 std::unique_ptr<Instruction, UncheckedDeleter<Instruction>>;
158 214
159 ExecutableType kind_; 215 ExecutableType kind_;
160 216
161 CheckBool Emit(ScopedInstruction instruction) WARN_UNUSED_RESULT; 217 CheckBool Emit(ScopedInstruction instruction) WARN_UNUSED_RESULT;
162 CheckBool EmitShared(Instruction* instruction) WARN_UNUSED_RESULT; 218 CheckBool EmitShared(Instruction* instruction) WARN_UNUSED_RESULT;
163 219
164 static const int kLabelLowerLimit; 220 static const int kLabelLowerLimit;
165 221
(...skipping 23 matching lines...) Expand all
189 245
190 // Converts |program| into encoded form, returning it as |*output|. 246 // Converts |program| into encoded form, returning it as |*output|.
191 // Returns C_OK if succeeded, otherwise returns an error status and sets 247 // Returns C_OK if succeeded, otherwise returns an error status and sets
192 // |*output| to null. 248 // |*output| to null.
193 Status Encode(const AssemblyProgram& program, 249 Status Encode(const AssemblyProgram& program,
194 std::unique_ptr<EncodedProgram>* output); 250 std::unique_ptr<EncodedProgram>* output);
195 251
196 } // namespace courgette 252 } // namespace courgette
197 253
198 #endif // COURGETTE_ASSEMBLY_PROGRAM_H_ 254 #endif // COURGETTE_ASSEMBLY_PROGRAM_H_
OLDNEW
« no previous file with comments | « courgette/adjustment_method_unittest.cc ('k') | courgette/assembly_program.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698