[Lldb-commits] [lldb] 82c02b7 - [lldb] Add support for MSP430 in LLDB.

Anton Korobeynikov via lldb-commits lldb-commits at lists.llvm.org
Mon Apr 17 11:05:16 PDT 2023


Author: Anton Korobeynikov
Date: 2023-04-17T11:05:09-07:00
New Revision: 82c02b733c7736507a41a26bebd37d3f8e88bd4e

URL: https://github.com/llvm/llvm-project/commit/82c02b733c7736507a41a26bebd37d3f8e88bd4e
DIFF: https://github.com/llvm/llvm-project/commit/82c02b733c7736507a41a26bebd37d3f8e88bd4e.diff

LOG: [lldb] Add support for MSP430 in LLDB.

Add MSP430 to the list of available targets, implement MSP430 ABI, add support for debugging targets with 16-bit address size.

The update is intended for use with MSPDebug, a GDB server implementation for MSP430.

Reviewed By: bulbazord, DavidSpickett

Differential Revision: https://reviews.llvm.org/D146965

Added: 
    lldb/source/Plugins/ABI/MSP430/ABISysV_msp430.cpp
    lldb/source/Plugins/ABI/MSP430/ABISysV_msp430.h
    lldb/source/Plugins/ABI/MSP430/CMakeLists.txt
    lldb/test/API/functionalities/gdb_remote_client/TestMSP430MSPDebug.py
    lldb/test/API/functionalities/gdb_remote_client/msp430.yaml

Modified: 
    lldb/include/lldb/Utility/ArchSpec.h
    lldb/include/lldb/Utility/DataExtractor.h
    lldb/source/Expression/IRMemoryMap.cpp
    lldb/source/Expression/LLVMUserExpression.cpp
    lldb/source/Host/common/NativeProcessProtocol.cpp
    lldb/source/Plugins/ABI/CMakeLists.txt
    lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
    lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
    lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.cpp
    lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
    lldb/source/Target/Platform.cpp
    lldb/source/Utility/ArchSpec.cpp
    lldb/unittests/Utility/ArchSpecTest.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Utility/ArchSpec.h b/lldb/include/lldb/Utility/ArchSpec.h
index 444d427c1bd44..2de517d765b2a 100644
--- a/lldb/include/lldb/Utility/ArchSpec.h
+++ b/lldb/include/lldb/Utility/ArchSpec.h
@@ -172,6 +172,8 @@ class ArchSpec {
     eCore_mips64r5el,
     eCore_mips64r6el,
 
+    eCore_msp430,
+
     eCore_ppc_generic,
     eCore_ppc_ppc601,
     eCore_ppc_ppc602,

diff  --git a/lldb/include/lldb/Utility/DataExtractor.h b/lldb/include/lldb/Utility/DataExtractor.h
index dbf0bce8c8d0d..0b7e771ed4f86 100644
--- a/lldb/include/lldb/Utility/DataExtractor.h
+++ b/lldb/include/lldb/Utility/DataExtractor.h
@@ -843,9 +843,7 @@ class DataExtractor {
   /// \param[in] addr_size
   ///     The size in bytes to use when extracting addresses.
   void SetAddressByteSize(uint32_t addr_size) {
-#ifdef LLDB_CONFIGURATION_DEBUG
-    assert(addr_size == 4 || addr_size == 8);
-#endif
+    assert(addr_size == 2 || addr_size == 4 || addr_size == 8);
     m_addr_size = addr_size;
   }
 

diff  --git a/lldb/source/Expression/IRMemoryMap.cpp b/lldb/source/Expression/IRMemoryMap.cpp
index 3c102dd4eaef1..951444db86a87 100644
--- a/lldb/source/Expression/IRMemoryMap.cpp
+++ b/lldb/source/Expression/IRMemoryMap.cpp
@@ -96,12 +96,21 @@ lldb::addr_t IRMemoryMap::FindSpace(size_t size) {
   // regions, walk forward through memory until a region is found that has
   // adequate space for our allocation.
   if (process_is_alive) {
-    const uint64_t end_of_memory = process_sp->GetAddressByteSize() == 8
-                                       ? 0xffffffffffffffffull
-                                       : 0xffffffffull;
-
-    lldbassert(process_sp->GetAddressByteSize() == 4 ||
-               end_of_memory != 0xffffffffull);
+    uint64_t end_of_memory;
+    switch (process_sp->GetAddressByteSize()) {
+    case 2:
+      end_of_memory = 0xffffull;
+      break;
+    case 4:
+      end_of_memory = 0xffffffffull;
+      break;
+    case 8:
+      end_of_memory = 0xffffffffffffffffull;
+      break;
+    default:
+      lldbassert(false && "Invalid address size.");
+      return LLDB_INVALID_ADDRESS;
+    }
 
     MemoryRegionInfo region_info;
     Status err = process_sp->GetMemoryRegionInfo(ret, region_info);
@@ -137,26 +146,31 @@ lldb::addr_t IRMemoryMap::FindSpace(size_t size) {
   // We've tried our algorithm, and it didn't work.  Now we have to reset back
   // to the end of the allocations we've already reported, or use a 'sensible'
   // default if this is our first allocation.
-
   if (m_allocations.empty()) {
     uint32_t address_byte_size = GetAddressByteSize();
     if (address_byte_size != UINT32_MAX) {
       switch (address_byte_size) {
-      case 8:
-        ret = 0xdead0fff00000000ull;
+      case 2:
+        ret = 0x8000ull;
         break;
       case 4:
         ret = 0xee000000ull;
         break;
-      default:
+      case 8:
+        ret = 0xdead0fff00000000ull;
         break;
+      default:
+        lldbassert(false && "Invalid address size.");
+        return LLDB_INVALID_ADDRESS;
       }
     }
   } else {
     auto back = m_allocations.rbegin();
     lldb::addr_t addr = back->first;
     size_t alloc_size = back->second.m_size;
-    ret = llvm::alignTo(addr + alloc_size, 4096);
+    auto arch = target_sp->GetArchitecture().GetTriple().getArch();
+    auto align = arch == llvm::Triple::msp430 ? 512 : 4096;
+    ret = llvm::alignTo(addr + alloc_size, align);
   }
 
   return ret;

diff  --git a/lldb/source/Expression/LLVMUserExpression.cpp b/lldb/source/Expression/LLVMUserExpression.cpp
index 6d11abbf876f4..af63a1629a647 100644
--- a/lldb/source/Expression/LLVMUserExpression.cpp
+++ b/lldb/source/Expression/LLVMUserExpression.cpp
@@ -333,7 +333,9 @@ bool LLVMUserExpression::PrepareToExecuteJITExpression(
     if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS) {
       Status alloc_error;
 
-      const size_t stack_frame_size = 512 * 1024;
+      auto arch = target->GetArchitecture().GetTriple().getArch();
+      const size_t stack_frame_size =
+          arch == llvm::Triple::msp430 ? 512 : 512 * 1024;
 
       const bool zero_memory = false;
 

diff  --git a/lldb/source/Host/common/NativeProcessProtocol.cpp b/lldb/source/Host/common/NativeProcessProtocol.cpp
index 95258e1ddc5ee..b3ef8f027bcfd 100644
--- a/lldb/source/Host/common/NativeProcessProtocol.cpp
+++ b/lldb/source/Host/common/NativeProcessProtocol.cpp
@@ -503,6 +503,7 @@ NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {
   static const uint8_t g_i386_opcode[] = {0xCC};
   static const uint8_t g_mips64_opcode[] = {0x00, 0x00, 0x00, 0x0d};
   static const uint8_t g_mips64el_opcode[] = {0x0d, 0x00, 0x00, 0x00};
+  static const uint8_t g_msp430_opcode[] = {0x43, 0x43};
   static const uint8_t g_s390x_opcode[] = {0x00, 0x01};
   static const uint8_t g_ppc_opcode[] = {0x7f, 0xe0, 0x00, 0x08};   // trap
   static const uint8_t g_ppcle_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap
@@ -528,6 +529,9 @@ NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {
   case llvm::Triple::mips64el:
     return llvm::ArrayRef(g_mips64el_opcode);
 
+  case llvm::Triple::msp430:
+    return llvm::ArrayRef(g_msp430_opcode);
+
   case llvm::Triple::systemz:
     return llvm::ArrayRef(g_s390x_opcode);
 

diff  --git a/lldb/source/Plugins/ABI/CMakeLists.txt b/lldb/source/Plugins/ABI/CMakeLists.txt
index d7cc39be514ac..828aea674ea68 100644
--- a/lldb/source/Plugins/ABI/CMakeLists.txt
+++ b/lldb/source/Plugins/ABI/CMakeLists.txt
@@ -1,4 +1,4 @@
-foreach(target AArch64 ARM ARC Hexagon Mips PowerPC SystemZ X86)
+foreach(target AArch64 ARM ARC Hexagon Mips MSP430 PowerPC SystemZ X86)
   if (${target} IN_LIST LLVM_TARGETS_TO_BUILD)
     add_subdirectory(${target})
   endif()

diff  --git a/lldb/source/Plugins/ABI/MSP430/ABISysV_msp430.cpp b/lldb/source/Plugins/ABI/MSP430/ABISysV_msp430.cpp
new file mode 100644
index 0000000000000..2e186285baf6a
--- /dev/null
+++ b/lldb/source/Plugins/ABI/MSP430/ABISysV_msp430.cpp
@@ -0,0 +1,366 @@
+//===-- ABISysV_msp430.cpp --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ABISysV_msp430.h"
+
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Core/ValueObjectMemory.h"
+#include "lldb/Core/ValueObjectRegister.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+
+#include "llvm/ADT/Triple.h"
+
+#include "llvm/IR/DerivedTypes.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+LLDB_PLUGIN_DEFINE_ADV(ABISysV_msp430, ABIMSP430)
+
+enum dwarf_regnums {
+  dwarf_pc = 0,
+  dwarf_sp,
+  dwarf_r2,
+  dwarf_r3,
+  dwarf_fp,
+  dwarf_r5,
+  dwarf_r6,
+  dwarf_r7,
+  dwarf_r8,
+  dwarf_r9,
+  dwarf_r10,
+  dwarf_r11,
+  dwarf_r12,
+  dwarf_r13,
+  dwarf_r14,
+  dwarf_r15,
+};
+
+static const RegisterInfo g_register_infos[] = {
+    {"r0",
+     "pc",
+     2,
+     0,
+     eEncodingUint,
+     eFormatHex,
+     {dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
+      LLDB_INVALID_REGNUM},
+     nullptr,
+     nullptr,
+     nullptr,
+    },
+    {"r1",
+     "sp",
+     2,
+     0,
+     eEncodingUint,
+     eFormatHex,
+     {dwarf_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
+      LLDB_INVALID_REGNUM},
+     nullptr,
+     nullptr,
+     nullptr,
+    },
+    {"r2",
+     "",
+     2,
+     0,
+     eEncodingUint,
+     eFormatHex,
+     {dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+      LLDB_INVALID_REGNUM},
+     nullptr,
+     nullptr,
+     nullptr,
+    },
+    {"r3",
+     "",
+     2,
+     0,
+     eEncodingUint,
+     eFormatHex,
+     {dwarf_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+      LLDB_INVALID_REGNUM},
+     nullptr,
+     nullptr,
+     nullptr,
+    },
+    {"r4",
+     "fp",
+     2,
+     0,
+     eEncodingUint,
+     eFormatHex,
+     {dwarf_fp, dwarf_fp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
+      LLDB_INVALID_REGNUM},
+     nullptr,
+     nullptr,
+     nullptr,
+    },
+    {"r5",
+     "",
+     2,
+     0,
+     eEncodingUint,
+     eFormatHex,
+     {dwarf_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+      LLDB_INVALID_REGNUM},
+     nullptr,
+     nullptr,
+     nullptr,
+    },
+    {"r6",
+     "",
+     2,
+     0,
+     eEncodingUint,
+     eFormatHex,
+     {dwarf_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+      LLDB_INVALID_REGNUM},
+     nullptr,
+     nullptr,
+     nullptr,
+    },
+    {"r7",
+     "",
+     2,
+     0,
+     eEncodingUint,
+     eFormatHex,
+     {dwarf_r7, dwarf_r7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+      LLDB_INVALID_REGNUM},
+     nullptr,
+     nullptr,
+     nullptr,
+    },
+    {"r8",
+     "",
+     2,
+     0,
+     eEncodingUint,
+     eFormatHex,
+     {dwarf_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+      LLDB_INVALID_REGNUM},
+     nullptr,
+     nullptr,
+     nullptr,
+    },
+    {"r9",
+     "",
+     2,
+     0,
+     eEncodingUint,
+     eFormatHex,
+     {dwarf_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+      LLDB_INVALID_REGNUM},
+     nullptr,
+     nullptr,
+     nullptr,
+    },
+    {"r10",
+     "",
+     2,
+     0,
+     eEncodingUint,
+     eFormatHex,
+     {dwarf_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+      LLDB_INVALID_REGNUM},
+     nullptr,
+     nullptr,
+     nullptr,
+    },
+    {"r11",
+     "",
+     2,
+     0,
+     eEncodingUint,
+     eFormatHex,
+     {dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+      LLDB_INVALID_REGNUM},
+     nullptr,
+     nullptr,
+     nullptr,
+    },
+    {"r12",
+     "",
+     2,
+     0,
+     eEncodingUint,
+     eFormatHex,
+     {dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+      LLDB_INVALID_REGNUM},
+     nullptr,
+     nullptr,
+     nullptr,
+    },
+    {"r13",
+     "",
+     2,
+     0,
+     eEncodingUint,
+     eFormatHex,
+     {dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+      LLDB_INVALID_REGNUM},
+     nullptr,
+     nullptr,
+     nullptr,
+    },
+    {"r14",
+     "",
+     2,
+     0,
+     eEncodingUint,
+     eFormatHex,
+     {dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+      LLDB_INVALID_REGNUM},
+     nullptr,
+     nullptr,
+     nullptr,
+    },
+    {"r15",
+     "",
+     2,
+     0,
+     eEncodingUint,
+     eFormatHex,
+     {dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+      LLDB_INVALID_REGNUM},
+     nullptr,
+     nullptr,
+     nullptr,
+    }};
+
+static const uint32_t k_num_register_infos =
+    sizeof(g_register_infos) / sizeof(RegisterInfo);
+
+const lldb_private::RegisterInfo *
+ABISysV_msp430::GetRegisterInfoArray(uint32_t &count) {
+  // Make the C-string names and alt_names for the register infos into const
+  // C-string values by having the ConstString unique the names in the global
+  // constant C-string pool.
+  count = k_num_register_infos;
+  return g_register_infos;
+}
+
+size_t ABISysV_msp430::GetRedZoneSize() const { return 0; }
+
+//------------------------------------------------------------------
+// Static Functions
+//------------------------------------------------------------------
+
+ABISP
+ABISysV_msp430::CreateInstance(lldb::ProcessSP process_sp,
+                               const ArchSpec &arch) {
+  if (arch.GetTriple().getArch() == llvm::Triple::msp430) {
+    return ABISP(
+        new ABISysV_msp430(std::move(process_sp), MakeMCRegisterInfo(arch)));
+  }
+  return ABISP();
+}
+
+bool ABISysV_msp430::PrepareTrivialCall(Thread &thread, lldb::addr_t sp,
+                                        lldb::addr_t pc, lldb::addr_t ra,
+                                        llvm::ArrayRef<addr_t> args) const {
+  // we don't use the traditional trivial call specialized for jit
+  return false;
+}
+
+bool ABISysV_msp430::GetArgumentValues(Thread &thread,
+                                       ValueList &values) const {
+  return false;
+}
+
+Status ABISysV_msp430::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+                                            lldb::ValueObjectSP &new_value_sp) {
+  return Status();
+}
+
+ValueObjectSP ABISysV_msp430::GetReturnValueObjectSimple(
+    Thread &thread, CompilerType &return_compiler_type) const {
+  ValueObjectSP return_valobj_sp;
+  return return_valobj_sp;
+}
+
+ValueObjectSP ABISysV_msp430::GetReturnValueObjectImpl(
+    Thread &thread, CompilerType &return_compiler_type) const {
+  ValueObjectSP return_valobj_sp;
+  return return_valobj_sp;
+}
+
+// called when we are on the first instruction of a new function
+bool ABISysV_msp430::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
+  unwind_plan.Clear();
+  unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+  uint32_t sp_reg_num = dwarf_sp;
+  uint32_t pc_reg_num = dwarf_pc;
+
+  UnwindPlan::RowSP row(new UnwindPlan::Row);
+  row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 2);
+  row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -2, true);
+  row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
+
+  unwind_plan.AppendRow(row);
+  unwind_plan.SetSourceName("msp430 at-func-entry default");
+  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+  return true;
+}
+
+bool ABISysV_msp430::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
+  unwind_plan.Clear();
+  unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+  uint32_t fp_reg_num = dwarf_fp;
+  uint32_t sp_reg_num = dwarf_sp;
+  uint32_t pc_reg_num = dwarf_pc;
+
+  UnwindPlan::RowSP row(new UnwindPlan::Row);
+  row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 2);
+  row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -2, true);
+  row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
+  row->SetRegisterLocationToUnspecified(fp_reg_num, true);
+
+  unwind_plan.AppendRow(row);
+  unwind_plan.SetSourceName("msp430 default unwind plan");
+  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+  unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+  return true;
+}
+
+bool ABISysV_msp430::RegisterIsVolatile(const RegisterInfo *reg_info) {
+  return !RegisterIsCalleeSaved(reg_info);
+}
+
+bool ABISysV_msp430::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
+  int reg = ((reg_info->byte_offset) / 2);
+
+  bool save = (reg >= 4) && (reg <= 10);
+  return save;
+}
+
+void ABISysV_msp430::Initialize(void) {
+  PluginManager::RegisterPlugin(
+      GetPluginNameStatic(), "System V ABI for msp430 targets", CreateInstance);
+}
+
+void ABISysV_msp430::Terminate(void) {
+  PluginManager::UnregisterPlugin(CreateInstance);
+}

diff  --git a/lldb/source/Plugins/ABI/MSP430/ABISysV_msp430.h b/lldb/source/Plugins/ABI/MSP430/ABISysV_msp430.h
new file mode 100644
index 0000000000000..91f48a8416112
--- /dev/null
+++ b/lldb/source/Plugins/ABI/MSP430/ABISysV_msp430.h
@@ -0,0 +1,88 @@
+//===-- ABISysV_msp430.h ----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_ABI_MSP430_ABISYSV_MSP430_H
+#define LLDB_SOURCE_PLUGINS_ABI_MSP430_ABISYSV_MSP430_H
+
+#include "lldb/Target/ABI.h"
+#include "lldb/lldb-private.h"
+
+class ABISysV_msp430 : public lldb_private::RegInfoBasedABI {
+public:
+  ~ABISysV_msp430() override = default;
+
+  size_t GetRedZoneSize() const override;
+
+  bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp,
+                          lldb::addr_t functionAddress,
+                          lldb::addr_t returnAddress,
+                          llvm::ArrayRef<lldb::addr_t> args) const override;
+
+  bool GetArgumentValues(lldb_private::Thread &thread,
+                         lldb_private::ValueList &values) const override;
+
+  lldb_private::Status
+  SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+                       lldb::ValueObjectSP &new_value) override;
+
+  lldb::ValueObjectSP
+  GetReturnValueObjectImpl(lldb_private::Thread &thread,
+                           lldb_private::CompilerType &type) const override;
+
+  bool
+  CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+  bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+  bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
+
+  bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
+    // Make sure the stack call frame addresses are 2 byte aligned
+    // and not zero
+    if (cfa & 0x01 || cfa == 0)
+      return false;
+    return true;
+  }
+
+  bool CodeAddressIsValid(lldb::addr_t pc) override { return true; }
+
+  const lldb_private::RegisterInfo *
+  GetRegisterInfoArray(uint32_t &count) override;
+
+  //------------------------------------------------------------------
+  // Static Functions
+  //------------------------------------------------------------------
+
+  static void Initialize();
+
+  static void Terminate();
+
+  static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp,
+                                    const lldb_private::ArchSpec &arch);
+
+  static llvm::StringRef GetPluginNameStatic() { return "sysv-msp430"; }
+
+  // PluginInterface protocol
+
+  llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+
+protected:
+  void CreateRegisterMapIfNeeded();
+
+  lldb::ValueObjectSP
+  GetReturnValueObjectSimple(lldb_private::Thread &thread,
+                             lldb_private::CompilerType &ast_type) const;
+
+  bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
+
+private:
+  using lldb_private::RegInfoBasedABI::RegInfoBasedABI;
+};
+
+#endif // LLDB_SOURCE_PLUGINS_ABI_MSP430_ABISYSV_MSP430_H

diff  --git a/lldb/source/Plugins/ABI/MSP430/CMakeLists.txt b/lldb/source/Plugins/ABI/MSP430/CMakeLists.txt
new file mode 100644
index 0000000000000..81abb2d9b16e0
--- /dev/null
+++ b/lldb/source/Plugins/ABI/MSP430/CMakeLists.txt
@@ -0,0 +1,12 @@
+add_lldb_library(lldbPluginABIMSP430 PLUGIN
+  ABISysV_msp430.cpp
+
+  LINK_LIBS
+    lldbCore
+    lldbSymbol
+    lldbTarget
+  LINK_COMPONENTS
+    Support
+    TargetParser
+  )
+

diff  --git a/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp b/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
index f26d6df1e9105..b0afe03946220 100644
--- a/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
+++ b/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
@@ -71,6 +71,7 @@ llvm::Triple::ArchType stringTo<llvm::Triple::ArchType>(llvm::StringRef Str) {
       .Case("arm", Triple::arm)
       .Cases("arm64", "arm64e", Triple::aarch64)
       .Case("mips", Triple::mips)
+      .Case("msp430", Triple::msp430)
       .Case("ppc", Triple::ppc)
       .Case("ppc64", Triple::ppc64)
       .Case("s390", Triple::systemz)

diff  --git a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
index bf226fabda5c9..755c13defa988 100644
--- a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
+++ b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
@@ -123,7 +123,7 @@ PlatformLinux::PlatformLinux(bool is_host)
         {llvm::Triple::x86_64, llvm::Triple::x86, llvm::Triple::arm,
          llvm::Triple::aarch64, llvm::Triple::mips64, llvm::Triple::mips64,
          llvm::Triple::hexagon, llvm::Triple::mips, llvm::Triple::mips64el,
-         llvm::Triple::mipsel, llvm::Triple::systemz},
+         llvm::Triple::mipsel, llvm::Triple::msp430, llvm::Triple::systemz},
         llvm::Triple::Linux);
   }
 }

diff  --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.cpp
index b391edced695f..8068614c9350c 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.cpp
@@ -19,6 +19,7 @@ namespace process_gdb_remote {
   }
 #define R64(name) REG(name, 8)
 #define R32(name) REG(name, 4)
+#define R16(name) REG(name, 2)
 
 static std::vector<DynamicRegisterInfo::Register> GetRegisters_aarch64() {
   ConstString empty_alt_name;
@@ -35,6 +36,18 @@ static std::vector<DynamicRegisterInfo::Register> GetRegisters_aarch64() {
   return registers;
 }
 
+static std::vector<DynamicRegisterInfo::Register> GetRegisters_msp430() {
+  ConstString empty_alt_name;
+  ConstString reg_set{"general purpose registers"};
+
+  std::vector<DynamicRegisterInfo::Register> registers{
+      R16(pc),  R16(sp),  R16(r2),  R16(r3), R16(fp),  R16(r5),
+      R16(r6),  R16(r7),  R16(r8),  R16(r9), R16(r10), R16(r11),
+      R16(r12), R16(r13), R16(r14), R16(r15)};
+
+  return registers;
+}
+
 static std::vector<DynamicRegisterInfo::Register> GetRegisters_x86() {
   ConstString empty_alt_name;
   ConstString reg_set{"general purpose registers"};
@@ -71,6 +84,8 @@ GetFallbackRegisters(const ArchSpec &arch_to_use) {
   switch (arch_to_use.GetMachine()) {
   case llvm::Triple::aarch64:
     return GetRegisters_aarch64();
+  case llvm::Triple::msp430:
+    return GetRegisters_msp430();
   case llvm::Triple::x86:
     return GetRegisters_x86();
   case llvm::Triple::x86_64:

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index cbe9f494b6acd..bff24b1c8c0cc 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -940,7 +940,8 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data,
 
   bool length_OK = data.ValidOffset(header.GetNextUnitOffset() - 1);
   bool version_OK = SymbolFileDWARF::SupportedVersion(header.m_version);
-  bool addr_size_OK = (header.m_addr_size == 4) || (header.m_addr_size == 8);
+  bool addr_size_OK = (header.m_addr_size == 2) || (header.m_addr_size == 4) ||
+                      (header.m_addr_size == 8);
   bool type_offset_OK =
       !header.IsTypeUnit() || (header.m_type_offset <= header.GetLength());
 

diff  --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index 1ddd7596280ee..50b54fb8c9c1b 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -1895,6 +1895,12 @@ size_t Platform::GetSoftwareBreakpointTrapOpcode(Target &target,
     trap_opcode_size = sizeof(g_hex_opcode);
   } break;
 
+  case llvm::Triple::msp430: {
+    static const uint8_t g_msp430_opcode[] = {0x43, 0x43};
+    trap_opcode = g_msp430_opcode;
+    trap_opcode_size = sizeof(g_msp430_opcode);
+  } break;
+
   case llvm::Triple::systemz: {
     static const uint8_t g_hex_opcode[] = {0x00, 0x01};
     trap_opcode = g_hex_opcode;

diff  --git a/lldb/source/Utility/ArchSpec.cpp b/lldb/source/Utility/ArchSpec.cpp
index c82097a9e6cdc..475d0c8a63a7b 100644
--- a/lldb/source/Utility/ArchSpec.cpp
+++ b/lldb/source/Utility/ArchSpec.cpp
@@ -154,6 +154,10 @@ static const CoreDefinition g_core_definitions[] = {
     {eByteOrderLittle, 8, 2, 4, llvm::Triple::mips64el,
      ArchSpec::eCore_mips64r6el, "mips64r6el"},
 
+    // MSP430
+    {eByteOrderLittle, 2, 2, 4, llvm::Triple::msp430, ArchSpec::eCore_msp430,
+     "msp430"},
+
     {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_generic,
      "powerpc"},
     {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc601,
@@ -402,6 +406,8 @@ static const ArchDefinitionEntry g_elf_arch_entries[] = {
      ArchSpec::eMIPSSubType_mips64r2el, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips64r2el
     {ArchSpec::eCore_mips64r6el, llvm::ELF::EM_MIPS,
      ArchSpec::eMIPSSubType_mips64r6el, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips64r6el
+    {ArchSpec::eCore_msp430, llvm::ELF::EM_MSP430, LLDB_INVALID_CPUTYPE,
+     0xFFFFFFFFu, 0xFFFFFFFFu}, // MSP430
     {ArchSpec::eCore_hexagon_generic, llvm::ELF::EM_HEXAGON,
      LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // HEXAGON
     {ArchSpec::eCore_arc, llvm::ELF::EM_ARC_COMPACT2, LLDB_INVALID_CPUTYPE,
@@ -899,6 +905,9 @@ bool ArchSpec::SetArchitecture(ArchitectureType arch_type, uint32_t cpu,
           case llvm::ELF::ELFOSABI_SOLARIS:
             m_triple.setOS(llvm::Triple::OSType::Solaris);
             break;
+          case llvm::ELF::ELFOSABI_STANDALONE:
+            m_triple.setOS(llvm::Triple::OSType::UnknownOS);
+            break;
           }
         } else if (arch_type == eArchTypeCOFF && os == llvm::Triple::Win32) {
           m_triple.setVendor(llvm::Triple::PC);

diff  --git a/lldb/test/API/functionalities/gdb_remote_client/TestMSP430MSPDebug.py b/lldb/test/API/functionalities/gdb_remote_client/TestMSP430MSPDebug.py
new file mode 100644
index 0000000000000..067bb087630b6
--- /dev/null
+++ b/lldb/test/API/functionalities/gdb_remote_client/TestMSP430MSPDebug.py
@@ -0,0 +1,110 @@
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from lldbsuite.test.gdbclientutils import *
+from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
+
+# This test ensures that LLDB correctly handles packets sent by MSPDebug.
+# https://github.com/dlbeer/mspdebug
+
+class MyResponder(MockGDBServerResponder):
+    def qSupported(self, client_supported):
+        return "PacketSize=4000"
+
+    def setBreakpoint(self, packet):
+        return "OK"
+
+    def stopPackets():
+        # Registers 3 to 15 are empty
+        regs3to15 = "".join('%02x:%s;' % (i, "00000000") for i in range(3, 16))
+        yield "T0500:00050000;01:00000000;02:00000000;" + regs3to15
+        yield "T0500:10050000;01:baff0000;02:05000000;" + regs3to15
+        yield "T0500:16050000;01:baff0000;02:05000000;" + regs3to15
+
+    stopPacket = stopPackets()
+    def haltReason(self):
+        return next(self.stopPacket)
+
+    def cont(self):
+        return self.haltReason()
+
+    # Memory dump
+    def readMemory(self, addr, length):
+        # Program memory
+        if (addr == 0x0400):
+            return ("ff"*256) + "3140c0ff0c43b0121c05b01281010000b240d2043c051c423c0530413180020081430000b01210053150020030411c4330413c402a0030410c433041" + ("ff"*196)
+        # Stack contents
+        if (addr == 0xfe00):
+            return ("ff"*442) + "280500000a05" + ("ff"*62) + "0005"
+
+class TestMSP430MSPDebug(GDBRemoteTestBase):
+
+    @skipIfLLVMTargetMissing("MSP430")
+    def test(self):
+        """
+        Test LLDB's MSP430 functionality.
+        """
+        target = self.createTarget("msp430.yaml")
+        self.server.responder = MyResponder()
+
+        if self.TraceOn():
+            self.runCmd("log enable gdb-remote packets")
+            self.addTearDownHook(
+                lambda: self.runCmd("log disable gdb-remote packets"))
+
+        process = self.connect(target)
+        lldbutil.expect_state_changes(self, self.dbg.GetListener(), process,
+                                      [lldb.eStateStopped])
+        num_threads = len(process.threads)
+        self.assertEqual(num_threads, 1, "Only one thread")
+        thread = process.GetThreadAtIndex(0)
+
+        # Test if a breakpoint can be set
+        bp = target.BreakpointCreateByName("func")
+        self.assertTrue(bp.IsValid())
+        bp.SetEnabled(True)
+        self.assertTrue(bp.IsEnabled())
+
+        # Test if the breakpoint address is resolved correctly
+        self.assertEqual(bp.GetNumLocations(), 1, "Only one location")
+        bp_loc = bp.GetLocationAtIndex(0);
+        self.assertTrue(bp_loc.GetAddress().GetLoadAddress(target) == 0x510,
+            "Address of main")
+
+        # Test if the process stops at the breakpoint
+        process.Continue()
+        self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonBreakpoint,
+            "Hit a breakpoint")
+
+        # Check if disassembler works and the current function is "func"
+        func = thread.GetFrameAtIndex(0).GetFunction()
+        insts = func.GetInstructions(target)
+        inst = insts.GetInstructionAtIndex(0)
+        self.assertEqual(inst.GetMnemonic(target), "mov")
+        self.assertEqual(inst.GetOperands(target), "#1234, &1340")
+
+        # Test if thread can step a single instruction
+        thread.StepInstruction(False)
+        self.assertTrue(thread.GetFrameAtIndex(0).GetPCAddress().GetLoadAddress(target) == 0x516,
+            "Address of the next instruction")
+
+        # Test if registers are being set correctly
+        registerSet = thread.GetFrameAtIndex(0).GetRegisters().GetValueAtIndex(0)
+        reg_val_dict = {
+             "pc": 0x0516,  "sp": 0xffba,  "r2": 0x0005,
+             "r3": 0x0000,  "fp": 0x0000,  "r5": 0x0000,
+             "r6": 0x0000,  "r7": 0x0000,  "r8": 0x0000,
+             "r9": 0x0000, "r10": 0x0000, "r11": 0x0000,
+            "r12": 0x0000, "r13": 0x0000, "r14": 0x0000,
+            "r15": 0x0000
+        }
+        for reg in registerSet:
+            self.assertEqual(reg.GetValueAsUnsigned(),
+                             reg_val_dict[reg.GetName()])
+
+        # Check if backtracing works:
+        self.assertTrue(len(thread.frames) >= 3)
+        crt0_addr = thread.GetFrameAtIndex(2).GetPCAddress().GetLoadAddress(target)
+        self.assertEqual(crt0_addr, 0x50a)
+
+

diff  --git a/lldb/test/API/functionalities/gdb_remote_client/msp430.yaml b/lldb/test/API/functionalities/gdb_remote_client/msp430.yaml
new file mode 100644
index 0000000000000..ef61b6691cb88
--- /dev/null
+++ b/lldb/test/API/functionalities/gdb_remote_client/msp430.yaml
@@ -0,0 +1,426 @@
+# File test.c, compiled with flags "-O0 -g"
+# Source code:
+#
+# int foo = 0;
+#
+# int func() {
+#     foo = 1234;
+#     return foo;
+# }
+#
+# int main() {
+#     return func();
+# }
+#
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  OSABI:           ELFOSABI_STANDALONE
+  Type:            ET_EXEC
+  Machine:         EM_MSP430
+  Flags:           [  ]
+  Entry:           0x500
+ProgramHeaders:
+  - Type:            PT_LOAD
+    Flags:           [ PF_X, PF_R ]
+    FirstSec:        .text
+    LastSec:         .bss
+    VAddr:           0x46C
+    Align:           0x4
+  - Type:            PT_LOAD
+    Flags:           [ PF_W, PF_R ]
+    FirstSec:        .data
+    LastSec:         .bss
+    VAddr:           0x53C
+    Align:           0x4
+  - Type:            PT_LOAD
+    Flags:           [ PF_R ]
+    FirstSec:        __interrupt_vector_31
+    LastSec:         __interrupt_vector_31
+    VAddr:           0xFFFE
+    Align:           0x4
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    Address:         0x500
+    AddressAlign:    0x4
+    Content:         3140C0FF0C43B0121C05B01281010000B240D2043C051C423C0530413180020081430000B01210053150020030411C4330413C402A0030410C433041
+  - Name:            .data
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    Address:         0x53C
+    AddressAlign:    0x1
+  - Name:            .bss
+    Type:            SHT_NOBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    Address:         0x53C
+    AddressAlign:    0x2
+    Size:            0x2
+  - Name:            __interrupt_vector_31
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC ]
+    Address:         0xFFFE
+    AddressAlign:    0x1
+    Offset:          0xD2
+    Content:         '0005'
+  - Name:            .rodata
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    Address:         0x500
+    AddressAlign:    0x1
+  - Name:            .rodata2
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE ]
+    Address:         0x500
+    AddressAlign:    0x1
+  - Name:            .noinit
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE ]
+    Address:         0x53E
+    AddressAlign:    0x1
+  - Name:            .persistent
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE ]
+    Address:         0x53E
+    AddressAlign:    0x1
+  - Name:            .MSP430.attributes
+    Type:            SHT_MSP430_ATTRIBUTES
+    AddressAlign:    0x1
+    Content:         41160000006D737061626900010B000000040106010801
+  - Name:            .comment
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_MERGE, SHF_STRINGS ]
+    AddressAlign:    0x1
+    EntSize:         0x1
+    Content:         4743433A20284D6974746F2053797374656D73204C696D69746564202D206D73703433302D67636320392E332E312E31312920392E332E3100636C616E672076657273696F6E2031362E302E30202868747470733A2F2F6769746875622E636F6D2F6163636573732D736F6674656B2F6C6C766D2D70726F6A6563742E67697420373634363331663864643330353231386339613938656165373535353464303436303236343032322900
+  - Name:            .debug_info
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x1
+    Content:         4D000000050001040000000001001D0001080000000000000002011E0000000800000002032E000000000202A1000304050204010C00000001510500042E00000004021200000001510600092E00000000
+  - Name:            .debug_abbrev
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x1
+    Content:         011101252513050325721710171B25111B120673170000023400032549133F193A0B3B0B0218000003240003253E0B0B0B0000042E00111B1206401803253A0B3B0B49133F19000000
+  - Name:            .debug_line
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x1
+    Content:         660000000500040037000000010101FB0E0D00010101010000000100000101011F010000000003011F020F051E011E000000002C97BF5F43C79BB948A69660B684FF4A0400000502100500001505060A130509670502064A0500063105090A830502060B4A0206000101
+  - Name:            .debug_frame
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x4
+    Content:         10000000FFFFFFFF04000400017E000C010280010C00000000000000100500000C00000014000000000000001C05000012000000440E044C0E020000
+  - Name:            .debug_str_offsets
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x1
+    Content:         2000000005000000000000007200000079000000970000009B0000009F000000A4000000
+  - Name:            .debug_line_str
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_MERGE, SHF_STRINGS ]
+    AddressAlign:    0x1
+    EntSize:         0x1
+    Content:         2F686F6D652F757365722F6465762F746573742F6D737034333000746573742E6300
+  - Type:            SectionHeaderTable
+    Sections:
+      - Name:            __interrupt_vector_31
+      - Name:            .rodata
+      - Name:            .rodata2
+      - Name:            .text
+      - Name:            .data
+      - Name:            .bss
+      - Name:            .noinit
+      - Name:            .persistent
+      - Name:            .MSP430.attributes
+      - Name:            .comment
+      - Name:            .debug_info
+      - Name:            .debug_abbrev
+      - Name:            .debug_line
+      - Name:            .debug_frame
+      - Name:            .debug_str
+      - Name:            .debug_str_offsets
+      - Name:            .debug_addr
+      - Name:            .debug_line_str
+      - Name:            .symtab
+      - Name:            .strtab
+      - Name:            .shstrtab
+Symbols:
+  - Name:            __interrupt_vector_31
+    Type:            STT_SECTION
+    Section:         __interrupt_vector_31
+    Value:           0xFFFE
+  - Name:            .rodata
+    Type:            STT_SECTION
+    Section:         .rodata
+    Value:           0x500
+  - Name:            .rodata2
+    Type:            STT_SECTION
+    Section:         .rodata2
+    Value:           0x500
+  - Name:            .text
+    Type:            STT_SECTION
+    Section:         .text
+    Value:           0x500
+  - Name:            .data
+    Type:            STT_SECTION
+    Section:         .data
+    Value:           0x53C
+  - Name:            .bss
+    Type:            STT_SECTION
+    Section:         .bss
+    Value:           0x53C
+  - Name:            .noinit
+    Type:            STT_SECTION
+    Section:         .noinit
+    Value:           0x53E
+  - Name:            .persistent
+    Type:            STT_SECTION
+    Section:         .persistent
+    Value:           0x53E
+  - Name:            .MSP430.attributes
+    Type:            STT_SECTION
+    Section:         .MSP430.attributes
+  - Name:            .comment
+    Type:            STT_SECTION
+    Section:         .comment
+  - Name:            .debug_info
+    Type:            STT_SECTION
+    Section:         .debug_info
+  - Name:            .debug_abbrev
+    Type:            STT_SECTION
+    Section:         .debug_abbrev
+  - Name:            .debug_line
+    Type:            STT_SECTION
+    Section:         .debug_line
+  - Name:            .debug_frame
+    Type:            STT_SECTION
+    Section:         .debug_frame
+  - Name:            .debug_str
+    Type:            STT_SECTION
+    Section:         .debug_str
+  - Name:            .debug_str_offsets
+    Type:            STT_SECTION
+    Section:         .debug_str_offsets
+  - Name:            .debug_addr
+    Type:            STT_SECTION
+    Section:         .debug_addr
+  - Name:            .debug_line_str
+    Type:            STT_SECTION
+    Section:         .debug_line_str
+  - Name:            __msp430_resetvec_hook
+    Section:         __interrupt_vector_31
+    Value:           0xFFFE
+  - Name:            .Loc.58.1
+    Section:         .text
+    Value:           0x500
+  - Name:            "L0\x01"
+    Section:         .text
+    Value:           0x504
+  - Name:            "L0\x01 (1)"
+    Section:         .text
+    Value:           0x500
+  - Name:            "L0\x01 (2)"
+    Section:         .text
+    Value:           0x504
+  - Name:            crt_main.o
+    Type:            STT_FILE
+    Index:           SHN_ABS
+  - Name:            .Loc.253.1
+    Section:         .text
+    Value:           0x504
+  - Name:            .Loc.254.1
+    Section:         .text
+    Value:           0x506
+  - Name:            "L0\x01 (3)"
+    Section:         .text
+    Value:           0x50A
+  - Name:            "L0\x01 (4)"
+    Section:         .text
+    Value:           0x504
+  - Name:            "L0\x01 (5)"
+    Section:         .text
+    Value:           0x50A
+  - Name:            crt_callexit.o
+    Type:            STT_FILE
+    Index:           SHN_ABS
+  - Name:            .Loc.267.1
+    Section:         .text
+    Value:           0x50A
+  - Name:            "L0\x01 (6)"
+    Section:         .text
+    Value:           0x50E
+  - Name:            "L0\x01 (7)"
+    Section:         .text
+    Value:           0x50A
+  - Name:            "L0\x01 (8)"
+    Section:         .text
+    Value:           0x50E
+  - Name:            test.c
+    Type:            STT_FILE
+    Index:           SHN_ABS
+  - Name:            syscalls.o
+    Type:            STT_FILE
+    Index:           SHN_ABS
+  - Name:            .Loc.59.1
+    Section:         .text
+    Value:           0x52E
+  - Name:            .Loc.60.1
+    Section:         .text
+    Value:           0x530
+  - Name:            .Loc.65.1
+    Section:         .text
+    Value:           0x532
+  - Name:            .Loc.66.1
+    Section:         .text
+    Value:           0x536
+  - Name:            .Loc.71.1
+    Section:         .text
+    Value:           0x538
+  - Name:            .Loc.72.1
+    Section:         .text
+    Value:           0x53A
+  - Name:            "L0\x01 (9)"
+    Section:         .text
+    Value:           0x53C
+  - Name:            "L0\x01 (10)"
+    Section:         .text
+    Value:           0x52E
+  - Name:            "L0\x01 (11)"
+    Section:         .text
+    Value:           0x53C
+  - Name:            __crt0_call_exit
+    Type:            STT_FUNC
+    Section:         .text
+    Binding:         STB_GLOBAL
+    Value:           0x50A
+    Size:            0x4
+  - Name:            getpid
+    Section:         .text
+    Binding:         STB_WEAK
+    Value:           0x532
+  - Name:            isatty
+    Section:         .text
+    Binding:         STB_WEAK
+    Value:           0x52E
+  - Name:            __crt0_start
+    Type:            STT_FUNC
+    Section:         .text
+    Binding:         STB_GLOBAL
+    Value:           0x500
+    Size:            0x4
+  - Name:            lseek
+    Index:           SHN_ABS
+    Binding:         STB_WEAK
+    Value:           0x186
+  - Name:            _isatty
+    Section:         .text
+    Binding:         STB_WEAK
+    Value:           0x52E
+  - Name:            fstat
+    Index:           SHN_ABS
+    Binding:         STB_WEAK
+    Value:           0x18A
+  - Name:            kill
+    Index:           SHN_ABS
+    Binding:         STB_WEAK
+    Value:           0x189
+  - Name:            _start
+    Section:         .text
+    Binding:         STB_GLOBAL
+    Value:           0x500
+  - Name:            read
+    Index:           SHN_ABS
+    Binding:         STB_WEAK
+    Value:           0x184
+  - Name:            __rom_highdatacopysize
+    Index:           SHN_ABS
+    Binding:         STB_WEAK
+  - Name:            gettimeofday
+    Section:         .text
+    Binding:         STB_WEAK
+    Value:           0x538
+    Size:            0x4
+  - Name:            main
+    Type:            STT_FUNC
+    Section:         .text
+    Binding:         STB_GLOBAL
+    Value:           0x51C
+    Size:            0x12
+  - Name:            __high_bsssize
+    Index:           SHN_ABS
+    Binding:         STB_WEAK
+  - Name:            __rom_highdatastart
+    Index:           SHN_ABS
+    Binding:         STB_WEAK
+  - Name:            __high_datastart
+    Index:           SHN_ABS
+    Binding:         STB_WEAK
+  - Name:            __upper_data_init
+    Index:           SHN_ABS
+    Binding:         STB_WEAK
+  - Name:            func
+    Type:            STT_FUNC
+    Section:         .text
+    Binding:         STB_GLOBAL
+    Value:           0x510
+    Size:            0xC
+  - Name:            foo
+    Type:            STT_OBJECT
+    Section:         .bss
+    Binding:         STB_GLOBAL
+    Value:           0x53C
+    Size:            0x2
+  - Name:            __stack
+    Section:         .persistent
+    Binding:         STB_GLOBAL
+    Value:           0xFFC0
+  - Name:            _edata
+    Section:         .data
+    Binding:         STB_GLOBAL
+    Value:           0x53C
+  - Name:            _end
+    Section:         .bss
+    Binding:         STB_GLOBAL
+    Value:           0x53E
+  - Name:            exit
+    Index:           SHN_ABS
+    Binding:         STB_WEAK
+    Value:           0x181
+  - Name:            __high_bssstart
+    Index:           SHN_ABS
+    Binding:         STB_WEAK
+  - Name:            __crt0_call_main
+    Type:            STT_FUNC
+    Section:         .text
+    Binding:         STB_GLOBAL
+    Value:           0x504
+    Size:            0x6
+  - Name:            _exit
+    Index:           SHN_ABS
+    Binding:         STB_WEAK
+    Value:           0x181
+  - Name:            open
+    Index:           SHN_ABS
+    Binding:         STB_WEAK
+    Value:           0x182
+  - Name:            close
+    Index:           SHN_ABS
+    Binding:         STB_WEAK
+    Value:           0x183
+DWARF:
+  debug_str:
+    - test.c
+    - foo
+    - int
+    - func
+    - main
+  debug_addr:
+    - Length:          0x10
+      Version:         0x5
+      AddressSize:     0x4
+      Entries:
+        - Address:         0x53C
+        - Address:         0x510
+        - Address:         0x51C
+...

diff  --git a/lldb/unittests/Utility/ArchSpecTest.cpp b/lldb/unittests/Utility/ArchSpecTest.cpp
index 43cec1f735ccd..de3590b73bbaa 100644
--- a/lldb/unittests/Utility/ArchSpecTest.cpp
+++ b/lldb/unittests/Utility/ArchSpecTest.cpp
@@ -123,6 +123,12 @@ TEST(ArchSpecTest, TestSetTriple) {
   EXPECT_STREQ("i686", AS.GetArchitectureName());
   EXPECT_EQ(ArchSpec::eCore_x86_32_i686, AS.GetCore());
 
+  AS = ArchSpec();
+  EXPECT_TRUE(AS.SetTriple("msp430---elf"));
+  EXPECT_EQ(llvm::Triple::msp430, AS.GetTriple().getArch());
+  EXPECT_STREQ("msp430", AS.GetArchitectureName());
+  EXPECT_EQ(ArchSpec::eCore_msp430, AS.GetCore());
+
   // Various flavors of invalid triples.
   AS = ArchSpec();
   EXPECT_FALSE(AS.SetTriple("unknown-unknown-unknown"));


        


More information about the lldb-commits mailing list