fcml  1.1.3
fcml_stateful_assembler.hpp
Go to the documentation of this file.
1 /*
2  * FCML - Free Code Manipulation Library.
3  * Copyright (C) 2010-2015 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 
35 namespace fcml {
36 
49 public:
50 
52  class SAFlush {
53  };
54 
65  StatefulAssembler( Assembler &assembler, AssemblerContext &context, bool enableParser = false ) :
66  _instructionBuilder(IB(FCML_TEXT(""))),
67  _assembler(assembler),
68  _context(context),
69  _codeLength(0) {
70  // Create parser if needed.
71  _parser = enableParser ? new Parser( assembler.getDialect() ) : NULL;
72  }
73 
77  virtual ~StatefulAssembler() {
78  if( _parser ) {
79  delete _parser;
80  }
81  }
82 
95  return add( ib );
96  }
97 
109  StatefulAssembler& add(const IB &ib) {
110  flush();
111  _instructionBuilder.setNotNull(true);
112  _instructionBuilder.setValue(ib);
113  return *this;
114  }
115 
125  return inst( mnemonic );
126  }
127 
136  StatefulAssembler& inst(const fcml_cstring &mnemonic) {
137  flush();
138  if( _parser ) {
139  // Parse instruction and then pass it to the assembler.
140  _parserContext.setIp( _context.getEntryPoint().getIP() );
141  ParserConfig &config = _parserContext.getConfig();
142  config.setThrowExceptionOnError(true);
143  _parser->parse( _parserContext, mnemonic, _parserResult );
144  *this << _parserResult.getInstruction();
145  } else {
146  // Parser is not available, so treat this string as a full instruction which
147  // have to be parsed.
148  _instructionBuilder.setNotNull(true);
149  _instructionBuilder.setValue(IB(mnemonic));
150  }
151  return *this;
152  }
153 
163  return op( Operand( reg ) );
164  }
165 
175  return op( Operand( imm ) );
176  }
177 
187  return op( Operand( address ) );
188  }
189 
199  return op( Operand( pointer ) );
200  }
201 
211  return op( operand );
212  }
213 
222  StatefulAssembler& op(const Operand &operand) {
223  if( !_instructionBuilder.isNotNull() ) {
224  throw IllegalStateException( FCML_TEXT( "No instruction builder available." ) );
225  }
226  IB &ib = _instructionBuilder.getValue();
227  ib.op( operand );
228  return *this;
229  }
230 
240  return op( Operand( reg ) );
241  }
242 
251  StatefulAssembler& op(const Integer &imm) {
252  return op( Operand( imm ) );
253  }
254 
263  StatefulAssembler& op(const Address &address) {
264  return op( Operand( address ) );
265  }
266 
275  StatefulAssembler& op(const FarPointer &pointer) {
276  return op( Operand( pointer ) );
277  }
278 
287  flush();
288  return *this;
289  }
290 
300  return inst( instruction );
301  }
302 
310  return set(prefix);
311  }
312 
320  return set( hint );
321  }
322 
330  return set( hint );
331  }
332 
339  StatefulAssembler& set( const InstructionPrefix &prefix ) {
340  if( !_instructionBuilder.isNotNull() ) {
341  throw IllegalStateException( FCML_TEXT( "No instruction builder available." ) );
342  }
343  _instructionBuilder.getValue() << prefix;
344  return *this;
345  }
346 
353  StatefulAssembler& set( const InstructionHint &hint ) {
354  if( !_instructionBuilder.isNotNull() ) {
355  throw IllegalStateException( FCML_TEXT( "No instruction builder available." ) );
356  }
357  _instructionBuilder.getValue() << hint;
358  return *this;
359  }
360 
367  StatefulAssembler& set( const OperandHint &hint ) {
368  if( !_instructionBuilder.isNotNull() ) {
369  throw IllegalStateException( FCML_TEXT( "No instruction builder available." ) );
370  }
371  _instructionBuilder.getValue() << hint;
372  return *this;
373  }
374 
383  StatefulAssembler& inst(const Instruction &instruction) {
384 
385  // Flush pending instruction if there is any.
386  flush();
387 
388  // Just in case.
389  AssemblerConf& config = _context.getConfig();
390  config.setIncrementIp( true );
391  config.setThrowExceptionOnError( true );
392 
393  // Assembler the instruction.
394  _assembler.assemble( _context, instruction, _result );
395 
396  // Store the chosen assembled instruction for future use.
397  const AssembledInstruction *assembledInstruction = _result.getChosenInstruction();
398  if( assembledInstruction ) {
399  _assembledInstructions.push_back( *assembledInstruction );
400  _codeLength += assembledInstruction->getCodeLength();
401  } else {
402  throw AssemblingFailedException( FCML_TEXT( "Chosen instruction hasn't been set. It seems that the instruction chooser isn't working correctly." ) );
403  }
404 
405  return *this;
406  }
407 
415  flush();
416  return CodeIterator( _assembledInstructions );
417  }
418 
425  std::vector<AssembledInstruction>& getAssembledInstructions() {
426  flush();
427  return _assembledInstructions;
428  }
429 
436  fcml_usize getCodeLength() {
437  flush();
438  return _codeLength;
439  }
440 
446  void flush() {
447  if( _instructionBuilder.isNotNull() ) {
448  // Build an instruction using the instruction builder.
449  Instruction instruction = _instructionBuilder.getValue().build();
450  // And clean the builder, is everything succeed.
451  _instructionBuilder.setNotNull(false);
452  // Assemble the instruction.
453  *this << instruction;
454  }
455  }
456 
462  static SAFlush FLUSH() {
463  return SAFlush();
464  }
465 
469  const ParserConfig& getParserConfig() const {
470  return _parserContext.getConfig();
471  }
472 
478  return _parserContext.getConfig();
479  }
480 
486  const SymbolTable* getSymbolTable() const {
487  return _parserContext.getSymbolTable();
488  }
489 
496  return _parserContext.getSymbolTable();
497  }
498 
504  void setSymbolTable( SymbolTable *symbolTable ) {
505  _parserContext.setSymbolTable( symbolTable );
506  }
507 
508 private:
509 
511  Parser *_parser;
513  ParserResult _parserResult;
515  ParserContext _parserContext;
517  AssemblerResult _result;
519  Nullable<IB> _instructionBuilder;
520  /* Assembler used to assemble code. */
521  Assembler &_assembler;
523  AssemblerContext &_context;
524  // Assembled instructions.
525  std::vector<AssembledInstruction> _assembledInstructions;
527  fcml_usize _codeLength;
528 
529 };
530 
531 }
532 
533 #endif /* FCML_STATEFUL_ASSEMBLER_HPP_ */
An instruction builder.
Definition: fcml_common.hpp:6624
C++ wrapper for FCML assembler.
fcml_usize getCodeLength() const
Gets number of bytes in the buffer.
Definition: fcml_assembler.hpp:124
Parser wrapper.
Definition: fcml_parser.hpp:383
static SAFlush FLUSH()
Creates flush indicated for "shift" operators.
Definition: fcml_stateful_assembler.hpp:462
void setThrowExceptionOnError(bool throwExceptionOnError)
Sets the way how the error handling is done.
Definition: fcml_assembler.hpp:475
fcml_usize getCodeLength()
Gets the code length of all assembled instructions available.
Definition: fcml_stateful_assembler.hpp:436
Assembler result.
Definition: fcml_assembler.hpp:177
Illegal state exception.
Definition: fcml_common.hpp:228
StatefulAssembler & op(const Address &address)
Adds the new address operand to the instruction builder associated with the buffer.
Definition: fcml_stateful_assembler.hpp:263
Assembling failed.
Definition: fcml_assembler.hpp:45
std::vector< AssembledInstruction > & getAssembledInstructions()
Gets all chosen assembled instructions.
Definition: fcml_stateful_assembler.hpp:425
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
Address operand.
Definition: fcml_common.hpp:3847
x86 - 64 register representation.
Definition: fcml_common.hpp:1574
Wraps operand hint and exposes factory methods for instruction hints.
Definition: fcml_common.hpp:436
void flush()
Assembles all pending instructions.
Definition: fcml_stateful_assembler.hpp:446
Assembler context.
Definition: fcml_assembler.hpp:498
Wrapper for nullable value types.
Definition: fcml_common.hpp:120
ParserConfig & getParserConfig()
Gets configuration used by parser if parsing is supported.
Definition: fcml_stateful_assembler.hpp:477
#define FCML_TEXT(x)
Used to code literal strings.
Definition: fcml_types.h:61
StatefulAssembler & op(const Operand &operand)
Adds an operand to the instruction builder associated with the buffer.
Definition: fcml_stateful_assembler.hpp:222
void setSymbolTable(SymbolTable *symbolTable)
Sets a new symbol table for the parser.
Definition: fcml_stateful_assembler.hpp:504
Describes far pointer.
Definition: fcml_common.hpp:3148
Definition: fcml_assembler.hpp:39
Wraps instruction hint and exposes factory methods for instruction hints.
Definition: fcml_common.hpp:377
virtual ~StatefulAssembler()
Destructor.
Definition: fcml_stateful_assembler.hpp:77
Parser configuration.
Definition: fcml_parser.hpp:53
Parser result.
Definition: fcml_parser.hpp:271
Instruction operand.
Definition: fcml_common.hpp:4247
Represents integer value.
Definition: fcml_common.hpp:675
void setIncrementIp(bool incrementIp)
Definition: fcml_assembler.hpp:427
An assembler wrapper.
Definition: fcml_assembler.hpp:696
void op(const Operand &operand)
Sets a next operand for the instruction.
Definition: fcml_common.hpp:6716
Describes an assembled instruction.
Definition: fcml_assembler.hpp:55
StatefulAssembler & inst(const Instruction &instruction)
Assembles an instruction in the given instruction builder.
Definition: fcml_stateful_assembler.hpp:383
StatefulAssembler(Assembler &assembler, AssemblerContext &context, bool enableParser=false)
Creates a stateful assembler for the given assembler and assembler context.
Definition: fcml_stateful_assembler.hpp:65
SymbolTable * getSymbolTable()
Gets symbol table used together with the parser.
Definition: fcml_stateful_assembler.hpp:495
fcml_st_symbol_table & getSymbolTable()
Gets native FCML symbol table.
Definition: fcml_symbols.hpp:177
StatefulAssembler & op(const Register &reg)
Adds the new register operand to the instruction builder associated with the buffer.
Definition: fcml_stateful_assembler.hpp:239
StatefulAssembler & op(const FarPointer &pointer)
Adds the new far pointer operand to the instruction builder associated with the buffer.
Definition: fcml_stateful_assembler.hpp:275
StatefulAssembler & operator<<(const IB &ib)
Adds instruction builder to the stateful assembler.
Definition: fcml_stateful_assembler.hpp:94
StatefulAssembler & inst(const fcml_cstring &mnemonic)
Creates an instruction builder for the given mnemonic.
Definition: fcml_stateful_assembler.hpp:136
CodeIterator getCodeIterator()
Gets iterator which allows to iterate through the whole machine code byte by byte.
Definition: fcml_stateful_assembler.hpp:414
void setThrowExceptionOnError(bool throwExceptionOnError)
Sets exception on error flag.
Definition: fcml_parser.hpp:133
Describes an instruction.
Definition: fcml_common.hpp:6207
Wraps instruction prefix and prepares factory methods for the hints.
Definition: fcml_common.hpp:287
const ParserConfig & getParserConfig() const
Gets configuration used by parser if parsing is supported.
Definition: fcml_stateful_assembler.hpp:469
Assembler configuration.
Definition: fcml_assembler.hpp:311
Parser context.
Definition: fcml_parser.hpp:149
Definition: fcml_symbols.hpp:142
StatefulAssembler & op(const Integer &imm)
Adds the new immediate operand to the instruction builder associated with the buffer.
Definition: fcml_stateful_assembler.hpp:251
Dialect & getDialect() const
Gets dialect associated with the assembler.
Definition: fcml_assembler.hpp:821
const SymbolTable * getSymbolTable() const
Gets symbol table used together with the parser.
Definition: fcml_stateful_assembler.hpp:486
Used only to indicate the need of the flush operation.
Definition: fcml_stateful_assembler.hpp:52
Iterates over machine code bytes from assembled instructions.
Definition: fcml_assembler.hpp:838
It&#39;s a stateful assembler which can be used to assemble instructions one by one on the fly...
Definition: fcml_stateful_assembler.hpp:48
C++ wrapper for instruction parser.
StatefulAssembler & add(const IB &ib)
Adds instruction builder to the stateful assembler.
Definition: fcml_stateful_assembler.hpp:109