1 // Copyright 2011 The Chromium Authors
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_
12 #include "courgette/courgette.h"
13 #include "courgette/image_utils.h"
14 #include "courgette/instruction_utils.h"
15 #include "courgette/label_manager.h"
16 #include "courgette/memory_allocator.h" // For CheckBool.
22 // An AssemblyProgram stores Labels extracted from an executable file, and
23 // (optionally) Label annotations. It is initialized by a Disassembler, but
24 // stores separate state so that the Disassembler can be deleted. Typical usage:
26 // * The Disassembler calls PrecomputeLabels() and injects RVAs for abs32/rel32
27 // references. These are used to initialize labels.
28 // * The Disassembler calls DefaultAssignIndexes() to assign addresses to
29 // positions in the address tables.
31 // * The Disassembler can use Labels in AssemblyProgram to convert the
32 // executable file to an EncodedProgram, serialized to an output stream.
33 // * Later, the Disassembler can use the AssemblyProgram to can be deserialized
34 // and assembled into the original executable file via an EncodedProgram.
36 // The optional step is to adjust Labels in the AssemblyProgram. One form of
37 // adjustment is to assign indexes in such a way as to make the EncodedProgram
38 // for an executable look more like the EncodedProgram for another exectuable.
39 // The adjustment process should call UnassignIndexes(), do its own assignment,
40 // and then call AssignRemainingIndexes() to ensure all indexes are assigned.
41 class AssemblyProgram {
43 AssemblyProgram(ExecutableType kind, uint64_t image_base);
45 AssemblyProgram(const AssemblyProgram&) = delete;
46 AssemblyProgram& operator=(const AssemblyProgram&) = delete;
50 ExecutableType kind() const { return kind_; }
51 const std::vector<Label*>& abs32_label_annotations() const {
52 return abs32_label_annotations_;
54 const std::vector<Label*>& rel32_label_annotations() const {
55 return rel32_label_annotations_;
58 // Traverses RVAs in |abs32_visitor| and |rel32_visitor| to precompute Labels.
59 void PrecomputeLabels(RvaVisitor* abs32_visitor, RvaVisitor* rel32_visitor);
61 void UnassignIndexes();
62 void DefaultAssignIndexes();
63 void AssignRemainingIndexes();
65 // Looks up abs32 label. Returns null if none found.
66 Label* FindAbs32Label(RVA rva);
68 // Looks up rel32 label. Returns null if none found.
69 Label* FindRel32Label(RVA rva);
71 // Uses |gen| to initializes |*_label_annotations_|.
72 CheckBool AnnotateLabels(const InstructionGenerator& gen);
74 // Initializes |encoded| by injecting basic data and Label data.
75 bool PrepareEncodedProgram(EncodedProgram* encoded) const;
78 static const int kLabelLowerLimit;
80 // Looks up a label or creates a new one. Might return nullptr.
81 Label* FindLabel(RVA rva, RVAToLabel* labels);
83 const ExecutableType kind_;
84 const uint64_t image_base_; // Desired or mandated base address of image.
86 // Storage and lookup of Labels associated with target addresses. We use
87 // separate abs32 and rel32 labels.
88 LabelManager abs32_label_manager_;
89 LabelManager rel32_label_manager_;
91 // Label pointers for each abs32 and rel32 location, sorted by file offset.
92 // These are used by Label adjustment during patch generation.
93 std::vector<Label*> abs32_label_annotations_;
94 std::vector<Label*> rel32_label_annotations_;
97 } // namespace courgette
99 #endif // COURGETTE_ASSEMBLY_PROGRAM_H_