1 //===-- SymbolTest.cpp ----------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
10 #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
11 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
12 #include "TestingSupport/SubsystemRAII.h"
13 #include "TestingSupport/TestUtilities.h"
15 #include "lldb/Core/DataFileCache.h"
16 #include "lldb/Core/Module.h"
17 #include "lldb/Host/FileSystem.h"
18 #include "lldb/Host/HostInfo.h"
19 #include "lldb/Symbol/Symbol.h"
20 #include "lldb/Symbol/Symtab.h"
21 #include "lldb/Utility/DataEncoder.h"
22 #include "lldb/Utility/DataExtractor.h"
26 #include "gtest/gtest.h"
29 using namespace lldb_private
;
30 using namespace lldb_private::plugin::dwarf
;
32 class SymtabTest
: public testing::Test
{
33 SubsystemRAII
<FileSystem
, HostInfo
, ObjectFileMachO
, SymbolFileDWARF
,
38 static void EncodeDecode(const Symtab
&object
, ByteOrder byte_order
) {
39 const uint8_t addr_size
= 8;
40 DataEncoder
file(byte_order
, addr_size
);
43 llvm::ArrayRef
<uint8_t> bytes
= file
.GetData();
44 DataExtractor
data(bytes
.data(), bytes
.size(), byte_order
, addr_size
);
45 Symtab
decoded_object(object
.GetObjectFile());
46 offset_t data_offset
= 0;
47 bool uuid_mismatch
= false;
48 decoded_object
.Decode(data
, &data_offset
, uuid_mismatch
);
49 ASSERT_EQ(object
.GetNumSymbols(), decoded_object
.GetNumSymbols());
50 for (size_t i
= 0; i
< object
.GetNumSymbols(); ++i
)
51 EXPECT_EQ(*object
.SymbolAtIndex(i
), *decoded_object
.SymbolAtIndex(i
));
54 static void EncodeDecode(const Symtab
&object
) {
55 EncodeDecode(object
, eByteOrderLittle
);
56 EncodeDecode(object
, eByteOrderBig
);
59 TEST_F(SymtabTest
, EncodeDecodeSymtab
) {
61 auto ExpectedFile
= TestFile::fromYaml(R
"(
108 content: FF8300D1E80300AA00008052FF1F00B9E81B00B9E10B00F9E20700F9FF830091C0035FD6
109 - sectname: __unwind_info
121 content: 010000001C000000000000001C000000000000001C00000002000000943F00003400000034000000B93F00000000000034000000030000000C000100100001000000000000200002
133 - cmd: LC_DYLD_CHAINED_FIXUPS
137 - cmd: LC_DYLD_EXPORTS_TRIE
167 - cmd: LC_LOAD_DYLINKER
170 Content: '/usr/lib/dyld'
174 uuid: 1EECD2B8-16EA-3FEC-AB3C-F46139DBD0E2
175 - cmd: LC_BUILD_VERSION
184 - cmd: LC_SOURCE_VERSION
196 current_version: 78643968
197 compatibility_version: 65536
198 Content: '/usr/lib/libc++.1.dylib'
205 current_version: 85917696
206 compatibility_version: 65536
207 Content: '/usr/lib/libSystem.B.dylib'
209 - cmd: LC_FUNCTION_STARTS
213 - cmd: LC_DATA_IN_CODE
217 - cmd: LC_CODE_SIGNATURE
275 - __mh_execute_header
277 - '/Users/gclayton/Documents/src/args/'
279 - '/Users/gclayton/Documents/src/args/main.o'
291 ASSERT_THAT_EXPECTED(ExpectedFile
, llvm::Succeeded());
292 auto module_sp
= std::make_shared
<Module
>(ExpectedFile
->moduleSpec());
293 ObjectFile
*objfile
= module_sp
->GetObjectFile();
294 ASSERT_NE(objfile
, nullptr);
296 // Test encoding and decoding an empty symbol table.
297 Symtab
symtab(objfile
);
298 symtab
.PreloadSymbols();
299 EncodeDecode(symtab
);
301 // Now encode and decode an actual symbol table from our yaml.
302 Symtab
*module_symtab
= module_sp
->GetSymtab();
303 ASSERT_NE(module_symtab
, nullptr);
304 module_symtab
->PreloadSymbols();
305 EncodeDecode(*module_symtab
);
308 TEST_F(SymtabTest
, TestDecodeCStringMaps
) {
309 // Symbol tables save out the symbols, but they also save out the symbol table
310 // name indexes. These name indexes are a map of sorted ConstString + T pairs
311 // and when they are decoded from a file, they are no longer sorted since
312 // ConstString objects can be sorted by "const char *" and the order in which
313 // these strings are created won't be the same in a new process. We need to
314 // ensure these name lookups happen correctly when we load the name indexes,
315 // so this test loads a symbol table from a cache file from
316 // "lldb/unittests/Symbol/Inputs/indexnames-symtab-cache" and make sure we
317 // can correctly lookup each of the names in the symbol table.
318 auto ExpectedFile
= TestFile::fromYaml(R
"(
365 content: 80018052C0035FD6E0028052C0035FD640048052C0035FD6FF8300D1FD7B01A9FD43009108008052E80B00B9BFC31FB8F4FFFF97F5FFFF97F6FFFF97E00B40B9FD7B41A9FF830091C0035FD6
366 - sectname: __unwind_info
378 content: 010000001C000000000000001C000000000000001C00000002000000643F00003400000034000000B13F00000000000034000000030000000C0002001400020000000001180000000000000400000002
390 - cmd: LC_DYLD_CHAINED_FIXUPS
394 - cmd: LC_DYLD_EXPORTS_TRIE
424 - cmd: LC_LOAD_DYLINKER
427 Content: '/usr/lib/dyld'
431 uuid: 3E94866E-0D1A-39BD-975B-64E8F1FDBAAE
432 - cmd: LC_BUILD_VERSION
441 - cmd: LC_SOURCE_VERSION
453 current_version: 85943299
454 compatibility_version: 65536
455 Content: '/usr/lib/libSystem.B.dylib'
457 - cmd: LC_FUNCTION_STARTS
461 - cmd: LC_DATA_IN_CODE
465 - cmd: LC_CODE_SIGNATURE
598 - __mh_execute_header
603 - '/Users/gclayton/Documents/objfiles/index-names/'
605 - '/Users/gclayton/Documents/objfiles/index-names/main.o'
613 FunctionStarts: [ 0x3F64, 0x3F6C, 0x3F74, 0x3F7C ]
616 // This data was taken from a hex dump of the object file from the above yaml
617 // and hexdumped so we can load the cache data in this test.
618 const uint8_t symtab_cache_bytes
[] = {
619 0x01, 0x10, 0x3e, 0x94, 0x86, 0x6e, 0x0d, 0x1a,
620 0x39, 0xbd, 0x97, 0x5b, 0x64, 0xe8, 0xf1, 0xfd,
621 0xba, 0xae, 0xff, 0x53, 0x54, 0x41, 0x42, 0x91,
622 0x00, 0x00, 0x00, 0x00, 0x2f, 0x55, 0x73, 0x65,
623 0x72, 0x73, 0x2f, 0x67, 0x63, 0x6c, 0x61, 0x79,
624 0x74, 0x6f, 0x6e, 0x2f, 0x44, 0x6f, 0x63, 0x75,
625 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x6f, 0x62,
626 0x6a, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x69,
627 0x6e, 0x64, 0x65, 0x78, 0x2d, 0x6e, 0x61, 0x6d,
628 0x65, 0x73, 0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x2e,
629 0x63, 0x00, 0x2f, 0x55, 0x73, 0x65, 0x72, 0x73,
630 0x2f, 0x67, 0x63, 0x6c, 0x61, 0x79, 0x74, 0x6f,
631 0x6e, 0x2f, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65,
632 0x6e, 0x74, 0x73, 0x2f, 0x6f, 0x62, 0x6a, 0x66,
633 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x64,
634 0x65, 0x78, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x73,
635 0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x6f, 0x00,
636 0x66, 0x6f, 0x6f, 0x00, 0x62, 0x61, 0x72, 0x00,
637 0x62, 0x61, 0x7a, 0x00, 0x6d, 0x61, 0x69, 0x6e,
638 0x00, 0x5f, 0x6d, 0x68, 0x5f, 0x65, 0x78, 0x65,
639 0x63, 0x75, 0x74, 0x65, 0x5f, 0x68, 0x65, 0x61,
640 0x64, 0x65, 0x72, 0x00, 0x53, 0x59, 0x4d, 0x42,
641 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
642 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x2a,
643 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
645 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
646 0x64, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
647 0x0a, 0x20, 0x01, 0x37, 0x00, 0x00, 0x00, 0x00,
648 0x7b, 0xc3, 0x69, 0x62, 0x00, 0x00, 0x00, 0x00,
649 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
650 0x01, 0x00, 0x66, 0x00, 0x04, 0x00, 0x00, 0x00,
651 0x00, 0x00, 0x02, 0x32, 0x01, 0x6d, 0x00, 0x00,
652 0x00, 0x01, 0x64, 0x3f, 0x00, 0x00, 0x01, 0x00,
653 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
654 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x08, 0x00,
655 0x00, 0x00, 0x00, 0x00, 0x02, 0x32, 0x01, 0x71,
656 0x00, 0x00, 0x00, 0x01, 0x6c, 0x3f, 0x00, 0x00,
657 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
658 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00,
659 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x32,
660 0x01, 0x75, 0x00, 0x00, 0x00, 0x01, 0x74, 0x3f,
661 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00,
662 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
663 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
664 0x02, 0x32, 0x01, 0x79, 0x00, 0x00, 0x00, 0x01,
665 0x7c, 0x3f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
666 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
667 0x00, 0x00, 0x0f, 0x00, 0x14, 0x00, 0x00, 0x00,
668 0x00, 0x00, 0x04, 0x12, 0x02, 0x7e, 0x00, 0x00,
669 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
670 0x00, 0x00, 0x64, 0x3f, 0x00, 0x00, 0x00, 0x00,
671 0x00, 0x00, 0x10, 0x00, 0x0f, 0x00, 0x01, 0x00,
672 0x43, 0x4d, 0x41, 0x50, 0x07, 0x00, 0x00, 0x00,
673 0x6d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
674 0x75, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
675 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
676 0x79, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
677 0x37, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
678 0x71, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
679 0x7e, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00
682 ASSERT_THAT_EXPECTED(ExpectedFile
, llvm::Succeeded());
683 auto module_sp
= std::make_shared
<Module
>(ExpectedFile
->moduleSpec());
684 ObjectFile
*objfile
= module_sp
->GetObjectFile();
685 ASSERT_NE(objfile
, nullptr);
687 // Test encoding and decoding an empty symbol table.
688 DataExtractor
data(symtab_cache_bytes
, sizeof(symtab_cache_bytes
),
689 eByteOrderLittle
, 8);
690 Symtab
symtab(objfile
);
691 offset_t data_offset
= 0;
692 bool uuid_mismatch
= false; // Gets set to true if signature doesn't match.
693 const bool success
= symtab
.Decode(data
, &data_offset
, uuid_mismatch
);
694 ASSERT_EQ(success
, true);
695 ASSERT_EQ(uuid_mismatch
, false);
697 // Now make sure that name lookup works for all symbols. This indicates that
698 // the Symtab::NameToIndexMap was decoded correctly and works as expected.
699 Symbol
*symbol
= nullptr;
700 symbol
= symtab
.FindFirstSymbolWithNameAndType(ConstString("main"),
703 Symtab::eVisibilityAny
);
704 ASSERT_NE(symbol
, nullptr);
705 symbol
= symtab
.FindFirstSymbolWithNameAndType(ConstString("foo"),
708 Symtab::eVisibilityAny
);
709 ASSERT_NE(symbol
, nullptr);
710 symbol
= symtab
.FindFirstSymbolWithNameAndType(ConstString("bar"),
713 Symtab::eVisibilityAny
);
714 ASSERT_NE(symbol
, nullptr);
715 symbol
= symtab
.FindFirstSymbolWithNameAndType(ConstString("baz"),
718 Symtab::eVisibilityAny
);
719 ASSERT_NE(symbol
, nullptr);