[Lldb-commits] [lldb] r249459 - Add missing GoLanguageRuntime files.
Ryan Brown via lldb-commits
lldb-commits at lists.llvm.org
Tue Oct 6 13:31:09 PDT 2015
Author: ribrdb
Date: Tue Oct 6 15:31:08 2015
New Revision: 249459
URL: http://llvm.org/viewvc/llvm-project?rev=249459&view=rev
Log:
Add missing GoLanguageRuntime files.
Added:
lldb/trunk/source/Plugins/LanguageRuntime/Go/
lldb/trunk/source/Plugins/LanguageRuntime/Go/CMakeLists.txt
lldb/trunk/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp
lldb/trunk/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.h
lldb/trunk/source/Plugins/LanguageRuntime/Go/Makefile
lldb/trunk/test/lang/go/runtime/
lldb/trunk/test/lang/go/runtime/TestGoASTContext.py
lldb/trunk/test/lang/go/runtime/main.go
Added: lldb/trunk/source/Plugins/LanguageRuntime/Go/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/Go/CMakeLists.txt?rev=249459&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/Go/CMakeLists.txt (added)
+++ lldb/trunk/source/Plugins/LanguageRuntime/Go/CMakeLists.txt Tue Oct 6 15:31:08 2015
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginLanguageRuntimeGo
+ GoLanguageRuntime.cpp
+ )
Added: lldb/trunk/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp?rev=249459&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp (added)
+++ lldb/trunk/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp Tue Oct 6 15:31:08 2015
@@ -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;
+}
+
Added: lldb/trunk/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.h?rev=249459&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.h (added)
+++ lldb/trunk/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.h Tue Oct 6 15:31:08 2015
@@ -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_
Added: lldb/trunk/source/Plugins/LanguageRuntime/Go/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/Go/Makefile?rev=249459&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/Go/Makefile (added)
+++ lldb/trunk/source/Plugins/LanguageRuntime/Go/Makefile Tue Oct 6 15:31:08 2015
@@ -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
Added: lldb/trunk/test/lang/go/runtime/TestGoASTContext.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/go/runtime/TestGoASTContext.py?rev=249459&view=auto
==============================================================================
--- lldb/trunk/test/lang/go/runtime/TestGoASTContext.py (added)
+++ lldb/trunk/test/lang/go/runtime/TestGoASTContext.py Tue Oct 6 15:31:08 2015
@@ -0,0 +1,79 @@
+"""Test the go dynamic type handling."""
+
+import os, time
+import unittest2
+import lldb
+import lldbutil
+from lldbtest import *
+
+class TestGoLanguageRuntime(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @python_api_test
+ @skipIfRemote # Not remote test suite ready
+ @skipUnlessGoInstalled
+ def test_with_dsym_and_python_api(self):
+ """Test GoASTContext dwarf parsing."""
+ self.buildGo()
+ self.launchProcess()
+ self.go_interface_types()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line numbers to break inside main().
+ self.main_source = "main.go"
+ self.break_line1 = line_number(self.main_source, '// Set breakpoint 1')
+ self.break_line2 = line_number(self.main_source, '// Set breakpoint 2')
+
+
+ def launchProcess(self):
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ bpt1 = target.BreakpointCreateByLocation(self.main_source, self.break_line1)
+ self.assertTrue(bpt1, VALID_BREAKPOINT)
+ bpt2 = target.BreakpointCreateByLocation(self.main_source, self.break_line2)
+ self.assertTrue(bpt2, VALID_BREAKPOINT)
+
+ # Now launch the process, and do not stop at entry point.
+ process = target.LaunchSimple (None, None, self.get_process_working_directory())
+
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # The stop reason of the thread should be breakpoint.
+ thread_list = lldbutil.get_threads_stopped_at_breakpoint (process, bpt1)
+
+ # Make sure we stopped at the first breakpoint.
+ self.assertTrue (len(thread_list) != 0, "No thread stopped at our breakpoint.")
+ self.assertTrue (len(thread_list) == 1, "More than one thread stopped at our breakpoint.")
+
+ frame = thread_list[0].GetFrameAtIndex(0)
+ self.assertTrue (frame, "Got a valid frame 0 frame.")
+
+ def go_interface_types(self):
+ f = self.frame()
+ v = f.FindVariable("a", lldb.eDynamicCanRunTarget)
+ self.assertEqual("*int", v.GetType().name)
+ self.assertEqual(1, v.Dereference().GetValueAsSigned())
+ v = f.FindVariable("b", lldb.eDynamicCanRunTarget)
+ self.assertEqual("*float64", v.GetType().name)
+ err = lldb.SBError()
+ self.assertEqual(2.0, v.Dereference().GetData().GetDouble(err, 0))
+ v = f.FindVariable("c", lldb.eDynamicCanRunTarget)
+ self.assertEqual("*main.SomeFooer", v.GetType().name)
+ self.assertEqual(9, v.Dereference().GetChildAtIndex(0).GetValueAsSigned())
+ v = f.FindVariable("d", lldb.eDynamicCanRunTarget)
+ self.assertEqual("*main.AnotherFooer", v.GetType().name)
+ self.assertEqual(-1, v.Dereference().GetChildAtIndex(0).GetValueAsSigned())
+ self.assertEqual(-2, v.Dereference().GetChildAtIndex(1).GetValueAsSigned())
+ self.assertEqual(-3, v.Dereference().GetChildAtIndex(2).GetValueAsSigned())
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Added: lldb/trunk/test/lang/go/runtime/main.go
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/go/runtime/main.go?rev=249459&view=auto
==============================================================================
--- lldb/trunk/test/lang/go/runtime/main.go (added)
+++ lldb/trunk/test/lang/go/runtime/main.go Tue Oct 6 15:31:08 2015
@@ -0,0 +1,38 @@
+package main
+
+import "fmt"
+
+type Fooer interface {
+ Foo() int
+}
+
+type SomeFooer struct {
+ val int
+}
+
+func (s SomeFooer) Foo() int {
+ return s.val
+}
+
+type AnotherFooer struct {
+ a, b, c int
+}
+
+func (s AnotherFooer) Foo() int {
+ return s.a
+}
+
+
+func printEface(a, b, c, d interface{}) {
+ fmt.Println(a, b, c, d) // Set breakpoint 1
+}
+
+func printIface(a, b Fooer) {
+ fmt.Println(a, b) // Set breakpoint 2
+}
+func main() {
+ sf := SomeFooer{9}
+ af := AnotherFooer{-1, -2, -3}
+ printEface(1,2.0, sf, af)
+ printIface(sf, af)
+}
\ No newline at end of file
More information about the lldb-commits
mailing list