Skip to content
This repository has been archived by the owner on Apr 23, 2020. It is now read-only.

Support demangling for D symbols via dlopen #3

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion include/lldb/Core/Mangled.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ class Mangled {
enum ManglingScheme {
eManglingSchemeNone = 0,
eManglingSchemeMSVC,
eManglingSchemeItanium
eManglingSchemeItanium,
eManglingSchemeD
};

//----------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions source/Core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ add_lldb_library(lldbCore
lldbPluginProcessUtility
lldbPluginCPlusPlusLanguage
lldbPluginObjCLanguage
lldbPluginDLanguage
lldbPluginObjectFileJIT
${LLDB_CURSES_LIBS}

Expand Down
9 changes: 9 additions & 0 deletions source/Core/Mangled.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
#include "Plugins/Language/ObjC/ObjCLanguage.h"
#include "Plugins/Language/D/DLanguage.h"

#include "llvm/ADT/StringRef.h" // for StringRef
#include "llvm/Support/Compiler.h" // for LLVM_PRETT...
Expand Down Expand Up @@ -74,6 +75,8 @@ static inline Mangled::ManglingScheme cstring_mangling_scheme(const char *s) {
return Mangled::eManglingSchemeMSVC;
if (s[0] == '_' && s[1] == 'Z')
return Mangled::eManglingSchemeItanium;
if (DLanguage::IsDMangledName(s))
return Mangled::eManglingSchemeD;
}
return Mangled::eManglingSchemeNone;
}
Expand Down Expand Up @@ -322,6 +325,10 @@ Mangled::GetDemangledName(lldb::LanguageType language) const {
}
break;
}
case eManglingSchemeD: {
demangled_name = DLanguage::demangle(m_mangled);
break;
}
case eManglingSchemeNone:
break;
}
Expand Down Expand Up @@ -431,6 +438,8 @@ lldb::LanguageType Mangled::GuessLanguage() const {
return lldb::eLanguageTypeC_plus_plus;
else if (ObjCLanguage::IsPossibleObjCMethodName(mangled_name))
return lldb::eLanguageTypeObjC;
else if (DLanguage::IsDMangledName(mangled_name))
return lldb::eLanguageTypeD;
}
} else {
// ObjC names aren't really mangled, so they won't necessarily be in the
Expand Down
1 change: 1 addition & 0 deletions source/Plugins/Language/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ add_subdirectory(Java)
add_subdirectory(ObjC)
add_subdirectory(ObjCPlusPlus)
add_subdirectory(OCaml)
add_subdirectory(D)
7 changes: 7 additions & 0 deletions source/Plugins/Language/D/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
add_lldb_library(lldbPluginDLanguage PLUGIN
DLanguage.cpp

LINK_LIBS
lldbCore
lldbTarget
)
123 changes: 123 additions & 0 deletions source/Plugins/Language/D/DLanguage.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
//===-- DLanguage.cpp
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "DLanguage.h"

#include "lldb/Core/PluginManager.h"
#include "lldb/Utility/ConstString.h"

#include <dlfcn.h>

using namespace lldb;
using namespace lldb_private;

char* lldbd_demangle(size_t length, const char* mangled);
void d_initialize();

// TODO:MOVE
struct SharedLib{
void* handle;
const char* libraryFile;
int flagDefault = RTLD_LOCAL | RTLD_LAZY;
SharedLib(){
}

~SharedLib(){
release();
}

// Return true of `dlopen` succeeded
bool open(const char* libraryFile, int flag)
{
release();
this->libraryFile = libraryFile;
handle = dlopen(libraryFile, flag);
if (handle)
return true;
return false;
}

void release()
{
// if(handle) seems needed: https://stackoverflow.com/questions/11412943is-it-safe-to-call-dlclosenull
if (handle)
dlclose(handle);
}

template<typename Fun>
Fun* getFun(const char*symbol)
{
assert(handle);
return reinterpret_cast<Fun*>(dlsym(handle, symbol));
}
};

void DLanguage::Initialize() {
PluginManager::RegisterPlugin(GetPluginNameStatic(), "D Language",
CreateInstance);
}

void DLanguage::Terminate() {
PluginManager::UnregisterPlugin(CreateInstance);
}

lldb_private::ConstString DLanguage::GetPluginNameStatic() {
static ConstString g_name("D");
return g_name;
}

//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
lldb_private::ConstString DLanguage::GetPluginName() {
return GetPluginNameStatic();
}

uint32_t DLanguage::GetPluginVersion() { return 1; }

//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
Language *DLanguage::CreateInstance(lldb::LanguageType language) {
switch (language) {
case lldb::eLanguageTypeD:
return new DLanguage();
default:
return nullptr;
}
}

char* DLanguage::demangle(const ConstString &mangled) {
auto len=mangled.GetLength();
auto s=mangled.GetCString();
// IMPROVE
static auto fun=[]() -> decltype(lldbd_demangle)*{
auto lib2=new SharedLib();
// TODO: so vs dylib
auto file="liblldbdplugin.dylib";
if(!lib2->open(file, lib2->flagDefault)){
return nullptr;
}

auto fun0=lib2->getFun<decltype(d_initialize)>("d_initialize");
(*fun0)();

auto fun=lib2->getFun<decltype(lldbd_demangle)>("lldbd_demangle");
assert(fun);
return fun;
}();
if(!fun) return nullptr;
return (*fun)(len, s);
}

bool DLanguage::IsDMangledName(const char *name) {
if (name == nullptr)
return false;
return (name[0] != '\0' && name[0] == '_' && name[1] == 'D');
}
57 changes: 57 additions & 0 deletions source/Plugins/Language/D/DLanguage.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//===-- DLanguage.h ----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_DLanguage_h_
#define liblldb_DLanguage_h_

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Target/Language.h"
#include "lldb/lldb-private.h"

namespace lldb_private {

class DLanguage : public Language {
public:
DLanguage() = default;

~DLanguage() override = default;

lldb::LanguageType GetLanguageType() const override {
return lldb::eLanguageTypeD;
}

//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
static void Initialize();

static void Terminate();

static lldb_private::Language *CreateInstance(lldb::LanguageType language);

static lldb_private::ConstString GetPluginNameStatic();

static bool IsDMangledName(const char *name);
// TODO: not static?
static char* demangle(const ConstString &mangled);

//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
ConstString GetPluginName() override;

uint32_t GetPluginVersion() override;
};

} // namespace lldb_private

#endif // liblldb_DLanguage_h_