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
14using namespace llvm;
15using namespace llvm::object;
16using namespace llvm::GOFF;
17
18namespace {
19char GOFFData[GOFF::RecordLength * 3] = {0x00};
20
21void 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
30void 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
45TEST(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
54TEST(GOFFObjectFileTest, ConstructGOFFObjectInvalidSize) {
55 constructInvalidGOFF(Size: 70);
56 constructInvalidGOFF(Size: 79);
57 constructInvalidGOFF(Size: 81);
58}
59
60TEST(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
81TEST(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
101TEST(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
143TEST(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
172TEST(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
223TEST(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
267TEST(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
316TEST(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
346TEST(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
377TEST(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
425TEST(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
468TEST(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
506TEST(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

source code of llvm/unittests/Object/GOFFObjectFileTest.cpp