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/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"
14 
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"
23 
24 #include <memory>
25 
26 #include "gtest/gtest.h"
27 
28 using namespace lldb;
29 using namespace lldb_private;
30 
31 class SymtabTest : public testing::Test {
32   SubsystemRAII<FileSystem, HostInfo, ObjectFileMachO, SymbolFileDWARF,
33                 TypeSystemClang>
34       subsystem;
35 };
36 
37 static void EncodeDecode(const Symtab &object, ByteOrder byte_order) {
38   const uint8_t addr_size = 8;
39   DataEncoder file(byte_order, addr_size);
40 
41   object.Encode(file);
42   llvm::ArrayRef<uint8_t> bytes = file.GetData();
43   DataExtractor data(bytes.data(), bytes.size(), byte_order, addr_size);
44   Symtab decoded_object(object.GetObjectFile());
45   offset_t data_offset = 0;
46   bool uuid_mismatch = false;
47   decoded_object.Decode(data, &data_offset, uuid_mismatch);
48   ASSERT_EQ(object.GetNumSymbols(), decoded_object.GetNumSymbols());
49   for (size_t i = 0; i < object.GetNumSymbols(); ++i)
50     EXPECT_EQ(*object.SymbolAtIndex(i), *decoded_object.SymbolAtIndex(i));
51 }
52 
53 static void EncodeDecode(const Symtab &object) {
54   EncodeDecode(object, eByteOrderLittle);
55   EncodeDecode(object, eByteOrderBig);
56 }
57 
58 TEST_F(SymtabTest, EncodeDecodeSymtab) {
59 
60   auto ExpectedFile = TestFile::fromYaml(R"(
61 --- !mach-o
62 FileHeader:
63   magic:           0xFEEDFACF
64   cputype:         0x100000C
65   cpusubtype:      0x0
66   filetype:        0x2
67   ncmds:           17
68   sizeofcmds:      792
69   flags:           0x200085
70   reserved:        0x0
71 LoadCommands:
72   - cmd:             LC_SEGMENT_64
73     cmdsize:         72
74     segname:         __PAGEZERO
75     vmaddr:          0
76     vmsize:          4294967296
77     fileoff:         0
78     filesize:        0
79     maxprot:         0
80     initprot:        0
81     nsects:          0
82     flags:           0
83   - cmd:             LC_SEGMENT_64
84     cmdsize:         232
85     segname:         __TEXT
86     vmaddr:          4294967296
87     vmsize:          16384
88     fileoff:         0
89     filesize:        16384
90     maxprot:         5
91     initprot:        5
92     nsects:          2
93     flags:           0
94     Sections:
95       - sectname:        __text
96         segname:         __TEXT
97         addr:            0x100003F94
98         size:            36
99         offset:          0x3F94
100         align:           2
101         reloff:          0x0
102         nreloc:          0
103         flags:           0x80000400
104         reserved1:       0x0
105         reserved2:       0x0
106         reserved3:       0x0
107         content:         FF8300D1E80300AA00008052FF1F00B9E81B00B9E10B00F9E20700F9FF830091C0035FD6
108       - sectname:        __unwind_info
109         segname:         __TEXT
110         addr:            0x100003FB8
111         size:            72
112         offset:          0x3FB8
113         align:           2
114         reloff:          0x0
115         nreloc:          0
116         flags:           0x0
117         reserved1:       0x0
118         reserved2:       0x0
119         reserved3:       0x0
120         content:         010000001C000000000000001C000000000000001C00000002000000943F00003400000034000000B93F00000000000034000000030000000C000100100001000000000000200002
121   - cmd:             LC_SEGMENT_64
122     cmdsize:         72
123     segname:         __LINKEDIT
124     vmaddr:          4294983680
125     vmsize:          16384
126     fileoff:         16384
127     filesize:        674
128     maxprot:         1
129     initprot:        1
130     nsects:          0
131     flags:           0
132   - cmd:             LC_DYLD_CHAINED_FIXUPS
133     cmdsize:         16
134     dataoff:         16384
135     datasize:        56
136   - cmd:             LC_DYLD_EXPORTS_TRIE
137     cmdsize:         16
138     dataoff:         16440
139     datasize:        48
140   - cmd:             LC_SYMTAB
141     cmdsize:         24
142     symoff:          16496
143     nsyms:           10
144     stroff:          16656
145     strsize:         128
146   - cmd:             LC_DYSYMTAB
147     cmdsize:         80
148     ilocalsym:       0
149     nlocalsym:       8
150     iextdefsym:      8
151     nextdefsym:      2
152     iundefsym:       10
153     nundefsym:       0
154     tocoff:          0
155     ntoc:            0
156     modtaboff:       0
157     nmodtab:         0
158     extrefsymoff:    0
159     nextrefsyms:     0
160     indirectsymoff:  0
161     nindirectsyms:   0
162     extreloff:       0
163     nextrel:         0
164     locreloff:       0
165     nlocrel:         0
166   - cmd:             LC_LOAD_DYLINKER
167     cmdsize:         32
168     name:            12
169     Content:         '/usr/lib/dyld'
170     ZeroPadBytes:    7
171   - cmd:             LC_UUID
172     cmdsize:         24
173     uuid:            1EECD2B8-16EA-3FEC-AB3C-F46139DBD0E2
174   - cmd:             LC_BUILD_VERSION
175     cmdsize:         32
176     platform:        1
177     minos:           786432
178     sdk:             786432
179     ntools:          1
180     Tools:
181       - tool:            3
182         version:         46596096
183   - cmd:             LC_SOURCE_VERSION
184     cmdsize:         16
185     version:         0
186   - cmd:             LC_MAIN
187     cmdsize:         24
188     entryoff:        16276
189     stacksize:       0
190   - cmd:             LC_LOAD_DYLIB
191     cmdsize:         48
192     dylib:
193       name:            24
194       timestamp:       2
195       current_version: 78643968
196       compatibility_version: 65536
197     Content:         '/usr/lib/libc++.1.dylib'
198     ZeroPadBytes:    1
199   - cmd:             LC_LOAD_DYLIB
200     cmdsize:         56
201     dylib:
202       name:            24
203       timestamp:       2
204       current_version: 85917696
205       compatibility_version: 65536
206     Content:         '/usr/lib/libSystem.B.dylib'
207     ZeroPadBytes:    6
208   - cmd:             LC_FUNCTION_STARTS
209     cmdsize:         16
210     dataoff:         16488
211     datasize:        8
212   - cmd:             LC_DATA_IN_CODE
213     cmdsize:         16
214     dataoff:         16496
215     datasize:        0
216   - cmd:             LC_CODE_SIGNATURE
217     cmdsize:         16
218     dataoff:         16784
219     datasize:        274
220 LinkEditData:
221   NameList:
222     - n_strx:          28
223       n_type:          0x64
224       n_sect:          0
225       n_desc:          0
226       n_value:         0
227     - n_strx:          64
228       n_type:          0x64
229       n_sect:          0
230       n_desc:          0
231       n_value:         0
232     - n_strx:          73
233       n_type:          0x66
234       n_sect:          0
235       n_desc:          1
236       n_value:         1639532873
237     - n_strx:          1
238       n_type:          0x2E
239       n_sect:          1
240       n_desc:          0
241       n_value:         4294983572
242     - n_strx:          115
243       n_type:          0x24
244       n_sect:          1
245       n_desc:          0
246       n_value:         4294983572
247     - n_strx:          1
248       n_type:          0x24
249       n_sect:          0
250       n_desc:          0
251       n_value:         36
252     - n_strx:          1
253       n_type:          0x4E
254       n_sect:          1
255       n_desc:          0
256       n_value:         36
257     - n_strx:          1
258       n_type:          0x64
259       n_sect:          1
260       n_desc:          0
261       n_value:         0
262     - n_strx:          2
263       n_type:          0xF
264       n_sect:          1
265       n_desc:          16
266       n_value:         4294967296
267     - n_strx:          22
268       n_type:          0xF
269       n_sect:          1
270       n_desc:          0
271       n_value:         4294983572
272   StringTable:
273     - ' '
274     - __mh_execute_header
275     - _main
276     - '/Users/gclayton/Documents/src/args/'
277     - main.cpp
278     - '/Users/gclayton/Documents/src/args/main.o'
279     - _main
280     - ''
281     - ''
282     - ''
283     - ''
284     - ''
285     - ''
286     - ''
287 ...
288 )");
289 
290   ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
291   auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());
292   ObjectFile *objfile = module_sp->GetObjectFile();
293   ASSERT_NE(objfile, nullptr);
294 
295   // Test encoding and decoding an empty symbol table.
296   Symtab symtab(objfile);
297   symtab.PreloadSymbols();
298   EncodeDecode(symtab);
299 
300   // Now encode and decode an actual symbol table from our yaml.
301   Symtab *module_symtab = module_sp->GetSymtab();
302   ASSERT_NE(module_symtab, nullptr);
303   module_symtab->PreloadSymbols();
304   EncodeDecode(*module_symtab);
305 }
306