fcml 1.3.0
Loading...
Searching...
No Matches
fcml_stateful_assembler.hpp
Go to the documentation of this file.
1/*
2 * FCML - Free Code Manipulation Library.
3 * Copyright (C) 2010-2020 Slawomir Wojtasiak
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
27#ifndef FCML_STATEFUL_ASSEMBLER_HPP_
28#define FCML_STATEFUL_ASSEMBLER_HPP_
29
30#include <vector>
31
32#include "fcml_assembler.hpp"
33#include "fcml_parser.hpp"
34
35namespace fcml {
36
51public:
52
54 class SAFlush {
55 };
56
69 bool enableParser = false) :
70 _instructionBuilder(IB(FCML_TEXT("")), false),
71 _assembler(assembler),
72 _context(context),
73 _codeLength(0) {
74 // Create parser if needed.
75 _parser = enableParser ? new Parser(assembler.getDialect()) : NULL;
76 }
77
82 if (_parser) {
83 delete _parser;
84 }
85 }
86
99 return add(ib);
100 }
101
114 flush();
115 _instructionBuilder.setNotNull(true);
116 _instructionBuilder.setValue(ib);
117 return *this;
118 }
119
129 return inst(mnemonic);
130 }
131
141 flush();
142 if (_parser) {
143 // Parse instruction and then pass it to the assembler.
144 _parserContext.setIp(_context.getEntryPoint().getIP());
145 ParserConfig &config = _parserContext.getConfig();
146 config.setThrowExceptionOnError(true);
147 _parser->parse(_parserContext, mnemonic, _parserResult);
148 *this << _parserResult.getInstruction();
149 } else {
150 // Parser is not available, so treat this string as a full
151 // instruction which have to be parsed.
152 _instructionBuilder.setNotNull(true);
153 _instructionBuilder.setValue(IB(mnemonic));
154 }
155 return *this;
156 }
157
168 return op(Operand(reg));
169 }
170
181 return op(Operand(imm));
182 }
183
194 return op(Operand(address));
195 }
196
207 return op(Operand(pointer));
208 }
209
219 return op(operand);
220 }
221
230 StatefulAssembler& op(const Operand &operand) {
231 if (!_instructionBuilder.isNotNull()) {
233 FCML_TEXT("No instruction builder available."));
234 }
235 IB &ib = _instructionBuilder.getValue();
236 ib.op(operand);
237 return *this;
238 }
239
250 return op(Operand(reg));
251 }
252
263 return op(Operand(imm));
264 }
265
275 StatefulAssembler& op(const Address &address) {
276 return op(Operand(address));
277 }
278
288 StatefulAssembler& op(const FarPointer &pointer) {
289 return op(Operand(pointer));
290 }
291
300 flush();
301 return *this;
302 }
303
313 return inst(instruction);
314 }
315
323 return set(prefix);
324 }
325
333 return set(hint);
334 }
335
343 return set(hint);
344 }
345
353 if (!_instructionBuilder.isNotNull()) {
355 FCML_TEXT("No instruction builder available."));
356 }
357 _instructionBuilder.getValue() << prefix;
358 return *this;
359 }
360
368 if (!_instructionBuilder.isNotNull()) {
370 FCML_TEXT("No instruction builder available."));
371 }
372 _instructionBuilder.getValue() << hint;
373 return *this;
374 }
375
383 if (!_instructionBuilder.isNotNull()) {
385 FCML_TEXT("No instruction builder available."));
386 }
387 _instructionBuilder.getValue() << hint;
388 return *this;
389 }
390
399 StatefulAssembler& inst(const Instruction &instruction) {
400
401 // Flush pending instruction if there is any.
402 flush();
403
404 // Just in case.
405 AssemblerConf &config = _context.getConfig();
406 config.setIncrementIp(true);
407 config.setThrowExceptionOnError(true);
408
409 // Assembler the instruction.
410 _assembler.assemble(_context, instruction, _result);
411
412 // Store the chosen assembled instruction for future use.
413 const AssembledInstruction *assembledInstruction =
414 _result.getChosenInstruction();
415 if (assembledInstruction) {
416 _assembledInstructions.push_back(*assembledInstruction);
417 _codeLength += assembledInstruction->getCodeLength();
418 } else {
420 FCML_TEXT("Chosen instruction hasn't been set. It seems "
421 "that the instruction chooser isn't working "
422 "correctly."));
423 }
424
425 return *this;
426 }
427
436 flush();
437 return CodeIterator(_assembledInstructions);
438 }
439
446 std::vector<AssembledInstruction>& getAssembledInstructions() {
447 flush();
448 return _assembledInstructions;
449 }
450
457 fcml_usize getCodeLength() {
458 flush();
459 return _codeLength;
460 }
461
467 void flush() {
468 if (_instructionBuilder.isNotNull()) {
469 // Build an instruction using the instruction builder.
470 Instruction instruction = _instructionBuilder.getValue().build();
471 // And clean the builder, is everything succeed.
472 _instructionBuilder.setNotNull(false);
473 // Assemble the instruction.
474 *this << instruction;
475 }
476 }
477
483 static SAFlush FLUSH() {
484 return SAFlush();
485 }
486
491 return _parserContext.getConfig();
492 }
493
499 return _parserContext.getConfig();
500 }
501
508 return _parserContext.getSymbolTable();
509 }
510
517 return _parserContext.getSymbolTable();
518 }
519
525 void setSymbolTable(SymbolTable *symbolTable) {
526 _parserContext.setSymbolTable(symbolTable);
527 }
528
529private:
530
532 Parser *_parser;
534 ParserResult _parserResult;
536 ParserContext _parserContext;
538 AssemblerResult _result;
540 Nullable<IB> _instructionBuilder;
541 /* Assembler used to assemble code. */
542 Assembler &_assembler;
544 AssemblerContext &_context;
545 // Assembled instructions.
546 std::vector<AssembledInstruction> _assembledInstructions;
548 fcml_usize _codeLength;
549
550};
551
552}
553
554#endif /* FCML_STATEFUL_ASSEMBLER_HPP_ */
Address operand.
Definition fcml_common.hpp:4601
Describes an assembled instruction.
Definition fcml_assembler.hpp:57
fcml_usize getCodeLength() const
Gets number of bytes in the buffer.
Definition fcml_assembler.hpp:128
Assembler configuration.
Definition fcml_assembler.hpp:321
void setIncrementIp(bool incrementIp)
Definition fcml_assembler.hpp:437
void setThrowExceptionOnError(bool throwExceptionOnError)
Sets the way how the error handling is done.
Definition fcml_assembler.hpp:487
Assembler context.
Definition fcml_assembler.hpp:510
const EntryPoint & getEntryPoint() const
Gets reference to the constant entry point instance associated with the context.
Definition fcml_assembler.hpp:573
const AssemblerConf & getConfig() const
Gets constant assembler configuration associated with the context.
Definition fcml_assembler.hpp:540
Assembler result.
Definition fcml_assembler.hpp:182
const AssembledInstruction * getChosenInstruction() const
Gets instruction chosen by the assembler as the preferred one.
Definition fcml_assembler.hpp:200
An assembler wrapper.
Definition fcml_assembler.hpp:717
Dialect & getDialect() const
Gets dialect associated with the assembler.
Definition fcml_assembler.hpp:855
fcml_ceh_error assemble(AssemblerContext &ctx, const Instruction &instruction, AssemblerResult &result)
Assembles given generic instruction model.
Definition fcml_assembler.hpp:760
Assembling failed.
Definition fcml_assembler.hpp:45
Iterates over machine code bytes from assembled instructions.
Definition fcml_assembler.hpp:872
fcml_ip getIP() const
Gets instruction pointer held by the entry point.
Definition fcml_common.hpp:641
Describes far pointer.
Definition fcml_common.hpp:3902
An instruction builder.
Definition fcml_common.hpp:7602
void op(const Operand &operand)
Sets a next operand for the instruction.
Definition fcml_common.hpp:7694
Illegal state exception.
Definition fcml_common.hpp:253
Wraps instruction prefix and prepares factory methods for the hints.
Definition fcml_common.hpp:312
Describes an instruction.
Definition fcml_common.hpp:7185
Represents integer value.
Definition fcml_common.hpp:700
Wrapper for nullable value types.
Definition fcml_common.hpp:120
Instruction operand.
Definition fcml_common.hpp:5184
Parser configuration.
Definition fcml_parser.hpp:55
void setThrowExceptionOnError(bool throwExceptionOnError)
Sets exception on error flag.
Definition fcml_parser.hpp:137
Parser context.
Definition fcml_parser.hpp:153
void setSymbolTable(SymbolTable *symbolTable)
Sets a symbol table for the instruction.
Definition fcml_parser.hpp:257
const ParserConfig & getConfig() const
Gets the parser configuration associated with the context.
Definition fcml_parser.hpp:186
void setIp(fcml_ip ip)
Gets a new instruction pointer.
Definition fcml_parser.hpp:216
const SymbolTable * getSymbolTable() const
Gets the symbol table associated with the context.
Definition fcml_parser.hpp:237
Parser result.
Definition fcml_parser.hpp:275
const Instruction & getInstruction() const
Gets the parsed instruction.
Definition fcml_parser.hpp:301
Parser wrapper.
Definition fcml_parser.hpp:387
fcml_ceh_error parse(ParserContext &ctx, const fcml_cstring &instruction, ParserResult &parserResult)
Parses instruction given in the parameters.
Definition fcml_parser.hpp:410
x86 - 64 register representation.
Definition fcml_common.hpp:1601
Used only to indicate the need of the flush operation.
Definition fcml_stateful_assembler.hpp:54
It's a stateful assembler which can be used to assemble instructions one by one on the fly.
Definition fcml_stateful_assembler.hpp:50
SymbolTable * getSymbolTable()
Gets symbol table used together with the parser.
Definition fcml_stateful_assembler.hpp:516
StatefulAssembler & set(const OperandHint &hint)
Adds an operand level hint to the instruction being built.
Definition fcml_stateful_assembler.hpp:382
const SymbolTable * getSymbolTable() const
Gets symbol table used together with the parser.
Definition fcml_stateful_assembler.hpp:507
StatefulAssembler & op(const FarPointer &pointer)
Adds the new far pointer operand to the instruction builder associated with the buffer.
Definition fcml_stateful_assembler.hpp:288
StatefulAssembler(Assembler &assembler, AssemblerContext &context, bool enableParser=false)
Creates a stateful assembler for the given assembler and assembler context.
Definition fcml_stateful_assembler.hpp:68
fcml_usize getCodeLength()
Gets the code length of all assembled instructions available.
Definition fcml_stateful_assembler.hpp:457
StatefulAssembler & inst(const fcml_cstring &mnemonic)
Creates an instruction builder for the given mnemonic.
Definition fcml_stateful_assembler.hpp:140
ParserConfig & getParserConfig()
Gets configuration used by parser if parsing is supported.
Definition fcml_stateful_assembler.hpp:498
StatefulAssembler & op(const Register &reg)
Adds the new register operand to the instruction builder associated with the buffer.
Definition fcml_stateful_assembler.hpp:249
std::vector< AssembledInstruction > & getAssembledInstructions()
Gets all chosen assembled instructions.
Definition fcml_stateful_assembler.hpp:446
StatefulAssembler & set(const InstructionPrefix &prefix)
Adds a prefix to the instruction being built.
Definition fcml_stateful_assembler.hpp:352
StatefulAssembler & op(const Operand &operand)
Adds an operand to the instruction builder associated with the buffer.
Definition fcml_stateful_assembler.hpp:230
virtual ~StatefulAssembler()
Destructor.
Definition fcml_stateful_assembler.hpp:81
StatefulAssembler & op(const Integer &imm)
Adds the new immediate operand to the instruction builder associated with the buffer.
Definition fcml_stateful_assembler.hpp:262
StatefulAssembler & add(const IB &ib)
Adds instruction builder to the stateful assembler.
Definition fcml_stateful_assembler.hpp:113
void setSymbolTable(SymbolTable *symbolTable)
Sets a new symbol table for the parser.
Definition fcml_stateful_assembler.hpp:525
StatefulAssembler & operator<<(const IB &ib)
Adds instruction builder to the stateful assembler.
Definition fcml_stateful_assembler.hpp:98
StatefulAssembler & op(const Address &address)
Adds the new address operand to the instruction builder associated with the buffer.
Definition fcml_stateful_assembler.hpp:275
const ParserConfig & getParserConfig() const
Gets configuration used by parser if parsing is supported.
Definition fcml_stateful_assembler.hpp:490
StatefulAssembler & set(const InstructionHint &hint)
Adds an instruction level hint to the instruction being built.
Definition fcml_stateful_assembler.hpp:367
StatefulAssembler & inst(const Instruction &instruction)
Assembles an instruction in the given instruction builder.
Definition fcml_stateful_assembler.hpp:399
static SAFlush FLUSH()
Creates flush indicated for "shift" operators.
Definition fcml_stateful_assembler.hpp:483
CodeIterator getCodeIterator()
Gets iterator which allows to iterate through the whole machine code byte by byte.
Definition fcml_stateful_assembler.hpp:435
void flush()
Assembles all pending instructions.
Definition fcml_stateful_assembler.hpp:467
Definition fcml_symbols.hpp:143
C++ wrapper for FCML assembler.
std::basic_string< fcml_char > fcml_cstring
By using this type definition here, it will be definitely much easier to support UNICODE in future re...
Definition fcml_common.hpp:53
C++ wrapper for instruction parser.
#define FCML_TEXT(x)
Used to code literal strings.
Definition fcml_types.h:61
Wraps instruction hint and exposes factory methods for instruction hints.
Definition fcml_common.hpp:402
Wraps operand hint and exposes factory methods for instruction hints.
Definition fcml_common.hpp:461