Implemented StorageManager support in the ELF:: namespace.
[aesalon.git] / monitor / src / StorageManager.cpp
blobf079fadf4f8df0400a0f26399583a974d1a96261
1 #include <sys/mman.h>
3 #include "StorageManager.h"
4 #include "asm/Operand.h"
5 #include "asm/Instruction.h"
6 #include "asm/InstructionList.h"
8 StorageManager::StorageManager() : data(NULL), data_size(0), unused_data_offset(0) {
9 /* Start off with a megabyte of memory . . . */
10 data_size = 1048576;
11 data = static_cast<Byte *>(mmap(NULL, data_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
14 StorageManager::~StorageManager() {
15 for(type_map_t::iterator i = type_map.begin(); i != type_map.end(); i ++) {
16 if(i->second == OPERAND_DATA) get_operand(i->first)->~Operand();
17 else if(i->second == INSTRUCTION_DATA) get_instruction(i->first)->~Instruction();
18 else if(i->second == INSTRUCTION_LIST_DATA) get_instruction_list(i->first)->~InstructionList();
20 munmap(data, data_size);
23 void StorageManager::alloc_more() {
24 /* Allocate another megabyte . . . */
25 data = static_cast<Byte *>(mremap(data, data_size, data_size += 1048576, MREMAP_MAYMOVE));
28 ASM::Operand *StorageManager::new_operand(std::string operand_string) {
29 while(unsigned(data_size - unused_data_offset) < sizeof(ASM::Operand)) alloc_more();
30 ASM::Operand *operand = new(data + unused_data_offset) ASM::Operand(unused_data_offset, operand_string);
31 unused_data_offset += sizeof(ASM::Operand);
32 return operand;
35 ASM::Operand *StorageManager::new_operand(ASM::Operand::operand_type_e type, Word address, ASM::Register reg, SWord offset) {
36 while(unsigned(data_size - unused_data_offset) < sizeof(ASM::Operand)) alloc_more();
37 ASM::Operand *operand = new(data + unused_data_offset) ASM::Operand(unused_data_offset, type, address, reg, offset);
38 unused_data_offset += sizeof(ASM::Operand);
39 type_map[operand->get_storage_offset()] = OPERAND_DATA;
40 return operand;
43 ASM::Instruction *StorageManager::new_instruction(std::string instruction, Word address) {
44 while(unsigned(data_size - unused_data_offset) < sizeof(ASM::Instruction)) alloc_more();
45 ASM::Instruction *ins = new(data + unused_data_offset) ASM::Instruction(unused_data_offset, instruction, address);
46 unused_data_offset += sizeof(ASM::Instruction);
47 type_map[ins->get_storage_offset()] = INSTRUCTION_DATA;
48 return ins;
51 ASM::InstructionList *StorageManager::new_instruction_list(Word offset) {
52 while(unsigned(data_size - unused_data_offset) < sizeof(ASM::InstructionList)) alloc_more();
53 ASM::InstructionList *il = new(data + unused_data_offset) ASM::InstructionList(unused_data_offset, offset);
54 unused_data_offset += sizeof(ASM::InstructionList);
55 type_map[il->get_storage_offset()] = INSTRUCTION_LIST_DATA;
56 return il;
59 ELF::Symbol *StorageManager::new_symbol(std::string symbol_name, Word address, Word size) {
60 while(unsigned(data_size - unused_data_offset) < sizeof(ELF::Symbol)) alloc_more();
61 ELF::Symbol *symbol = new(data + unused_data_offset) ELF::Symbol(unused_data_offset, symbol_name, address, size);
62 unused_data_offset += sizeof(ELF::Symbol);
63 type_map[symbol->get_storage_offset()] = SYMBOL_DATA;
64 return symbol;
67 ASM::Operand *StorageManager::get_operand(StorageOffset storage_offset) const {
68 if(type_map.at(storage_offset) != OPERAND_DATA) return 0;
69 return reinterpret_cast<ASM::Operand *>(data + storage_offset);
72 ASM::Instruction *StorageManager::get_instruction(StorageOffset storage_offset) const {
73 if(type_map.at(storage_offset) != INSTRUCTION_DATA) return 0;
74 return reinterpret_cast<ASM::Instruction *>(data + storage_offset);
77 ASM::InstructionList *StorageManager::get_instruction_list(StorageOffset storage_offset) const {
78 if(type_map.at(storage_offset) != INSTRUCTION_LIST_DATA) return 0;
79 return reinterpret_cast<ASM::InstructionList *>(data + storage_offset);
82 ELF::Symbol *StorageManager::get_symbol(StorageOffset storage_offset) const {
83 if(type_map.at(storage_offset) != SYMBOL_DATA) return 0;
84 return reinterpret_cast<ELF::Symbol *>(data + storage_offset);