180814287SRaphael Isemann //===-- TestObjectFileELF.cpp ---------------------------------------------===// 2efddda3dSPavel Labath // 3efddda3dSPavel Labath // 42946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 52946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 62946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7efddda3dSPavel Labath // 8efddda3dSPavel Labath //===----------------------------------------------------------------------===// 9efddda3dSPavel Labath 10efddda3dSPavel Labath #include "Plugins/ObjectFile/ELF/ObjectFileELF.h" 1184a68569SPavel Labath #include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h" 125dca0596SRaphael Isemann #include "TestingSupport/SubsystemRAII.h" 13e2867bc4SPavel Labath #include "TestingSupport/TestUtilities.h" 14efddda3dSPavel Labath #include "lldb/Core/Module.h" 15efddda3dSPavel Labath #include "lldb/Core/ModuleSpec.h" 16efddda3dSPavel Labath #include "lldb/Core/Section.h" 1746376966SJonas Devlieghere #include "lldb/Host/FileSystem.h" 18efddda3dSPavel Labath #include "lldb/Host/HostInfo.h" 196868d2ddSNathan Lanza #include "lldb/Utility/DataBufferHeap.h" 20e7d85688SVedant Kumar #include "llvm/ADT/Optional.h" 21e2867bc4SPavel Labath #include "llvm/Support/Compression.h" 22efddda3dSPavel Labath #include "llvm/Support/FileUtilities.h" 23efddda3dSPavel Labath #include "llvm/Support/Path.h" 24efddda3dSPavel Labath #include "llvm/Support/Program.h" 25efddda3dSPavel Labath #include "llvm/Support/raw_ostream.h" 268a777920SGreg Clayton #include "llvm/Testing/Support/Error.h" 27efddda3dSPavel Labath #include "gtest/gtest.h" 28efddda3dSPavel Labath 29efddda3dSPavel Labath using namespace lldb_private; 30efddda3dSPavel Labath using namespace lldb; 31efddda3dSPavel Labath 32efddda3dSPavel Labath class ObjectFileELFTest : public testing::Test { 335dca0596SRaphael Isemann SubsystemRAII<FileSystem, HostInfo, ObjectFileELF, SymbolFileSymtab> 345dca0596SRaphael Isemann subsystems; 35efddda3dSPavel Labath }; 36efddda3dSPavel Labath 37efddda3dSPavel Labath TEST_F(ObjectFileELFTest, SectionsResolveConsistently) { 38a2e270faSPavel Labath auto ExpectedFile = TestFile::fromYaml(R"( 39a2e270faSPavel Labath --- !ELF 40a2e270faSPavel Labath FileHeader: 41a2e270faSPavel Labath Class: ELFCLASS64 42a2e270faSPavel Labath Data: ELFDATA2LSB 43a2e270faSPavel Labath Type: ET_EXEC 44a2e270faSPavel Labath Machine: EM_X86_64 45a2e270faSPavel Labath Entry: 0x0000000000400180 46a2e270faSPavel Labath Sections: 47a2e270faSPavel Labath - Name: .note.gnu.build-id 48a2e270faSPavel Labath Type: SHT_NOTE 49a2e270faSPavel Labath Flags: [ SHF_ALLOC ] 50a2e270faSPavel Labath Address: 0x0000000000400158 51a2e270faSPavel Labath AddressAlign: 0x0000000000000004 52a2e270faSPavel Labath Content: 040000001400000003000000474E55003F3EC29E3FD83E49D18C4D49CD8A730CC13117B6 53a2e270faSPavel Labath - Name: .text 54a2e270faSPavel Labath Type: SHT_PROGBITS 55a2e270faSPavel Labath Flags: [ SHF_ALLOC, SHF_EXECINSTR ] 56a2e270faSPavel Labath Address: 0x0000000000400180 57a2e270faSPavel Labath AddressAlign: 0x0000000000000010 58a2e270faSPavel Labath Content: 554889E58B042500106000890425041060005DC3 59a2e270faSPavel Labath - Name: .data 60a2e270faSPavel Labath Type: SHT_PROGBITS 61a2e270faSPavel Labath Flags: [ SHF_WRITE, SHF_ALLOC ] 62a2e270faSPavel Labath Address: 0x0000000000601000 63a2e270faSPavel Labath AddressAlign: 0x0000000000000004 64a2e270faSPavel Labath Content: 2F000000 65a2e270faSPavel Labath - Name: .bss 66a2e270faSPavel Labath Type: SHT_NOBITS 67a2e270faSPavel Labath Flags: [ SHF_WRITE, SHF_ALLOC ] 68a2e270faSPavel Labath Address: 0x0000000000601004 69a2e270faSPavel Labath AddressAlign: 0x0000000000000004 70a2e270faSPavel Labath Size: 0x0000000000000004 71a2e270faSPavel Labath Symbols: 72a2e270faSPavel Labath - Name: Y 73a2e270faSPavel Labath Type: STT_OBJECT 74a2e270faSPavel Labath Section: .data 75a2e270faSPavel Labath Value: 0x0000000000601000 76a2e270faSPavel Labath Size: 0x0000000000000004 77a2e270faSPavel Labath Binding: STB_GLOBAL 78a2e270faSPavel Labath - Name: _start 79a2e270faSPavel Labath Type: STT_FUNC 80a2e270faSPavel Labath Section: .text 81a2e270faSPavel Labath Value: 0x0000000000400180 82a2e270faSPavel Labath Size: 0x0000000000000014 83a2e270faSPavel Labath Binding: STB_GLOBAL 84a2e270faSPavel Labath - Name: X 85a2e270faSPavel Labath Type: STT_OBJECT 86a2e270faSPavel Labath Section: .bss 87a2e270faSPavel Labath Value: 0x0000000000601004 88a2e270faSPavel Labath Size: 0x0000000000000004 89a2e270faSPavel Labath Binding: STB_GLOBAL 90a2e270faSPavel Labath ... 91a2e270faSPavel Labath )"); 92a2e270faSPavel Labath ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); 93efddda3dSPavel Labath 94a2e270faSPavel Labath ModuleSpec spec{FileSpec(ExpectedFile->name())}; 95a2e270faSPavel Labath spec.GetSymbolFileSpec().SetFile(ExpectedFile->name(), 96a2e270faSPavel Labath FileSpec::Style::native); 97efddda3dSPavel Labath auto module_sp = std::make_shared<Module>(spec); 98efddda3dSPavel Labath SectionList *list = module_sp->GetSectionList(); 99efddda3dSPavel Labath ASSERT_NE(nullptr, list); 100efddda3dSPavel Labath 101efddda3dSPavel Labath auto bss_sp = list->FindSectionByName(ConstString(".bss")); 102efddda3dSPavel Labath ASSERT_NE(nullptr, bss_sp); 103efddda3dSPavel Labath auto data_sp = list->FindSectionByName(ConstString(".data")); 104efddda3dSPavel Labath ASSERT_NE(nullptr, data_sp); 105efddda3dSPavel Labath auto text_sp = list->FindSectionByName(ConstString(".text")); 106efddda3dSPavel Labath ASSERT_NE(nullptr, text_sp); 107efddda3dSPavel Labath 108efddda3dSPavel Labath const Symbol *X = module_sp->FindFirstSymbolWithNameAndType(ConstString("X"), 109efddda3dSPavel Labath eSymbolTypeAny); 110efddda3dSPavel Labath ASSERT_NE(nullptr, X); 111efddda3dSPavel Labath EXPECT_EQ(bss_sp, X->GetAddress().GetSection()); 112efddda3dSPavel Labath 113efddda3dSPavel Labath const Symbol *Y = module_sp->FindFirstSymbolWithNameAndType(ConstString("Y"), 114efddda3dSPavel Labath eSymbolTypeAny); 115efddda3dSPavel Labath ASSERT_NE(nullptr, Y); 116efddda3dSPavel Labath EXPECT_EQ(data_sp, Y->GetAddress().GetSection()); 117efddda3dSPavel Labath 118efddda3dSPavel Labath const Symbol *start = module_sp->FindFirstSymbolWithNameAndType( 119efddda3dSPavel Labath ConstString("_start"), eSymbolTypeAny); 120efddda3dSPavel Labath ASSERT_NE(nullptr, start); 121efddda3dSPavel Labath EXPECT_EQ(text_sp, start->GetAddress().GetSection()); 122efddda3dSPavel Labath } 1234f033125SPavel Labath 1244f033125SPavel Labath // Test that GetModuleSpecifications works on an "atypical" object file which 1254f033125SPavel Labath // has section headers right after the ELF header (instead of the more common 1264f033125SPavel Labath // layout where the section headers are at the very end of the object file). 127bca95f8aSPavel Labath // 128bca95f8aSPavel Labath // Test file generated with yaml2obj (@svn rev 324254) from the following input: 129bca95f8aSPavel Labath /* 130bca95f8aSPavel Labath --- !ELF 131bca95f8aSPavel Labath FileHeader: 132bca95f8aSPavel Labath Class: ELFCLASS64 133bca95f8aSPavel Labath Data: ELFDATA2LSB 134bca95f8aSPavel Labath Type: ET_EXEC 135bca95f8aSPavel Labath Machine: EM_X86_64 136bca95f8aSPavel Labath Entry: 0x00000000004003D0 137bca95f8aSPavel Labath Sections: 138bca95f8aSPavel Labath - Name: .note.gnu.build-id 139bca95f8aSPavel Labath Type: SHT_NOTE 140bca95f8aSPavel Labath Flags: [ SHF_ALLOC ] 141bca95f8aSPavel Labath Address: 0x0000000000400274 142bca95f8aSPavel Labath AddressAlign: 0x0000000000000004 143bca95f8aSPavel Labath Content: 040000001400000003000000474E55001B8A73AC238390E32A7FF4AC8EBE4D6A41ECF5C9 144bca95f8aSPavel Labath - Name: .text 145bca95f8aSPavel Labath Type: SHT_PROGBITS 146bca95f8aSPavel Labath Flags: [ SHF_ALLOC, SHF_EXECINSTR ] 147bca95f8aSPavel Labath Address: 0x00000000004003D0 148bca95f8aSPavel Labath AddressAlign: 0x0000000000000010 149bca95f8aSPavel Labath Content: DEADBEEFBAADF00D 150bca95f8aSPavel Labath ... 151bca95f8aSPavel Labath */ 1524f033125SPavel Labath TEST_F(ObjectFileELFTest, GetModuleSpecifications_EarlySectionHeaders) { 1534f033125SPavel Labath std::string SO = GetInputFilePath("early-section-headers.so"); 1544f033125SPavel Labath ModuleSpecList Specs; 1558f3be7a3SJonas Devlieghere ASSERT_EQ(1u, ObjectFile::GetModuleSpecifications(FileSpec(SO), 0, 0, Specs)); 1564f033125SPavel Labath ModuleSpec Spec; 1574f033125SPavel Labath ASSERT_TRUE(Specs.GetModuleSpecAtIndex(0, Spec)) ; 1584f033125SPavel Labath UUID Uuid; 159*1beffc18SJaroslav Sevcik Uuid.SetFromStringRef("1b8a73ac238390e32a7ff4ac8ebe4d6a41ecf5c9"); 1604f033125SPavel Labath EXPECT_EQ(Spec.GetUUID(), Uuid); 1614f033125SPavel Labath } 162ad6690afSAntonio Afonso 163ad6690afSAntonio Afonso TEST_F(ObjectFileELFTest, GetSymtab_NoSymEntryPointArmThumbAddressClass) { 164ad6690afSAntonio Afonso /* 165ad6690afSAntonio Afonso // nosym-entrypoint-arm-thumb.s 166ad6690afSAntonio Afonso .thumb_func 167ad6690afSAntonio Afonso _start: 168ad6690afSAntonio Afonso mov r0, #42 169ad6690afSAntonio Afonso mov r7, #1 170ad6690afSAntonio Afonso svc #0 171ad6690afSAntonio Afonso // arm-linux-androideabi-as nosym-entrypoint-arm-thumb.s 172ad6690afSAntonio Afonso // -o nosym-entrypoint-arm-thumb.o 173ad6690afSAntonio Afonso // arm-linux-androideabi-ld nosym-entrypoint-arm-thumb.o 174ad6690afSAntonio Afonso // -o nosym-entrypoint-arm-thumb -e 0x8075 -s 175ad6690afSAntonio Afonso */ 176ad6690afSAntonio Afonso auto ExpectedFile = TestFile::fromYaml(R"( 177ad6690afSAntonio Afonso --- !ELF 178ad6690afSAntonio Afonso FileHeader: 179ad6690afSAntonio Afonso Class: ELFCLASS32 180ad6690afSAntonio Afonso Data: ELFDATA2LSB 181ad6690afSAntonio Afonso Type: ET_EXEC 182ad6690afSAntonio Afonso Machine: EM_ARM 183ad6690afSAntonio Afonso Flags: [ EF_ARM_SOFT_FLOAT, EF_ARM_EABI_VER5 ] 184ad6690afSAntonio Afonso Entry: 0x0000000000008075 185ad6690afSAntonio Afonso Sections: 186ad6690afSAntonio Afonso - Name: .text 187ad6690afSAntonio Afonso Type: SHT_PROGBITS 188ad6690afSAntonio Afonso Flags: [ SHF_ALLOC, SHF_EXECINSTR ] 189ad6690afSAntonio Afonso Address: 0x0000000000008074 190ad6690afSAntonio Afonso AddressAlign: 0x0000000000000002 191ad6690afSAntonio Afonso Content: 2A20012700DF 192ad6690afSAntonio Afonso - Name: .data 193ad6690afSAntonio Afonso Type: SHT_PROGBITS 194ad6690afSAntonio Afonso Flags: [ SHF_WRITE, SHF_ALLOC ] 195ad6690afSAntonio Afonso Address: 0x0000000000009000 196ad6690afSAntonio Afonso AddressAlign: 0x0000000000000001 197ad6690afSAntonio Afonso Content: '' 198ad6690afSAntonio Afonso - Name: .bss 199ad6690afSAntonio Afonso Type: SHT_NOBITS 200ad6690afSAntonio Afonso Flags: [ SHF_WRITE, SHF_ALLOC ] 201ad6690afSAntonio Afonso Address: 0x0000000000009000 202ad6690afSAntonio Afonso AddressAlign: 0x0000000000000001 203ad6690afSAntonio Afonso - Name: .note.gnu.gold-version 204ad6690afSAntonio Afonso Type: SHT_NOTE 205ad6690afSAntonio Afonso AddressAlign: 0x0000000000000004 206ad6690afSAntonio Afonso Content: 040000000900000004000000474E5500676F6C6420312E3131000000 207ad6690afSAntonio Afonso - Name: .ARM.attributes 208ad6690afSAntonio Afonso Type: SHT_ARM_ATTRIBUTES 209ad6690afSAntonio Afonso AddressAlign: 0x0000000000000001 210ad6690afSAntonio Afonso Content: '4113000000616561626900010900000006020901' 211ad6690afSAntonio Afonso ... 212ad6690afSAntonio Afonso )"); 213ad6690afSAntonio Afonso ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); 214ad6690afSAntonio Afonso 215ad6690afSAntonio Afonso ModuleSpec spec{FileSpec(ExpectedFile->name())}; 216ad6690afSAntonio Afonso spec.GetSymbolFileSpec().SetFile(ExpectedFile->name(), 217ad6690afSAntonio Afonso FileSpec::Style::native); 218ad6690afSAntonio Afonso auto module_sp = std::make_shared<Module>(spec); 219ad6690afSAntonio Afonso 220ad6690afSAntonio Afonso auto entry_point_addr = module_sp->GetObjectFile()->GetEntryPointAddress(); 221ad6690afSAntonio Afonso ASSERT_TRUE(entry_point_addr.GetOffset() & 1); 222ad6690afSAntonio Afonso // Decrease the offsite by 1 to make it into a breakable address since this 223ad6690afSAntonio Afonso // is Thumb. 224ad6690afSAntonio Afonso entry_point_addr.SetOffset(entry_point_addr.GetOffset() - 1); 225ad6690afSAntonio Afonso ASSERT_EQ(entry_point_addr.GetAddressClass(), 226ad6690afSAntonio Afonso AddressClass::eCodeAlternateISA); 227ad6690afSAntonio Afonso } 228ad6690afSAntonio Afonso 229ad6690afSAntonio Afonso TEST_F(ObjectFileELFTest, GetSymtab_NoSymEntryPointArmAddressClass) { 230ad6690afSAntonio Afonso /* 231ad6690afSAntonio Afonso // nosym-entrypoint-arm.s 232ad6690afSAntonio Afonso _start: 233ad6690afSAntonio Afonso movs r0, #42 234ad6690afSAntonio Afonso movs r7, #1 235ad6690afSAntonio Afonso svc #0 236ad6690afSAntonio Afonso // arm-linux-androideabi-as nosym-entrypoint-arm.s 237ad6690afSAntonio Afonso // -o nosym-entrypoint-arm.o 238ad6690afSAntonio Afonso // arm-linux-androideabi-ld nosym-entrypoint-arm.o 239ad6690afSAntonio Afonso // -o nosym-entrypoint-arm -e 0x8074 -s 240ad6690afSAntonio Afonso */ 241ad6690afSAntonio Afonso auto ExpectedFile = TestFile::fromYaml(R"( 242ad6690afSAntonio Afonso --- !ELF 243ad6690afSAntonio Afonso FileHeader: 244ad6690afSAntonio Afonso Class: ELFCLASS32 245ad6690afSAntonio Afonso Data: ELFDATA2LSB 246ad6690afSAntonio Afonso Type: ET_EXEC 247ad6690afSAntonio Afonso Machine: EM_ARM 248ad6690afSAntonio Afonso Flags: [ EF_ARM_SOFT_FLOAT, EF_ARM_EABI_VER5 ] 249ad6690afSAntonio Afonso Entry: 0x0000000000008074 250ad6690afSAntonio Afonso Sections: 251ad6690afSAntonio Afonso - Name: .text 252ad6690afSAntonio Afonso Type: SHT_PROGBITS 253ad6690afSAntonio Afonso Flags: [ SHF_ALLOC, SHF_EXECINSTR ] 254ad6690afSAntonio Afonso Address: 0x0000000000008074 255ad6690afSAntonio Afonso AddressAlign: 0x0000000000000004 256ad6690afSAntonio Afonso Content: 2A00A0E30170A0E3000000EF 257ad6690afSAntonio Afonso - Name: .data 258ad6690afSAntonio Afonso Type: SHT_PROGBITS 259ad6690afSAntonio Afonso Flags: [ SHF_WRITE, SHF_ALLOC ] 260ad6690afSAntonio Afonso Address: 0x0000000000009000 261ad6690afSAntonio Afonso AddressAlign: 0x0000000000000001 262ad6690afSAntonio Afonso Content: '' 263ad6690afSAntonio Afonso - Name: .bss 264ad6690afSAntonio Afonso Type: SHT_NOBITS 265ad6690afSAntonio Afonso Flags: [ SHF_WRITE, SHF_ALLOC ] 266ad6690afSAntonio Afonso Address: 0x0000000000009000 267ad6690afSAntonio Afonso AddressAlign: 0x0000000000000001 268ad6690afSAntonio Afonso - Name: .note.gnu.gold-version 269ad6690afSAntonio Afonso Type: SHT_NOTE 270ad6690afSAntonio Afonso AddressAlign: 0x0000000000000004 271ad6690afSAntonio Afonso Content: 040000000900000004000000474E5500676F6C6420312E3131000000 272ad6690afSAntonio Afonso - Name: .ARM.attributes 273ad6690afSAntonio Afonso Type: SHT_ARM_ATTRIBUTES 274ad6690afSAntonio Afonso AddressAlign: 0x0000000000000001 275ad6690afSAntonio Afonso Content: '4113000000616561626900010900000006010801' 276ad6690afSAntonio Afonso ... 277ad6690afSAntonio Afonso )"); 278ad6690afSAntonio Afonso ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); 279ad6690afSAntonio Afonso 280ad6690afSAntonio Afonso ModuleSpec spec{FileSpec(ExpectedFile->name())}; 281ad6690afSAntonio Afonso spec.GetSymbolFileSpec().SetFile(ExpectedFile->name(), 282ad6690afSAntonio Afonso FileSpec::Style::native); 283ad6690afSAntonio Afonso auto module_sp = std::make_shared<Module>(spec); 284ad6690afSAntonio Afonso 285ad6690afSAntonio Afonso auto entry_point_addr = module_sp->GetObjectFile()->GetEntryPointAddress(); 286ad6690afSAntonio Afonso ASSERT_EQ(entry_point_addr.GetAddressClass(), AddressClass::eCode); 287ad6690afSAntonio Afonso } 288