1 | //===- GOFFObjectFileTest.cpp - Tests for GOFFObjectFile ------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "llvm/Object/GOFFObjectFile.h" |
10 | #include "llvm/Support/MemoryBuffer.h" |
11 | #include "llvm/Testing/Support/Error.h" |
12 | #include "gtest/gtest.h" |
13 | |
14 | using namespace llvm; |
15 | using namespace llvm::object; |
16 | using namespace llvm::GOFF; |
17 | |
18 | namespace { |
19 | char GOFFData[GOFF::RecordLength * 3] = {0x00}; |
20 | |
21 | void constructValidGOFF(size_t Size) { |
22 | StringRef ValidSize(GOFFData, Size); |
23 | Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = |
24 | object::ObjectFile::createGOFFObjectFile( |
25 | Object: MemoryBufferRef(ValidSize, "dummyGOFF" )); |
26 | |
27 | ASSERT_THAT_EXPECTED(GOFFObjOrErr, Succeeded()); |
28 | } |
29 | |
30 | void constructInvalidGOFF(size_t Size) { |
31 | // Construct GOFFObject with record of length != multiple of 80. |
32 | StringRef InvalidData(GOFFData, Size); |
33 | Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = |
34 | object::ObjectFile::createGOFFObjectFile( |
35 | Object: MemoryBufferRef(InvalidData, "dummyGOFF" )); |
36 | |
37 | ASSERT_THAT_EXPECTED( |
38 | GOFFObjOrErr, |
39 | FailedWithMessage("object file is not the right size. Must be a multiple " |
40 | "of 80 bytes, but is " + |
41 | std::to_string(Size) + " bytes" )); |
42 | } |
43 | } // namespace |
44 | |
45 | TEST(GOFFObjectFileTest, ConstructGOFFObjectValidSize) { |
46 | GOFFData[0] = (char)0x03; |
47 | GOFFData[1] = (char)0xF0; |
48 | GOFFData[80] = (char)0x03; |
49 | GOFFData[81] = (char)0x40; |
50 | constructValidGOFF(Size: 160); |
51 | constructValidGOFF(Size: 0); |
52 | } |
53 | |
54 | TEST(GOFFObjectFileTest, ConstructGOFFObjectInvalidSize) { |
55 | constructInvalidGOFF(Size: 70); |
56 | constructInvalidGOFF(Size: 79); |
57 | constructInvalidGOFF(Size: 81); |
58 | } |
59 | |
60 | TEST(GOFFObjectFileTest, MissingHDR) { |
61 | char GOFFData[GOFF::RecordLength * 2] = {0x00}; |
62 | |
63 | // ESD record. |
64 | GOFFData[0] = (char)0x03; |
65 | |
66 | // END record. |
67 | GOFFData[GOFF::RecordLength] = (char)0x03; |
68 | GOFFData[GOFF::RecordLength + 1] = (char)0x40; |
69 | |
70 | StringRef Data(GOFFData, GOFF::RecordLength * 2); |
71 | |
72 | Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = |
73 | object::ObjectFile::createGOFFObjectFile( |
74 | Object: MemoryBufferRef(Data, "dummyGOFF" )); |
75 | |
76 | ASSERT_THAT_EXPECTED( |
77 | GOFFObjOrErr, |
78 | FailedWithMessage("object file must start with HDR record" )); |
79 | } |
80 | |
81 | TEST(GOFFObjectFileTest, MissingEND) { |
82 | char GOFFData[GOFF::RecordLength * 2] = {0x00}; |
83 | |
84 | // HDR record. |
85 | GOFFData[0] = (char)0x03; |
86 | GOFFData[1] = (char)0xF0; |
87 | |
88 | // ESD record. |
89 | GOFFData[GOFF::RecordLength] = (char)0x03; |
90 | |
91 | StringRef Data(GOFFData, GOFF::RecordLength * 2); |
92 | |
93 | Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = |
94 | object::ObjectFile::createGOFFObjectFile( |
95 | Object: MemoryBufferRef(Data, "dummyGOFF" )); |
96 | |
97 | ASSERT_THAT_EXPECTED( |
98 | GOFFObjOrErr, FailedWithMessage("object file must end with END record" )); |
99 | } |
100 | |
101 | TEST(GOFFObjectFileTest, GetSymbolName) { |
102 | char GOFFData[GOFF::RecordLength * 3] = {0x00}; |
103 | |
104 | // HDR record. |
105 | GOFFData[0] = (char)0x03; |
106 | GOFFData[1] = (char)0xF0; |
107 | |
108 | // ESD record. |
109 | GOFFData[GOFF::RecordLength] = (char)0x03; |
110 | GOFFData[GOFF::RecordLength + 3] = (char)0x02; |
111 | GOFFData[GOFF::RecordLength + 7] = (char)0x01; |
112 | GOFFData[GOFF::RecordLength + 11] = (char)0x01; |
113 | GOFFData[GOFF::RecordLength + 71] = (char)0x05; // Size of symbol name. |
114 | GOFFData[GOFF::RecordLength + 72] = (char)0xC8; // Symbol name is Hello. |
115 | GOFFData[GOFF::RecordLength + 73] = (char)0x85; |
116 | GOFFData[GOFF::RecordLength + 74] = (char)0x93; |
117 | GOFFData[GOFF::RecordLength + 75] = (char)0x93; |
118 | GOFFData[GOFF::RecordLength + 76] = (char)0x96; |
119 | |
120 | // END record. |
121 | GOFFData[GOFF::RecordLength * 2] = 0x03; |
122 | GOFFData[GOFF::RecordLength * 2 + 1] = 0x40; |
123 | |
124 | StringRef Data(GOFFData, GOFF::RecordLength * 3); |
125 | |
126 | Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = |
127 | object::ObjectFile::createGOFFObjectFile( |
128 | Object: MemoryBufferRef(Data, "dummyGOFF" )); |
129 | |
130 | ASSERT_THAT_EXPECTED(GOFFObjOrErr, Succeeded()); |
131 | |
132 | GOFFObjectFile *GOFFObj = dyn_cast<GOFFObjectFile>(Val: (*GOFFObjOrErr).get()); |
133 | |
134 | for (SymbolRef Symbol : GOFFObj->symbols()) { |
135 | Expected<StringRef> SymbolNameOrErr = GOFFObj->getSymbolName(Symbol); |
136 | ASSERT_THAT_EXPECTED(SymbolNameOrErr, Succeeded()); |
137 | StringRef SymbolName = SymbolNameOrErr.get(); |
138 | |
139 | EXPECT_EQ(SymbolName, "Hello" ); |
140 | } |
141 | } |
142 | |
143 | TEST(GOFFObjectFileTest, ConcatenatedGOFFFile) { |
144 | char GOFFData[GOFF::RecordLength * 6] = {0x00}; |
145 | |
146 | // HDR record. |
147 | GOFFData[0] = (char)0x03; |
148 | GOFFData[1] = (char)0xF0; |
149 | // ESD record. |
150 | GOFFData[GOFF::RecordLength] = (char)0x03; |
151 | // END record. |
152 | GOFFData[GOFF::RecordLength * 2] = (char)0x03; |
153 | GOFFData[GOFF::RecordLength * 2 + 1] = (char)0x40; |
154 | // HDR record. |
155 | GOFFData[GOFF::RecordLength * 3] = (char)0x03; |
156 | GOFFData[GOFF::RecordLength * 3 + 1] = (char)0xF0; |
157 | // ESD record. |
158 | GOFFData[GOFF::RecordLength * 4] = (char)0x03; |
159 | // END record. |
160 | GOFFData[GOFF::RecordLength * 5] = (char)0x03; |
161 | GOFFData[GOFF::RecordLength * 5 + 1] = (char)0x40; |
162 | |
163 | StringRef Data(GOFFData, GOFF::RecordLength * 6); |
164 | |
165 | Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = |
166 | object::ObjectFile::createGOFFObjectFile( |
167 | Object: MemoryBufferRef(Data, "dummyGOFF" )); |
168 | |
169 | ASSERT_THAT_EXPECTED(GOFFObjOrErr, Succeeded()); |
170 | } |
171 | |
172 | TEST(GOFFObjectFileTest, ContinuationGetSymbolName) { |
173 | char GOFFContData[GOFF::RecordLength * 4] = {0x00}; |
174 | |
175 | // HDR record. |
176 | GOFFContData[0] = (char)0x03; |
177 | GOFFContData[1] = (char)0xF0; |
178 | |
179 | // ESD record. |
180 | GOFFContData[GOFF::RecordLength] = (char)0x03; |
181 | GOFFContData[GOFF::RecordLength + 1] = (char)0x01; |
182 | GOFFContData[GOFF::RecordLength + 3] = (char)0x02; |
183 | GOFFContData[GOFF::RecordLength + 7] = (char)0x01; |
184 | GOFFContData[GOFF::RecordLength + 11] = (char)0x01; |
185 | GOFFContData[GOFF::RecordLength + 71] = (char)0x0A; // Size of symbol name. |
186 | GOFFContData[GOFF::RecordLength + 72] = (char)0xC8; // Symbol name is HelloWorld. |
187 | GOFFContData[GOFF::RecordLength + 73] = (char)0x85; |
188 | GOFFContData[GOFF::RecordLength + 74] = (char)0x93; |
189 | GOFFContData[GOFF::RecordLength + 75] = (char)0x93; |
190 | GOFFContData[GOFF::RecordLength + 76] = (char)0x96; |
191 | GOFFContData[GOFF::RecordLength + 77] = (char)0xA6; |
192 | GOFFContData[GOFF::RecordLength + 78] = (char)0x96; |
193 | GOFFContData[GOFF::RecordLength + 79] = (char)0x99; |
194 | |
195 | // ESD continuation record. |
196 | GOFFContData[GOFF::RecordLength * 2] = (char)0x03; |
197 | GOFFContData[GOFF::RecordLength * 2 + 1] = (char)0x02; // No further continuations. |
198 | GOFFContData[GOFF::RecordLength * 2 + 3] = (char)0x93; |
199 | GOFFContData[GOFF::RecordLength * 2 + 4] = (char)0x84; |
200 | |
201 | // END record. |
202 | GOFFContData[GOFF::RecordLength * 3] = (char)0x03; |
203 | GOFFContData[GOFF::RecordLength * 3 + 1] = (char)0x40; |
204 | |
205 | StringRef Data(GOFFContData, GOFF::RecordLength * 4); |
206 | |
207 | Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = |
208 | object::ObjectFile::createGOFFObjectFile( |
209 | Object: MemoryBufferRef(Data, "dummyGOFF" )); |
210 | |
211 | ASSERT_THAT_EXPECTED(GOFFObjOrErr, Succeeded()); |
212 | |
213 | GOFFObjectFile *GOFFObj = dyn_cast<GOFFObjectFile>(Val: (*GOFFObjOrErr).get()); |
214 | |
215 | for (SymbolRef Symbol : GOFFObj->symbols()) { |
216 | Expected<StringRef> SymbolNameOrErr = GOFFObj->getSymbolName(Symbol); |
217 | ASSERT_THAT_EXPECTED(SymbolNameOrErr, Succeeded()); |
218 | StringRef SymbolName = SymbolNameOrErr.get(); |
219 | EXPECT_EQ(SymbolName, "Helloworld" ); |
220 | } |
221 | } |
222 | |
223 | TEST(GOFFObjectFileTest, ContinuationBitNotSet) { |
224 | char GOFFContData[GOFF::RecordLength * 4] = {0x00}; |
225 | |
226 | // HDR record. |
227 | GOFFContData[0] = (char)0x03; |
228 | GOFFContData[1] = (char)0xF0; |
229 | |
230 | // ESD record. |
231 | GOFFContData[GOFF::RecordLength] = (char)0x03; |
232 | GOFFContData[GOFF::RecordLength + 1] = (char)0x01; |
233 | GOFFContData[GOFF::RecordLength + 3] = (char)0x02; |
234 | GOFFContData[GOFF::RecordLength + 7] = (char)0x01; |
235 | GOFFContData[GOFF::RecordLength + 11] = (char)0x01; |
236 | GOFFContData[GOFF::RecordLength + 71] = (char)0x0A; // Size of symbol name. |
237 | GOFFContData[GOFF::RecordLength + 72] = (char)0xC8; // Symbol name is HelloWorld. |
238 | GOFFContData[GOFF::RecordLength + 73] = (char)0x85; |
239 | GOFFContData[GOFF::RecordLength + 74] = (char)0x93; |
240 | GOFFContData[GOFF::RecordLength + 75] = (char)0x93; |
241 | GOFFContData[GOFF::RecordLength + 76] = (char)0x96; |
242 | GOFFContData[GOFF::RecordLength + 77] = (char)0xA6; |
243 | GOFFContData[GOFF::RecordLength + 78] = (char)0x96; |
244 | GOFFContData[GOFF::RecordLength + 79] = (char)0x99; |
245 | |
246 | // ESD continuation record. |
247 | GOFFContData[GOFF::RecordLength * 2] = (char)0x03; |
248 | GOFFContData[GOFF::RecordLength * 2 + 1] = (char)0x00; |
249 | GOFFContData[GOFF::RecordLength * 2 + 3] = (char)0x93; |
250 | GOFFContData[GOFF::RecordLength * 2 + 4] = (char)0x84; |
251 | |
252 | // END record. |
253 | GOFFContData[GOFF::RecordLength * 3] = (char)0x03; |
254 | GOFFContData[GOFF::RecordLength * 3 + 1] = (char)0x40; |
255 | |
256 | StringRef Data(GOFFContData, GOFF::RecordLength * 4); |
257 | |
258 | Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = |
259 | object::ObjectFile::createGOFFObjectFile( |
260 | Object: MemoryBufferRef(Data, "dummyGOFF" )); |
261 | EXPECT_THAT_EXPECTED( |
262 | GOFFObjOrErr, |
263 | FailedWithMessage("record 2 is not a continuation record but the " |
264 | "preceding record is continued" )); |
265 | } |
266 | |
267 | TEST(GOFFObjectFileTest, ContinuationRecordNotTerminated) { |
268 | char GOFFContData[GOFF::RecordLength * 4] = {0x00}; |
269 | |
270 | // HDR record. |
271 | GOFFContData[0] = (char)0x03; |
272 | GOFFContData[1] = (char)0xF0; |
273 | |
274 | // ESD record. |
275 | GOFFContData[GOFF::RecordLength] = (char)0x03; |
276 | GOFFContData[GOFF::RecordLength + 1] = (char)0x01; |
277 | GOFFContData[GOFF::RecordLength + 3] = (char)0x02; |
278 | GOFFContData[GOFF::RecordLength + 7] = (char)0x01; |
279 | GOFFContData[GOFF::RecordLength + 11] = (char)0x01; |
280 | GOFFContData[GOFF::RecordLength + 71] = (char)0x0A; // Size of symbol name. |
281 | GOFFContData[GOFF::RecordLength + 72] = (char)0xC8; // Symbol name is HelloWorld. |
282 | GOFFContData[GOFF::RecordLength + 73] = (char)0x85; |
283 | GOFFContData[GOFF::RecordLength + 74] = (char)0x93; |
284 | GOFFContData[GOFF::RecordLength + 75] = (char)0x93; |
285 | GOFFContData[GOFF::RecordLength + 76] = (char)0x96; |
286 | GOFFContData[GOFF::RecordLength + 77] = (char)0xA6; |
287 | GOFFContData[GOFF::RecordLength + 78] = (char)0x96; |
288 | GOFFContData[GOFF::RecordLength + 79] = (char)0x99; |
289 | |
290 | // ESD continuation record. |
291 | GOFFContData[GOFF::RecordLength * 2] = (char)0x03; |
292 | GOFFContData[GOFF::RecordLength * 2 + 1] = (char)0x03; // Continued bit set. |
293 | GOFFContData[GOFF::RecordLength * 2 + 3] = (char)0x93; |
294 | GOFFContData[GOFF::RecordLength * 2 + 4] = (char)0x84; |
295 | |
296 | // END record. |
297 | GOFFContData[GOFF::RecordLength * 3] = (char)0x03; |
298 | GOFFContData[GOFF::RecordLength * 3 + 1] = (char)0x40; |
299 | |
300 | StringRef Data(GOFFContData, GOFF::RecordLength * 4); |
301 | |
302 | Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = |
303 | object::ObjectFile::createGOFFObjectFile( |
304 | Object: MemoryBufferRef(Data, "dummyGOFF" )); |
305 | ASSERT_THAT_EXPECTED(GOFFObjOrErr, Succeeded()); |
306 | |
307 | GOFFObjectFile *GOFFObj = dyn_cast<GOFFObjectFile>(Val: (*GOFFObjOrErr).get()); |
308 | |
309 | for (SymbolRef Symbol : GOFFObj->symbols()) { |
310 | Expected<StringRef> SymbolNameOrErr = GOFFObj->getSymbolName(Symbol); |
311 | EXPECT_THAT_EXPECTED(SymbolNameOrErr, |
312 | FailedWithMessage("continued bit should not be set" )); |
313 | } |
314 | } |
315 | |
316 | TEST(GOFFObjectFileTest, PrevNotContinued) { |
317 | char GOFFContData[GOFF::RecordLength * 4] = {0x00}; |
318 | |
319 | // HDR record. |
320 | GOFFContData[0] = (char)0x03; |
321 | GOFFContData[1] = (char)0xF0; |
322 | |
323 | // ESD record, with continued bit not set. |
324 | GOFFContData[GOFF::RecordLength] = (char)0x03; |
325 | |
326 | // ESD continuation record. |
327 | GOFFContData[GOFF::RecordLength * 2] = (char)0x03; |
328 | GOFFContData[GOFF::RecordLength * 2 + 1] = (char)0x02; |
329 | |
330 | // END record. |
331 | GOFFContData[GOFF::RecordLength * 3] = (char)0x03; |
332 | GOFFContData[GOFF::RecordLength * 3 + 1] = (char)0x40; |
333 | |
334 | StringRef Data(GOFFContData, GOFF::RecordLength * 4); |
335 | |
336 | Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = |
337 | object::ObjectFile::createGOFFObjectFile( |
338 | Object: MemoryBufferRef(Data, "dummyGOFF" )); |
339 | |
340 | ASSERT_THAT_EXPECTED( |
341 | GOFFObjOrErr, |
342 | FailedWithMessage("record 2 is a continuation record that is not " |
343 | "preceded by a continued record" )); |
344 | } |
345 | |
346 | TEST(GOFFObjectFileTest, ContinuationTypeMismatch) { |
347 | char GOFFContData[GOFF::RecordLength * 4] = {0x00}; |
348 | |
349 | // HDR record. |
350 | GOFFContData[0] = (char)0x03; |
351 | GOFFContData[1] = (char)0xF0; |
352 | |
353 | // ESD record. |
354 | GOFFContData[GOFF::RecordLength] = (char)0x03; |
355 | GOFFContData[GOFF::RecordLength + 1] = (char)0x01; // Continued to next record. |
356 | |
357 | // END continuation record. |
358 | GOFFContData[GOFF::RecordLength * 2] = (char)0x03; |
359 | GOFFContData[GOFF::RecordLength * 2 + 1] = (char)0x42; |
360 | |
361 | // END record. |
362 | GOFFContData[GOFF::RecordLength * 3] = (char)0x03; |
363 | GOFFContData[GOFF::RecordLength * 3 + 1] = (char)0x40; |
364 | |
365 | StringRef Data(GOFFContData, GOFF::RecordLength * 4); |
366 | |
367 | Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = |
368 | object::ObjectFile::createGOFFObjectFile( |
369 | Object: MemoryBufferRef(Data, "dummyGOFF" )); |
370 | |
371 | ASSERT_THAT_EXPECTED( |
372 | GOFFObjOrErr, |
373 | FailedWithMessage("record 2 is a continuation record that does not match " |
374 | "the type of the previous record" )); |
375 | } |
376 | |
377 | TEST(GOFFObjectFileTest, TwoSymbols) { |
378 | char GOFFData[GOFF::RecordLength * 4] = {0x00}; |
379 | |
380 | // HDR record. |
381 | GOFFData[0] = (char)0x03; |
382 | GOFFData[1] = (char)0xF0; |
383 | |
384 | // ESD record 1. |
385 | GOFFData[GOFF::RecordLength] = (char)0x03; |
386 | GOFFData[GOFF::RecordLength + 3] = (char)0x00; |
387 | GOFFData[GOFF::RecordLength + 7] = (char)0x01; // ESDID. |
388 | GOFFData[GOFF::RecordLength + 71] = (char)0x01; // Size of symbol name. |
389 | GOFFData[GOFF::RecordLength + 72] = (char)0xa7; // Symbol name is x. |
390 | |
391 | // ESD record 2. |
392 | GOFFData[GOFF::RecordLength * 2] = (char)0x03; |
393 | GOFFData[GOFF::RecordLength * 2 + 3] = (char)0x03; |
394 | GOFFData[GOFF::RecordLength * 2 + 7] = (char)0x02; // ESDID. |
395 | GOFFData[GOFF::RecordLength * 2 + 11] = (char)0x01; // Parent ESDID. |
396 | GOFFData[GOFF::RecordLength * 2 + 71] = (char)0x05; // Size of symbol name. |
397 | GOFFData[GOFF::RecordLength * 2 + 72] = (char)0xC8; // Symbol name is Hello. |
398 | GOFFData[GOFF::RecordLength * 2 + 73] = (char)0x85; |
399 | GOFFData[GOFF::RecordLength * 2 + 74] = (char)0x93; |
400 | GOFFData[GOFF::RecordLength * 2 + 75] = (char)0x93; |
401 | GOFFData[GOFF::RecordLength * 2 + 76] = (char)0x96; |
402 | |
403 | // END record. |
404 | GOFFData[GOFF::RecordLength * 3] = (char)0x03; |
405 | GOFFData[GOFF::RecordLength * 3 + 1] = (char)0x40; |
406 | |
407 | StringRef Data(GOFFData, GOFF::RecordLength * 4); |
408 | |
409 | Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = |
410 | object::ObjectFile::createGOFFObjectFile( |
411 | Object: MemoryBufferRef(Data, "dummyGOFF" )); |
412 | |
413 | ASSERT_THAT_EXPECTED(GOFFObjOrErr, Succeeded()); |
414 | |
415 | GOFFObjectFile *GOFFObj = dyn_cast<GOFFObjectFile>(Val: (*GOFFObjOrErr).get()); |
416 | |
417 | for (SymbolRef Symbol : GOFFObj->symbols()) { |
418 | Expected<StringRef> SymbolNameOrErr = GOFFObj->getSymbolName(Symbol); |
419 | ASSERT_THAT_EXPECTED(SymbolNameOrErr, Succeeded()); |
420 | StringRef SymbolName = SymbolNameOrErr.get(); |
421 | EXPECT_EQ(SymbolName, "Hello" ); |
422 | } |
423 | } |
424 | |
425 | TEST(GOFFObjectFileTest, InvalidSymbolType) { |
426 | char GOFFData[GOFF::RecordLength * 3] = {0x00}; |
427 | |
428 | // HDR record. |
429 | GOFFData[0] = (char)0x03; |
430 | GOFFData[1] = (char)0xF0; |
431 | |
432 | // ESD record. |
433 | GOFFData[GOFF::RecordLength] = (char)0x03; |
434 | GOFFData[GOFF::RecordLength + 3] = (char)0x05; |
435 | GOFFData[GOFF::RecordLength + 7] = (char)0x01; |
436 | GOFFData[GOFF::RecordLength + 11] = (char)0x01; |
437 | GOFFData[GOFF::RecordLength + 71] = (char)0x01; // Size of symbol name. |
438 | GOFFData[GOFF::RecordLength + 72] = (char)0xC8; // Symbol name. |
439 | |
440 | // END record. |
441 | GOFFData[GOFF::RecordLength * 2] = (char)0x03; |
442 | GOFFData[GOFF::RecordLength * 2 + 1] = (char)0x40; |
443 | |
444 | StringRef Data(GOFFData, GOFF::RecordLength * 3); |
445 | |
446 | Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = |
447 | object::ObjectFile::createGOFFObjectFile( |
448 | Object: MemoryBufferRef(Data, "dummyGOFF" )); |
449 | |
450 | ASSERT_THAT_EXPECTED(GOFFObjOrErr, Succeeded()); |
451 | |
452 | GOFFObjectFile *GOFFObj = dyn_cast<GOFFObjectFile>(Val: (*GOFFObjOrErr).get()); |
453 | |
454 | for (SymbolRef Symbol : GOFFObj->symbols()) { |
455 | Expected<SymbolRef::Type> SymbolType = Symbol.getType(); |
456 | EXPECT_THAT_EXPECTED( |
457 | SymbolType, |
458 | FailedWithMessage("ESD record 1 has invalid symbol type 0x05" )); |
459 | |
460 | Expected<section_iterator> SymSI = Symbol.getSection(); |
461 | ASSERT_THAT_EXPECTED( |
462 | SymSI, |
463 | FailedWithMessage( |
464 | "symbol with ESD id 1 refers to invalid section with ESD id 1" )); |
465 | } |
466 | } |
467 | |
468 | TEST(GOFFObjectFileTest, InvalidERSymbolType) { |
469 | char GOFFData[GOFF::RecordLength * 3] = {0x00}; |
470 | |
471 | // HDR record. |
472 | GOFFData[0] = (char)0x03; |
473 | GOFFData[1] = (char)0xF0; |
474 | |
475 | // ESD record. |
476 | GOFFData[GOFF::RecordLength] = (char)0x03; |
477 | GOFFData[GOFF::RecordLength + 3] = (char)0x04; |
478 | GOFFData[GOFF::RecordLength + 7] = (char)0x01; |
479 | GOFFData[GOFF::RecordLength + 11] = (char)0x01; |
480 | GOFFData[GOFF::RecordLength + 63] = (char)0x03; // Unknown executable type. |
481 | GOFFData[GOFF::RecordLength + 71] = (char)0x01; // Size of symbol name. |
482 | GOFFData[GOFF::RecordLength + 72] = (char)0xC8; // Symbol name. |
483 | |
484 | // END record. |
485 | GOFFData[GOFF::RecordLength * 2] = (char)0x03; |
486 | GOFFData[GOFF::RecordLength * 2 + 1] = (char)0x40; |
487 | |
488 | StringRef Data(GOFFData, GOFF::RecordLength * 3); |
489 | |
490 | Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = |
491 | object::ObjectFile::createGOFFObjectFile( |
492 | Object: MemoryBufferRef(Data, "dummyGOFF" )); |
493 | |
494 | ASSERT_THAT_EXPECTED(GOFFObjOrErr, Succeeded()); |
495 | |
496 | GOFFObjectFile *GOFFObj = dyn_cast<GOFFObjectFile>(Val: (*GOFFObjOrErr).get()); |
497 | |
498 | for (SymbolRef Symbol : GOFFObj->symbols()) { |
499 | Expected<SymbolRef::Type> SymbolType = Symbol.getType(); |
500 | EXPECT_THAT_EXPECTED( |
501 | SymbolType, |
502 | FailedWithMessage("ESD record 1 has unknown Executable type 0x03" )); |
503 | } |
504 | } |
505 | |
506 | TEST(GOFFObjectFileTest, TXTConstruct) { |
507 | char GOFFData[GOFF::RecordLength * 6] = {}; |
508 | |
509 | // HDR record. |
510 | GOFFData[0] = 0x03; |
511 | GOFFData[1] = 0xF0; |
512 | GOFFData[50] = 0x01; |
513 | |
514 | // ESD record. |
515 | GOFFData[GOFF::RecordLength] = 0x03; |
516 | GOFFData[GOFF::RecordLength + 7] = 0x01; // ESDID. |
517 | GOFFData[GOFF::RecordLength + 71] = 0x05; // Size of symbol name. |
518 | GOFFData[GOFF::RecordLength + 72] = 0xa5; // Symbol name is v. |
519 | GOFFData[GOFF::RecordLength + 73] = 0x81; // Symbol name is a. |
520 | GOFFData[GOFF::RecordLength + 74] = 0x99; // Symbol name is r. |
521 | GOFFData[GOFF::RecordLength + 75] = 0x7b; // Symbol name is #. |
522 | GOFFData[GOFF::RecordLength + 76] = 0x83; // Symbol name is c. |
523 | |
524 | // ESD record. |
525 | GOFFData[GOFF::RecordLength * 2] = 0x03; |
526 | GOFFData[GOFF::RecordLength * 2 + 3] = 0x01; |
527 | GOFFData[GOFF::RecordLength * 2 + 7] = 0x02; // ESDID. |
528 | GOFFData[GOFF::RecordLength * 2 + 11] = 0x01; // Parent ESDID. |
529 | GOFFData[GOFF::RecordLength * 2 + 27] = 0x08; // Length. |
530 | GOFFData[GOFF::RecordLength * 2 + 40] = 0x01; // Name Space ID. |
531 | GOFFData[GOFF::RecordLength * 2 + 41] = 0x80; |
532 | GOFFData[GOFF::RecordLength * 2 + 60] = 0x04; // Size of symbol name. |
533 | GOFFData[GOFF::RecordLength * 2 + 61] = 0x04; // Size of symbol name. |
534 | GOFFData[GOFF::RecordLength * 2 + 63] = 0x0a; // Size of symbol name. |
535 | GOFFData[GOFF::RecordLength * 2 + 66] = 0x03; // Size of symbol name. |
536 | GOFFData[GOFF::RecordLength * 2 + 71] = 0x08; // Size of symbol name. |
537 | GOFFData[GOFF::RecordLength * 2 + 72] = 0xc3; // Symbol name is c. |
538 | GOFFData[GOFF::RecordLength * 2 + 73] = 0x6d; // Symbol name is _. |
539 | GOFFData[GOFF::RecordLength * 2 + 74] = 0xc3; // Symbol name is c. |
540 | GOFFData[GOFF::RecordLength * 2 + 75] = 0xd6; // Symbol name is o. |
541 | GOFFData[GOFF::RecordLength * 2 + 76] = 0xc4; // Symbol name is D. |
542 | GOFFData[GOFF::RecordLength * 2 + 77] = 0xc5; // Symbol name is E. |
543 | GOFFData[GOFF::RecordLength * 2 + 78] = 0xf6; // Symbol name is 6. |
544 | GOFFData[GOFF::RecordLength * 2 + 79] = 0xf4; // Symbol name is 4. |
545 | |
546 | // ESD record. |
547 | GOFFData[GOFF::RecordLength * 3] = 0x03; |
548 | GOFFData[GOFF::RecordLength * 3 + 3] = 0x02; |
549 | GOFFData[GOFF::RecordLength * 3 + 7] = 0x03; // ESDID. |
550 | GOFFData[GOFF::RecordLength * 3 + 11] = 0x02; // Parent ESDID. |
551 | GOFFData[GOFF::RecordLength * 3 + 71] = 0x05; // Size of symbol name. |
552 | GOFFData[GOFF::RecordLength * 3 + 72] = 0xa5; // Symbol name is v. |
553 | GOFFData[GOFF::RecordLength * 3 + 73] = 0x81; // Symbol name is a. |
554 | GOFFData[GOFF::RecordLength * 3 + 74] = 0x99; // Symbol name is r. |
555 | GOFFData[GOFF::RecordLength * 3 + 75] = 0x7b; // Symbol name is #. |
556 | GOFFData[GOFF::RecordLength * 3 + 76] = 0x83; // Symbol name is c. |
557 | |
558 | // TXT record. |
559 | GOFFData[GOFF::RecordLength * 4] = 0x03; |
560 | GOFFData[GOFF::RecordLength * 4 + 1] = 0x10; |
561 | GOFFData[GOFF::RecordLength * 4 + 7] = 0x02; |
562 | GOFFData[GOFF::RecordLength * 4 + 23] = 0x08; // Data Length. |
563 | GOFFData[GOFF::RecordLength * 4 + 24] = 0x12; |
564 | GOFFData[GOFF::RecordLength * 4 + 25] = 0x34; |
565 | GOFFData[GOFF::RecordLength * 4 + 26] = 0x56; |
566 | GOFFData[GOFF::RecordLength * 4 + 27] = 0x78; |
567 | GOFFData[GOFF::RecordLength * 4 + 28] = 0x9a; |
568 | GOFFData[GOFF::RecordLength * 4 + 29] = 0xbc; |
569 | GOFFData[GOFF::RecordLength * 4 + 30] = 0xde; |
570 | GOFFData[GOFF::RecordLength * 4 + 31] = 0xf0; |
571 | |
572 | // END record. |
573 | GOFFData[GOFF::RecordLength * 5] = 0x03; |
574 | GOFFData[GOFF::RecordLength * 5 + 1] = 0x40; |
575 | GOFFData[GOFF::RecordLength * 5 + 11] = 0x06; |
576 | |
577 | StringRef Data(GOFFData, GOFF::RecordLength * 6); |
578 | |
579 | Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = |
580 | object::ObjectFile::createGOFFObjectFile( |
581 | Object: MemoryBufferRef(Data, "dummyGOFF" )); |
582 | |
583 | ASSERT_THAT_EXPECTED(GOFFObjOrErr, Succeeded()); |
584 | |
585 | GOFFObjectFile *GOFFObj = dyn_cast<GOFFObjectFile>(Val: (*GOFFObjOrErr).get()); |
586 | auto Symbols = GOFFObj->symbols(); |
587 | ASSERT_EQ(std::distance(Symbols.begin(), Symbols.end()), 1); |
588 | SymbolRef Symbol = *Symbols.begin(); |
589 | Expected<StringRef> SymbolNameOrErr = GOFFObj->getSymbolName(Symbol); |
590 | ASSERT_THAT_EXPECTED(SymbolNameOrErr, Succeeded()); |
591 | StringRef SymbolName = SymbolNameOrErr.get(); |
592 | EXPECT_EQ(SymbolName, "var#c" ); |
593 | |
594 | auto Sections = GOFFObj->sections(); |
595 | ASSERT_EQ(std::distance(Sections.begin(), Sections.end()), 1); |
596 | SectionRef Section = *Sections.begin(); |
597 | Expected<StringRef> SectionContent = Section.getContents(); |
598 | ASSERT_THAT_EXPECTED(SectionContent, Succeeded()); |
599 | StringRef Contents = SectionContent.get(); |
600 | EXPECT_EQ(Contents, "\x12\x34\x56\x78\x9a\xbc\xde\xf0" ); |
601 | } |
602 | |