ScEpTIC.emulator.memory package

Submodules

ScEpTIC.emulator.memory.memory_access_trace module

class ScEpTIC.emulator.memory.memory_access_trace.MemoryAccessTrace(clock, pc, address, value, dimension, op_type, metadata)

Bases: object

Class representing an operation performed over a memory cell

ScEpTIC.emulator.memory.utils module

ScEpTIC.emulator.memory.utils.calc_crc(data, n_bits)

Computes the CRC of the data :param data: data to convert :param n_bits: number of bits for CRC (supported CRC16, CRC32, and CRC64) :return: CRC in integer representation

ScEpTIC.emulator.memory.utils.check_data(data, bits)

Checks if data converted to binary corresponds to the given bits :returns: is_match, data_value, bits_value Note: data_value and bits_value are None if is_match is True

ScEpTIC.emulator.memory.utils.crc16(data, poly=4129, init=0)

Computes CRC-16-CCITT (XModem) checksum

ScEpTIC.emulator.memory.utils.crc64(data, poly=27, init=18446744073709551615)

Computes CRC-64-ISO without a lookup table (bitwise).

ScEpTIC.emulator.memory.utils.crc8(data, poly=7, init=0)

Compute the CRC-8-ATM checksum.

ScEpTIC.emulator.memory.utils.from_binary(data, conv_type)

Converts data from binary to conv_type :param data: data to convert :param conv_type: target type of the conversion :return: converted data

ScEpTIC.emulator.memory.utils.str_to_time(t)

Converts a given time to seconds. Supported textual representations:

  • u -> microseconds

  • m -> milliseconds

  • s -> seconds

  • M -> minutes

  • H -> hours

Example: 10M is converted to 600 seconds. :param t: time in seconds or in textual representation

ScEpTIC.emulator.memory.utils.to_binary(data, n_bits)

Converts data to its binary notation, using n_bits :param data: data to convert :param n_bits: number of bits to use in the representation :return: binary data

ScEpTIC.emulator.memory.virtual_global_symbol_table module

class ScEpTIC.emulator.memory.virtual_global_symbol_table.VirtualGlobalSymbolTable(base_address, address_prefix, mmu=None)

Bases: VirtualStack

This class extends the stack and contains only symbols (i.e., global variables). Note that global variables resides on fixed positions on top of the stack. This class represents an abstraction that simplifies the analysis of intermittence anomalies w.r.t. global variables.

allocate(name, composition, initial_values, dimension_in_bits=True, alignment=None)

Allocates the required space for a given symbol name. The space is allocated accordingly to the given composition, which is a list of lists. Each element of the list is a sublist containing the number of elements and their dimension. It returns the address of the first allocated cell of the symbol.

deallocate(address)

Deallocation not supported for this memory type.

diff(dump)

Returns the difference between the current state of the register file and the one saved inside a dump.

dump()

Returns a dump of the GST.

get_symbol_from_address(address)
get_used_size()
Returns:

the used size in bytes

get_visual_dump(head_string)

Returns a string representing the memory

has_symbol(name)

Returns if a given symbol is in the VirtualGlobalSymbolTable

read_from_symbol_name(name, dimension, dimension_in_bits=True)

Returns the value of a symbol, given its name and dimension. The request is “forwared” to the stack’s read function, after having calculated the needed address.

read_string_from_address(address)

Reads a string from a memory address

reset()

Performs the CPU reset operation

restore(dump)

Restores a dump of the heap.

set_state_as_base_state()

Sets the current state as the base state, which is the one restored when reset() is called.

sync_mmu()
write_from_symbol_name(name, dimension, content, dimension_in_bits=True)

Writes the given value to the specified symbol, given its name and dimension. The request is “forwared” to the stack’s write function, after having calculated the needed address.

ScEpTIC.emulator.memory.virtual_global_symbol_table_unifier module

class ScEpTIC.emulator.memory.virtual_global_symbol_table_unifier.VirtualGlobalSymbolTableUnifier(memory, default_ram, other_ram_section)

Bases: object

Interface used to interact transparently with one or two Global Symbol Tables. It directly interfaces with the memory, in order to get the require gst. It does not retain memory information, just interfaces with it.

The default_ram states which RAM will be used to store variables when section is not specified or is not other_ram_section, which is used to identify variables to be stored in the RAM complementary to default_ram.

allocate(name, section, composition, initial_values, dimension_in_bits=True, alignment=None)

Allocates the symbol accordingly to the given section. If section is None, it allocates it to the default gst.

deallocate(address)

Deallocation not possible in gst.

property default_gst

Returns the gst of the default ram.

get_address_symbol(address)

Returns the symbol name from a given address.

get_cell_input_lookup(address)

Returns the input lookup information of cell in a given address.

get_cells_from_address(address, dimension, dimension_in_bits=True, resolve_address=True)

Performs the call to the correct get_cells_from_address method

get_symbol_address(name)

Returns the absolute address of a given symbol.

get_visual_dump()

Returns a string representing the memory

has_symbol(name)

Returns if a symbol is in any gst.

property other_gst

Returns the gst of the complementary ram.

read(address, dimension, dimension_in_bits=True, ignore_mmu=False)

Reads a symbol cell’s content from the GST.

read_from_symbol_name(name, dimension, dimension_in_bits=True)

Calls read method of the gst in which the symbol is.

set_cell_input_lookup(address, input_lookup)

Sets the input lookup information of cell in a given address.

set_cells_from_address(address, cells, resolve_address=True)

Performs the call to the correct set_cells_from_address method

set_state_as_base_state()

Sets the current state as the base state, which is the one restored when reset() is called.

simulate_mmu_read_on_cells(cells)
sync_mmu()
write(address, dimension, content, dimension_in_bits=True, ignore_mmu=False)

Writes into a symbol cell.

write_from_symbol_name(name, dimension, content, dimension_in_bits=True)

Calls write method of the gst in which the symbol is.

ScEpTIC.emulator.memory.virtual_heap module

class ScEpTIC.emulator.memory.virtual_heap.VirtualHeap(base_address, address_prefix, mmu=None)

Bases: VirtualMemory

Implementation of the heap.

allocate(dimension, dimension_in_bits=True, append_prefix=True, alignment=None)

Allocates a cell with a given dimension and returns its address. It checks for available garbage space, and if it is found the cell will be allocated there.

deallocate(address, resolve_address=True)

Marks as garbage the group of cells containing address. It also merges adjacent garbage cells and if the cell is at the end of the heap, simply removes it.

diff(dump)

Returns the difference between the current state of the register file and the one saved inside a dump.

dump()

Returns a dump of the heap.

get_used_size()
Returns:

the used size in bytes

reallocate(address, dimension, dimension_in_bits=True, resolve_address=True, alignment=None)

It reallocates a group of cells to fit a given dimension. The address of the first element of the group is returned. (It can change or not)

reset()

Performs the CPU reset operation

restore(dump)

Restores a dump of the heap.

ScEpTIC.emulator.memory.virtual_memory module

class ScEpTIC.emulator.memory.virtual_memory.VirtualMemory(base_address, address_prefix, mmu=None)

Bases: object

Basic representation of the memory. It contains cells inside the dictionary _memory (the keys are the initial addresses of each cell)

convert_dimension(dimension, dimension_in_bits)

Converts a dimension from bits to bytes, if dimension_in_bits is True.

diff(dump)

Returns the difference between the current state of the register file and the one saved inside a dump.

dump()

Returns a dump of the virtual memory.

get_address_from_real_address(address)
get_address_prefix()
get_cell_input_lookup(address, resolve_address=True)

Returns the input lookup information of cell in a given address.

get_cells_from_address(address, dimension, dimension_in_bits=True, resolve_address=True)

Returns the cells starting from a given address, s.t. the overall dimension is the given one.

get_real_address(address)

Returns the actual address (in integer) by removing the address prefix char.

get_used_size()
Returns:

the used size in bytes

get_visual_dump()

Returns a string representing the memory

property mem_type

Returns the class of the memory. VirtualMemory is extended by other memory representations.

read(address, dimension, dimension_in_bits=True, resolve_address=True, ignore_mmu=False)

Returns the content of a cell, given its address and dimension. If dimension is different from the one of the cell, it returns an invalid value (None)

reset()

Performs the CPU reset operation

restore(dump)

Restores a dump of the virtual memory.

set_cell_input_lookup(address, input_lookup_data, resolve_address=True)

Sets the input lookup information of cell in a given address.

set_cells_from_address(address, cells, resolve_address=True)

Copies the content from a given list of cells starting from the given address.

simulate_mmu_read_on_cells(cells)
write(address, dimension, content, dimension_in_bits=True, resolve_address=True, ignore_mmu=False)

Writes the given content into a cell, given its address. If dimension is different from the one of the cell, it gets rebased.

ScEpTIC.emulator.memory.virtual_memory_cell module

class ScEpTIC.emulator.memory.virtual_memory_cell.VirtualMemoryCell(address, address_prefix, dimension, content=None, garbage=False, alignment=None)

Bases: object

Class that represents a single memory cell. Cells do not have a fixed dimension, but each cell refers to a single element (e.g. variable)

property absolute_address

Returns the absolute address of the cell

collect_memory_trace(op_type)
free()

Frees the cell like it is done with C function “free”

get_bit_size()
get_content()
get_input_lookup()

Returns the input lookup information of the cell.

remap(dimension)

Remaps the dimension of the cell and invalidates the cell content.

set_content(content)
set_input_lookup(input_lookup_data)

Sets the input lookup information of the cell.

set_lookup(old_content, current_pc, current_clock, memory_mapped=False)

Sets lookup informations for memory anomaly checks.

set_memory_mapped(current_pc, current_clock, old_memory_address, old_dimension)

Sets lookup informations for memory anomaly checks.

ScEpTIC.emulator.memory.virtual_ram module

class ScEpTIC.emulator.memory.virtual_ram.NonVolatileRAM(config)

Bases: VirtualRAM

Non-volatile Memory.

force_reset()

Forces reset of NVM

reset()

NVM is persistent w.r.t. CPU reset

class ScEpTIC.emulator.memory.virtual_ram.VirtualRAM(config)

Bases: object

RAM base object. It may contain stack, heap and global symbol table.

check_memory_size()

Checks memory size

property ram_type

Returns the name of the RAM.

reset()

Performs the CPU reset operation

class ScEpTIC.emulator.memory.virtual_ram.VolatileRAM(config)

Bases: VirtualRAM

Static RAM.

ScEpTIC.emulator.memory.virtual_stack module

class ScEpTIC.emulator.memory.virtual_stack.VirtualStack(base_address, address_prefix, mmu=None)

Bases: VirtualMemory

Extension of VirtualMemory which represents the stack of the simulated program. In this implementation the stack grows from lower to higher addresses.

Write and read functions are necessary due to the memory allocation method given by LLVM-IR. It does not handle the stack: firstly it allocates some space, then it writes to it.

PUSH and POP operations are to support function calls.

allocate(dimension, dimension_in_bits=True, metadata=None, alignment=None)

Allocates elements on top of the stack.

deallocate(address, resolve_address=True, ignore_exception=False)

Decrements the ESP (-> deallocation all the cells until a given address). It doesn’t really remove data.

pop(dimension, dimension_in_bits=True)

Pops the value on the top of the stack

push(dimension, content, metadata=None, dimension_in_bits=True)

Push a given value on top of the stack

Module contents

class ScEpTIC.emulator.memory.Memory(config)

Bases: object

This class represents the memory and is in charge of interfacing with it. It initializes both Volatile and Non-Volatile Memory, accordingly to a given configuration. Stack and Heap must be present and can reside only into one Memory at a time, in any combination. Global Symbol Table must be present and can reside in Volatile Memory, Non-Volatile Memory, or both.

All the memory spaces between stack, heap and global symbol tables are separated.

Memory has not a maximum dimension, since this simulator is not focused on memory representation. In order to get a correct memory representation, I should also put all the things in the stack (saved PC, canaries) and I would be bounded to the compiler back-end conversions and architecture-dependent optimizations.

Not having a memory size, makes difficult to have a continuous memory space such that at a certain address the Volatile Memory ends and starts the NVM, but makes possible to test the program for a generic architecture and then verify if it fits the arch. memory requirements. This is why the Volatile Memory and NVM have overlapping addresses (but will be accessed correctly accordingly to the configuration).

Having variables in both Volatile Memory and NVM will require a sort of “lookup table”, or the data layout should be performed. In this implementation, the lookup table for the variables contains also them and extends the stack with some functionalities. In this way:

  • There is a better separation between global variables and local stack

  • With the VirtualGlobalSymbolTableUnifier is easy to access a variable “transparently” (independently if it resides in NVM or Volatile Memory)

  • There is no need to differentiate addresses between Volatile Memory and NVM.

  • Is possible to compare directly a portion (stack, heap, vars) of the NVM and Volatile memory with a previous dump

Stack and heap are kept as separated objects (and not directly mapped to the same “memory”) because I do not have to deal with overflows that causes the stack or heap to be damaged.

add_offset(address, offset, offset_in_bits=True)

Add an offset to an absolute address

check_memory_size()

Checks memory size

static convert_dimension(dimension, dimension_in_bits)

Converts a dimension from bits to bytes, if dimension_in_bits is True.

static extract_prefix_from_address(address)

Extracts the prefix of an absolute address.

force_nvm_reset()

Resets the NVM.

get_cell_input_lookup(address)

Returns the input lookup information of cell in a given address.

get_cells_from_address(address, dimension, dimension_in_bits=True, resolve_address=True)

Performs the call to the correct get_cells_from_address method

property heap

Returns transparently the heap Heap must be in volatile or nvm. If volatile memory not initialized or heap not in volatile memory, it must be in nvm, otherwise the memory has not been initialized and an exception have been raised on init.

read(address, dimension, dimension_in_bits=True)

Performs the call to the correct read method.

reset()

Performs the CPU reset operation

set_cell_input_lookup(address, input_lookup)

Sets the input lookup information of cell in a given address.

set_cells_from_address(address, cells, resolve_address=True)

Performs the call to the correct set_cells_from_address method

simulate_mmu_read_on_cells(cells)
property stack

Returns transparently the stack Stack must be in volatile or non-volatile memory. If volatile memory not initialized or stack not in volatile memory, it must be in nvm, otherwise the memory has not been initialized and an exception have been raised on init.

write(address, dimension, content, dimension_in_bits=True)

Performs the call to the correct write method.