Skip to content

Commit

Permalink
Unit test for Symtab::InitNameIndexes
Browse files Browse the repository at this point in the history
Summary: In order to exploit the potential of LLVM's new ItaniumPartialDemangler for indexing in LLDB, we expect conceptual changes in the implementation of the InitNameIndexes function. Here is a unit test that aims at covering all relevant code paths in that function.

Reviewers: labath, jingham, JDevlieghere

Reviewed By: JDevlieghere

Subscribers: friss, teemperor, davide, clayborg, erik.pilkington, lldb-commits, mgorny

Differential Revision: https://reviews.llvm.org/D49909

llvm-svn: 338695
  • Loading branch information
weliveindetail committed Aug 2, 2018
1 parent dc1d168 commit 149fede
Show file tree
Hide file tree
Showing 3 changed files with 261 additions and 1 deletion.
12 changes: 12 additions & 0 deletions lldb/unittests/Core/CMakeLists.txt
Expand Up @@ -11,7 +11,19 @@ add_lldb_unittest(LLDBCoreTests
LINK_LIBS
lldbCore
lldbHost
lldbSymbol
lldbPluginObjectFileELF
lldbPluginSymbolVendorELF
lldbUtilityHelpers
LLVMTestingSupport
LINK_COMPONENTS
Support
)

add_dependencies(LLDBCoreTests yaml2obj)
add_definitions(-DYAML2OBJ="$<TARGET_FILE:yaml2obj>")

set(test_inputs
mangled-function-names.yaml
)
add_unittest_inputs(LLDBCoreTests "${test_inputs}")
116 changes: 116 additions & 0 deletions lldb/unittests/Core/Inputs/mangled-function-names.yaml
@@ -0,0 +1,116 @@
--- !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
Content: 554889E58B0425A80000005DC30F1F00
- Name: .anothertext
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
Address: 0x0000000000000010
AddressAlign: 0x0000000000000010
Content: 554889E54883EC20488D0425A8000000C745FC00000000488945F0488B45F08B08894DECE8C7FFFFFF8B4DEC01C189C84883C4205D746573742073747200C3
- Name: .eh_frame
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC ]
Address: 0x0000000000000050
AddressAlign: 0x0000000000000008
Content: 1400000000000000017A5200017810011B0C0708900100001C0000001C00000090FFFFFF0D00000000410E108602430D06000000000000001C0000003C00000080FFFFFF3F00000000410E108602430D0600000000000000
- Name: .data
Type: SHT_PROGBITS
Flags: [ SHF_WRITE, SHF_ALLOC ]
Address: 0x00000000000000A8
AddressAlign: 0x0000000000000004
Content: '01000000'
- Name: .comment
Type: SHT_PROGBITS
Flags: [ SHF_MERGE, SHF_STRINGS ]
AddressAlign: 0x0000000000000001
Content: 5562756E747520636C616E672076657273696F6E20332E352D317562756E74753120287472756E6B2920286261736564206F6E204C4C564D20332E352900
Symbols:
Local:
- Type: STT_SECTION
Section: .text
- Type: STT_SECTION
Section: .anothertext
Value: 0x0000000000000010
- Type: STT_SECTION
Section: .eh_frame
Value: 0x0000000000000050
- Type: STT_SECTION
Section: .data
Value: 0x00000000000000A8
- Type: STT_SECTION
Section: .comment
- Name: /tmp/a.c
Type: STT_FILE
- Type: STT_FILE
Global:
- Name: somedata
Type: STT_OBJECT
Section: .anothertext
Value: 0x0000000000000045
- Name: main
Type: STT_FUNC
Section: .anothertext
Value: 0x0000000000000010
Size: 0x000000000000003F
- Name: _Z3foov
Type: STT_FUNC
Section: .text
Size: 0x000000000000000D
- Name: puts@GLIBC_2.5
Type: STT_FUNC
Section: .text
Size: 0x000000000000000D
- Name: puts@GLIBC_2.6
Type: STT_FUNC
Section: .text
Size: 0x000000000000000D
- Name: _Z5annotv@VERSION3
Type: STT_FUNC
Section: .text
Size: 0x000000000000000D
- Name: _ZN1AC2Ev
Type: STT_FUNC
Section: .text
Size: 0x000000000000000D
- Name: _ZN1AD2Ev
Type: STT_FUNC
Section: .text
Size: 0x000000000000000D
- Name: _ZN1A3barEv
Type: STT_FUNC
Section: .text
Size: 0x000000000000000D
- Name: _ZGVZN4llvm4dbgsEvE7thestrm
Type: STT_FUNC
Section: .text
Size: 0x000000000000000D
- Name: _ZZN4llvm4dbgsEvE7thestrm
Type: STT_FUNC
Section: .text
Size: 0x000000000000000D
- Name: _ZTVN5clang4DeclE
Type: STT_FUNC
Section: .text
Size: 0x000000000000000D
- Name: -[ObjCfoo]
Type: STT_FUNC
Section: .text
Size: 0x000000000000000D
- Name: +[B ObjCbar(WithCategory)]
Type: STT_FUNC
Section: .text
Size: 0x000000000000000D
- Name: _Z12undemangableEvx42
Type: STT_FUNC
Section: .text
Size: 0x000000000000000D
...
134 changes: 133 additions & 1 deletion lldb/unittests/Core/MangledTest.cpp
Expand Up @@ -7,9 +7,21 @@
//
//===----------------------------------------------------------------------===//

#include "gtest/gtest.h"
#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
#include "Plugins/SymbolVendor/ELF/SymbolVendorELF.h"
#include "TestingSupport/TestUtilities.h"

#include "lldb/Core/Mangled.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.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 "gtest/gtest.h"

using namespace lldb;
using namespace lldb_private;
Expand All @@ -36,3 +48,123 @@ TEST(MangledTest, EmptyForInvalidName) {

EXPECT_STREQ("", TheDemangled.GetCString());
}

#define ASSERT_NO_ERROR(x) \
if (std::error_code ASSERT_NO_ERROR_ec = x) { \
llvm::SmallString<128> MessageStorage; \
llvm::raw_svector_ostream Message(MessageStorage); \
Message << #x ": did not return errc::success.\n" \
<< "error number: " << ASSERT_NO_ERROR_ec.value() << "\n" \
<< "error message: " << ASSERT_NO_ERROR_ec.message() << "\n"; \
GTEST_FATAL_FAILURE_(MessageStorage.c_str()); \
} else { \
}

TEST(MangledTest, NameIndexes_FindFunctionSymbols) {
HostInfo::Initialize();
ObjectFileELF::Initialize();
SymbolVendorELF::Initialize();

std::string Yaml = GetInputFilePath("mangled-function-names.yaml");
llvm::SmallString<128> Obj;
ASSERT_NO_ERROR(llvm::sys::fs::createTemporaryFile(
"mangled-function-names-%%%%%%", "obj", Obj));

llvm::FileRemover Deleter(Obj);
llvm::StringRef Args[] = {YAML2OBJ, Yaml};
llvm::StringRef ObjRef = Obj;
const llvm::Optional<llvm::StringRef> redirects[] = {llvm::None, ObjRef,
llvm::None};
ASSERT_EQ(0,
llvm::sys::ExecuteAndWait(YAML2OBJ, Args, llvm::None, redirects));
uint64_t Size;
ASSERT_NO_ERROR(llvm::sys::fs::file_size(Obj, Size));
ASSERT_GT(Size, 0u);

ModuleSpec Spec{FileSpec(Obj, false)};
Spec.GetSymbolFileSpec().SetFile(Obj, false, FileSpec::Style::native);
auto M = std::make_shared<Module>(Spec);

auto Count = [M](const char *Name, FunctionNameType Type) -> int {
SymbolContextList SymList;
return M->FindFunctionSymbols(ConstString(Name), Type, SymList);
};

// 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));

SymbolVendorELF::Terminate();
ObjectFileELF::Terminate();
HostInfo::Terminate();
}

0 comments on commit 149fede

Please sign in to comment.