summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/llvm/lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp')
-rw-r--r--gnu/llvm/lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp287
1 files changed, 287 insertions, 0 deletions
diff --git a/gnu/llvm/lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp b/gnu/llvm/lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp
new file mode 100644
index 00000000000..01ad2ab4d19
--- /dev/null
+++ b/gnu/llvm/lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp
@@ -0,0 +1,287 @@
+//===-- TestObjectFileELF.cpp -----------------------------------*- C++ -*-===//
+//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
+#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
+#include "TestingSupport/SubsystemRAII.h"
+#include "TestingSupport/TestUtilities.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/Support/Compression.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Program.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Testing/Support/Error.h"
+#include "gtest/gtest.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+class ObjectFileELFTest : public testing::Test {
+ SubsystemRAII<FileSystem, HostInfo, ObjectFileELF, SymbolFileSymtab>
+ subsystems;
+};
+
+TEST_F(ObjectFileELFTest, SectionsResolveConsistently) {
+ auto ExpectedFile = TestFile::fromYaml(R"(
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_X86_64
+ Entry: 0x0000000000400180
+Sections:
+ - Name: .note.gnu.build-id
+ Type: SHT_NOTE
+ Flags: [ SHF_ALLOC ]
+ Address: 0x0000000000400158
+ AddressAlign: 0x0000000000000004
+ Content: 040000001400000003000000474E55003F3EC29E3FD83E49D18C4D49CD8A730CC13117B6
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x0000000000400180
+ AddressAlign: 0x0000000000000010
+ Content: 554889E58B042500106000890425041060005DC3
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x0000000000601000
+ AddressAlign: 0x0000000000000004
+ Content: 2F000000
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x0000000000601004
+ AddressAlign: 0x0000000000000004
+ Size: 0x0000000000000004
+Symbols:
+ - Name: Y
+ Type: STT_OBJECT
+ Section: .data
+ Value: 0x0000000000601000
+ Size: 0x0000000000000004
+ Binding: STB_GLOBAL
+ - Name: _start
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x0000000000400180
+ Size: 0x0000000000000014
+ Binding: STB_GLOBAL
+ - Name: X
+ Type: STT_OBJECT
+ Section: .bss
+ Value: 0x0000000000601004
+ Size: 0x0000000000000004
+ Binding: STB_GLOBAL
+...
+)");
+ ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
+
+ ModuleSpec spec{FileSpec(ExpectedFile->name())};
+ spec.GetSymbolFileSpec().SetFile(ExpectedFile->name(),
+ FileSpec::Style::native);
+ auto module_sp = std::make_shared<Module>(spec);
+ SectionList *list = module_sp->GetSectionList();
+ ASSERT_NE(nullptr, list);
+
+ auto bss_sp = list->FindSectionByName(ConstString(".bss"));
+ ASSERT_NE(nullptr, bss_sp);
+ auto data_sp = list->FindSectionByName(ConstString(".data"));
+ ASSERT_NE(nullptr, data_sp);
+ auto text_sp = list->FindSectionByName(ConstString(".text"));
+ ASSERT_NE(nullptr, text_sp);
+
+ const Symbol *X = module_sp->FindFirstSymbolWithNameAndType(ConstString("X"),
+ eSymbolTypeAny);
+ ASSERT_NE(nullptr, X);
+ EXPECT_EQ(bss_sp, X->GetAddress().GetSection());
+
+ const Symbol *Y = module_sp->FindFirstSymbolWithNameAndType(ConstString("Y"),
+ eSymbolTypeAny);
+ ASSERT_NE(nullptr, Y);
+ EXPECT_EQ(data_sp, Y->GetAddress().GetSection());
+
+ const Symbol *start = module_sp->FindFirstSymbolWithNameAndType(
+ ConstString("_start"), eSymbolTypeAny);
+ ASSERT_NE(nullptr, start);
+ EXPECT_EQ(text_sp, start->GetAddress().GetSection());
+}
+
+// Test that GetModuleSpecifications works on an "atypical" object file which
+// has section headers right after the ELF header (instead of the more common
+// layout where the section headers are at the very end of the object file).
+//
+// Test file generated with yaml2obj (@svn rev 324254) from the following input:
+/*
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_X86_64
+ Entry: 0x00000000004003D0
+Sections:
+ - Name: .note.gnu.build-id
+ Type: SHT_NOTE
+ Flags: [ SHF_ALLOC ]
+ Address: 0x0000000000400274
+ AddressAlign: 0x0000000000000004
+ Content: 040000001400000003000000474E55001B8A73AC238390E32A7FF4AC8EBE4D6A41ECF5C9
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x00000000004003D0
+ AddressAlign: 0x0000000000000010
+ Content: DEADBEEFBAADF00D
+...
+*/
+TEST_F(ObjectFileELFTest, GetModuleSpecifications_EarlySectionHeaders) {
+ std::string SO = GetInputFilePath("early-section-headers.so");
+ ModuleSpecList Specs;
+ ASSERT_EQ(1u, ObjectFile::GetModuleSpecifications(FileSpec(SO), 0, 0, Specs));
+ ModuleSpec Spec;
+ ASSERT_TRUE(Specs.GetModuleSpecAtIndex(0, Spec)) ;
+ UUID Uuid;
+ Uuid.SetFromStringRef("1b8a73ac238390e32a7ff4ac8ebe4d6a41ecf5c9", 20);
+ EXPECT_EQ(Spec.GetUUID(), Uuid);
+}
+
+TEST_F(ObjectFileELFTest, GetSymtab_NoSymEntryPointArmThumbAddressClass) {
+ /*
+ // nosym-entrypoint-arm-thumb.s
+ .thumb_func
+ _start:
+ mov r0, #42
+ mov r7, #1
+ svc #0
+ // arm-linux-androideabi-as nosym-entrypoint-arm-thumb.s
+ // -o nosym-entrypoint-arm-thumb.o
+ // arm-linux-androideabi-ld nosym-entrypoint-arm-thumb.o
+ // -o nosym-entrypoint-arm-thumb -e 0x8075 -s
+ */
+ auto ExpectedFile = TestFile::fromYaml(R"(
+--- !ELF
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_ARM
+ Flags: [ EF_ARM_SOFT_FLOAT, EF_ARM_EABI_VER5 ]
+ Entry: 0x0000000000008075
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x0000000000008074
+ AddressAlign: 0x0000000000000002
+ Content: 2A20012700DF
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x0000000000009000
+ AddressAlign: 0x0000000000000001
+ Content: ''
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x0000000000009000
+ AddressAlign: 0x0000000000000001
+ - Name: .note.gnu.gold-version
+ Type: SHT_NOTE
+ AddressAlign: 0x0000000000000004
+ Content: 040000000900000004000000474E5500676F6C6420312E3131000000
+ - Name: .ARM.attributes
+ Type: SHT_ARM_ATTRIBUTES
+ AddressAlign: 0x0000000000000001
+ Content: '4113000000616561626900010900000006020901'
+...
+)");
+ ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
+
+ ModuleSpec spec{FileSpec(ExpectedFile->name())};
+ spec.GetSymbolFileSpec().SetFile(ExpectedFile->name(),
+ FileSpec::Style::native);
+ auto module_sp = std::make_shared<Module>(spec);
+
+ auto entry_point_addr = module_sp->GetObjectFile()->GetEntryPointAddress();
+ ASSERT_TRUE(entry_point_addr.GetOffset() & 1);
+ // Decrease the offsite by 1 to make it into a breakable address since this
+ // is Thumb.
+ entry_point_addr.SetOffset(entry_point_addr.GetOffset() - 1);
+ ASSERT_EQ(entry_point_addr.GetAddressClass(),
+ AddressClass::eCodeAlternateISA);
+}
+
+TEST_F(ObjectFileELFTest, GetSymtab_NoSymEntryPointArmAddressClass) {
+ /*
+ // nosym-entrypoint-arm.s
+ _start:
+ movs r0, #42
+ movs r7, #1
+ svc #0
+ // arm-linux-androideabi-as nosym-entrypoint-arm.s
+ // -o nosym-entrypoint-arm.o
+ // arm-linux-androideabi-ld nosym-entrypoint-arm.o
+ // -o nosym-entrypoint-arm -e 0x8074 -s
+ */
+ auto ExpectedFile = TestFile::fromYaml(R"(
+--- !ELF
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_ARM
+ Flags: [ EF_ARM_SOFT_FLOAT, EF_ARM_EABI_VER5 ]
+ Entry: 0x0000000000008074
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x0000000000008074
+ AddressAlign: 0x0000000000000004
+ Content: 2A00A0E30170A0E3000000EF
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x0000000000009000
+ AddressAlign: 0x0000000000000001
+ Content: ''
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x0000000000009000
+ AddressAlign: 0x0000000000000001
+ - Name: .note.gnu.gold-version
+ Type: SHT_NOTE
+ AddressAlign: 0x0000000000000004
+ Content: 040000000900000004000000474E5500676F6C6420312E3131000000
+ - Name: .ARM.attributes
+ Type: SHT_ARM_ATTRIBUTES
+ AddressAlign: 0x0000000000000001
+ Content: '4113000000616561626900010900000006010801'
+...
+)");
+ ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
+
+ ModuleSpec spec{FileSpec(ExpectedFile->name())};
+ spec.GetSymbolFileSpec().SetFile(ExpectedFile->name(),
+ FileSpec::Style::native);
+ auto module_sp = std::make_shared<Module>(spec);
+
+ auto entry_point_addr = module_sp->GetObjectFile()->GetEntryPointAddress();
+ ASSERT_EQ(entry_point_addr.GetAddressClass(), AddressClass::eCode);
+} \ No newline at end of file