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

Side by Side Diff: courgette/assembly_program.cc

Issue 2793153003: [Courgette] Refactor: Store Label Annotation in AssemblyProgram for patch generation. (Closed)
Patch Set: Rename *_label_annotation to *_label_annotations. Created 3 years, 8 months 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/assembly_program.h ('k') | courgette/courgette_tool.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 #include "courgette/assembly_program.h" 5 #include "courgette/assembly_program.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "courgette/courgette.h" 9 #include "courgette/courgette.h"
10 #include "courgette/disassembler.h"
10 #include "courgette/encoded_program.h" 11 #include "courgette/encoded_program.h"
11 12
12 namespace courgette { 13 namespace courgette {
13 14
14 namespace { 15 namespace {
15 16
16 // Sets the current address for the emitting instructions. 17 // Sets the current address for the emitting instructions.
17 class OriginInstruction : public Instruction { 18 class OriginInstruction : public Instruction {
18 public: 19 public:
19 explicit OriginInstruction(RVA rva) : Instruction(ORIGIN, 0), rva_(rva) {} 20 explicit OriginInstruction(RVA rva) : Instruction(ORIGIN, 0), rva_(rva) {}
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 uint16_t op_size_; 98 uint16_t op_size_;
98 }; 99 };
99 100
100 /******** InstructionCountReceptor ********/ 101 /******** InstructionCountReceptor ********/
101 102
102 // An InstructionReceptor that counts space occupied by emitted instructions. 103 // An InstructionReceptor that counts space occupied by emitted instructions.
103 class InstructionCountReceptor : public InstructionReceptor { 104 class InstructionCountReceptor : public InstructionReceptor {
104 public: 105 public:
105 InstructionCountReceptor() = default; 106 InstructionCountReceptor() = default;
106 107
107 size_t size() const { return size_; } 108 size_t abs_count() const { return abs_count_; }
109 size_t rel_count() const { return rel_count_; }
108 110
109 // InstructionReceptor: 111 // InstructionReceptor:
110 // TODO(huangs): 2016/11: Populate these with size_ += ...
111 CheckBool EmitPeRelocs() override { return true; } 112 CheckBool EmitPeRelocs() override { return true; }
112 CheckBool EmitElfRelocation() override { return true; } 113 CheckBool EmitElfRelocation() override { return true; }
113 CheckBool EmitElfARMRelocation() override { return true; } 114 CheckBool EmitElfARMRelocation() override { return true; }
114 CheckBool EmitOrigin(RVA rva) override { return true; } 115 CheckBool EmitOrigin(RVA rva) override { return true; }
115 CheckBool EmitSingleByte(uint8_t byte) override { return true; } 116 CheckBool EmitSingleByte(uint8_t byte) override { return true; }
116 CheckBool EmitMultipleBytes(const uint8_t* bytes, size_t len) override { 117 CheckBool EmitMultipleBytes(const uint8_t* bytes, size_t len) override {
117 return true; 118 return true;
118 } 119 }
119 CheckBool EmitRel32(Label* label) override { return true; } 120 CheckBool EmitRel32(Label* label) override {
121 ++rel_count_;
122 return true;
123 }
120 CheckBool EmitRel32ARM(uint16_t op, 124 CheckBool EmitRel32ARM(uint16_t op,
121 Label* label, 125 Label* label,
122 const uint8_t* arm_op, 126 const uint8_t* arm_op,
123 uint16_t op_size) override { 127 uint16_t op_size) override {
128 ++rel_count_;
124 return true; 129 return true;
125 } 130 }
126 CheckBool EmitAbs32(Label* label) override { return true; } 131 CheckBool EmitAbs32(Label* label) override {
127 CheckBool EmitAbs64(Label* label) override { return true; } 132 ++abs_count_;
133 return true;
134 }
135 CheckBool EmitAbs64(Label* label) override {
136 ++abs_count_;
137 return true;
138 }
128 139
129 private: 140 private:
130 size_t size_ = 0; 141 size_t abs_count_ = 0;
142 size_t rel_count_ = 0;
131 143
132 DISALLOW_COPY_AND_ASSIGN(InstructionCountReceptor); 144 DISALLOW_COPY_AND_ASSIGN(InstructionCountReceptor);
133 }; 145 };
134 146
135 /******** InstructionStoreReceptor ********/ 147 /******** InstructionStoreReceptor ********/
136 148
137 // An InstructionReceptor that stores emitted instructions. 149 // An InstructionReceptor that stores emitted instructions.
138 class InstructionStoreReceptor : public InstructionReceptor { 150 class InstructionStoreReceptor : public InstructionReceptor {
139 public: 151 public:
140 explicit InstructionStoreReceptor(AssemblyProgram* program) 152 InstructionStoreReceptor(AssemblyProgram* program, bool annotate_labels)
141 : program_(program) { 153 : program_(program), annotate_labels_(annotate_labels) {
142 CHECK(program_); 154 CHECK(program_);
143 } 155 }
144 156
145 // TODO(huangs): 2016/11: Add Reserve(). 157 // TODO(huangs): 2017/04: Add Reserve().
146 158
147 // InstructionReceptor: 159 // InstructionReceptor:
148 // TODO(huangs): 2016/11: Replace stub with implementation. 160 // TODO(huangs): 2017/04: Move implementations here.
149 CheckBool EmitPeRelocs() override { return program_->EmitPeRelocs(); } 161 CheckBool EmitPeRelocs() override { return program_->EmitPeRelocs(); }
150 CheckBool EmitElfRelocation() override { 162 CheckBool EmitElfRelocation() override {
151 return program_->EmitElfRelocation(); 163 return program_->EmitElfRelocation();
152 } 164 }
153 CheckBool EmitElfARMRelocation() override { 165 CheckBool EmitElfARMRelocation() override {
154 return program_->EmitElfARMRelocation(); 166 return program_->EmitElfARMRelocation();
155 } 167 }
156 CheckBool EmitOrigin(RVA rva) override { return program_->EmitOrigin(rva); } 168 CheckBool EmitOrigin(RVA rva) override { return program_->EmitOrigin(rva); }
157 CheckBool EmitSingleByte(uint8_t byte) override { 169 CheckBool EmitSingleByte(uint8_t byte) override {
158 return program_->EmitSingleByte(byte); 170 return program_->EmitSingleByte(byte);
159 } 171 }
160 CheckBool EmitMultipleBytes(const uint8_t* bytes, size_t len) override { 172 CheckBool EmitMultipleBytes(const uint8_t* bytes, size_t len) override {
161 return program_->EmitMultipleBytes(bytes, len); 173 return program_->EmitMultipleBytes(bytes, len);
162 } 174 }
163 CheckBool EmitRel32(Label* label) override { 175 CheckBool EmitRel32(Label* label) override {
176 if (annotate_labels_)
177 program_->mutable_rel32_label_annotations()->push_back(label);
164 return program_->EmitRel32(label); 178 return program_->EmitRel32(label);
165 } 179 }
166 CheckBool EmitRel32ARM(uint16_t op, 180 CheckBool EmitRel32ARM(uint16_t op,
167 Label* label, 181 Label* label,
168 const uint8_t* arm_op, 182 const uint8_t* arm_op,
169 uint16_t op_size) override { 183 uint16_t op_size) override {
184 if (annotate_labels_)
185 program_->mutable_rel32_label_annotations()->push_back(label);
170 return program_->EmitRel32ARM(op, label, arm_op, op_size); 186 return program_->EmitRel32ARM(op, label, arm_op, op_size);
171 } 187 }
172 CheckBool EmitAbs32(Label* label) override { 188 CheckBool EmitAbs32(Label* label) override {
189 if (annotate_labels_)
190 program_->mutable_abs32_label_annotations()->push_back(label);
173 return program_->EmitAbs32(label); 191 return program_->EmitAbs32(label);
174 } 192 }
175 CheckBool EmitAbs64(Label* label) override { 193 CheckBool EmitAbs64(Label* label) override {
194 if (annotate_labels_)
195 program_->mutable_abs32_label_annotations()->push_back(label);
176 return program_->EmitAbs64(label); 196 return program_->EmitAbs64(label);
177 } 197 }
178 198
179 private: 199 private:
180 AssemblyProgram* program_; 200 AssemblyProgram* program_;
201 const bool annotate_labels_;
181 202
182 DISALLOW_COPY_AND_ASSIGN(InstructionStoreReceptor); 203 DISALLOW_COPY_AND_ASSIGN(InstructionStoreReceptor);
183 }; 204 };
184 205
185 } // namespace 206 } // namespace
186 207
187 /******** AssemblyProgram ********/ 208 /******** AssemblyProgram ********/
188 209
189 AssemblyProgram::AssemblyProgram(ExecutableType kind, uint64_t image_base) 210 AssemblyProgram::AssemblyProgram(ExecutableType kind, uint64_t image_base)
190 : kind_(kind), image_base_(image_base) {} 211 : kind_(kind), image_base_(image_base) {}
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 } 308 }
288 309
289 Label* AssemblyProgram::FindAbs32Label(RVA rva) { 310 Label* AssemblyProgram::FindAbs32Label(RVA rva) {
290 return abs32_label_manager_.Find(rva); 311 return abs32_label_manager_.Find(rva);
291 } 312 }
292 313
293 Label* AssemblyProgram::FindRel32Label(RVA rva) { 314 Label* AssemblyProgram::FindRel32Label(RVA rva) {
294 return rel32_label_manager_.Find(rva); 315 return rel32_label_manager_.Find(rva);
295 } 316 }
296 317
297 void AssemblyProgram::HandleInstructionLabels( 318 CheckBool AssemblyProgram::GenerateInstructions(const InstructionGenerator& gen,
298 const AssemblyProgram::LabelHandlerMap& handler_map) const { 319 bool annotate_labels) {
299 for (const Instruction* instruction : instructions_) { 320 // Pass 1: Count storage space required and reserve in advance.
300 LabelHandlerMap::const_iterator it = handler_map.find(instruction->op());
301 if (it != handler_map.end()) {
302 it->second.Run(
303 static_cast<const InstructionWithLabel*>(instruction)->label());
304 }
305 }
306 }
307
308 CheckBool AssemblyProgram::GenerateInstructions(
309 const InstructionGenerator& gen) {
310 // Pass 1: Count the space needed to store instructions.
311 InstructionCountReceptor count_receptor; 321 InstructionCountReceptor count_receptor;
312 if (!gen.Run(&count_receptor)) 322 if (!gen.Run(&count_receptor))
313 return false; 323 return false;
314 324
315 // Pass 2: Emit all instructions to preallocated buffer (uses Phase 1 count). 325 if (annotate_labels) {
316 InstructionStoreReceptor store_receptor(this); 326 DCHECK(abs32_label_annotations_.empty());
317 // TODO(huangs): 2017/03: Pass |count_receptor->size()| to |store_receptor_| 327 abs32_label_annotations_.reserve(count_receptor.abs_count());
318 // to reserve space for raw data. 328 DCHECK(rel32_label_annotations_.empty());
329 rel32_label_annotations_.reserve(count_receptor.rel_count());
330 }
331
332 // Pass 2: Emit all instructions to reserved buffer (uses Phase 1 count).
333 // Populates |abs32_label_annotations_| and |re32_label_annotations_| if
334 // |annotate_labels| is true.
335 InstructionStoreReceptor store_receptor(this, annotate_labels);
319 return gen.Run(&store_receptor); 336 return gen.Run(&store_receptor);
320 } 337 }
321 338
322 CheckBool AssemblyProgram::Emit(ScopedInstruction instruction) { 339 CheckBool AssemblyProgram::Emit(ScopedInstruction instruction) {
323 if (!instruction || !instructions_.push_back(instruction.get())) 340 if (!instruction || !instructions_.push_back(instruction.get()))
324 return false; 341 return false;
325 // Ownership successfully passed to instructions_. 342 // Ownership successfully passed to instructions_.
326 ignore_result(instruction.release()); 343 ignore_result(instruction.release());
327 return true; 344 return true;
328 } 345 }
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 Status Encode(const AssemblyProgram& program, 462 Status Encode(const AssemblyProgram& program,
446 std::unique_ptr<EncodedProgram>* output) { 463 std::unique_ptr<EncodedProgram>* output) {
447 // Explicitly release any memory associated with the output before encoding. 464 // Explicitly release any memory associated with the output before encoding.
448 output->reset(); 465 output->reset();
449 466
450 *output = program.Encode(); 467 *output = program.Encode();
451 return (*output) ? C_OK : C_GENERAL_ERROR; 468 return (*output) ? C_OK : C_GENERAL_ERROR;
452 } 469 }
453 470
454 } // namespace courgette 471 } // namespace courgette
OLDNEW
« no previous file with comments | « courgette/assembly_program.h ('k') | courgette/courgette_tool.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698