17 for(map<string, char *>::const_iterator
18 i(objectFiles.begin()), end(objectFiles.end());
25 void Loader::Load(const std::string &filePath) {
26 std::ifstream file(filePath.c_str());
27 file.seekg(0, std::ios::end);
28 int fileLength(file.tellg());
29 int length(fileLength + 15);
31 char *block = new char[length];
32 ObjectFileHeader *header =
33 reinterpret_cast<ObjectFileHeader *>(block);
35 unsigned long padding =
36 reinterpret_cast<unsigned long>(block) % 16;
38 header = reinterpret_cast<ObjectFileHeader *>(
39 block + (16 - padding));
42 file.seekg(0, std::ios::beg);
43 file.read(reinterpret_cast<char *>(header), fileLength);
46 header->IntegrityCheck(fileLength);
48 LoadExports(header->ident,
49 header->ExportsBegin(),
50 header->ExportsEnd());
51 LoadExternals(header->ident,
52 header->ExternalsBegin(),
53 header->ExternalsEnd());
54 LoadObjects(header->ident,
55 header->ObjectsBegin(),
56 header->ObjectsEnd());
57 LoadArrays(header->ident,
58 header->ArraysBegin(),
64 objectFiles.insert(make_pair(filePath, block));
67 void Loader::LoadExports(char *src, Export *begin, Export *end) {
68 for (Export *i = begin; i < end; ++i) {
69 string identifier(src + i->nameOffset);
70 LoadedExport &exp(exports[identifier]);
71 exp.typeId = i->typeId;
72 exp.location = src + i->dataOffset;
73 exports.insert(make_pair(identifier, exp));
77 void Loader::LoadExternals(char *src, External *begin, External *end) {
78 for (External *i = begin; i < end; ++i) {
79 string identifier(src + i->nameOffset);
80 map<string, LoadedExport>::const_iterator
81 exp(exports.find(identifier));
82 if (exp == exports.end()) {
83 throw std::runtime_error("undefined reference to "
86 const TypeDescription &td(TypeDescription::Get(exp->second.typeId));
87 char *dest = src + i->referenceOffset;
89 std::memcpy(dest, exp->second.location, td.Size());
91 std::memcpy(dest, &exp->second.location, sizeof(char *));
96 void Loader::LoadObjects(char *src, Object *begin, Object *end) {
97 for (Object *i = begin; i < end; i = i->Next()) {
98 const TypeDescription &td =
99 TypeDescription::Get(i->typeId);
100 if (td.NeedsLinking()) {
101 LoadObject(src, i->RawObject(), td);
106 void Loader::LoadObject(char *src, char *object, const TypeDescription &td) {
107 for (TypeDescription::FieldIterator
108 i(td.FieldsBegin()), end(td.FieldsEnd());
110 const FieldDescription &field = i->second;
111 if (!field.IsReferenced() && !field.IsAggregate()) {
114 char **dest(reinterpret_cast<char **>(object + field.Offset()));
116 *dest = src + *reinterpret_cast<unsigned int *>(dest);
121 void Loader::LoadArrays(char *src, Array *begin, Array *end) {
122 for (Array *i = begin; i < end; i = i->Next()) {
124 for (char *j = i->Data(), *end = i->Data() + i->size;
125 j < end; j += sizeof(void *)) {
126 *reinterpret_cast<char **>(j) =
127 src + *reinterpret_cast<unsigned int *>(j);
130 const TypeDescription &td = TypeDescription::Get(i->typeId);
131 for (char *j = i->Data(), *end = i->Data() + i->size;
132 j < end; j += td.Size()) {
133 LoadObject(src, j, td);