]> git.localhorst.tv Git - l2e.git/blob - src/loader/ObjectFile.cpp
b6ab2b71c57e3724a93b0a5d987ad6ccf9fc1f32
[l2e.git] / src / loader / ObjectFile.cpp
1 #include "ObjectFile.h"
2
3 #include <stdexcept>
4
5 using std::runtime_error;
6
7
8 namespace loader {
9
10 ObjectFileHeader::ObjectFileHeader()
11 : versionId(FORMAT_ID)
12 , exportsBegin(0)
13 , exportsEnd(0)
14 , externalsBegin(0)
15 , externalsEnd(0)
16 , objectsBegin(0)
17 , objectsEnd(0)
18 , arraysBegin(0)
19 , arraysEnd(0) {
20         ident[0] = 'L';
21         ident[1] = '2';
22         ident[2] = 'E';
23         ident[3] = '\n';
24 }
25
26 void ObjectFileHeader::IntegrityCheck(unsigned int fsize) const {
27         if (ident[0] != 'L'
28                         || ident[1] != '2'
29                         || ident[2] != 'E'
30                         || ident[3] != '\n') {
31                 throw runtime_error("magic bytes mismatch");
32         }
33         if (versionId != FORMAT_ID) {
34                 throw runtime_error("format ID mismatch");
35         }
36         if (!CheckSection(exportsBegin, exportsEnd, fsize)) {
37                 throw runtime_error("exports section out of bounds");
38         }
39         if ((exportsEnd - exportsBegin) % sizeof(Export) != 0) {
40                 throw runtime_error("bogus exports section end");
41         }
42         if (!CheckSection(externalsBegin, externalsEnd, fsize)) {
43                 throw runtime_error("externals section out of bounds");
44         }
45         if ((externalsEnd - externalsBegin) % sizeof(External) != 0) {
46                 throw runtime_error("bogus externals section end");
47         }
48         if (!CheckSection(imagesBegin, imagesEnd, fsize)) {
49                 throw runtime_error("images section out of bounds");
50         }
51         if ((imagesEnd - imagesBegin) % sizeof(Image) != 0) {
52                 throw runtime_error("bogus images section end");
53         }
54         if (!CheckSection(objectsBegin, objectsEnd, fsize)) {
55                 throw runtime_error("objects section out of bounds");
56         }
57         if (!CheckSection(arraysBegin, arraysEnd, fsize)) {
58                 throw runtime_error("arrays section out of bounds");
59         }
60 }
61
62 bool ObjectFileHeader::CheckSection(
63                 unsigned int begin,
64                 unsigned int end,
65                 unsigned int fsize) const {
66         return begin >= sizeof(ObjectFileHeader)
67                         && (begin < fsize || begin == end)
68                         && end >= begin
69                         && end <= fsize;
70 }
71
72 Export *ObjectFileHeader::ExportsBegin() {
73         char *data = reinterpret_cast<char *>(this);
74         return reinterpret_cast<Export *>(data + exportsBegin);
75 }
76
77 Export *ObjectFileHeader::ExportsEnd() {
78         char *data = reinterpret_cast<char *>(this);
79         return reinterpret_cast<Export *>(data + exportsEnd);
80 }
81
82 External *ObjectFileHeader::ExternalsBegin() {
83         char *data = reinterpret_cast<char *>(this);
84         return reinterpret_cast<External *>(data + externalsBegin);
85 }
86
87 External *ObjectFileHeader::ExternalsEnd() {
88         char *data = reinterpret_cast<char *>(this);
89         return reinterpret_cast<External *>(data + externalsEnd);
90 }
91
92 Image *ObjectFileHeader::ImagesBegin() {
93         char *data = reinterpret_cast<char *>(this);
94         return reinterpret_cast<Image *>(data + imagesBegin);
95 }
96
97 Image *ObjectFileHeader::ImagesEnd() {
98         char *data = reinterpret_cast<char *>(this);
99         return reinterpret_cast<Image *>(data + imagesEnd);
100 }
101
102 Object *ObjectFileHeader::ObjectsBegin() {
103         char *data = reinterpret_cast<char *>(this);
104         return reinterpret_cast<Object *>(data + objectsBegin);
105 }
106
107 Object *ObjectFileHeader::ObjectsEnd() {
108         char *data = reinterpret_cast<char *>(this);
109         return reinterpret_cast<Object *>(data + objectsEnd);
110 }
111
112 Array *ObjectFileHeader::ArraysBegin() {
113         char *data = reinterpret_cast<char *>(this);
114         return reinterpret_cast<Array *>(data + arraysBegin);
115 }
116
117 Array *ObjectFileHeader::ArraysEnd() {
118         char *data = reinterpret_cast<char *>(this);
119         return reinterpret_cast<Array *>(data + arraysEnd);
120 }
121
122
123 char *Object::RawObject() {
124         return reinterpret_cast<char *>(this) + sizeof(Object);
125 }
126
127 Object *Object::Next() {
128         return reinterpret_cast<Object *>(RawObject() + size);
129 }
130
131
132 char *Array::Data() {
133         return reinterpret_cast<char *>(this) + sizeof(Array);
134 }
135
136 Array *Array::Next() {
137         return reinterpret_cast<Array *>(Data() + size);
138 }
139
140 }