summaryrefslogtreecommitdiff
path: root/lldb
diff options
context:
space:
mode:
Diffstat (limited to 'lldb')
-rw-r--r--lldb/include/lldb/Utility/ArchSpec.h2
-rw-r--r--lldb/include/lldb/Utility/DataExtractor.h4
-rw-r--r--lldb/source/Expression/IRMemoryMap.cpp36
-rw-r--r--lldb/source/Expression/LLVMUserExpression.cpp4
-rw-r--r--lldb/source/Host/common/NativeProcessProtocol.cpp4
-rw-r--r--lldb/source/Plugins/ABI/CMakeLists.txt2
-rw-r--r--lldb/source/Plugins/ABI/MSP430/ABISysV_msp430.cpp365
-rw-r--r--lldb/source/Plugins/ABI/MSP430/ABISysV_msp430.h88
-rw-r--r--lldb/source/Plugins/ABI/MSP430/CMakeLists.txt12
-rw-r--r--lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp1
-rw-r--r--lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp2
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.cpp15
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp3
-rw-r--r--lldb/source/Target/Platform.cpp6
-rw-r--r--lldb/source/Utility/ArchSpec.cpp9
-rw-r--r--lldb/test/API/functionalities/gdb_remote_client/TestMSP430MSPDebug.py110
-rw-r--r--lldb/test/API/functionalities/gdb_remote_client/msp430.yaml426
-rw-r--r--lldb/unittests/Utility/ArchSpecTest.cpp6
18 files changed, 1077 insertions, 18 deletions
diff --git a/lldb/include/lldb/Utility/ArchSpec.h b/lldb/include/lldb/Utility/ArchSpec.h
index 444d427c1bd4..2de517d765b2 100644
--- a/lldb/include/lldb/Utility/ArchSpec.h
+++ b/lldb/include/lldb/Utility/ArchSpec.h
@@ -172,6 +172,8 @@ public:
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 dbf0bce8c8d0..0b7e771ed4f8 100644
--- a/lldb/include/lldb/Utility/DataExtractor.h
+++ b/lldb/include/lldb/Utility/DataExtractor.h
@@ -843,9 +843,7 @@ public:
/// \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 3c102dd4eaef..951444db86a8 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 6d11abbf876f..af63a1629a64 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 95258e1ddc5e..b3ef8f027bcf 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 d7cc39be514a..828aea674ea6 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 000000000000..7fb651aa6c18
--- /dev/null
+++ b/lldb/source/Plugins/ABI/MSP430/ABISysV_msp430.cpp
@@ -0,0 +1,365 @@
+//===-- 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/IR/DerivedTypes.h"
+#include "llvm/TargetParser/Triple.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 000000000000..91f48a841611
--- /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 000000000000..81abb2d9b16e
--- /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 f26d6df1e910..b0afe0394622 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 bf226fabda5c..755c13defa98 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 b391edced695..8068614c9350 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 cbe9f494b6ac..bff24b1c8c0c 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 1ddd7596280e..50b54fb8c9c1 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 c82097a9e6cd..475d0c8a63a7 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 000000000000..067bb087630b
--- /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 000000000000..ef61b6691cb8
--- /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 43cec1f735cc..de3590b73bba 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"));