362 lines · cpp
1//===-- ABISysV_msp430.cpp --------------------------------------*- C++ -*-===//2//3// The LLVM Compiler Infrastructure4//5// This file is distributed under the University of Illinois Open Source6// License. See LICENSE.TXT for details.7//8//===----------------------------------------------------------------------===//9 10#include "ABISysV_msp430.h"11 12#include "lldb/Core/Module.h"13#include "lldb/Core/PluginManager.h"14#include "lldb/Core/Value.h"15#include "lldb/Symbol/UnwindPlan.h"16#include "lldb/Target/Process.h"17#include "lldb/Target/RegisterContext.h"18#include "lldb/Target/StackFrame.h"19#include "lldb/Target/Target.h"20#include "lldb/Target/Thread.h"21#include "lldb/Utility/ConstString.h"22#include "lldb/Utility/DataExtractor.h"23#include "lldb/Utility/Log.h"24#include "lldb/Utility/RegisterValue.h"25#include "lldb/ValueObject/ValueObjectConstResult.h"26#include "lldb/ValueObject/ValueObjectMemory.h"27#include "lldb/ValueObject/ValueObjectRegister.h"28 29#include "llvm/IR/DerivedTypes.h"30#include "llvm/TargetParser/Triple.h"31 32using namespace lldb;33using namespace lldb_private;34 35LLDB_PLUGIN_DEFINE_ADV(ABISysV_msp430, ABIMSP430)36 37enum dwarf_regnums {38 dwarf_pc = 0,39 dwarf_sp,40 dwarf_r2,41 dwarf_r3,42 dwarf_fp,43 dwarf_r5,44 dwarf_r6,45 dwarf_r7,46 dwarf_r8,47 dwarf_r9,48 dwarf_r10,49 dwarf_r11,50 dwarf_r12,51 dwarf_r13,52 dwarf_r14,53 dwarf_r15,54};55 56static const RegisterInfo g_register_infos[] = {57 {"r0",58 "pc",59 2,60 0,61 eEncodingUint,62 eFormatHex,63 {dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,64 LLDB_INVALID_REGNUM},65 nullptr,66 nullptr,67 nullptr,68 },69 {"r1",70 "sp",71 2,72 0,73 eEncodingUint,74 eFormatHex,75 {dwarf_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,76 LLDB_INVALID_REGNUM},77 nullptr,78 nullptr,79 nullptr,80 },81 {"r2",82 "",83 2,84 0,85 eEncodingUint,86 eFormatHex,87 {dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,88 LLDB_INVALID_REGNUM},89 nullptr,90 nullptr,91 nullptr,92 },93 {"r3",94 "",95 2,96 0,97 eEncodingUint,98 eFormatHex,99 {dwarf_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,100 LLDB_INVALID_REGNUM},101 nullptr,102 nullptr,103 nullptr,104 },105 {"r4",106 "fp",107 2,108 0,109 eEncodingUint,110 eFormatHex,111 {dwarf_fp, dwarf_fp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,112 LLDB_INVALID_REGNUM},113 nullptr,114 nullptr,115 nullptr,116 },117 {"r5",118 "",119 2,120 0,121 eEncodingUint,122 eFormatHex,123 {dwarf_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,124 LLDB_INVALID_REGNUM},125 nullptr,126 nullptr,127 nullptr,128 },129 {"r6",130 "",131 2,132 0,133 eEncodingUint,134 eFormatHex,135 {dwarf_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,136 LLDB_INVALID_REGNUM},137 nullptr,138 nullptr,139 nullptr,140 },141 {"r7",142 "",143 2,144 0,145 eEncodingUint,146 eFormatHex,147 {dwarf_r7, dwarf_r7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,148 LLDB_INVALID_REGNUM},149 nullptr,150 nullptr,151 nullptr,152 },153 {"r8",154 "",155 2,156 0,157 eEncodingUint,158 eFormatHex,159 {dwarf_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,160 LLDB_INVALID_REGNUM},161 nullptr,162 nullptr,163 nullptr,164 },165 {"r9",166 "",167 2,168 0,169 eEncodingUint,170 eFormatHex,171 {dwarf_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,172 LLDB_INVALID_REGNUM},173 nullptr,174 nullptr,175 nullptr,176 },177 {"r10",178 "",179 2,180 0,181 eEncodingUint,182 eFormatHex,183 {dwarf_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,184 LLDB_INVALID_REGNUM},185 nullptr,186 nullptr,187 nullptr,188 },189 {"r11",190 "",191 2,192 0,193 eEncodingUint,194 eFormatHex,195 {dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,196 LLDB_INVALID_REGNUM},197 nullptr,198 nullptr,199 nullptr,200 },201 {"r12",202 "",203 2,204 0,205 eEncodingUint,206 eFormatHex,207 {dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,208 LLDB_INVALID_REGNUM},209 nullptr,210 nullptr,211 nullptr,212 },213 {"r13",214 "",215 2,216 0,217 eEncodingUint,218 eFormatHex,219 {dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,220 LLDB_INVALID_REGNUM},221 nullptr,222 nullptr,223 nullptr,224 },225 {"r14",226 "",227 2,228 0,229 eEncodingUint,230 eFormatHex,231 {dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,232 LLDB_INVALID_REGNUM},233 nullptr,234 nullptr,235 nullptr,236 },237 {"r15",238 "",239 2,240 0,241 eEncodingUint,242 eFormatHex,243 {dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,244 LLDB_INVALID_REGNUM},245 nullptr,246 nullptr,247 nullptr,248 }};249 250static const uint32_t k_num_register_infos =251 sizeof(g_register_infos) / sizeof(RegisterInfo);252 253const lldb_private::RegisterInfo *254ABISysV_msp430::GetRegisterInfoArray(uint32_t &count) {255 // Make the C-string names and alt_names for the register infos into const256 // C-string values by having the ConstString unique the names in the global257 // constant C-string pool.258 count = k_num_register_infos;259 return g_register_infos;260}261 262size_t ABISysV_msp430::GetRedZoneSize() const { return 0; }263 264//------------------------------------------------------------------265// Static Functions266//------------------------------------------------------------------267 268ABISP269ABISysV_msp430::CreateInstance(lldb::ProcessSP process_sp,270 const ArchSpec &arch) {271 if (arch.GetTriple().getArch() == llvm::Triple::msp430) {272 return ABISP(273 new ABISysV_msp430(std::move(process_sp), MakeMCRegisterInfo(arch)));274 }275 return ABISP();276}277 278bool ABISysV_msp430::PrepareTrivialCall(Thread &thread, lldb::addr_t sp,279 lldb::addr_t pc, lldb::addr_t ra,280 llvm::ArrayRef<addr_t> args) const {281 // we don't use the traditional trivial call specialized for jit282 return false;283}284 285bool ABISysV_msp430::GetArgumentValues(Thread &thread,286 ValueList &values) const {287 return false;288}289 290Status ABISysV_msp430::SetReturnValueObject(lldb::StackFrameSP &frame_sp,291 lldb::ValueObjectSP &new_value_sp) {292 return Status();293}294 295ValueObjectSP ABISysV_msp430::GetReturnValueObjectSimple(296 Thread &thread, CompilerType &return_compiler_type) const {297 ValueObjectSP return_valobj_sp;298 return return_valobj_sp;299}300 301ValueObjectSP ABISysV_msp430::GetReturnValueObjectImpl(302 Thread &thread, CompilerType &return_compiler_type) const {303 ValueObjectSP return_valobj_sp;304 return return_valobj_sp;305}306 307// called when we are on the first instruction of a new function308UnwindPlanSP ABISysV_msp430::CreateFunctionEntryUnwindPlan() {309 uint32_t sp_reg_num = dwarf_sp;310 uint32_t pc_reg_num = dwarf_pc;311 312 UnwindPlan::Row row;313 row.GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 2);314 row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -2, true);315 row.SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);316 317 auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);318 plan_sp->AppendRow(std::move(row));319 plan_sp->SetSourceName("msp430 at-func-entry default");320 plan_sp->SetSourcedFromCompiler(eLazyBoolNo);321 return plan_sp;322}323 324UnwindPlanSP ABISysV_msp430::CreateDefaultUnwindPlan() {325 uint32_t fp_reg_num = dwarf_fp;326 uint32_t sp_reg_num = dwarf_sp;327 uint32_t pc_reg_num = dwarf_pc;328 329 UnwindPlan::Row row;330 row.GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 2);331 row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -2, true);332 row.SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);333 row.SetRegisterLocationToUnspecified(fp_reg_num, true);334 335 auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);336 plan_sp->AppendRow(std::move(row));337 plan_sp->SetSourceName("msp430 default unwind plan");338 plan_sp->SetSourcedFromCompiler(eLazyBoolNo);339 plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);340 return plan_sp;341}342 343bool ABISysV_msp430::RegisterIsVolatile(const RegisterInfo *reg_info) {344 return !RegisterIsCalleeSaved(reg_info);345}346 347bool ABISysV_msp430::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {348 int reg = ((reg_info->byte_offset) / 2);349 350 bool save = (reg >= 4) && (reg <= 10);351 return save;352}353 354void ABISysV_msp430::Initialize(void) {355 PluginManager::RegisterPlugin(356 GetPluginNameStatic(), "System V ABI for msp430 targets", CreateInstance);357}358 359void ABISysV_msp430::Terminate(void) {360 PluginManager::UnregisterPlugin(CreateInstance);361}362