fcml  1.1.3
fcml_lag_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_LAG_ASSEMBLER_HPP_
28 #define FCML_LAG_ASSEMBLER_HPP_
29 
30 #include "fcml_assembler.hpp"
31 #include "fcml_symbols.hpp"
32 
33 #include "fcml_lag_assembler.h"
34 
35 namespace fcml {
36 
39 public:
40 
46  }
47 
53  }
54 
55 public:
56 
64  return _errorContainer;
65  }
66 
72  fcml_usize getSize() const {
73  return static_cast<fcml_usize>(_assembledInstructions.size());
74  }
75 
84  const AssembledInstruction& operator[] ( fcml_usize index ) const {
85  if( index > _assembledInstructions.size() ) {
86  throw BadArgumentException(FCML_TEXT("Array index out of bound."), FCML_CEH_GEC_VALUE_OUT_OF_RANGE);
87  }
88  return _assembledInstructions[index];
89  }
90 
97  const std::vector<AssembledInstruction>& getAssembledInstructions() const {
98  return _assembledInstructions;
99  }
100 
108  return CodeIterator( _assembledInstructions );
109  }
110 
115  void clear() {
116  _errorContainer.clean();
117  _assembledInstructions.clear();
118  }
119 
120 protected:
121 
123  friend class MultiPassAssembler;
124 
131  std::vector<AssembledInstruction>& getAssembledInstructions() {
132  return _assembledInstructions;
133  }
134 
141  void setErrorContainer(const ErrorContainer& errorContainer) {
142  _errorContainer = errorContainer;
143  }
144 
145 private:
146 
148  ErrorContainer _errorContainer;
150  std::vector<AssembledInstruction> _assembledInstructions;
151 
152 };
153 
158 
159 public:
160 
166  _symbolTable( NULL ) {
167  }
168 
176  _entryPoint( operatingMode, ip ),
177  _symbolTable( NULL ) {
178  }
179 
180 public:
181 
188  const AssemblerConf& getConfig() const {
189  return _config;
190  }
191 
199  return _config;
200  }
201 
208  void setConfig(const AssemblerConf& config) {
209  _config = config;
210  }
211 
218  const EntryPoint& getEntryPoint() const {
219  return _entryPoint;
220  }
221 
229  return _entryPoint;
230  }
231 
238  void setEntryPoint(const EntryPoint& entryPoint) {
239  _entryPoint = entryPoint;
240  }
241 
248  void setIP( fcml_ip ip ) {
249  _entryPoint.setIP(ip);
250  }
251 
258  void incrementIP( fcml_ip ip ) {
259  _entryPoint.incrementIP( ip );
260  }
261 
269  _entryPoint.setOpMode( operatingMode );
270  }
271 
278  void setAddressSizeAttribute( fcml_usize addressSizeAttribute ) {
279  _entryPoint.setAddressSizeAttribute( addressSizeAttribute );
280  }
281 
288  void setOperandSizeAttribute( fcml_usize operandSizeAttribute ) {
289  _entryPoint.setOperandSizeAttribute( operandSizeAttribute );
290  }
291 
298  const SymbolTable* getSymbolTable() const {
299  return _symbolTable;
300  }
301 
309  return _symbolTable;
310  }
311 
318  void setSymbolTable( SymbolTable* symbolTable ) {
319  _symbolTable = symbolTable;
320  }
321 
322 private:
324  EntryPoint _entryPoint;
326  AssemblerConf _config;
328  SymbolTable *_symbolTable;
329 };
330 
335 class MultiPassAssembler: public NonCopyable, protected DialectAware, protected SymbolTableAware {
336 public:
337 
345  _dialect(dialect) {
346  fcml_ceh_error error = ::fcml_fn_assembler_init( extractDialect( dialect ), &_assembler);
347  if (error) {
348  throw InitException(FCML_TEXT("Cannot initialize the assembler."), error);
349  }
350  }
351 
357  if (_assembler) {
358  ::fcml_fn_assembler_free(_assembler);
359  _assembler = NULL;
360  }
361  }
362 
363 public:
364 
375  fcml_ceh_error assemble( MultiPassAssemblerContext &ctx, const fcml_string *instructions, MultiPassAssemblerResult &result ) {
376 
377  /* Prepare assembler context. */
378  fcml_st_lag_assembler_context context = {0};
379 
380  AssemblerTypeConverter::convert( ctx.getConfig(), context.configuration );
381  TypeConverter::convert( ctx.getEntryPoint(), context.entry_point );
382 
383  SymbolTable *symbolTable = ctx.getSymbolTable();
384  context.symbol_table = symbolTable ? extractSymbolTable( *symbolTable ) : NULL;
385  context.assembler = _assembler;
386 
387  /* Prepare assembler result. */
390 
392 
393  try {
394 
395  result.clear();
396 
397  error = ::fcml_fn_lag_assemble( &context, instructions, &res );
398 
399  /* Failed or not, convert assembler errors. */
400 
401  ErrorContainer errorContainer;
402  ErrorTypeConverter::convert( res.errors, errorContainer );
403 
404  /* Prepares assembler result. */
405 
406  result.setErrorContainer( errorContainer );
407 
408  if( error && ctx.getConfig().isThrowExceptionOnError() ) {
410  throw AssemblingFailedException( errorContainer.prepareErrorMessage( FCML_TEXT("Assembling failed") ), errorContainer, error );
411  }
412 
413  if( !error ) {
414 
415  std::vector<AssembledInstruction> &assembledInstructions = result.getAssembledInstructions();
416 
417  assembledInstructions.clear();
418 
419  ErrorContainer instructionWarnings;
420  fcml_st_assembled_instruction *next_instruction = res.instructions;
421  while( next_instruction ) {
422  fcml_st_ceh_error_container &instruction_warnings = next_instruction->warnings;
423  ErrorTypeConverter::convert( instruction_warnings, instructionWarnings );
424  const AssembledInstruction assembledInstruction( next_instruction->code, next_instruction->code_length, instructionWarnings );
425  assembledInstructions.push_back( assembledInstruction );
426  next_instruction = next_instruction->next;
427  }
428 
429  // Convert it back to the context because it might have been
430  // modified during assembling process (IP incrementation etc).
431  TypeConverter::convert( context.entry_point, ctx.getEntryPoint() );
432 
433  }
434 
436 
437  } catch( std::exception &exc ) {
438  // If anything failed, free assembler results.
440  throw exc;
441  }
442 
443  return error;
444  }
445 
446 private:
447 
448  // The dialect used by the assembler.
449  Dialect &_dialect;
450  // The initialized assembler instance used by the wrapper.
451  fcml_st_assembler *_assembler;
452 
453 };
454 
455 }
456 
457 #endif /* FCML_LAG_ASSEMBLER_HPP_ */
const AssemblerConf & getConfig() const
Gets constant reference to assembler configuration.
Definition: fcml_lag_assembler.hpp:188
C++ wrapper for FCML assembler.
void setEntryPoint(const EntryPoint &entryPoint)
Sets a new entry point.
Definition: fcml_lag_assembler.hpp:238
CodeIterator getCodeIterator()
Gets iterator which allows to iterate through the whole machine code byte by byte.
Definition: fcml_lag_assembler.hpp:107
fcml_usize getSize() const
Gets number of assembled instructions.
Definition: fcml_lag_assembler.hpp:72
void setAddressSizeAttribute(fcml_usize addressSizeAttribute)
Sets a new address size attribute for the entry point.
Definition: fcml_lag_assembler.hpp:278
const std::vector< AssembledInstruction > & getAssembledInstructions() const
Gets constant vector of all assembled instructions.
Definition: fcml_lag_assembler.hpp:97
void setIP(fcml_ip ip)
Sets a new instruction pointer.
Definition: fcml_lag_assembler.hpp:248
std::vector< AssembledInstruction > & getAssembledInstructions()
Gets vector of all assembled instructions.
Definition: fcml_lag_assembler.hpp:131
LIB_EXPORT void LIB_CALL fcml_fn_lag_assembler_result_prepare(fcml_st_lag_assembler_result *result)
Prepares reusable result holder for assembler.
void setErrorContainer(const ErrorContainer &errorContainer)
Sets new error container for the result.
Definition: fcml_lag_assembler.hpp:141
Assembling failed.
Definition: fcml_assembler.hpp:45
fcml_st_assembler_conf configuration
Assembler behavior can be configured here.
Definition: fcml_lag_assembler.h:51
fcml_st_ceh_error_container errors
Error and warning messages from one-line assembler.
Definition: fcml_lag_assembler.h:39
EntryPoint & getEntryPoint()
Gets reference to the entry point.
Definition: fcml_lag_assembler.hpp:228
Container for all collected errors and warnings.
Definition: fcml_errors.h:162
An assembler wrapper, as you can see the assembler context is managed internally and is not exposed o...
Definition: fcml_lag_assembler.hpp:335
#define FCML_TEXT(x)
Used to code literal strings.
Definition: fcml_types.h:61
const EntryPoint & getEntryPoint() const
Gets constant reference to the entry point.
Definition: fcml_lag_assembler.hpp:218
struct fcml_st_assembled_instruction * next
Next assembled instruction in the chain.
Definition: fcml_assembler.h:77
Holds instruction pointer, processor operating mode and memory segment flags.
Definition: fcml_common.hpp:499
Assembler result which contains all assembled instructions.
Definition: fcml_lag_assembler.hpp:38
MultiPassAssembler(Dialect &dialect)
Creates multi-pass assembler for a dialect.
Definition: fcml_lag_assembler.hpp:344
Load-and-go assembler runtime context.
Definition: fcml_lag_assembler.h:47
fcml_st_ceh_error_container warnings
Warning messages related to assembled instruction.
Definition: fcml_assembler.h:79
Definition: fcml_assembler.hpp:39
void setConfig(const AssemblerConf &config)
Sets a new assembler configuration.
Definition: fcml_lag_assembler.hpp:208
MultiPassAssemblerContext(EntryPoint::OperatingMode operatingMode, fcml_ip ip=0)
Creates assembler context for given operating mode and instruction pointer.
Definition: fcml_lag_assembler.hpp:175
fcml_st_assembled_instruction * instructions
Chain of assembled instructions.
Definition: fcml_lag_assembler.h:43
fcml_cstring prepareErrorMessage(const fcml_cstring &message) const
Prepares an error message basing on the first error in the container.
Definition: fcml_errors.hpp:283
Inherit from this class in order to get access to the native FCML dialect structure.
Definition: fcml_dialect.hpp:97
virtual ~MultiPassAssemblerResult()
Virtual destructor.
Definition: fcml_lag_assembler.hpp:52
Used mainly in case of integers and offsets.
Definition: fcml_errors.h:54
LIB_EXPORT void LIB_CALL fcml_fn_lag_assembler_result_free(fcml_st_lag_assembler_result *result)
Cleans result holder.
const SymbolTable * getSymbolTable() const
Gets a pointer to the constant symbol table stored in the context.
Definition: fcml_lag_assembler.hpp:298
fcml_ceh_error assemble(MultiPassAssemblerContext &ctx, const fcml_string *instructions, MultiPassAssemblerResult &result)
Assembles given instruction model.
Definition: fcml_lag_assembler.hpp:375
fcml_st_entry_point entry_point
Instruction entry point configuration.
Definition: fcml_lag_assembler.h:53
LIB_EXPORT fcml_ceh_error LIB_CALL fcml_fn_lag_assemble(fcml_st_lag_assembler_context *context, const fcml_string *source_code, fcml_st_lag_assembler_result *result)
Multipass load-and-go assembler.
fcml_st_symbol_table symbol_table
Symbols table.
Definition: fcml_lag_assembler.h:55
Derive from this class if you really need access to the native symbol table.
Definition: fcml_symbols.hpp:245
MultiPassAssemblerResult()
Default constructor.
Definition: fcml_lag_assembler.hpp:45
fcml_int64_t fcml_ip
General instruction pointer holder.
Definition: fcml_common.h:95
Describes an assembled instruction.
Definition: fcml_assembler.hpp:55
void incrementIP(fcml_ip ip)
Increments the instruction pointer by given number of bytes.
Definition: fcml_lag_assembler.hpp:258
void setOperandSizeAttribute(fcml_usize operandSizeAttribute)
Sets a new operand size attribute for the entry point.
Definition: fcml_lag_assembler.hpp:288
OperatingMode
Supported operating modes.
Definition: fcml_common.hpp:506
void setOperatingMode(EntryPoint::OperatingMode operatingMode)
Sets a new processor operating mode for the entry point.
Definition: fcml_lag_assembler.hpp:268
AssemblerConf & getConfig()
Gets reference to the assembler configuration.
Definition: fcml_lag_assembler.hpp:198
void clear()
Clears the result.
Definition: fcml_lag_assembler.hpp:115
Result holder for load-and-go assembler.
Definition: fcml_lag_assembler.h:37
Wraps multiple errors into one component.
Definition: fcml_errors.hpp:148
Experimental multiline load-and-go assembler implementation.
SymbolTable * getSymbolTable()
Gets a pointer to the symbol table stored in the context.
Definition: fcml_lag_assembler.hpp:308
bool isThrowExceptionOnError() const
Returns true if exception should be thrown when assembling fails.
Definition: fcml_assembler.hpp:465
const AssembledInstruction & operator[](fcml_usize index) const
Gets one assembled instruction by its index.
Definition: fcml_lag_assembler.hpp:84
fcml_uint8_t * code
Instruction machine code.
Definition: fcml_assembler.h:81
Operation succeed.
Definition: fcml_errors.h:42
void clean()
Cleans all errors and warnings.
Definition: fcml_errors.hpp:296
Assembler configuration.
Definition: fcml_assembler.hpp:311
Bad arguments.
Definition: fcml_common.hpp:217
LIB_EXPORT void LIB_CALL fcml_fn_assembler_free(fcml_st_assembler *assembler)
Frees assembler instance.
Encoded instruction.
Definition: fcml_assembler.h:75
An abstract dialect.
Definition: fcml_dialect.hpp:41
void setSymbolTable(SymbolTable *symbolTable)
Sets a new symbol table for the context.
Definition: fcml_lag_assembler.hpp:318
LIB_EXPORT fcml_ceh_error LIB_CALL fcml_fn_assembler_init(const fcml_st_dialect *dialect, fcml_st_assembler **assembler)
Initializes assembler for given dialect.
Definition: fcml_symbols.hpp:142
C++ API for symbols handling.
fcml_st_assembler * assembler
Assembler instance that should be used to assemble instructions.
Definition: fcml_lag_assembler.h:49
struct fcml_st_assembler fcml_st_assembler
Abstract assembler representation.
Definition: fcml_assembler.h:43
Component can not be initialized correctly.
Definition: fcml_common.hpp:206
virtual ~MultiPassAssembler()
Virtual destructor.
Definition: fcml_lag_assembler.hpp:356
fcml_uint16_t fcml_ceh_error
All error codes should be held in variables of this type.
Definition: fcml_errors.h:139
fcml_usize code_length
Instruction code length in bytes.
Definition: fcml_assembler.h:83
MultiPassAssemblerContext()
Default constructor.
Definition: fcml_lag_assembler.hpp:165
Assembler context.
Definition: fcml_lag_assembler.hpp:157
Iterates over machine code bytes from assembled instructions.
Definition: fcml_assembler.hpp:838
Object which shouldn&#39;t be copied can inherit from this class.
Definition: fcml_common.hpp:263
const ErrorContainer & getErrorContainer() const
Gets error container.
Definition: fcml_lag_assembler.hpp:63