90 using namespace std::chrono;
91 using namespace r_code;
95 Reference::Reference() {
98 Reference::Reference(
const uint16 i,
const Class &c,
const Class &cc) : index_(i), class_(c), cast_class_(cc) {
103 Metadata::Metadata() {
106 Class *Metadata::get_class(std::string &class_name) {
108 unordered_map<std::string, Class>::iterator it = classes_.find(class_name);
109 if (it != classes_.end())
114 Class *Metadata::get_class(uint16 opcode) {
116 return &classes_by_opcodes_[opcode];
119 void Metadata::write(word32 *data) {
121 data[0] = classes_by_opcodes_.size();
124 for (i = 0; i < classes_by_opcodes_.size(); ++i) {
126 classes_by_opcodes_[i].write(data + offset);
127 offset += classes_by_opcodes_[i].get_size();
130 data[offset++] = classes_.size();
131 unordered_map<std::string, Class>::iterator it = classes_.begin();
132 for (; it != classes_.end(); ++it) {
134 r_code::Write(data + offset, it->first);
135 offset += r_code::GetSize(it->first);
136 data[offset] = it->second.atom_.asOpcode();
140 data[offset++] = sys_classes_.size();
141 it = sys_classes_.begin();
142 for (; it != sys_classes_.end(); ++it) {
144 r_code::Write(data + offset, it->first);
145 offset += r_code::GetSize(it->first);
146 data[offset] = it->second.atom_.asOpcode();
150 data[offset++] = class_names_.size();
151 for (i = 0; i < class_names_.size(); ++i) {
153 r_code::Write(data + offset, class_names_[i]);
154 offset += r_code::GetSize(class_names_[i]);
157 data[offset++] = operator_names_.size();
158 for (i = 0; i < operator_names_.size(); ++i) {
160 r_code::Write(data + offset, operator_names_[i]);
161 offset += r_code::GetSize(operator_names_[i]);
164 data[offset++] = function_names_.size();
165 for (i = 0; i < function_names_.size(); ++i) {
167 r_code::Write(data + offset, function_names_[i]);
168 offset += r_code::GetSize(function_names_[i]);
172 void Metadata::read(word32 *data, uint32 size) {
174 uint16 class_count = data[0];
177 for (i = 0; i < class_count; ++i) {
180 c.read(data + offset);
181 classes_by_opcodes_.push_back(c);
182 offset += c.get_size();
185 uint16 classes_count = data[offset++];
186 for (i = 0; i < classes_count; ++i) {
189 r_code::Read(data + offset, s);
190 offset += r_code::GetSize(s);
191 classes_[s] = classes_by_opcodes_[data[offset++]];
194 uint16 sys_classes_count = data[offset++];
195 for (i = 0; i < sys_classes_count; ++i) {
198 r_code::Read(data + offset, s);
199 offset += r_code::GetSize(s);
200 sys_classes_[s] = classes_by_opcodes_[data[offset++]];
203 uint16 class_names_count = data[offset++];
204 for (i = 0; i < class_names_count; ++i) {
207 r_code::Read(data + offset, s);
208 class_names_.push_back(s);
209 offset += r_code::GetSize(s);
212 uint16 operator_names_count = data[offset++];
213 for (i = 0; i < operator_names_count; ++i) {
216 r_code::Read(data + offset, s);
217 operator_names_.push_back(s);
218 offset += r_code::GetSize(s);
221 uint16 function_names_count = data[offset++];
222 for (i = 0; i < function_names_count; ++i) {
225 r_code::Read(data + offset, s);
226 function_names_.push_back(s);
227 offset += r_code::GetSize(s);
231 uint32 Metadata::get_size() {
233 return get_class_array_size() +
235 get_sys_classes_size() +
236 get_class_names_size() +
237 get_operator_names_size() +
238 get_function_names_size();
280 uint32 Metadata::get_class_array_size() {
283 for (uint32 i = 0; i < classes_by_opcodes_.size(); ++i)
284 size += classes_by_opcodes_[i].get_size();
288 uint32 Metadata::get_classes_size() {
291 unordered_map<std::string, Class>::iterator it = classes_.begin();
292 for (; it != classes_.end(); ++it)
293 size += r_code::GetSize(it->first) + 1;
297 uint32 Metadata::get_sys_classes_size() {
300 unordered_map<std::string, Class>::iterator it = sys_classes_.begin();
301 for (; it != sys_classes_.end(); ++it)
302 size += r_code::GetSize(it->first) + 1;
306 uint32 Metadata::get_class_names_size() {
309 for (uint32 i = 0; i < class_names_.size(); ++i)
310 size += r_code::GetSize(class_names_[i]);
314 uint32 Metadata::get_operator_names_size() {
317 for (uint32 i = 0; i < operator_names_.size(); ++i)
318 size += r_code::GetSize(operator_names_[i]);
322 uint32 Metadata::get_function_names_size() {
325 for (uint32 i = 0; i < function_names_.size(); ++i)
326 size += r_code::GetSize(function_names_[i]);
332 void ObjectMap::shift(uint16 offset) {
334 for (uint32 i = 0; i < objects_.size(); ++i)
335 objects_[i] += offset;
338 void ObjectMap::write(word32 *data) {
340 for (uint32 i = 0; i < objects_.size(); ++i)
341 data[i] = objects_[i];
344 void ObjectMap::read(word32 *data, uint32 size) {
346 for (uint16 i = 0; i < size; ++i)
347 objects_.push_back(data[i]);
350 uint32 ObjectMap::get_size()
const {
352 return objects_.size();
357 CodeSegment::~CodeSegment() {
359 for (uint32 i = 0; i < objects_.size(); ++i)
363 void CodeSegment::write(word32 *data) {
366 for (uint32 i = 0; i < objects_.size(); ++i) {
368 objects_[i]->write(data + offset);
369 offset += objects_[i]->get_size();
373 void CodeSegment::read(word32 *data, uint16 object_count) {
376 for (uint16 i = 0; i < object_count; ++i) {
379 o->read(data + offset);
380 objects_.push_back(o);
381 offset += o->get_size();
385 uint32 CodeSegment::get_size() {
388 for (uint32 i = 0; i < objects_.size(); ++i)
389 size += objects_[i]->get_size();
402 ObjectNames::~ObjectNames() {
405 void ObjectNames::write(word32 *data) {
407 data[0] = symbols_.size();
411 unordered_map<uint32, std::string>::const_iterator n;
412 for (n = symbols_.begin(); n != symbols_.end(); ++n) {
414 data[index] = n->first;
415 uint32 symbol_length = n->second.length() + 1;
416 uint32 _symbol_length = symbol_length / 4;
417 uint32 __symbol_length = symbol_length % 4;
420 data[index + 1] = _symbol_length;
421 memcpy(data + index + 2, n->second.c_str(), symbol_length);
422 index += _symbol_length + 2;
426 void ObjectNames::read(word32 *data) {
428 uint32 symbol_count = data[0];
430 for (uint32 i = 0; i < symbol_count; ++i) {
432 uint32 oid = data[index];
433 uint32 symbol_length = data[index + 1];
434 std::string symbol((
char *)(data + index + 2));
435 symbols_[oid] = symbol;
437 index += symbol_length + 2;
441 uint32 ObjectNames::get_size() {
445 unordered_map<uint32, std::string>::const_iterator n;
446 for (n = symbols_.begin(); n != symbols_.end(); ++n) {
449 uint32 symbol_length = n->second.length() + 1;
450 uint32 _symbol_length = symbol_length / 4;
451 uint32 __symbol_length = symbol_length % 4;
454 size += _symbol_length;
460 uint32 ObjectNames::findSymbol(
const std::string& name) {
461 for (
auto entry = symbols_.begin(); entry != symbols_.end(); ++entry) {
462 if (entry->second == name)
466 return UNDEFINED_OID;
471 Image::Image() : map_offset_(0), timestamp_(seconds(0)) {
477 void Image::add_sys_object(
SysObject *
object, std::string name) {
479 add_sys_object(
object);
481 object_names_.symbols_[
object->oid_] = name;
484 void Image::add_sys_object(
SysObject *
object) {
486 code_segment_.objects_.push_back(
object);
487 object_map_.objects_.push_back(map_offset_);
488 map_offset_ +=
object->get_size();
494 for (o = objects.begin(); o != objects.end(); ++o) {
496 if (include_invalidated || !(*o)->is_invalidated())
497 add_object(*o, include_invalidated);
506 for (o = objects.begin(); o != objects.end(); ++o)
507 add_object(*o, imported_objects);
512 inline uint32 Image::get_reference_count(
const Code *
object)
const {
514 switch (object->code(0).getDescriptor()) {
516 return object->references_size() - MDL_HIDDEN_REFS;
517 case Atom::COMPOSITE_STATE:
518 return object->references_size() - CST_HIDDEN_REFS;
520 return object->references_size();
524 void Image::add_object(
Code *
object,
bool include_invalidated) {
526 unordered_map<Code *, uint16>::iterator it = ptrs_to_indices_.find(
object);
527 if (it != ptrs_to_indices_.end())
531 uint16 reference_count = get_reference_count(
object);
532 for (uint16 i = 0; i < reference_count; ++i) {
534 Code *reference =
object->get_reference(i);
535 if (include_invalidated || reference->get_oid() == UNDEFINED_OID ||
536 reference->is_invalidated())
537 add_object(reference, include_invalidated);
541 ptrs_to_indices_[object] = object_index = code_segment_.objects_.size();
543 add_sys_object(sys_object);
548 uint32 _object = (uint32)
object;
549 sys_object->references_[0] = (_object & 0x0000FFFF);
550 sys_object->references_[1] = (_object >> 16);
551 #elif defined ARCH_64
552 uint64 _object = (uint64)
object;
553 sys_object->references_[0] = _object & 0x0000FFFF;
554 sys_object->references_[1] = (_object >> 16) & 0x0000FFFF;
555 sys_object->references_[2] = (_object >> 32) & 0x0000FFFF;
556 sys_object->references_[3] = (_object >> 48) & 0x0000FFFF;
560 SysObject *Image::add_object(
Code *
object, vector<SysObject *> &imported_objects) {
562 unordered_map<Code *, uint16>::iterator it = ptrs_to_indices_.find(
object);
563 if (it != ptrs_to_indices_.end())
564 return code_segment_.objects_[it->second];
567 ptrs_to_indices_[object] = object_index = code_segment_.objects_.size();
569 add_sys_object(sys_object);
571 uint16 reference_count = get_reference_count(
object);
572 for (uint16 i = 0; i < reference_count; ++i) {
574 Code *reference =
object->get_reference(i);
575 if (reference->get_oid() == UNDEFINED_OID)
576 add_object(reference, imported_objects);
579 unordered_map<Code *, uint16>::iterator it = ptrs_to_indices_.find(reference);
580 if (it == ptrs_to_indices_.end()) {
582 SysObject *sys_ref = add_object(reference, imported_objects);
583 imported_objects.push_back(sys_ref);
589 unordered_set<_View *, _View::Hash, _View::Equal>::const_iterator v;
590 for (v = object->views_.begin(); v != object->views_.end(); ++v) {
592 for (uint8 j = 0; j < 2; ++j) {
594 Code *reference = (*v)->references_[j];
597 unordered_map<r_code::Code *, uint16>::const_iterator index = ptrs_to_indices_.find(reference);
598 if (index == ptrs_to_indices_.end()) {
600 SysObject *sys_ref = add_object(reference, imported_objects);
601 imported_objects.push_back(sys_ref);
611 uint32 _object = (uint32)
object;
612 sys_object->references_[0] = (_object & 0x0000FFFF);
613 sys_object->references_[1] = (_object >> 16);
614 #elif defined ARCH_64
615 uint64 _object = (uint64)
object;
616 sys_object->references_[0] = _object & 0x0000FFFF;
617 sys_object->references_[1] = (_object >> 16) & 0x0000FFFF;
618 sys_object->references_[2] = (_object >> 32) & 0x0000FFFF;
619 sys_object->references_[3] = (_object >> 48) & 0x0000FFFF;
625 void Image::build_references() {
629 for (uint32 i = 0; i < code_segment_.objects_.size(); ++i) {
631 sys_object = code_segment_.objects_[i];
634 uint32 _object = sys_object->references_[0];
635 _object |= (sys_object->references_[1] << 16);
636 object = (
Code *)_object;
637 #elif defined ARCH_64
638 uint64 _object = sys_object->references_[0];
639 _object |= ((uint64)(sys_object->references_[1]) << 16);
640 _object |= ((uint64)(sys_object->references_[2]) << 32);
641 _object |= ((uint64)(sys_object->references_[3]) << 48);
642 object = (
Code *)_object;
644 sys_object->references_.clear();
645 build_references(sys_object,
object);
649 void Image::build_references(
SysObject *sys_object,
Code *
object) {
653 uint16 referenced_object_index;
654 uint16 reference_count = get_reference_count(
object);
655 for (i = 0; i < reference_count; ++i) {
657 unordered_map<r_code::Code *, uint16>::const_iterator index = ptrs_to_indices_.find(object->get_reference(i));
658 if (index != ptrs_to_indices_.end()) {
660 referenced_object_index = index->second;
661 sys_object->references_.push_back(referenced_object_index);
666 unordered_set<_View *, _View::Hash, _View::Equal>::const_iterator v;
667 for (i = 0, v = object->views_.begin(); v != object->views_.end(); ++i, ++v) {
669 for (uint8 j = 0; j < 2; ++j) {
671 Code *reference = (*v)->references_[j];
674 unordered_map<r_code::Code *, uint16>::const_iterator index = ptrs_to_indices_.find(reference);
675 if (index != ptrs_to_indices_.end()) {
677 referenced_object_index = index->second;
678 sys_object->views_[i]->references_[j] = referenced_object_index;
688 for (uint16 i = 0; i < code_segment_.objects_.size(); ++i)
689 ram_objects[i] = mem->build_object(code_segment_.objects_[i]);
690 unpack_objects(ram_objects);
696 for (uint16 i = 0; i < code_segment_.objects_.size(); ++i) {
698 SysObject *sys_object = code_segment_.objects_[i];
699 Code *ram_object = ram_objects[i];
701 for (uint16 j = 0; j < sys_object->views_.size(); ++j) {
703 SysView *sys_v = sys_object->views_[j];
704 _View *v = ram_object->build_view(sys_v);
705 for (uint16 k = 0; k < sys_v->references_.size(); ++k)
706 v->references_[k] = ram_objects[sys_v->references_[k]];
708 ram_object->views_.insert(v);
711 for (uint16 j = 0; j < sys_object->references_.size(); ++j)
712 ram_object->set_reference(j, ram_objects[sys_object->references_[j]]);