Hi people,

As some of you are already aware I have been working towards a lldb port
which debugs CSRs Kalimba chips. I have recently added a PlatformKalimba
plugin. With some slight tweaking to the .note parsing section of the
ObjectFileELF and a few Makefiles, my lldb build now lists "kalimba" as
an available Platform and associates any kalimba binary Targets with this Platform.

Now I do not currently have submit access for lldb (though we are
planning on adding lldb buildbots and running the testsuites soon, so
perhaps this situation will change in the future), so I've built a patch
which comprises this work. The impact of the patch on the rest of lldb
is minimal, and since I am not running the testsuites yet, I have spent
some time testing my build against a linux binary, and can claim that
all the basic run, paused, step, backtrace, inspect variables commands
still work. Indeed the platform commands continue to work as expected
for the host linux platform.

So I'd appreciate if anyone could cast their eyes over this patch and
see if it looks ok to submit or if it is missing anything. I've based the PlatformKalimba on PlatformLinux and basically stripped out anything
which I don't think is immediately applicable. I've also removed any
copied comments, since for the most part they are historic, and in order
to try to keep the source reasonably self-documenting. I'll also add
that the platform is deliberately incomplete, and will be fleshed
subsequently. I hope I made no CMake mistakes, I have little experience with CMake, and so my CMakeLists.txt files are all based on copying from other CMakeLists.txts.

Anyway,
I look forward to your feedback.

thanks
Matthew Gardiner


Member of the CSR plc group of companies. CSR plc registered in England and 
Wales, registered number 4187346, registered office Churchill House, Cambridge 
Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Keep up to date with CSR on our 
technical blog, www.csr.com/blog, CSR people blog, www.csr.com/people, YouTube, 
www.youtube.com/user/CSRplc, Facebook, 
www.facebook.com/pages/CSR/191038434253534, or follow us on Twitter at 
www.twitter.com/CSR_plc.
New for 2014, you can now access the wide range of products powered by aptX at 
www.aptx.com.
Index: lib/Makefile
===================================================================
--- lib/Makefile	(revision 212924)
+++ lib/Makefile	(working copy)
@@ -76,7 +76,8 @@
 	lldbPluginPlatformLinux.a \
 	lldbPluginPlatformWindows.a \
 	lldbPluginPlatformFreeBSD.a \
-	lldbPluginPlatformPOSIX.a
+	lldbPluginPlatformPOSIX.a \
+	lldbPluginPlatformKalimba.a
 
 # Because GCC requires RTTI enabled for lldbCore (see source/Core/Makefile) it is
 # necessary to also link the clang rewriter libraries so vtable references can
Index: source/Core/ArchSpec.cpp
===================================================================
--- source/Core/ArchSpec.cpp	(revision 212924)
+++ source/Core/ArchSpec.cpp	(working copy)
@@ -115,7 +115,7 @@
     { eByteOrderLittle, 4, 4, 4 , llvm::Triple::UnknownArch , ArchSpec::eCore_uknownMach32  , "unknown-mach-32" },
     { eByteOrderLittle, 8, 4, 4 , llvm::Triple::UnknownArch , ArchSpec::eCore_uknownMach64  , "unknown-mach-64" },
 
-    { eByteOrderLittle, 4, 1, 1 , llvm::Triple::UnknownArch , ArchSpec::eCore_kalimba  , "kalimba" }
+    { eByteOrderLittle, 4, 1, 1 , llvm::Triple::kalimba , ArchSpec::eCore_kalimba  , "kalimba" }
 };
 
 struct ArchDefinitionEntry
Index: source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
===================================================================
--- source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp	(revision 212924)
+++ source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp	(working copy)
@@ -46,6 +46,7 @@
 const char *const LLDB_NT_OWNER_FREEBSD = "FreeBSD";
 const char *const LLDB_NT_OWNER_GNU     = "GNU";
 const char *const LLDB_NT_OWNER_NETBSD  = "NetBSD";
+const char *const LLDB_NT_OWNER_CSR     = "csr";
 
 // ELF note type definitions
 const elf_word LLDB_NT_FREEBSD_ABI_TAG  = 0x01;
@@ -1221,7 +1222,25 @@
             if (log)
                 log->Printf ("ObjectFileELF::%s detected NetBSD, min version constant %" PRIu32, __FUNCTION__, version_info);
         }
+        // Process CSR kalimba notes
+        else if ((note.n_type == LLDB_NT_GNU_ABI_TAG) &&
+                (note.n_name == LLDB_NT_OWNER_CSR))
+        {
+            // We'll consume the payload below.
+            processed = true;
+            arch_spec.GetTriple().setOS(llvm::Triple::OSType::UnknownOS);
+            arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::CSR);
 
+            // TODO At some point the description string could be processed.
+            // It could provide a steer towards the kalimba variant which
+            // this ELF targets.
+            if(note.n_descsz)
+            {
+                const char *cstr = data.GetCStr(&offset, llvm::RoundUpToAlignment (note.n_descsz, 4));
+                (void)cstr;
+            }
+        }
+
         if (!processed)
             offset += llvm::RoundUpToAlignment(note.n_descsz, 4);
     }
Index: source/Plugins/Platform/CMakeLists.txt
===================================================================
--- source/Plugins/Platform/CMakeLists.txt	(revision 212924)
+++ source/Plugins/Platform/CMakeLists.txt	(working copy)
@@ -10,3 +10,4 @@
 
 add_subdirectory(POSIX)
 add_subdirectory(gdb-server)
+add_subdirectory(Kalimba)
Index: source/Plugins/Platform/Kalimba/CMakeLists.txt
===================================================================
--- source/Plugins/Platform/Kalimba/CMakeLists.txt	(revision 0)
+++ source/Plugins/Platform/Kalimba/CMakeLists.txt	(working copy)
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginPlatformKalimba
+  PlatformKalimba.cpp
+  )
Index: source/Plugins/Platform/Kalimba/Makefile
===================================================================
--- source/Plugins/Platform/Kalimba/Makefile	(revision 0)
+++ source/Plugins/Platform/Kalimba/Makefile	(working copy)
@@ -0,0 +1,14 @@
+##===- source/Plugins/Platform/Kalimba/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 := lldbPluginPlatformKalimba
+BUILD_ARCHIVE = 1
+
+include $(LLDB_LEVEL)/Makefile
Index: source/Plugins/Platform/Kalimba/PlatformKalimba.cpp
===================================================================
--- source/Plugins/Platform/Kalimba/PlatformKalimba.cpp	(revision 0)
+++ source/Plugins/Platform/Kalimba/PlatformKalimba.cpp	(working copy)
@@ -0,0 +1,366 @@
+//===-- PlatformKalimba.cpp ---------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
+#include "PlatformKalimba.h"
+#include "lldb/Host/Config.h"
+
+// C Includes
+#include <stdio.h>
+#ifndef LLDB_DISABLE_POSIX
+#include <sys/utsname.h>
+#endif
+
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleList.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Process.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+static uint32_t g_initialize_count = 0;
+
+Platform *
+PlatformKalimba::CreateInstance (bool force, const ArchSpec *arch)
+{
+    bool create = force;
+    if (create == false && arch && arch->IsValid())
+    {
+        const llvm::Triple &triple = arch->GetTriple();
+        switch (triple.getVendor())
+        {
+            case llvm::Triple::CSR:
+                create = true;
+                break;
+
+            default:
+                break;
+        }
+    }
+    if (create)
+        return new PlatformKalimba(false);
+    return NULL;
+}
+
+lldb_private::ConstString
+PlatformKalimba::GetPluginNameStatic (bool /*is_host*/)
+{
+    static ConstString g_remote_name("kalimba");
+    return g_remote_name;
+}
+
+const char *
+PlatformKalimba::GetPluginDescriptionStatic (bool /*is_host*/)
+{
+    return "Kalimba user platform plug-in.";
+}
+
+lldb_private::ConstString
+PlatformKalimba::GetPluginName()
+{
+    return GetPluginNameStatic(false);
+}
+
+void
+PlatformKalimba::Initialize ()
+{
+    if (g_initialize_count++ == 0)
+    {
+        PluginManager::RegisterPlugin(PlatformKalimba::GetPluginNameStatic(false),
+                                      PlatformKalimba::GetPluginDescriptionStatic(false),
+                                      PlatformKalimba::CreateInstance);
+    }
+}
+
+void
+PlatformKalimba::Terminate ()
+{
+    if (g_initialize_count > 0)
+    {
+        if (--g_initialize_count == 0)
+        {
+            PluginManager::UnregisterPlugin (PlatformKalimba::CreateInstance);
+        }
+    }
+}
+
+Error
+PlatformKalimba::ResolveExecutable (const FileSpec &exe_file,
+                                  const ArchSpec &exe_arch,
+                                  lldb::ModuleSP &exe_module_sp,
+                                  const FileSpecList *module_search_paths_ptr)
+{
+    Error error;
+    char exe_path[PATH_MAX];
+    FileSpec resolved_exe_file (exe_file);
+
+    if (!resolved_exe_file.Exists())
+    {
+        exe_file.GetPath(exe_path, sizeof(exe_path));
+        error.SetErrorStringWithFormat("unable to find executable for '%s'", exe_path);
+    }
+
+    if (error.Success())
+    {
+        ModuleSpec module_spec (resolved_exe_file, exe_arch);
+        if (exe_arch.IsValid())
+        {
+            error = ModuleList::GetSharedModule (module_spec, 
+                                                 exe_module_sp, 
+                                                 NULL, 
+                                                 NULL,
+                                                 NULL);
+            if (error.Fail())
+            {
+                // If we failed, it may be because the vendor and os aren't known. If that is the
+                // case, try setting them to the host architecture and give it another try.
+                llvm::Triple &module_triple = module_spec.GetArchitecture().GetTriple(); 
+                bool is_vendor_specified = (module_triple.getVendor() != llvm::Triple::UnknownVendor);
+                bool is_os_specified = (module_triple.getOS() != llvm::Triple::UnknownOS);
+                if (!is_vendor_specified || !is_os_specified)
+                {
+                    const llvm::Triple &host_triple = Host::GetArchitecture (Host::eSystemDefaultArchitecture).GetTriple();
+
+                    if (!is_vendor_specified)
+                        module_triple.setVendorName (host_triple.getVendorName());
+                    if (!is_os_specified)
+                        module_triple.setOSName (host_triple.getOSName());
+
+                    error = ModuleList::GetSharedModule (module_spec, 
+                                                         exe_module_sp, 
+                                                         NULL, 
+                                                         NULL,
+                                                         NULL);
+                }
+            }
+        
+            // TODO find out why exe_module_sp might be NULL            
+            if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL)
+            {
+                exe_module_sp.reset();
+                error.SetErrorStringWithFormat ("'%s' doesn't contain the architecture %s",
+                                                exe_file.GetPath().c_str(),
+                                                exe_arch.GetArchitectureName());
+            }
+        }
+        else
+        {
+            // No valid architecture was specified, ask the platform for
+            // the architectures that we should be using (in the correct order)
+            // and see if we can find a match that way
+            StreamString arch_names;
+            for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx)
+            {
+                error = ModuleList::GetSharedModule (module_spec, 
+                                                     exe_module_sp, 
+                                                     NULL, 
+                                                     NULL,
+                                                     NULL);
+                // Did we find an executable using one of the 
+                if (error.Success())
+                {
+                    if (exe_module_sp && exe_module_sp->GetObjectFile())
+                        break;
+                    else
+                        error.SetErrorToGenericError();
+                }
+                
+                if (idx > 0)
+                    arch_names.PutCString (", ");
+                arch_names.PutCString (module_spec.GetArchitecture().GetArchitectureName());
+            }
+            
+            if (error.Fail() || !exe_module_sp)
+            {
+                error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
+                                                exe_file.GetPath().c_str(),
+                                                GetPluginName().GetCString(),
+                                                arch_names.GetString().c_str());
+            }
+        }
+    }
+
+    return error;
+}
+
+Error
+PlatformKalimba::GetFileWithUUID (const FileSpec &/*platform_file*/, 
+                                const UUID */*uuid_ptr*/, FileSpec &/*local_file*/)
+{
+    return Error();
+}
+
+
+//------------------------------------------------------------------
+/// Default Constructor
+//------------------------------------------------------------------
+PlatformKalimba::PlatformKalimba (bool is_host) :
+    Platform(is_host),  // This is the local host platform
+    m_remote_platform_sp ()
+{
+}
+
+//------------------------------------------------------------------
+/// Destructor.
+///
+/// The destructor is virtual since this class is designed to be
+/// inherited from by the plug-in instance.
+//------------------------------------------------------------------
+PlatformKalimba::~PlatformKalimba()
+{
+}
+
+bool
+PlatformKalimba::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
+{
+    bool success = false;
+    if (IsHost())
+    {
+        success = Platform::GetProcessInfo (pid, process_info);
+    }
+    else
+    {
+        if (m_remote_platform_sp) 
+            success = m_remote_platform_sp->GetProcessInfo (pid, process_info);
+    }
+    return success;
+}
+
+bool
+PlatformKalimba::GetSupportedArchitectureAtIndex (uint32_t /*idx*/, ArchSpec &arch)
+{
+    arch = ArchSpec("kalimba-csr-unknown");
+    return true;
+}
+
+void
+PlatformKalimba::GetStatus (Stream &strm)
+{
+    Platform::GetStatus(strm);
+}
+
+size_t
+PlatformKalimba::GetSoftwareBreakpointTrapOpcode (Target &/*target*/, 
+                                                BreakpointSite */*bp_site*/)
+{
+    return 0;
+}
+
+Error
+PlatformKalimba::LaunchProcess (ProcessLaunchInfo &launch_info)
+{
+    Error error;
+    
+    if (IsHost())
+    {
+        if (launch_info.GetFlags().Test (eLaunchFlagLaunchInShell))
+        {
+            const bool is_localhost = true;
+            const bool will_debug = launch_info.GetFlags().Test(eLaunchFlagDebug);
+            const bool first_arg_is_full_shell_command = false;
+            uint32_t num_resumes = GetResumeCountForLaunchInfo (launch_info);
+            if (!launch_info.ConvertArgumentsForLaunchingInShell (error,
+                                                                  is_localhost,
+                                                                  will_debug,
+                                                                  first_arg_is_full_shell_command,
+                                                                  num_resumes))
+                return error;
+        }
+        error = Platform::LaunchProcess (launch_info);
+    }
+    else
+    {
+        error.SetErrorString ("the platform is not currently connected");
+    }
+    return error;
+}
+
+lldb::ProcessSP
+PlatformKalimba::Attach(ProcessAttachInfo &attach_info,
+                      Debugger &debugger,
+                      Target *target,
+                      Listener &listener,
+                      Error &error)
+{
+    lldb::ProcessSP process_sp;
+    if (IsHost())
+    {
+        if (target == NULL)
+        {
+            TargetSP new_target_sp;
+            ArchSpec emptyArchSpec;
+
+            error = debugger.GetTargetList().CreateTarget (debugger,
+                                                           NULL,
+                                                           emptyArchSpec,
+                                                           false,
+                                                           m_remote_platform_sp,
+                                                           new_target_sp);
+            target = new_target_sp.get();
+        }
+        else
+            error.Clear();
+
+        if (target && error.Success())
+        {
+            debugger.GetTargetList().SetSelectedTarget(target);
+
+            process_sp = target->CreateProcess (listener,
+                                                attach_info.GetProcessPluginName(),
+                                                NULL);
+
+            if (process_sp)
+                error = process_sp->Attach (attach_info);
+        }
+    }
+    else
+    {
+        if (m_remote_platform_sp)
+            process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, listener, error);
+        else
+            error.SetErrorString ("the platform is not currently connected");
+    }
+    return process_sp;
+}
+
+void
+PlatformKalimba::CalculateTrapHandlerSymbolNames ()
+{   
+    m_trap_handlers.push_back (ConstString ("_sigtramp"));
+}   
+
+Error
+PlatformKalimba::LaunchNativeProcess (
+    ProcessLaunchInfo &,
+    lldb_private::NativeProcessProtocol::NativeDelegate &,
+    NativeProcessProtocolSP &)
+{
+    return Error();
+}
+
+Error
+PlatformKalimba::AttachNativeProcess (lldb::pid_t,
+                                    lldb_private::NativeProcessProtocol::NativeDelegate &,
+                                    NativeProcessProtocolSP &)
+{
+    return Error();
+}
+
Index: source/Plugins/Platform/Kalimba/PlatformKalimba.h
===================================================================
--- source/Plugins/Platform/Kalimba/PlatformKalimba.h	(revision 0)
+++ source/Plugins/Platform/Kalimba/PlatformKalimba.h	(working copy)
@@ -0,0 +1,125 @@
+//===-- PlatformKalimba.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_PlatformKalimba_h_
+#define liblldb_PlatformKalimba_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Target/Platform.h"
+
+namespace lldb_private {
+
+    class PlatformKalimba : public Platform
+    {
+    public:
+
+        static void
+        Initialize ();
+
+        static void
+        Terminate ();
+        
+        PlatformKalimba (bool is_host);
+
+        virtual
+        ~PlatformKalimba();
+
+        //------------------------------------------------------------
+        // lldb_private::PluginInterface functions
+        //------------------------------------------------------------
+        static Platform *
+        CreateInstance (bool force, const lldb_private::ArchSpec *arch);
+
+        static lldb_private::ConstString
+        GetPluginNameStatic (bool is_host);
+
+        static const char *
+        GetPluginDescriptionStatic (bool is_host);
+
+        virtual lldb_private::ConstString
+        GetPluginName();
+        
+        virtual uint32_t
+        GetPluginVersion()
+        {
+            return 1;
+        }
+
+        //------------------------------------------------------------
+        // lldb_private::Platform functions
+        //------------------------------------------------------------
+        virtual Error
+        ResolveExecutable (const FileSpec &exe_file,
+                           const ArchSpec &arch,
+                           lldb::ModuleSP &module_sp,
+                           const FileSpecList *module_search_paths_ptr);
+
+        virtual const char *
+        GetDescription ()
+        {
+            return GetPluginDescriptionStatic(IsHost());
+        }
+
+        virtual void
+        GetStatus (Stream &strm);
+
+        virtual Error
+        GetFileWithUUID (const FileSpec &platform_file,
+                         const UUID* uuid, FileSpec &local_file);
+
+        virtual bool
+        GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &proc_info);
+
+        virtual bool
+        GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch);
+
+        virtual size_t
+        GetSoftwareBreakpointTrapOpcode (Target &target, 
+                                         BreakpointSite *bp_site);
+
+        virtual lldb_private::Error
+        LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info);
+
+        virtual lldb::ProcessSP
+        Attach(ProcessAttachInfo &attach_info, Debugger &debugger,
+               Target *target, Listener &listener, Error &error);
+
+        // Kalimba processes can not be launched by spawning and attaching.
+        virtual bool
+        CanDebugProcess ()
+        {
+            return false;
+        }
+
+        virtual void
+        CalculateTrapHandlerSymbolNames ();
+
+        Error
+        LaunchNativeProcess (
+            ProcessLaunchInfo &launch_info,
+            lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate,
+            NativeProcessProtocolSP &process_sp) override;
+
+        Error
+        AttachNativeProcess (lldb::pid_t pid,
+                             lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate,
+                             NativeProcessProtocolSP &process_sp) override;
+
+    protected:
+        lldb::PlatformSP m_remote_platform_sp;
+
+    private:
+        DISALLOW_COPY_AND_ASSIGN (PlatformKalimba);
+    };
+} // namespace lldb_private
+
+#endif  // liblldb_PlatformKalimba_h_
Index: source/Plugins/Platform/Makefile
===================================================================
--- source/Plugins/Platform/Makefile	(revision 212924)
+++ source/Plugins/Platform/Makefile	(working copy)
@@ -11,7 +11,7 @@
 
 include $(LLDB_LEVEL)/../../Makefile.config
 
-DIRS := gdb-server MacOSX Linux FreeBSD POSIX Windows
+DIRS := gdb-server MacOSX Linux FreeBSD POSIX Windows Kalimba
 
 # ifeq ($(HOST_OS),Darwin)
 #   DIRS += MacOSX
Index: source/lldb.cpp
===================================================================
--- source/lldb.cpp	(revision 212924)
+++ source/lldb.cpp	(working copy)
@@ -43,6 +43,7 @@
 #include "Plugins/Platform/Linux/PlatformLinux.h"
 #include "Plugins/Platform/POSIX/PlatformPOSIX.h"
 #include "Plugins/Platform/Windows/PlatformWindows.h"
+#include "Plugins/Platform/Kalimba/PlatformKalimba.h"
 #include "Plugins/Process/elf-core/ProcessElfCore.h"
 #include "Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h"
 #include "Plugins/SymbolVendor/ELF/SymbolVendorELF.h"
@@ -123,6 +124,7 @@
         PlatformFreeBSD::Initialize();
         PlatformLinux::Initialize();
         PlatformWindows::Initialize();
+        PlatformKalimba::Initialize();
         SymbolFileDWARFDebugMap::Initialize();
         ItaniumABILanguageRuntime::Initialize();
 #ifndef LLDB_DISABLE_PYTHON
_______________________________________________
lldb-dev mailing list
lldb-dev@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev

Reply via email to