fcml  1.2.2
fcml_lag_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_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."),
88  }
89  return _assembledInstructions[index];
90  }
91 
98  const std::vector<AssembledInstruction>& getAssembledInstructions() const {
99  return _assembledInstructions;
100  }
101 
110  return CodeIterator(_assembledInstructions);
111  }
112 
118  void clear() {
119  _errorContainer.clean();
120  _assembledInstructions.clear();
121  }
122 
123 protected:
124 
126  friend class MultiPassAssembler;
127 
134  std::vector<AssembledInstruction>& getAssembledInstructions() {
135  return _assembledInstructions;
136  }
137 
144  void setErrorContainer(const ErrorContainer &errorContainer) {
145  _errorContainer = errorContainer;
146  }
147 
148 private:
149 
151  ErrorContainer _errorContainer;
153  std::vector<AssembledInstruction> _assembledInstructions;
154 
155 };
156 
161 
162 public:
163 
169  _symbolTable( NULL) {
170  }
171 
179  fcml_ip ip = 0) :
180  _entryPoint(operatingMode, ip), _symbolTable( NULL) {
181  }
182 
183 public:
184 
191  const AssemblerConf& getConfig() const {
192  return _config;
193  }
194 
202  return _config;
203  }
204 
211  void setConfig(const AssemblerConf &config) {
212  _config = config;
213  }
214 
221  const EntryPoint& getEntryPoint() const {
222  return _entryPoint;
223  }
224 
232  return _entryPoint;
233  }
234 
241  void setEntryPoint(const EntryPoint &entryPoint) {
242  _entryPoint = entryPoint;
243  }
244 
251  void setIP(fcml_ip ip) {
252  _entryPoint.setIP(ip);
253  }
254 
262  void incrementIP(fcml_ip ip) {
263  _entryPoint.incrementIP(ip);
264  }
265 
273  _entryPoint.setOpMode(operatingMode);
274  }
275 
282  void setAddressSizeAttribute(fcml_usize addressSizeAttribute) {
283  _entryPoint.setAddressSizeAttribute(addressSizeAttribute);
284  }
285 
292  void setOperandSizeAttribute(fcml_usize operandSizeAttribute) {
293  _entryPoint.setOperandSizeAttribute(operandSizeAttribute);
294  }
295 
302  const SymbolTable* getSymbolTable() const {
303  return _symbolTable;
304  }
305 
313  return _symbolTable;
314  }
315 
322  void setSymbolTable(SymbolTable *symbolTable) {
323  _symbolTable = symbolTable;
324  }
325 
326 private:
328  EntryPoint _entryPoint;
330  AssemblerConf _config;
332  SymbolTable *_symbolTable;
333 };
334 
341  protected DialectAware,
342  protected SymbolTableAware {
343 public:
344 
352  _dialect(dialect) {
353  fcml_ceh_error error = ::fcml_fn_assembler_init(extractDialect(dialect),
354  &_assembler);
355  if (error) {
356  throw InitException(FCML_TEXT("Cannot initialize the assembler."),
357  error);
358  }
359  }
360 
366  if (_assembler) {
367  ::fcml_fn_assembler_free(_assembler);
368  _assembler = NULL;
369  }
370  }
371 
372 public:
373 
386  const fcml_string *instructions, MultiPassAssemblerResult &result) {
387 
388  /* Prepare assembler context. */
389  fcml_st_lag_assembler_context context = { 0 };
390 
391  AssemblerTypeConverter::convert(ctx.getConfig(), context.configuration);
392  TypeConverter::convert(ctx.getEntryPoint(), context.entry_point);
393 
394  SymbolTable *symbolTable = ctx.getSymbolTable();
395  context.symbol_table =
396  symbolTable ? extractSymbolTable(*symbolTable) : NULL;
397  context.assembler = _assembler;
398 
399  /* Prepare assembler result. */
402 
404 
405  try {
406 
407  result.clear();
408 
409  error = ::fcml_fn_lag_assemble(&context, instructions, &res);
410 
411  /* Failed or not, convert assembler errors. */
412 
413  ErrorContainer errorContainer;
414  ErrorTypeConverter::convert(res.errors, errorContainer);
415 
416  /* Prepares assembler result. */
417 
418  result.setErrorContainer(errorContainer);
419 
420  if (error && ctx.getConfig().isThrowExceptionOnError()) {
423  errorContainer.prepareErrorMessage(
424  FCML_TEXT("Assembling failed")), errorContainer,
425  error);
426  }
427 
428  if (!error) {
429 
430  std::vector<AssembledInstruction> &assembledInstructions =
431  result.getAssembledInstructions();
432 
433  assembledInstructions.clear();
434 
435  ErrorContainer instructionWarnings;
436  fcml_st_assembled_instruction *next_instruction =
437  res.instructions;
438  while (next_instruction) {
439  fcml_st_ceh_error_container &instruction_warnings =
440  next_instruction->warnings;
441  ErrorTypeConverter::convert(instruction_warnings,
442  instructionWarnings);
443  const AssembledInstruction assembledInstruction(
444  next_instruction->code,
445  next_instruction->code_length, instructionWarnings);
446  assembledInstructions.push_back(assembledInstruction);
447  next_instruction = next_instruction->next;
448  }
449 
450  // Convert it back to the context because it might have been
451  // modified during assembling process (IP incrementation etc).
452  TypeConverter::convert(context.entry_point,
453  ctx.getEntryPoint());
454 
455  }
456 
458 
459  } catch (std::exception &exc) {
460  // If anything failed, free assembler results.
462  throw exc;
463  }
464 
465  return error;
466  }
467 
468 private:
469 
470  // The dialect used by the assembler.
471  Dialect &_dialect;
472  // The initialized assembler instance used by the wrapper.
473  fcml_st_assembler *_assembler;
474 
475 };
476 
477 }
478 
479 #endif /* FCML_LAG_ASSEMBLER_HPP_ */
const AssemblerConf & getConfig() const
Gets constant reference to assembler configuration.
Definition: fcml_lag_assembler.hpp:191
C++ wrapper for FCML assembler.
void setEntryPoint(const EntryPoint &entryPoint)
Sets a new entry point.
Definition: fcml_lag_assembler.hpp:241
CodeIterator getCodeIterator()
Gets iterator which allows to iterate through the whole machine code byte by byte.
Definition: fcml_lag_assembler.hpp:109
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:282
const std::vector< AssembledInstruction > & getAssembledInstructions() const
Gets constant vector of all assembled instructions.
Definition: fcml_lag_assembler.hpp:98
void setIP(fcml_ip ip)
Sets a new instruction pointer.
Definition: fcml_lag_assembler.hpp:251
std::vector< AssembledInstruction > & getAssembledInstructions()
Gets vector of all assembled instructions.
Definition: fcml_lag_assembler.hpp:134
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:144
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:231
Container for all collected errors and warnings.
Definition: fcml_errors.h:180
An assembler wrapper, as you can see the assembler context is managed internally and is not exposed o...
Definition: fcml_lag_assembler.hpp:340
#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:221
struct fcml_st_assembled_instruction * next
Next assembled instruction in the chain.
Definition: fcml_assembler.h:87
Holds instruction pointer, processor operating mode and memory segment flags.
Definition: fcml_common.hpp:524
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:351
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:89
Definition: fcml_assembler.hpp:39
void setConfig(const AssemblerConf &config)
Sets a new assembler configuration.
Definition: fcml_lag_assembler.hpp:211
MultiPassAssemblerContext(EntryPoint::OperatingMode operatingMode, fcml_ip ip=0)
Creates assembler context for given operating mode and instruction pointer.
Definition: fcml_lag_assembler.hpp:178
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:98
virtual ~MultiPassAssemblerResult()
Virtual destructor.
Definition: fcml_lag_assembler.hpp:52
Used mainly in case of integers and offsets.
Definition: fcml_errors.h:55
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:302
fcml_ceh_error assemble(MultiPassAssemblerContext &ctx, const fcml_string *instructions, MultiPassAssemblerResult &result)
Assembles given instruction model.
Definition: fcml_lag_assembler.hpp:385
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:251
MultiPassAssemblerResult()
Default constructor.
Definition: fcml_lag_assembler.hpp:45
fcml_int64_t fcml_ip
General instruction pointer holder.
Definition: fcml_common.h:96
Describes an assembled instruction.
Definition: fcml_assembler.hpp:57
void incrementIP(fcml_ip ip)
Increments the instruction pointer by given number of bytes.
Definition: fcml_lag_assembler.hpp:262
void setOperandSizeAttribute(fcml_usize operandSizeAttribute)
Sets a new operand size attribute for the entry point.
Definition: fcml_lag_assembler.hpp:292
OperatingMode
Supported operating modes.
Definition: fcml_common.hpp:531
void setOperatingMode(EntryPoint::OperatingMode operatingMode)
Sets a new processor operating mode for the entry point.
Definition: fcml_lag_assembler.hpp:272
AssemblerConf & getConfig()
Gets reference to the assembler configuration.
Definition: fcml_lag_assembler.hpp:201
void clear()
Clears the result.
Definition: fcml_lag_assembler.hpp:118
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:312
bool isThrowExceptionOnError() const
Returns true if exception should be thrown when assembling fails.
Definition: fcml_assembler.hpp:476
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:91
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:321
Bad arguments.
Definition: fcml_common.hpp:242
LIB_EXPORT void LIB_CALL fcml_fn_assembler_free(fcml_st_assembler *assembler)
Frees assembler instance.
Encoded instruction.
Definition: fcml_assembler.h:85
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:322
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:143
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:231
virtual ~MultiPassAssembler()
Virtual destructor.
Definition: fcml_lag_assembler.hpp:365
fcml_uint16_t fcml_ceh_error
All error codes should be held in variables of this type.
Definition: fcml_errors.h:156
fcml_usize code_length
Instruction code length in bytes.
Definition: fcml_assembler.h:93
MultiPassAssemblerContext()
Default constructor.
Definition: fcml_lag_assembler.hpp:168
Assembler context.
Definition: fcml_lag_assembler.hpp:160
Iterates over machine code bytes from assembled instructions.
Definition: fcml_assembler.hpp:872
Object which shouldn&#39;t be copied can inherit from this class.
Definition: fcml_common.hpp:288
const ErrorContainer & getErrorContainer() const
Gets error container.
Definition: fcml_lag_assembler.hpp:63