[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