1//===-- SymbolTest.cpp ----------------------------------------------------===//
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 "Plugins/ObjectFile/ELF/ObjectFileELF.h"
10#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
11#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
12#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
13#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
14#include "TestingSupport/SubsystemRAII.h"
15#include "TestingSupport/TestUtilities.h"
16
17#include "lldb/Core/DataFileCache.h"
18#include "lldb/Core/Module.h"
19#include "lldb/Host/FileSystem.h"
20#include "lldb/Host/HostInfo.h"
21#include "lldb/Symbol/Symbol.h"
22#include "lldb/Symbol/Symtab.h"
23#include "lldb/Utility/DataEncoder.h"
24#include "lldb/Utility/DataExtractor.h"
25
26#include <memory>
27
28#include "gtest/gtest.h"
29
30using namespace lldb;
31using namespace lldb_private;
32using namespace lldb_private::plugin::dwarf;
33
34class SymtabTest : public testing::Test {
35 SubsystemRAII<FileSystem, HostInfo, ObjectFileMachO, SymbolFileDWARF,
36 ObjectFileELF, SymbolFileSymtab, TypeSystemClang>
37 subsystem;
38};
39
40static void EncodeDecode(const Symtab &object, ByteOrder byte_order) {
41 const uint8_t addr_size = 8;
42 DataEncoder file(byte_order, addr_size);
43
44 object.Encode(encoder&: file);
45 llvm::ArrayRef<uint8_t> bytes = file.GetData();
46 DataExtractor data(bytes.data(), bytes.size(), byte_order, addr_size);
47 Symtab decoded_object(object.GetObjectFile());
48 offset_t data_offset = 0;
49 bool uuid_mismatch = false;
50 decoded_object.Decode(data, offset_ptr: &data_offset, uuid_mismatch);
51 ASSERT_EQ(object.GetNumSymbols(), decoded_object.GetNumSymbols());
52 for (size_t i = 0; i < object.GetNumSymbols(); ++i)
53 EXPECT_EQ(*object.SymbolAtIndex(i), *decoded_object.SymbolAtIndex(i));
54}
55
56static void EncodeDecode(const Symtab &object) {
57 EncodeDecode(object, byte_order: eByteOrderLittle);
58 EncodeDecode(object, byte_order: eByteOrderBig);
59}
60
61TEST_F(SymtabTest, EncodeDecodeSymtab) {
62
63 auto ExpectedFile = TestFile::fromYaml(Yaml: R"(
64--- !mach-o
65FileHeader:
66 magic: 0xFEEDFACF
67 cputype: 0x100000C
68 cpusubtype: 0x0
69 filetype: 0x2
70 ncmds: 17
71 sizeofcmds: 792
72 flags: 0x200085
73 reserved: 0x0
74LoadCommands:
75 - cmd: LC_SEGMENT_64
76 cmdsize: 72
77 segname: __PAGEZERO
78 vmaddr: 0
79 vmsize: 4294967296
80 fileoff: 0
81 filesize: 0
82 maxprot: 0
83 initprot: 0
84 nsects: 0
85 flags: 0
86 - cmd: LC_SEGMENT_64
87 cmdsize: 232
88 segname: __TEXT
89 vmaddr: 4294967296
90 vmsize: 16384
91 fileoff: 0
92 filesize: 16384
93 maxprot: 5
94 initprot: 5
95 nsects: 2
96 flags: 0
97 Sections:
98 - sectname: __text
99 segname: __TEXT
100 addr: 0x100003F94
101 size: 36
102 offset: 0x3F94
103 align: 2
104 reloff: 0x0
105 nreloc: 0
106 flags: 0x80000400
107 reserved1: 0x0
108 reserved2: 0x0
109 reserved3: 0x0
110 content: FF8300D1E80300AA00008052FF1F00B9E81B00B9E10B00F9E20700F9FF830091C0035FD6
111 - sectname: __unwind_info
112 segname: __TEXT
113 addr: 0x100003FB8
114 size: 72
115 offset: 0x3FB8
116 align: 2
117 reloff: 0x0
118 nreloc: 0
119 flags: 0x0
120 reserved1: 0x0
121 reserved2: 0x0
122 reserved3: 0x0
123 content: 010000001C000000000000001C000000000000001C00000002000000943F00003400000034000000B93F00000000000034000000030000000C000100100001000000000000200002
124 - cmd: LC_SEGMENT_64
125 cmdsize: 72
126 segname: __LINKEDIT
127 vmaddr: 4294983680
128 vmsize: 16384
129 fileoff: 16384
130 filesize: 674
131 maxprot: 1
132 initprot: 1
133 nsects: 0
134 flags: 0
135 - cmd: LC_DYLD_CHAINED_FIXUPS
136 cmdsize: 16
137 dataoff: 16384
138 datasize: 56
139 - cmd: LC_DYLD_EXPORTS_TRIE
140 cmdsize: 16
141 dataoff: 16440
142 datasize: 48
143 - cmd: LC_SYMTAB
144 cmdsize: 24
145 symoff: 16496
146 nsyms: 10
147 stroff: 16656
148 strsize: 128
149 - cmd: LC_DYSYMTAB
150 cmdsize: 80
151 ilocalsym: 0
152 nlocalsym: 8
153 iextdefsym: 8
154 nextdefsym: 2
155 iundefsym: 10
156 nundefsym: 0
157 tocoff: 0
158 ntoc: 0
159 modtaboff: 0
160 nmodtab: 0
161 extrefsymoff: 0
162 nextrefsyms: 0
163 indirectsymoff: 0
164 nindirectsyms: 0
165 extreloff: 0
166 nextrel: 0
167 locreloff: 0
168 nlocrel: 0
169 - cmd: LC_LOAD_DYLINKER
170 cmdsize: 32
171 name: 12
172 Content: '/usr/lib/dyld'
173 ZeroPadBytes: 7
174 - cmd: LC_UUID
175 cmdsize: 24
176 uuid: 1EECD2B8-16EA-3FEC-AB3C-F46139DBD0E2
177 - cmd: LC_BUILD_VERSION
178 cmdsize: 32
179 platform: 1
180 minos: 786432
181 sdk: 786432
182 ntools: 1
183 Tools:
184 - tool: 3
185 version: 46596096
186 - cmd: LC_SOURCE_VERSION
187 cmdsize: 16
188 version: 0
189 - cmd: LC_MAIN
190 cmdsize: 24
191 entryoff: 16276
192 stacksize: 0
193 - cmd: LC_LOAD_DYLIB
194 cmdsize: 48
195 dylib:
196 name: 24
197 timestamp: 2
198 current_version: 78643968
199 compatibility_version: 65536
200 Content: '/usr/lib/libc++.1.dylib'
201 ZeroPadBytes: 1
202 - cmd: LC_LOAD_DYLIB
203 cmdsize: 56
204 dylib:
205 name: 24
206 timestamp: 2
207 current_version: 85917696
208 compatibility_version: 65536
209 Content: '/usr/lib/libSystem.B.dylib'
210 ZeroPadBytes: 6
211 - cmd: LC_FUNCTION_STARTS
212 cmdsize: 16
213 dataoff: 16488
214 datasize: 8
215 - cmd: LC_DATA_IN_CODE
216 cmdsize: 16
217 dataoff: 16496
218 datasize: 0
219 - cmd: LC_CODE_SIGNATURE
220 cmdsize: 16
221 dataoff: 16784
222 datasize: 274
223LinkEditData:
224 NameList:
225 - n_strx: 28
226 n_type: 0x64
227 n_sect: 0
228 n_desc: 0
229 n_value: 0
230 - n_strx: 64
231 n_type: 0x64
232 n_sect: 0
233 n_desc: 0
234 n_value: 0
235 - n_strx: 73
236 n_type: 0x66
237 n_sect: 0
238 n_desc: 1
239 n_value: 1639532873
240 - n_strx: 1
241 n_type: 0x2E
242 n_sect: 1
243 n_desc: 0
244 n_value: 4294983572
245 - n_strx: 115
246 n_type: 0x24
247 n_sect: 1
248 n_desc: 0
249 n_value: 4294983572
250 - n_strx: 1
251 n_type: 0x24
252 n_sect: 0
253 n_desc: 0
254 n_value: 36
255 - n_strx: 1
256 n_type: 0x4E
257 n_sect: 1
258 n_desc: 0
259 n_value: 36
260 - n_strx: 1
261 n_type: 0x64
262 n_sect: 1
263 n_desc: 0
264 n_value: 0
265 - n_strx: 2
266 n_type: 0xF
267 n_sect: 1
268 n_desc: 16
269 n_value: 4294967296
270 - n_strx: 22
271 n_type: 0xF
272 n_sect: 1
273 n_desc: 0
274 n_value: 4294983572
275 StringTable:
276 - ' '
277 - __mh_execute_header
278 - _main
279 - '/Users/gclayton/Documents/src/args/'
280 - main.cpp
281 - '/Users/gclayton/Documents/src/args/main.o'
282 - _main
283 - ''
284 - ''
285 - ''
286 - ''
287 - ''
288 - ''
289 - ''
290...
291)");
292
293 ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
294 auto module_sp = std::make_shared<Module>(args: ExpectedFile->moduleSpec());
295 ObjectFile *objfile = module_sp->GetObjectFile();
296 ASSERT_NE(objfile, nullptr);
297
298 // Test encoding and decoding an empty symbol table.
299 Symtab symtab(objfile);
300 symtab.PreloadSymbols();
301 EncodeDecode(object: symtab);
302
303 // Now encode and decode an actual symbol table from our yaml.
304 Symtab *module_symtab = module_sp->GetSymtab();
305 ASSERT_NE(module_symtab, nullptr);
306 module_symtab->PreloadSymbols();
307 EncodeDecode(object: *module_symtab);
308}
309
310TEST_F(SymtabTest, TestDecodeCStringMaps) {
311 // Symbol tables save out the symbols, but they also save out the symbol table
312 // name indexes. These name indexes are a map of sorted ConstString + T pairs
313 // and when they are decoded from a file, they are no longer sorted since
314 // ConstString objects can be sorted by "const char *" and the order in which
315 // these strings are created won't be the same in a new process. We need to
316 // ensure these name lookups happen correctly when we load the name indexes,
317 // so this test loads a symbol table from a cache file from
318 // "lldb/unittests/Symbol/Inputs/indexnames-symtab-cache" and make sure we
319 // can correctly lookup each of the names in the symbol table.
320 auto ExpectedFile = TestFile::fromYaml(Yaml: R"(
321--- !mach-o
322FileHeader:
323 magic: 0xFEEDFACF
324 cputype: 0x100000C
325 cpusubtype: 0x0
326 filetype: 0x2
327 ncmds: 16
328 sizeofcmds: 744
329 flags: 0x200085
330 reserved: 0x0
331LoadCommands:
332 - cmd: LC_SEGMENT_64
333 cmdsize: 72
334 segname: __PAGEZERO
335 vmaddr: 0
336 vmsize: 4294967296
337 fileoff: 0
338 filesize: 0
339 maxprot: 0
340 initprot: 0
341 nsects: 0
342 flags: 0
343 - cmd: LC_SEGMENT_64
344 cmdsize: 232
345 segname: __TEXT
346 vmaddr: 4294967296
347 vmsize: 16384
348 fileoff: 0
349 filesize: 16384
350 maxprot: 5
351 initprot: 5
352 nsects: 2
353 flags: 0
354 Sections:
355 - sectname: __text
356 segname: __TEXT
357 addr: 0x100003F64
358 size: 76
359 offset: 0x3F64
360 align: 2
361 reloff: 0x0
362 nreloc: 0
363 flags: 0x80000400
364 reserved1: 0x0
365 reserved2: 0x0
366 reserved3: 0x0
367 content: 80018052C0035FD6E0028052C0035FD640048052C0035FD6FF8300D1FD7B01A9FD43009108008052E80B00B9BFC31FB8F4FFFF97F5FFFF97F6FFFF97E00B40B9FD7B41A9FF830091C0035FD6
368 - sectname: __unwind_info
369 segname: __TEXT
370 addr: 0x100003FB0
371 size: 80
372 offset: 0x3FB0
373 align: 2
374 reloff: 0x0
375 nreloc: 0
376 flags: 0x0
377 reserved1: 0x0
378 reserved2: 0x0
379 reserved3: 0x0
380 content: 010000001C000000000000001C000000000000001C00000002000000643F00003400000034000000B13F00000000000034000000030000000C0002001400020000000001180000000000000400000002
381 - cmd: LC_SEGMENT_64
382 cmdsize: 72
383 segname: __LINKEDIT
384 vmaddr: 4294983680
385 vmsize: 16384
386 fileoff: 16384
387 filesize: 994
388 maxprot: 1
389 initprot: 1
390 nsects: 0
391 flags: 0
392 - cmd: LC_DYLD_CHAINED_FIXUPS
393 cmdsize: 16
394 dataoff: 16384
395 datasize: 56
396 - cmd: LC_DYLD_EXPORTS_TRIE
397 cmdsize: 16
398 dataoff: 16440
399 datasize: 80
400 - cmd: LC_SYMTAB
401 cmdsize: 24
402 symoff: 16528
403 nsyms: 25
404 stroff: 16928
405 strsize: 176
406 - cmd: LC_DYSYMTAB
407 cmdsize: 80
408 ilocalsym: 0
409 nlocalsym: 20
410 iextdefsym: 20
411 nextdefsym: 5
412 iundefsym: 25
413 nundefsym: 0
414 tocoff: 0
415 ntoc: 0
416 modtaboff: 0
417 nmodtab: 0
418 extrefsymoff: 0
419 nextrefsyms: 0
420 indirectsymoff: 0
421 nindirectsyms: 0
422 extreloff: 0
423 nextrel: 0
424 locreloff: 0
425 nlocrel: 0
426 - cmd: LC_LOAD_DYLINKER
427 cmdsize: 32
428 name: 12
429 Content: '/usr/lib/dyld'
430 ZeroPadBytes: 7
431 - cmd: LC_UUID
432 cmdsize: 24
433 uuid: 3E94866E-0D1A-39BD-975B-64E8F1FDBAAE
434 - cmd: LC_BUILD_VERSION
435 cmdsize: 32
436 platform: 1
437 minos: 786432
438 sdk: 787200
439 ntools: 1
440 Tools:
441 - tool: 3
442 version: 49938432
443 - cmd: LC_SOURCE_VERSION
444 cmdsize: 16
445 version: 0
446 - cmd: LC_MAIN
447 cmdsize: 24
448 entryoff: 16252
449 stacksize: 0
450 - cmd: LC_LOAD_DYLIB
451 cmdsize: 56
452 dylib:
453 name: 24
454 timestamp: 2
455 current_version: 85943299
456 compatibility_version: 65536
457 Content: '/usr/lib/libSystem.B.dylib'
458 ZeroPadBytes: 6
459 - cmd: LC_FUNCTION_STARTS
460 cmdsize: 16
461 dataoff: 16520
462 datasize: 8
463 - cmd: LC_DATA_IN_CODE
464 cmdsize: 16
465 dataoff: 16528
466 datasize: 0
467 - cmd: LC_CODE_SIGNATURE
468 cmdsize: 16
469 dataoff: 17104
470 datasize: 274
471LinkEditData:
472 NameList:
473 - n_strx: 43
474 n_type: 0x64
475 n_sect: 0
476 n_desc: 0
477 n_value: 0
478 - n_strx: 91
479 n_type: 0x64
480 n_sect: 0
481 n_desc: 0
482 n_value: 0
483 - n_strx: 98
484 n_type: 0x66
485 n_sect: 0
486 n_desc: 1
487 n_value: 1651098491
488 - n_strx: 1
489 n_type: 0x2E
490 n_sect: 1
491 n_desc: 0
492 n_value: 4294983524
493 - n_strx: 152
494 n_type: 0x24
495 n_sect: 1
496 n_desc: 0
497 n_value: 4294983524
498 - n_strx: 1
499 n_type: 0x24
500 n_sect: 0
501 n_desc: 0
502 n_value: 8
503 - n_strx: 1
504 n_type: 0x4E
505 n_sect: 1
506 n_desc: 0
507 n_value: 8
508 - n_strx: 1
509 n_type: 0x2E
510 n_sect: 1
511 n_desc: 0
512 n_value: 4294983532
513 - n_strx: 157
514 n_type: 0x24
515 n_sect: 1
516 n_desc: 0
517 n_value: 4294983532
518 - n_strx: 1
519 n_type: 0x24
520 n_sect: 0
521 n_desc: 0
522 n_value: 8
523 - n_strx: 1
524 n_type: 0x4E
525 n_sect: 1
526 n_desc: 0
527 n_value: 8
528 - n_strx: 1
529 n_type: 0x2E
530 n_sect: 1
531 n_desc: 0
532 n_value: 4294983540
533 - n_strx: 162
534 n_type: 0x24
535 n_sect: 1
536 n_desc: 0
537 n_value: 4294983540
538 - n_strx: 1
539 n_type: 0x24
540 n_sect: 0
541 n_desc: 0
542 n_value: 8
543 - n_strx: 1
544 n_type: 0x4E
545 n_sect: 1
546 n_desc: 0
547 n_value: 8
548 - n_strx: 1
549 n_type: 0x2E
550 n_sect: 1
551 n_desc: 0
552 n_value: 4294983548
553 - n_strx: 167
554 n_type: 0x24
555 n_sect: 1
556 n_desc: 0
557 n_value: 4294983548
558 - n_strx: 1
559 n_type: 0x24
560 n_sect: 0
561 n_desc: 0
562 n_value: 52
563 - n_strx: 1
564 n_type: 0x4E
565 n_sect: 1
566 n_desc: 0
567 n_value: 52
568 - n_strx: 1
569 n_type: 0x64
570 n_sect: 1
571 n_desc: 0
572 n_value: 0
573 - n_strx: 2
574 n_type: 0xF
575 n_sect: 1
576 n_desc: 16
577 n_value: 4294967296
578 - n_strx: 22
579 n_type: 0xF
580 n_sect: 1
581 n_desc: 0
582 n_value: 4294983532
583 - n_strx: 27
584 n_type: 0xF
585 n_sect: 1
586 n_desc: 0
587 n_value: 4294983540
588 - n_strx: 32
589 n_type: 0xF
590 n_sect: 1
591 n_desc: 0
592 n_value: 4294983524
593 - n_strx: 37
594 n_type: 0xF
595 n_sect: 1
596 n_desc: 0
597 n_value: 4294983548
598 StringTable:
599 - ' '
600 - __mh_execute_header
601 - _bar
602 - _baz
603 - _foo
604 - _main
605 - '/Users/gclayton/Documents/objfiles/index-names/'
606 - main.c
607 - '/Users/gclayton/Documents/objfiles/index-names/main.o'
608 - _foo
609 - _bar
610 - _baz
611 - _main
612 - ''
613 - ''
614 - ''
615 FunctionStarts: [ 0x3F64, 0x3F6C, 0x3F74, 0x3F7C ]
616...
617)");
618 // This data was taken from a hex dump of the object file from the above yaml
619 // and hexdumped so we can load the cache data in this test.
620 const uint8_t symtab_cache_bytes[] = {
621 0x01, 0x10, 0x3e, 0x94, 0x86, 0x6e, 0x0d, 0x1a,
622 0x39, 0xbd, 0x97, 0x5b, 0x64, 0xe8, 0xf1, 0xfd,
623 0xba, 0xae, 0xff, 0x53, 0x54, 0x41, 0x42, 0x91,
624 0x00, 0x00, 0x00, 0x00, 0x2f, 0x55, 0x73, 0x65,
625 0x72, 0x73, 0x2f, 0x67, 0x63, 0x6c, 0x61, 0x79,
626 0x74, 0x6f, 0x6e, 0x2f, 0x44, 0x6f, 0x63, 0x75,
627 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x6f, 0x62,
628 0x6a, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x69,
629 0x6e, 0x64, 0x65, 0x78, 0x2d, 0x6e, 0x61, 0x6d,
630 0x65, 0x73, 0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x2e,
631 0x63, 0x00, 0x2f, 0x55, 0x73, 0x65, 0x72, 0x73,
632 0x2f, 0x67, 0x63, 0x6c, 0x61, 0x79, 0x74, 0x6f,
633 0x6e, 0x2f, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65,
634 0x6e, 0x74, 0x73, 0x2f, 0x6f, 0x62, 0x6a, 0x66,
635 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x64,
636 0x65, 0x78, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x73,
637 0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x6f, 0x00,
638 0x66, 0x6f, 0x6f, 0x00, 0x62, 0x61, 0x72, 0x00,
639 0x62, 0x61, 0x7a, 0x00, 0x6d, 0x61, 0x69, 0x6e,
640 0x00, 0x5f, 0x6d, 0x68, 0x5f, 0x65, 0x78, 0x65,
641 0x63, 0x75, 0x74, 0x65, 0x5f, 0x68, 0x65, 0x61,
642 0x64, 0x65, 0x72, 0x00, 0x53, 0x59, 0x4d, 0x42,
643 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
644 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x2a,
645 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
646 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
647 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
648 0x64, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
649 0x0a, 0x20, 0x01, 0x37, 0x00, 0x00, 0x00, 0x00,
650 0x7b, 0xc3, 0x69, 0x62, 0x00, 0x00, 0x00, 0x00,
651 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
652 0x01, 0x00, 0x66, 0x00, 0x04, 0x00, 0x00, 0x00,
653 0x00, 0x00, 0x02, 0x32, 0x01, 0x6d, 0x00, 0x00,
654 0x00, 0x01, 0x64, 0x3f, 0x00, 0x00, 0x01, 0x00,
655 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
656 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x08, 0x00,
657 0x00, 0x00, 0x00, 0x00, 0x02, 0x32, 0x01, 0x71,
658 0x00, 0x00, 0x00, 0x01, 0x6c, 0x3f, 0x00, 0x00,
659 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
660 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00,
661 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x32,
662 0x01, 0x75, 0x00, 0x00, 0x00, 0x01, 0x74, 0x3f,
663 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00,
664 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
665 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
666 0x02, 0x32, 0x01, 0x79, 0x00, 0x00, 0x00, 0x01,
667 0x7c, 0x3f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
668 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
669 0x00, 0x00, 0x0f, 0x00, 0x14, 0x00, 0x00, 0x00,
670 0x00, 0x00, 0x04, 0x12, 0x02, 0x7e, 0x00, 0x00,
671 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
672 0x00, 0x00, 0x64, 0x3f, 0x00, 0x00, 0x00, 0x00,
673 0x00, 0x00, 0x10, 0x00, 0x0f, 0x00, 0x01, 0x00,
674 0x43, 0x4d, 0x41, 0x50, 0x07, 0x00, 0x00, 0x00,
675 0x6d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
676 0x75, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
677 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
678 0x79, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
679 0x37, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
680 0x71, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
681 0x7e, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00
682 };
683
684 ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
685 auto module_sp = std::make_shared<Module>(args: ExpectedFile->moduleSpec());
686 ObjectFile *objfile = module_sp->GetObjectFile();
687 ASSERT_NE(objfile, nullptr);
688
689 // Test encoding and decoding an empty symbol table.
690 DataExtractor data(symtab_cache_bytes, sizeof(symtab_cache_bytes),
691 eByteOrderLittle, 8);
692 Symtab symtab(objfile);
693 offset_t data_offset = 0;
694 bool uuid_mismatch = false; // Gets set to true if signature doesn't match.
695 const bool success = symtab.Decode(data, offset_ptr: &data_offset, uuid_mismatch);
696 ASSERT_EQ(success, true);
697 ASSERT_EQ(uuid_mismatch, false);
698
699 // Now make sure that name lookup works for all symbols. This indicates that
700 // the Symtab::NameToIndexMap was decoded correctly and works as expected.
701 Symbol *symbol = nullptr;
702 symbol = symtab.FindFirstSymbolWithNameAndType(name: ConstString("main"),
703 symbol_type: eSymbolTypeCode,
704 symbol_debug_type: Symtab::eDebugAny,
705 symbol_visibility: Symtab::eVisibilityAny);
706 ASSERT_NE(symbol, nullptr);
707 symbol = symtab.FindFirstSymbolWithNameAndType(name: ConstString("foo"),
708 symbol_type: eSymbolTypeCode,
709 symbol_debug_type: Symtab::eDebugAny,
710 symbol_visibility: Symtab::eVisibilityAny);
711 ASSERT_NE(symbol, nullptr);
712 symbol = symtab.FindFirstSymbolWithNameAndType(name: ConstString("bar"),
713 symbol_type: eSymbolTypeCode,
714 symbol_debug_type: Symtab::eDebugAny,
715 symbol_visibility: Symtab::eVisibilityAny);
716 ASSERT_NE(symbol, nullptr);
717 symbol = symtab.FindFirstSymbolWithNameAndType(name: ConstString("baz"),
718 symbol_type: eSymbolTypeCode,
719 symbol_debug_type: Symtab::eDebugAny,
720 symbol_visibility: Symtab::eVisibilityAny);
721 ASSERT_NE(symbol, nullptr);
722}
723
724TEST_F(SymtabTest, TestSymbolFileCreatedOnDemand) {
725 auto ExpectedFile = TestFile::fromYaml(Yaml: R"(
726--- !ELF
727FileHeader:
728 Class: ELFCLASS64
729 Data: ELFDATA2LSB
730 Type: ET_EXEC
731 Machine: EM_X86_64
732 Entry: 0x0000000000400180
733Sections:
734 - Name: .text
735 Type: SHT_PROGBITS
736 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
737 Address: 0x0000000000400180
738 AddressAlign: 0x0000000000000010
739 Content: 554889E58B042500106000890425041060005DC3
740Symbols:
741 - Name: _start
742 Type: STT_FUNC
743 Section: .text
744 Value: 0x0000000000400180
745 Size: 0x0000000000000014
746 Binding: STB_GLOBAL
747...
748)");
749 ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
750 auto module_sp = std::make_shared<Module>(args: ExpectedFile->moduleSpec());
751
752 // The symbol file should not be created by default.
753 Symtab *module_symtab = module_sp->GetSymtab(/*can_create=*/false);
754 ASSERT_EQ(module_symtab, nullptr);
755
756 // But it should be created on demand.
757 module_symtab = module_sp->GetSymtab(/*can_create=*/true);
758 ASSERT_NE(module_symtab, nullptr);
759
760 // And we should be able to get it again once it has been created.
761 Symtab *cached_module_symtab = module_sp->GetSymtab(/*can_create=*/false);
762 ASSERT_EQ(module_symtab, cached_module_symtab);
763}
764
765TEST_F(SymtabTest, TestSymbolTableCreatedOnDemand) {
766 const char *yamldata = R"(
767--- !ELF
768FileHeader:
769 Class: ELFCLASS64
770 Data: ELFDATA2LSB
771 Type: ET_EXEC
772 Machine: EM_386
773DWARF:
774 debug_abbrev:
775 - Table:
776 - Code: 0x00000001
777 Tag: DW_TAG_compile_unit
778 Children: DW_CHILDREN_no
779 Attributes:
780 - Attribute: DW_AT_addr_base
781 Form: DW_FORM_sec_offset
782 debug_info:
783 - Version: 5
784 AddrSize: 4
785 UnitType: DW_UT_compile
786 Entries:
787 - AbbrCode: 0x00000001
788 Values:
789 - Value: 0x8 # Offset of the first Address past the header
790 - AbbrCode: 0x0
791 debug_addr:
792 - Version: 5
793 AddressSize: 4
794 Entries:
795 - Address: 0x1234
796 - Address: 0x5678
797 debug_line:
798 - Length: 42
799 Version: 2
800 PrologueLength: 36
801 MinInstLength: 1
802 DefaultIsStmt: 1
803 LineBase: 251
804 LineRange: 14
805 OpcodeBase: 13
806 StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ]
807 IncludeDirs:
808 - '/tmp'
809 Files:
810 - Name: main.cpp
811 DirIdx: 1
812 ModTime: 0
813 Length: 0
814)";
815 llvm::Expected<TestFile> file = TestFile::fromYaml(Yaml: yamldata);
816 EXPECT_THAT_EXPECTED(file, llvm::Succeeded());
817 auto module_sp = std::make_shared<Module>(args: file->moduleSpec());
818
819 SymbolFile *symbol_file = module_sp->GetSymbolFile();
820 // At this point, the symbol table is not created. This is because the above
821 // yaml data contains the necessary sections in order for
822 // SymbolFileDWARF::CalculateAbilities() to identify all abilities, saving it
823 // from calling SymbolFileDWARFDebugMap::CalculateAbilities(), which
824 // eventually loads the symbol table, which we don't want.
825
826 // The symbol table should not be created if asked not to.
827 Symtab *symtab = symbol_file->GetSymtab(/*can_create=*/false);
828 ASSERT_EQ(symtab, nullptr);
829
830 // But it should be created on demand.
831 symtab = symbol_file->GetSymtab(/*can_create=*/true);
832 ASSERT_NE(symtab, nullptr);
833
834 // And we should be able to get it again once it has been created.
835 Symtab *cached_symtab = symbol_file->GetSymtab(/*can_create=*/false);
836 ASSERT_EQ(symtab, cached_symtab);
837}
838

source code of lldb/unittests/Symbol/SymtabTest.cpp