Skip to content

Commit

Permalink
Add missing GoLanguageRuntime files.
Browse files Browse the repository at this point in the history
llvm-svn: 249459
  • Loading branch information
Ryan Brown committed Oct 6, 2015
1 parent 05e9cb5 commit 2b56f86
Show file tree
Hide file tree
Showing 6 changed files with 467 additions and 0 deletions.
5 changes: 5 additions & 0 deletions lldb/source/Plugins/LanguageRuntime/Go/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
set(LLVM_NO_RTTI 1)

add_lldb_library(lldbPluginLanguageRuntimeGo
GoLanguageRuntime.cpp
)
238 changes: 238 additions & 0 deletions lldb/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
//===-- GoLanguageRuntime.cpp --------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "GoLanguageRuntime.h"

#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectMemory.h"
#include "lldb/Symbol/GoASTContext.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "llvm/ADT/Twine.h"

#include <vector>

using namespace lldb;
using namespace lldb_private;

namespace {
ValueObjectSP GetChild(ValueObject& obj, const char* name, bool dereference = true) {
ConstString name_const_str(name);
ValueObjectSP result = obj.GetChildMemberWithName(name_const_str, true);
if (dereference && result && result->IsPointerType()) {
Error err;
result = result->Dereference(err);
if (err.Fail())
result.reset();
}
return result;
}

ConstString ReadString(ValueObject& str, Process* process) {
ConstString result;
ValueObjectSP data = GetChild(str, "str", false);
ValueObjectSP len = GetChild(str, "len");
if (len && data)
{
Error err;
lldb::addr_t addr = data->GetPointerValue();
if (addr == LLDB_INVALID_ADDRESS)
return result;
uint64_t byte_size = len->GetValueAsUnsigned(0);
char* buf = new char[byte_size + 1];
buf[byte_size] = 0;
size_t bytes_read = process->ReadMemory (addr,
buf,
byte_size,
err);
if (!(err.Fail() || bytes_read != byte_size))
result = ConstString(buf, bytes_read);
delete[] buf;
}
return result;
}

ConstString
ReadTypeName(ValueObjectSP type, Process* process)
{
if (ValueObjectSP uncommon = GetChild(*type, "x"))
{
ValueObjectSP name = GetChild(*uncommon, "name");
ValueObjectSP package = GetChild(*uncommon, "pkgpath");
if (name && name->GetPointerValue() != 0 && package && package->GetPointerValue() != 0)
{
ConstString package_const_str = ReadString(*package, process);
ConstString name_const_str = ReadString(*name, process);
if (package_const_str.GetLength() == 0)
return name_const_str;
return ConstString((package_const_str.GetStringRef() + "." + name_const_str.GetStringRef()).str());
}
}
ValueObjectSP name = GetChild(*type, "_string");
if (name)
return ReadString(*name, process);
return ConstString("");
}

CompilerType
LookupRuntimeType(ValueObjectSP type, ExecutionContext* exe_ctx, bool* is_direct)
{
uint8_t kind = GetChild(*type, "kind")->GetValueAsUnsigned(0);
*is_direct = GoASTContext::IsDirectIface(kind);
if (GoASTContext::IsPointerKind(kind))
{
CompilerType type_ptr = type->GetCompilerType().GetPointerType();
Error err;
ValueObjectSP elem = type->CreateValueObjectFromAddress("elem", type->GetAddressOf() + type->GetByteSize(), *exe_ctx, type_ptr)->Dereference(err);
if (err.Fail())
return CompilerType();
bool tmp_direct;
return LookupRuntimeType(elem, exe_ctx, &tmp_direct).GetPointerType();
}
Target *target = exe_ctx->GetTargetPtr();
Process *process = exe_ctx->GetProcessPtr();

ConstString const_typename = ReadTypeName(type, process);
if (const_typename.GetLength() == 0)
return CompilerType();

SymbolContext sc;
TypeList type_list;
uint32_t num_matches = target->GetImages().FindTypes (sc,
const_typename,
false,
2,
type_list);
if (num_matches > 0) {
return type_list.GetTypeAtIndex(0)->GetFullCompilerType();
}
return CompilerType();
}

}

bool
GoLanguageRuntime::CouldHaveDynamicValue (ValueObject &in_value)
{
return GoASTContext::IsGoInterface(in_value.GetCompilerType());
}

bool
GoLanguageRuntime::GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name, Address &dynamic_address,
Value::ValueType &value_type)
{
value_type = Value::eValueTypeScalar;
class_type_or_name.Clear();
if (CouldHaveDynamicValue (in_value))
{
Error err;
ValueObjectSP iface = in_value.GetStaticValue();
ValueObjectSP data_sp = GetChild(*iface, "data", false);
if (!data_sp)
return false;

if (ValueObjectSP tab = GetChild(*iface, "tab"))
iface = tab;
ValueObjectSP type = GetChild(*iface, "_type");
if (!type)
{
return false;
}

bool direct;
ExecutionContext exe_ctx (in_value.GetExecutionContextRef());
CompilerType final_type = LookupRuntimeType(type, &exe_ctx, &direct);
if (!final_type)
return false;
if (direct)
{
class_type_or_name.SetCompilerType(final_type);
}
else
{
// TODO: implement reference types or fix caller to support dynamic types that aren't pointers
// so we don't have to introduce this extra pointer.
class_type_or_name.SetCompilerType(final_type.GetPointerType());
}

dynamic_address.SetLoadAddress(data_sp->GetPointerValue(), exe_ctx.GetTargetPtr());

return true;
}
return false;
}

TypeAndOrName
GoLanguageRuntime::FixUpDynamicType(const TypeAndOrName &type_and_or_name, ValueObject &static_value)
{
return type_and_or_name;
}

//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
LanguageRuntime *
GoLanguageRuntime::CreateInstance (Process *process, lldb::LanguageType language)
{
if (language == eLanguageTypeGo)
return new GoLanguageRuntime (process);
else
return NULL;
}

void
GoLanguageRuntime::Initialize()
{
PluginManager::RegisterPlugin (GetPluginNameStatic(),
"Go Language Runtime",
CreateInstance);
}

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

lldb_private::ConstString
GoLanguageRuntime::GetPluginNameStatic()
{
static ConstString g_name("golang");
return g_name;
}

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

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

93 changes: 93 additions & 0 deletions lldb/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
//===-- GoLanguageRuntime.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_GoLanguageRuntime_h_
#define liblldb_GoLanguageRuntime_h_

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-private.h"
#include "lldb/Breakpoint/BreakpointResolver.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Core/Value.h"

namespace lldb_private {

class GoLanguageRuntime :
public lldb_private::LanguageRuntime
{
public:
~GoLanguageRuntime() { }

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

bool
GetObjectDescription(Stream &str, ValueObject &object) override
{
// TODO(ribrdb): Maybe call String() method?
return false;
}

bool
GetObjectDescription(Stream &str, Value &value, ExecutionContextScope *exe_scope) override
{
return false;
}

bool GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name, Address &address,
Value::ValueType &value_type) override;

bool CouldHaveDynamicValue(ValueObject &in_value) override;

lldb::BreakpointResolverSP
CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp) override
{
return lldb::BreakpointResolverSP();
}

TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name, ValueObject &static_value) override;

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

static void
Terminate();

static lldb_private::LanguageRuntime *
CreateInstance (Process *process, lldb::LanguageType language);

static lldb_private::ConstString
GetPluginNameStatic();

//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
virtual lldb_private::ConstString
GetPluginName();

virtual uint32_t
GetPluginVersion();

private:
GoLanguageRuntime(Process *process) : lldb_private::LanguageRuntime(process) { } // Call CreateInstance instead.
};

} // namespace lldb_private

#endif // liblldb_GoLanguageRuntime_h_
14 changes: 14 additions & 0 deletions lldb/source/Plugins/LanguageRuntime/Go/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
##===- Source/Plugins/LangRuntime/Go/Makefile ----*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##

LLDB_LEVEL := ../../../..
LIBRARYNAME := lldbPluginLanguageRuntimeGo
BUILD_ARCHIVE = 1

include $(LLDB_LEVEL)/Makefile
Loading

0 comments on commit 2b56f86

Please sign in to comment.