1 : // Copyright 2012 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 : //
15 : // Provides an assembler that assembles to basic block instruction lists.
16 :
17 : #ifndef SYZYGY_BLOCK_GRAPH_BASIC_BLOCK_ASSEMBLER_H_
18 : #define SYZYGY_BLOCK_GRAPH_BASIC_BLOCK_ASSEMBLER_H_
19 :
20 : #include "syzygy/block_graph/basic_block.h"
21 : #include "syzygy/core/assembler.h"
22 :
23 : namespace block_graph {
24 :
25 : using core::ValueSize;
26 :
27 : class BasicBlockAssembler;
28 : class Operand;
29 :
30 : class Value {
31 : public:
32 : // Default construction.
33 : Value();
34 : // Constructs an 8- or 32-bit value, depending on the minimum number of bits
35 : // required to represent the Value. If the value can be encoded using 8-bits
36 : // to have the same representation under sign extension, then an 8-bit Value
37 : // will be created; otherwise, a 32-bit absolute Value will be created.
38 : explicit Value(uint32 value);
39 : // Constructs an absolute value having a specific bit width.
40 : Value(uint32 value, core::ValueSize size);
41 : // Constructs a 32 bit absolute value referring to the basic block @p bb.
42 : explicit Value(BasicBlock* bb);
43 : // Constructs a 32 bit absolute value referring to @p block at @p offset.
44 : Value(BlockGraph::Block* block, BlockGraph::Offset offset);
45 : // Explicitly specified size and reference info.
46 : Value(uint32 value, ValueSize size, const BasicBlockReference& ref);
47 : // Copy construction.
48 : Value(const Value& other);
49 :
50 : // Destructor.
51 : ~Value();
52 :
53 : // Assignment operator.
54 : const Value& operator=(const Value& other);
55 :
56 : // @name Accessors.
57 : // @{
58 E : uint32 value() const { return value_.value(); }
59 E : core::ValueSize size() const { return value_.size(); }
60 E : const BasicBlockReference &reference() const { return reference_; }
61 : // @}
62 :
63 : // Comparison operator.
64 : bool operator==(const Value& rhs) const;
65 :
66 : private:
67 : // Private constructor for Operand.
68 : Value(const BasicBlockReference& ref, const core::ValueImpl& value);
69 :
70 : friend class BasicBlockAssembler;
71 : friend class Operand;
72 :
73 : BasicBlockReference reference_;
74 : core::ValueImpl value_;
75 : };
76 :
77 : // Displacements and immediates behave near-identically, but are semantically
78 : // slightly different.
79 : typedef Value Immediate;
80 : typedef Value Displacement;
81 :
82 : // An operand implies indirection to memory through one of the myriad
83 : // modes supported by IA32.
84 : class Operand {
85 : public:
86 : // A register-indirect mode.
87 : explicit Operand(core::Register base);
88 :
89 : // A register-indirect with displacement mode.
90 : Operand(core::Register base, const Displacement& displ);
91 :
92 : // A displacement-only mode.
93 : explicit Operand(const Displacement& displ);
94 :
95 : // The full [base + index * scale + displ32] mode.
96 : // @note esp cannot be used as an index register.
97 : Operand(core::Register base,
98 : core::Register index,
99 : core::ScaleFactor scale,
100 : const Displacement& displ);
101 :
102 : // The full [base + index * scale] mode.
103 : // @note esp cannot be used as an index register.
104 : Operand(core::Register base,
105 : core::Register index,
106 : core::ScaleFactor scale);
107 :
108 : // The [index * scale + displ32] mode.
109 : // @note esp cannot be used as an index register.
110 : Operand(core::Register index,
111 : core::ScaleFactor scale,
112 : const Displacement& displ);
113 :
114 : // Copy constructor.
115 : Operand(const Operand& o);
116 :
117 : // Destructor.
118 : ~Operand();
119 :
120 : // Assignment operator.
121 : const Operand& operator=(const Operand& other);
122 :
123 : // @name Accessors.
124 : // @{
125 E : core::RegisterCode base() const { return operand_.base(); }
126 E : core::RegisterCode index() const { return operand_.index(); }
127 E : core::ScaleFactor scale() const { return operand_.scale(); }
128 E : Displacement displacement() const {
129 E : return Displacement(reference_, operand_.displacement());
130 E : }
131 : // @}
132 :
133 : private:
134 : friend class BasicBlockAssembler;
135 :
136 : BasicBlockReference reference_;
137 : core::OperandImpl operand_;
138 : };
139 :
140 : class BasicBlockAssembler {
141 : public:
142 : typedef BlockGraph::Block::SourceRange SourceRange;
143 : typedef BasicBlock::Instructions Instructions;
144 : typedef core::Register Register;
145 : typedef core::ConditionCode ConditionCode;
146 :
147 : // Constructs a basic block assembler that inserts new instructions
148 : // into @p *list at @p where.
149 : BasicBlockAssembler(const Instructions::iterator& where,
150 : Instructions *list);
151 :
152 : // Constructs a basic block assembler that inserts new instructions into
153 : // @p *list at @p where, assuming a starting address of @p location.
154 : BasicBlockAssembler(uint32 location,
155 : const Instructions::iterator& where,
156 : Instructions *list);
157 :
158 : // @returns The source range injected into created instructions.
159 E : SourceRange source_range() const { return serializer_.source_range(); }
160 :
161 : // Set the SourceRange injected repeatedly into each instruction created via
162 : // the assembler. This should be used with care because it causes the OMAP
163 : // information to no longer be 1:1 mapping, and may confuse some debuggers.
164 : // @param source_range The source range set to each created instructions.
165 E : void set_source_range(const SourceRange& source_range) {
166 E : serializer_.set_source_range(source_range);
167 E : }
168 :
169 : // @name Call instructions.
170 : // @{
171 : void call(const Immediate& dst);
172 : void call(const Operand& dst);
173 : // @}
174 :
175 : // @name Jmp instructions.
176 : // @{
177 : void jmp(const Immediate& dst);
178 : void jmp(const Operand& dst);
179 : // @}
180 :
181 : // @name Conditional branch instruction.
182 : // @{
183 : void j(ConditionCode code, const Immediate& dst);
184 : // @}
185 :
186 : // @name Byte mov varieties.
187 : // @{
188 : void mov_b(const Operand& dst, const Immediate& src);
189 : // @}
190 :
191 : // @name Double-word mov varieties.
192 : // @{
193 : void mov(Register dst, Register src);
194 : void mov(Register dst, const Operand& src);
195 : void mov(const Operand& dst, Register src);
196 : void mov(Register dst, const Immediate& src);
197 : void mov(const Operand& dst, const Immediate& src);
198 : // @}
199 :
200 : // @name load effective address.
201 : void lea(Register dst, const Operand& src);
202 :
203 : // @name stack manipulation.
204 : // @{
205 : void push(Register src);
206 : void push(const Immediate& src);
207 : void push(const Operand& src);
208 :
209 : void pop(Register src);
210 : void pop(const Operand& src);
211 : // @}
212 :
213 : // @name Ret instructions.
214 : // @{
215 : void ret();
216 : void ret(uint16 n);
217 : // @}
218 :
219 : private:
220 : class BasicBlockSerializer
221 : : public core::AssemblerImpl::InstructionSerializer {
222 : public:
223 : BasicBlockSerializer(const Instructions::iterator& where,
224 : Instructions* list);
225 :
226 : virtual void AppendInstruction(uint32 location,
227 : const uint8* bytes,
228 : size_t num_bytes,
229 : const size_t *ref_locations,
230 : const void* const* refs,
231 : size_t num_refs) OVERRIDE;
232 :
233 E : SourceRange source_range() const { return source_range_; }
234 E : void set_source_range(const SourceRange& source_range) {
235 E : source_range_ = source_range;
236 E : }
237 :
238 : private:
239 : Instructions::iterator where_;
240 : Instructions* list_;
241 :
242 : // Source range set to instructions appended by this serializer.
243 : SourceRange source_range_;
244 : };
245 :
246 : BasicBlockSerializer serializer_;
247 : core::AssemblerImpl asm_;
248 : };
249 :
250 : } // namespace block_graph
251 :
252 : #endif // SYZYGY_BLOCK_GRAPH_BASIC_BLOCK_ASSEMBLER_H_
|