[lldb][test] Try a workaround for module cache test on Arm/AArch64 Linux
[llvm-project.git] / lldb / unittests / ObjectFile / ELF / TestObjectFileELF.cpp
blob80abc5b80f84dfbd2f3f550551b27e0b73c83125
1 //===-- TestObjectFileELF.cpp ---------------------------------------------===//
2 //
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
10 #include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
11 #include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
12 #include "TestingSupport/SubsystemRAII.h"
13 #include "TestingSupport/TestUtilities.h"
14 #include "lldb/Core/Module.h"
15 #include "lldb/Core/ModuleSpec.h"
16 #include "lldb/Core/Section.h"
17 #include "lldb/Host/FileSystem.h"
18 #include "lldb/Host/HostInfo.h"
19 #include "lldb/Utility/DataBufferHeap.h"
20 #include "llvm/Support/Compression.h"
21 #include "llvm/Support/FileUtilities.h"
22 #include "llvm/Support/Path.h"
23 #include "llvm/Support/Program.h"
24 #include "llvm/Support/raw_ostream.h"
25 #include "llvm/Testing/Support/Error.h"
26 #include "gtest/gtest.h"
28 using namespace lldb_private;
29 using namespace lldb;
31 class ObjectFileELFTest : public testing::Test {
32 SubsystemRAII<FileSystem, HostInfo, ObjectFileELF, SymbolFileSymtab>
33 subsystems;
36 TEST_F(ObjectFileELFTest, SectionsResolveConsistently) {
37 auto ExpectedFile = TestFile::fromYaml(R"(
38 --- !ELF
39 FileHeader:
40 Class: ELFCLASS64
41 Data: ELFDATA2LSB
42 Type: ET_EXEC
43 Machine: EM_X86_64
44 Entry: 0x0000000000400180
45 Sections:
46 - Name: .note.gnu.build-id
47 Type: SHT_NOTE
48 Flags: [ SHF_ALLOC ]
49 Address: 0x0000000000400158
50 AddressAlign: 0x0000000000000004
51 Content: 040000001400000003000000474E55003F3EC29E3FD83E49D18C4D49CD8A730CC13117B6
52 - Name: .text
53 Type: SHT_PROGBITS
54 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
55 Address: 0x0000000000400180
56 AddressAlign: 0x0000000000000010
57 Content: 554889E58B042500106000890425041060005DC3
58 - Name: .data
59 Type: SHT_PROGBITS
60 Flags: [ SHF_WRITE, SHF_ALLOC ]
61 Address: 0x0000000000601000
62 AddressAlign: 0x0000000000000004
63 Content: 2F000000
64 - Name: .bss
65 Type: SHT_NOBITS
66 Flags: [ SHF_WRITE, SHF_ALLOC ]
67 Address: 0x0000000000601004
68 AddressAlign: 0x0000000000000004
69 Size: 0x0000000000000004
70 Symbols:
71 - Name: Y
72 Type: STT_OBJECT
73 Section: .data
74 Value: 0x0000000000601000
75 Size: 0x0000000000000004
76 Binding: STB_GLOBAL
77 - Name: _start
78 Type: STT_FUNC
79 Section: .text
80 Value: 0x0000000000400180
81 Size: 0x0000000000000014
82 Binding: STB_GLOBAL
83 - Name: X
84 Type: STT_OBJECT
85 Section: .bss
86 Value: 0x0000000000601004
87 Size: 0x0000000000000004
88 Binding: STB_GLOBAL
89 ...
90 )");
91 ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
93 auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());
94 SectionList *list = module_sp->GetSectionList();
95 ASSERT_NE(nullptr, list);
97 auto bss_sp = list->FindSectionByName(ConstString(".bss"));
98 ASSERT_NE(nullptr, bss_sp);
99 auto data_sp = list->FindSectionByName(ConstString(".data"));
100 ASSERT_NE(nullptr, data_sp);
101 auto text_sp = list->FindSectionByName(ConstString(".text"));
102 ASSERT_NE(nullptr, text_sp);
104 const Symbol *X = module_sp->FindFirstSymbolWithNameAndType(ConstString("X"),
105 eSymbolTypeAny);
106 ASSERT_NE(nullptr, X);
107 EXPECT_EQ(bss_sp, X->GetAddress().GetSection());
109 const Symbol *Y = module_sp->FindFirstSymbolWithNameAndType(ConstString("Y"),
110 eSymbolTypeAny);
111 ASSERT_NE(nullptr, Y);
112 EXPECT_EQ(data_sp, Y->GetAddress().GetSection());
114 const Symbol *start = module_sp->FindFirstSymbolWithNameAndType(
115 ConstString("_start"), eSymbolTypeAny);
116 ASSERT_NE(nullptr, start);
117 EXPECT_EQ(text_sp, start->GetAddress().GetSection());
120 // Test that GetModuleSpecifications works on an "atypical" object file which
121 // has section headers right after the ELF header (instead of the more common
122 // layout where the section headers are at the very end of the object file).
124 // Test file generated with yaml2obj (@svn rev 324254) from the following input:
126 --- !ELF
127 FileHeader:
128 Class: ELFCLASS64
129 Data: ELFDATA2LSB
130 Type: ET_EXEC
131 Machine: EM_X86_64
132 Entry: 0x00000000004003D0
133 Sections:
134 - Name: .note.gnu.build-id
135 Type: SHT_NOTE
136 Flags: [ SHF_ALLOC ]
137 Address: 0x0000000000400274
138 AddressAlign: 0x0000000000000004
139 Content: 040000001400000003000000474E55001B8A73AC238390E32A7FF4AC8EBE4D6A41ECF5C9
140 - Name: .text
141 Type: SHT_PROGBITS
142 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
143 Address: 0x00000000004003D0
144 AddressAlign: 0x0000000000000010
145 Content: DEADBEEFBAADF00D
148 TEST_F(ObjectFileELFTest, GetModuleSpecifications_EarlySectionHeaders) {
149 std::string SO = GetInputFilePath("early-section-headers.so");
150 ModuleSpecList Specs;
151 ASSERT_EQ(1u, ObjectFile::GetModuleSpecifications(FileSpec(SO), 0, 0, Specs));
152 ModuleSpec Spec;
153 ASSERT_TRUE(Specs.GetModuleSpecAtIndex(0, Spec)) ;
154 UUID Uuid;
155 Uuid.SetFromStringRef("1b8a73ac238390e32a7ff4ac8ebe4d6a41ecf5c9");
156 EXPECT_EQ(Spec.GetUUID(), Uuid);
159 TEST_F(ObjectFileELFTest, GetModuleSpecifications_OffsetSizeWithNormalFile) {
160 std::string SO = GetInputFilePath("liboffset-test.so");
161 ModuleSpecList Specs;
162 ASSERT_EQ(1u, ObjectFile::GetModuleSpecifications(FileSpec(SO), 0, 0, Specs));
163 ModuleSpec Spec;
164 ASSERT_TRUE(Specs.GetModuleSpecAtIndex(0, Spec)) ;
165 UUID Uuid;
166 Uuid.SetFromStringRef("7D6E4738");
167 EXPECT_EQ(Spec.GetUUID(), Uuid);
168 EXPECT_EQ(Spec.GetObjectOffset(), 0UL);
169 EXPECT_EQ(Spec.GetObjectSize(), 3600UL);
170 EXPECT_EQ(FileSystem::Instance().GetByteSize(FileSpec(SO)), 3600UL);
173 TEST_F(ObjectFileELFTest, GetModuleSpecifications_OffsetSizeWithOffsetFile) {
174 // The contents of offset-test.bin are
175 // - 0-1023: \0
176 // - 1024-4623: liboffset-test.so (offset: 1024, size: 3600, CRC32: 7D6E4738)
177 // - 4624-4639: \0
178 std::string SO = GetInputFilePath("offset-test.bin");
179 ModuleSpecList Specs;
180 ASSERT_EQ(
181 1u, ObjectFile::GetModuleSpecifications(FileSpec(SO), 1024, 3600, Specs));
182 ModuleSpec Spec;
183 ASSERT_TRUE(Specs.GetModuleSpecAtIndex(0, Spec)) ;
184 UUID Uuid;
185 Uuid.SetFromStringRef("7D6E4738");
186 EXPECT_EQ(Spec.GetUUID(), Uuid);
187 EXPECT_EQ(Spec.GetObjectOffset(), 1024UL);
188 EXPECT_EQ(Spec.GetObjectSize(), 3600UL);
189 EXPECT_EQ(FileSystem::Instance().GetByteSize(FileSpec(SO)), 4640UL);
192 TEST_F(ObjectFileELFTest, GetSymtab_NoSymEntryPointArmThumbAddressClass) {
194 // nosym-entrypoint-arm-thumb.s
195 .thumb_func
196 _start:
197 mov r0, #42
198 mov r7, #1
199 svc #0
200 // arm-linux-androideabi-as nosym-entrypoint-arm-thumb.s
201 // -o nosym-entrypoint-arm-thumb.o
202 // arm-linux-androideabi-ld nosym-entrypoint-arm-thumb.o
203 // -o nosym-entrypoint-arm-thumb -e 0x8075 -s
205 auto ExpectedFile = TestFile::fromYaml(R"(
206 --- !ELF
207 FileHeader:
208 Class: ELFCLASS32
209 Data: ELFDATA2LSB
210 Type: ET_EXEC
211 Machine: EM_ARM
212 Flags: [ EF_ARM_SOFT_FLOAT, EF_ARM_EABI_VER5 ]
213 Entry: 0x0000000000008075
214 Sections:
215 - Name: .text
216 Type: SHT_PROGBITS
217 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
218 Address: 0x0000000000008074
219 AddressAlign: 0x0000000000000002
220 Content: 2A20012700DF
221 - Name: .data
222 Type: SHT_PROGBITS
223 Flags: [ SHF_WRITE, SHF_ALLOC ]
224 Address: 0x0000000000009000
225 AddressAlign: 0x0000000000000001
226 Content: ''
227 - Name: .bss
228 Type: SHT_NOBITS
229 Flags: [ SHF_WRITE, SHF_ALLOC ]
230 Address: 0x0000000000009000
231 AddressAlign: 0x0000000000000001
232 - Name: .note.gnu.gold-version
233 Type: SHT_NOTE
234 AddressAlign: 0x0000000000000004
235 Content: 040000000900000004000000474E5500676F6C6420312E3131000000
236 - Name: .ARM.attributes
237 Type: SHT_ARM_ATTRIBUTES
238 AddressAlign: 0x0000000000000001
239 Content: '4113000000616561626900010900000006020901'
241 )");
242 ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
244 auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());
246 auto entry_point_addr = module_sp->GetObjectFile()->GetEntryPointAddress();
247 ASSERT_TRUE(entry_point_addr.GetOffset() & 1);
248 // Decrease the offsite by 1 to make it into a breakable address since this
249 // is Thumb.
250 entry_point_addr.SetOffset(entry_point_addr.GetOffset() - 1);
251 ASSERT_EQ(entry_point_addr.GetAddressClass(),
252 AddressClass::eCodeAlternateISA);
255 TEST_F(ObjectFileELFTest, GetSymtab_NoSymEntryPointArmAddressClass) {
257 // nosym-entrypoint-arm.s
258 _start:
259 movs r0, #42
260 movs r7, #1
261 svc #0
262 // arm-linux-androideabi-as nosym-entrypoint-arm.s
263 // -o nosym-entrypoint-arm.o
264 // arm-linux-androideabi-ld nosym-entrypoint-arm.o
265 // -o nosym-entrypoint-arm -e 0x8074 -s
267 auto ExpectedFile = TestFile::fromYaml(R"(
268 --- !ELF
269 FileHeader:
270 Class: ELFCLASS32
271 Data: ELFDATA2LSB
272 Type: ET_EXEC
273 Machine: EM_ARM
274 Flags: [ EF_ARM_SOFT_FLOAT, EF_ARM_EABI_VER5 ]
275 Entry: 0x0000000000008074
276 Sections:
277 - Name: .text
278 Type: SHT_PROGBITS
279 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
280 Address: 0x0000000000008074
281 AddressAlign: 0x0000000000000004
282 Content: 2A00A0E30170A0E3000000EF
283 - Name: .data
284 Type: SHT_PROGBITS
285 Flags: [ SHF_WRITE, SHF_ALLOC ]
286 Address: 0x0000000000009000
287 AddressAlign: 0x0000000000000001
288 Content: ''
289 - Name: .bss
290 Type: SHT_NOBITS
291 Flags: [ SHF_WRITE, SHF_ALLOC ]
292 Address: 0x0000000000009000
293 AddressAlign: 0x0000000000000001
294 - Name: .note.gnu.gold-version
295 Type: SHT_NOTE
296 AddressAlign: 0x0000000000000004
297 Content: 040000000900000004000000474E5500676F6C6420312E3131000000
298 - Name: .ARM.attributes
299 Type: SHT_ARM_ATTRIBUTES
300 AddressAlign: 0x0000000000000001
301 Content: '4113000000616561626900010900000006010801'
303 )");
304 ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
306 auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());
308 auto entry_point_addr = module_sp->GetObjectFile()->GetEntryPointAddress();
309 ASSERT_EQ(entry_point_addr.GetAddressClass(), AddressClass::eCode);