Summary: This patch extends the ModuleSpec class to include a DataBufferSP which contains the module data. If this data is provided, LLDB won't try to hit the filesystem to create the Module, but use only the data stored in the ModuleSpec. Reviewers: labath, espindola Subscribers: emaste, MaskRay, lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D83512
250 lines
9.2 KiB
C++
250 lines
9.2 KiB
C++
//===-- MangledTest.cpp ---------------------------------------------------===//
|
|
//
|
|
// 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/Mangled.h"
|
|
#include "lldb/Core/Module.h"
|
|
#include "lldb/Core/ModuleSpec.h"
|
|
#include "lldb/Host/FileSystem.h"
|
|
#include "lldb/Host/HostInfo.h"
|
|
#include "lldb/Symbol/SymbolContext.h"
|
|
|
|
#include "llvm/Support/FileUtilities.h"
|
|
#include "llvm/Support/Path.h"
|
|
#include "llvm/Support/Program.h"
|
|
#include "llvm/Testing/Support/Error.h"
|
|
|
|
#include "gtest/gtest.h"
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
TEST(MangledTest, ResultForValidName) {
|
|
ConstString MangledName("_ZN1a1b1cIiiiEEvm");
|
|
Mangled TheMangled(MangledName);
|
|
ConstString TheDemangled = TheMangled.GetDemangledName();
|
|
|
|
ConstString ExpectedResult("void a::b::c<int, int, int>(unsigned long)");
|
|
EXPECT_STREQ(ExpectedResult.GetCString(), TheDemangled.GetCString());
|
|
}
|
|
|
|
TEST(MangledTest, ResultForBlockInvocation) {
|
|
ConstString MangledName("___Z1fU13block_pointerFviE_block_invoke");
|
|
Mangled TheMangled(MangledName);
|
|
ConstString TheDemangled = TheMangled.GetDemangledName();
|
|
|
|
ConstString ExpectedResult(
|
|
"invocation function for block in f(void (int) block_pointer)");
|
|
EXPECT_STREQ(ExpectedResult.GetCString(), TheDemangled.GetCString());
|
|
}
|
|
|
|
TEST(MangledTest, EmptyForInvalidName) {
|
|
ConstString MangledName("_ZN1a1b1cmxktpEEvm");
|
|
Mangled TheMangled(MangledName);
|
|
ConstString TheDemangled = TheMangled.GetDemangledName();
|
|
|
|
EXPECT_STREQ("", TheDemangled.GetCString());
|
|
}
|
|
|
|
TEST(MangledTest, NameIndexes_FindFunctionSymbols) {
|
|
SubsystemRAII<FileSystem, HostInfo, ObjectFileELF, SymbolFileSymtab>
|
|
subsystems;
|
|
|
|
auto ExpectedFile = TestFile::fromYaml(R"(
|
|
--- !ELF
|
|
FileHeader:
|
|
Class: ELFCLASS64
|
|
Data: ELFDATA2LSB
|
|
Type: ET_EXEC
|
|
Machine: EM_X86_64
|
|
Sections:
|
|
- Name: .text
|
|
Type: SHT_PROGBITS
|
|
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
|
AddressAlign: 0x0000000000000010
|
|
Size: 0x20
|
|
- Name: .anothertext
|
|
Type: SHT_PROGBITS
|
|
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
|
Address: 0x0000000000000010
|
|
AddressAlign: 0x0000000000000010
|
|
Size: 0x40
|
|
- Name: .data
|
|
Type: SHT_PROGBITS
|
|
Flags: [ SHF_WRITE, SHF_ALLOC ]
|
|
Address: 0x00000000000000A8
|
|
AddressAlign: 0x0000000000000004
|
|
Content: '01000000'
|
|
Symbols:
|
|
- Name: somedata
|
|
Type: STT_OBJECT
|
|
Section: .anothertext
|
|
Value: 0x0000000000000045
|
|
Binding: STB_GLOBAL
|
|
- Name: main
|
|
Type: STT_FUNC
|
|
Section: .anothertext
|
|
Value: 0x0000000000000010
|
|
Size: 0x000000000000003F
|
|
Binding: STB_GLOBAL
|
|
- Name: _Z3foov
|
|
Type: STT_FUNC
|
|
Section: .text
|
|
Size: 0x000000000000000D
|
|
Binding: STB_GLOBAL
|
|
- Name: puts@GLIBC_2.5
|
|
Type: STT_FUNC
|
|
Section: .text
|
|
Size: 0x000000000000000D
|
|
Binding: STB_GLOBAL
|
|
- Name: puts@GLIBC_2.6
|
|
Type: STT_FUNC
|
|
Section: .text
|
|
Size: 0x000000000000000D
|
|
Binding: STB_GLOBAL
|
|
- Name: _Z5annotv@VERSION3
|
|
Type: STT_FUNC
|
|
Section: .text
|
|
Size: 0x000000000000000D
|
|
Binding: STB_GLOBAL
|
|
- Name: _ZN1AC2Ev
|
|
Type: STT_FUNC
|
|
Section: .text
|
|
Size: 0x000000000000000D
|
|
Binding: STB_GLOBAL
|
|
- Name: _ZN1AD2Ev
|
|
Type: STT_FUNC
|
|
Section: .text
|
|
Size: 0x000000000000000D
|
|
Binding: STB_GLOBAL
|
|
- Name: _ZN1A3barEv
|
|
Type: STT_FUNC
|
|
Section: .text
|
|
Size: 0x000000000000000D
|
|
Binding: STB_GLOBAL
|
|
- Name: _ZGVZN4llvm4dbgsEvE7thestrm
|
|
Type: STT_FUNC
|
|
Section: .text
|
|
Size: 0x000000000000000D
|
|
Binding: STB_GLOBAL
|
|
- Name: _ZZN4llvm4dbgsEvE7thestrm
|
|
Type: STT_FUNC
|
|
Section: .text
|
|
Size: 0x000000000000000D
|
|
Binding: STB_GLOBAL
|
|
- Name: _ZTVN5clang4DeclE
|
|
Type: STT_FUNC
|
|
Section: .text
|
|
Size: 0x000000000000000D
|
|
Binding: STB_GLOBAL
|
|
- Name: -[ObjCfoo]
|
|
Type: STT_FUNC
|
|
Section: .text
|
|
Size: 0x000000000000000D
|
|
Binding: STB_GLOBAL
|
|
- Name: +[B ObjCbar(WithCategory)]
|
|
Type: STT_FUNC
|
|
Section: .text
|
|
Size: 0x000000000000000D
|
|
Binding: STB_GLOBAL
|
|
- Name: _Z12undemangableEvx42
|
|
Type: STT_FUNC
|
|
Section: .text
|
|
Size: 0x000000000000000D
|
|
Binding: STB_GLOBAL
|
|
...
|
|
)");
|
|
ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
|
|
|
|
auto M = std::make_shared<Module>(ExpectedFile->moduleSpec());
|
|
|
|
auto Count = [M](const char *Name, FunctionNameType Type) -> int {
|
|
SymbolContextList SymList;
|
|
M->FindFunctionSymbols(ConstString(Name), Type, SymList);
|
|
return SymList.GetSize();
|
|
};
|
|
|
|
// Unmangled
|
|
EXPECT_EQ(1, Count("main", eFunctionNameTypeFull));
|
|
EXPECT_EQ(1, Count("main", eFunctionNameTypeBase));
|
|
EXPECT_EQ(0, Count("main", eFunctionNameTypeMethod));
|
|
|
|
// Itanium mangled
|
|
EXPECT_EQ(1, Count("_Z3foov", eFunctionNameTypeFull));
|
|
EXPECT_EQ(1, Count("_Z3foov", eFunctionNameTypeBase));
|
|
EXPECT_EQ(1, Count("foo", eFunctionNameTypeBase));
|
|
EXPECT_EQ(0, Count("foo", eFunctionNameTypeMethod));
|
|
|
|
// Unmangled with linker annotation
|
|
EXPECT_EQ(1, Count("puts@GLIBC_2.5", eFunctionNameTypeFull));
|
|
EXPECT_EQ(1, Count("puts@GLIBC_2.6", eFunctionNameTypeFull));
|
|
EXPECT_EQ(2, Count("puts", eFunctionNameTypeFull));
|
|
EXPECT_EQ(2, Count("puts", eFunctionNameTypeBase));
|
|
EXPECT_EQ(0, Count("puts", eFunctionNameTypeMethod));
|
|
|
|
// Itanium mangled with linker annotation
|
|
EXPECT_EQ(1, Count("_Z5annotv@VERSION3", eFunctionNameTypeFull));
|
|
EXPECT_EQ(1, Count("_Z5annotv", eFunctionNameTypeFull));
|
|
EXPECT_EQ(1, Count("_Z5annotv", eFunctionNameTypeBase));
|
|
EXPECT_EQ(0, Count("annot", eFunctionNameTypeBase));
|
|
EXPECT_EQ(0, Count("annot", eFunctionNameTypeMethod));
|
|
|
|
// Itanium mangled ctor A::A()
|
|
EXPECT_EQ(1, Count("_ZN1AC2Ev", eFunctionNameTypeFull));
|
|
EXPECT_EQ(1, Count("_ZN1AC2Ev", eFunctionNameTypeBase));
|
|
EXPECT_EQ(1, Count("A", eFunctionNameTypeMethod));
|
|
EXPECT_EQ(0, Count("A", eFunctionNameTypeBase));
|
|
|
|
// Itanium mangled dtor A::~A()
|
|
EXPECT_EQ(1, Count("_ZN1AD2Ev", eFunctionNameTypeFull));
|
|
EXPECT_EQ(1, Count("_ZN1AD2Ev", eFunctionNameTypeBase));
|
|
EXPECT_EQ(1, Count("~A", eFunctionNameTypeMethod));
|
|
EXPECT_EQ(0, Count("~A", eFunctionNameTypeBase));
|
|
|
|
// Itanium mangled method A::bar()
|
|
EXPECT_EQ(1, Count("_ZN1A3barEv", eFunctionNameTypeFull));
|
|
EXPECT_EQ(1, Count("_ZN1A3barEv", eFunctionNameTypeBase));
|
|
EXPECT_EQ(1, Count("bar", eFunctionNameTypeMethod));
|
|
EXPECT_EQ(0, Count("bar", eFunctionNameTypeBase));
|
|
|
|
// Itanium mangled names that are explicitly excluded from parsing
|
|
EXPECT_EQ(1, Count("_ZGVZN4llvm4dbgsEvE7thestrm", eFunctionNameTypeFull));
|
|
EXPECT_EQ(1, Count("_ZGVZN4llvm4dbgsEvE7thestrm", eFunctionNameTypeBase));
|
|
EXPECT_EQ(0, Count("dbgs", eFunctionNameTypeMethod));
|
|
EXPECT_EQ(0, Count("dbgs", eFunctionNameTypeBase));
|
|
EXPECT_EQ(1, Count("_ZZN4llvm4dbgsEvE7thestrm", eFunctionNameTypeFull));
|
|
EXPECT_EQ(1, Count("_ZZN4llvm4dbgsEvE7thestrm", eFunctionNameTypeBase));
|
|
EXPECT_EQ(0, Count("dbgs", eFunctionNameTypeMethod));
|
|
EXPECT_EQ(0, Count("dbgs", eFunctionNameTypeBase));
|
|
EXPECT_EQ(1, Count("_ZTVN5clang4DeclE", eFunctionNameTypeFull));
|
|
EXPECT_EQ(1, Count("_ZTVN5clang4DeclE", eFunctionNameTypeBase));
|
|
EXPECT_EQ(0, Count("Decl", eFunctionNameTypeMethod));
|
|
EXPECT_EQ(0, Count("Decl", eFunctionNameTypeBase));
|
|
|
|
// ObjC mangled static
|
|
EXPECT_EQ(1, Count("-[ObjCfoo]", eFunctionNameTypeFull));
|
|
EXPECT_EQ(1, Count("-[ObjCfoo]", eFunctionNameTypeBase));
|
|
EXPECT_EQ(0, Count("ObjCfoo", eFunctionNameTypeMethod));
|
|
|
|
// ObjC mangled method with category
|
|
EXPECT_EQ(1, Count("+[B ObjCbar(WithCategory)]", eFunctionNameTypeFull));
|
|
EXPECT_EQ(1, Count("+[B ObjCbar(WithCategory)]", eFunctionNameTypeBase));
|
|
EXPECT_EQ(0, Count("ObjCbar", eFunctionNameTypeMethod));
|
|
|
|
// Invalid things: unable to decode but still possible to find by full name
|
|
EXPECT_EQ(1, Count("_Z12undemangableEvx42", eFunctionNameTypeFull));
|
|
EXPECT_EQ(1, Count("_Z12undemangableEvx42", eFunctionNameTypeBase));
|
|
EXPECT_EQ(0, Count("_Z12undemangableEvx42", eFunctionNameTypeMethod));
|
|
EXPECT_EQ(0, Count("undemangable", eFunctionNameTypeBase));
|
|
EXPECT_EQ(0, Count("undemangable", eFunctionNameTypeMethod));
|
|
}
|