15 for(map<string, char *>::const_iterator
16 i(objectFiles.begin()), end(objectFiles.end());
23 void Loader::Load(const std::string &filePath) {
24 std::ifstream file(filePath.c_str());
25 file.seekg(0, std::ios::end);
26 int fileLength(file.tellg());
27 int length(fileLength + 15);
29 char *block = new char[length];
30 ObjectFileHeader *header =
31 reinterpret_cast<ObjectFileHeader *>(block);
33 unsigned long padding =
34 reinterpret_cast<unsigned long>(block) % 16;
36 header = reinterpret_cast<ObjectFileHeader *>(
37 block + (16 - padding));
40 file.seekg(0, std::ios::beg);
41 file.read(reinterpret_cast<char *>(header), fileLength);
44 header->IntegrityCheck(fileLength);
46 LoadExports(header->ident,
47 header->ExportsBegin(),
48 header->ExportsEnd());
49 LoadExternals(header->ident,
50 header->ExternalsBegin(),
51 header->ExternalsEnd());
52 LoadObjects(header->ident,
53 header->ObjectsBegin(),
54 header->ObjectsEnd());
59 objectFiles.insert(make_pair(filePath, block));
62 void Loader::LoadExports(char *src, Export *begin, Export *end) {
63 for (Export *i = begin; i < end; ++i) {
64 string identifier(src + i->nameOffset);
65 LoadedExport &exp(exports[identifier]);
66 exp.typeId = i->typeId;
67 exp.location = src + i->dataOffset;
71 void Loader::LoadExternals(char *src, External *begin, External *end) {
72 for (External *i = begin; i < end; ++i) {
73 string identifier(src + i->nameOffset);
74 map<string, LoadedExport>::const_iterator
75 exp(exports.find(identifier));
76 if (exp == exports.end()) {
77 throw std::runtime_error("undefined reference to "
80 const TypeDescription &td(TypeDescription::Get(exp->second.typeId));
81 char *dest = src + i->referenceOffset;
83 std::memcpy(dest, exp->second.location, td.Size());
85 std::memcpy(dest, &exp->second.location, sizeof(char *));
90 void Loader::LoadObjects(char *src, Object *begin, Object *end) {
91 for (Object *i = begin; i < end; i = i->Next()) {
92 const TypeDescription &td =
93 TypeDescription::Get(i->typeId);
94 if (td.NeedsLinking()) {
95 LoadObject(src, i->RawObject(), td);
100 void Loader::LoadObject(char *src, char *object, const TypeDescription &td) {
101 for (TypeDescription::FieldIterator
102 i(td.FieldsBegin()), end(td.FieldsEnd());
104 const FieldDescription &field = i->second;
105 if (!field.IsReferenced() && !field.IsAggregate()) {
108 char **dest(reinterpret_cast<char **>(object + field.Offset()));
110 *dest = src + *reinterpret_cast<unsigned int *>(dest);