1 //===-- ABISysV_msp430.cpp --------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // 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/Core/ValueObjectConstResult.h"
16 #include "lldb/Core/ValueObjectMemory.h"
17 #include "lldb/Core/ValueObjectRegister.h"
18 #include "lldb/Symbol/UnwindPlan.h"
19 #include "lldb/Target/Process.h"
20 #include "lldb/Target/RegisterContext.h"
21 #include "lldb/Target/StackFrame.h"
22 #include "lldb/Target/Target.h"
23 #include "lldb/Target/Thread.h"
24 #include "lldb/Utility/ConstString.h"
25 #include "lldb/Utility/DataExtractor.h"
26 #include "lldb/Utility/Log.h"
27 #include "lldb/Utility/RegisterValue.h"
28 
29 #include "llvm/IR/DerivedTypes.h"
30 #include "llvm/TargetParser/Triple.h"
31 
32 using namespace lldb;
33 using namespace lldb_private;
34 
35 LLDB_PLUGIN_DEFINE_ADV(ABISysV_msp430, ABIMSP430)
36 
37 enum 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 
56 static 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 
250 static const uint32_t k_num_register_infos =
251     sizeof(g_register_infos) / sizeof(RegisterInfo);
252 
253 const lldb_private::RegisterInfo *
254 ABISysV_msp430::GetRegisterInfoArray(uint32_t &count) {
255   // Make the C-string names and alt_names for the register infos into const
256   // C-string values by having the ConstString unique the names in the global
257   // constant C-string pool.
258   count = k_num_register_infos;
259   return g_register_infos;
260 }
261 
262 size_t ABISysV_msp430::GetRedZoneSize() const { return 0; }
263 
264 //------------------------------------------------------------------
265 // Static Functions
266 //------------------------------------------------------------------
267 
268 ABISP
269 ABISysV_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 
278 bool 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 jit
282   return false;
283 }
284 
285 bool ABISysV_msp430::GetArgumentValues(Thread &thread,
286                                        ValueList &values) const {
287   return false;
288 }
289 
290 Status ABISysV_msp430::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
291                                             lldb::ValueObjectSP &new_value_sp) {
292   return Status();
293 }
294 
295 ValueObjectSP ABISysV_msp430::GetReturnValueObjectSimple(
296     Thread &thread, CompilerType &return_compiler_type) const {
297   ValueObjectSP return_valobj_sp;
298   return return_valobj_sp;
299 }
300 
301 ValueObjectSP 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 function
308 bool ABISysV_msp430::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
309   unwind_plan.Clear();
310   unwind_plan.SetRegisterKind(eRegisterKindDWARF);
311 
312   uint32_t sp_reg_num = dwarf_sp;
313   uint32_t pc_reg_num = dwarf_pc;
314 
315   UnwindPlan::RowSP row(new UnwindPlan::Row);
316   row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 2);
317   row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -2, true);
318   row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
319 
320   unwind_plan.AppendRow(row);
321   unwind_plan.SetSourceName("msp430 at-func-entry default");
322   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
323   return true;
324 }
325 
326 bool ABISysV_msp430::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
327   unwind_plan.Clear();
328   unwind_plan.SetRegisterKind(eRegisterKindDWARF);
329 
330   uint32_t fp_reg_num = dwarf_fp;
331   uint32_t sp_reg_num = dwarf_sp;
332   uint32_t pc_reg_num = dwarf_pc;
333 
334   UnwindPlan::RowSP row(new UnwindPlan::Row);
335   row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 2);
336   row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -2, true);
337   row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
338   row->SetRegisterLocationToUnspecified(fp_reg_num, true);
339 
340   unwind_plan.AppendRow(row);
341   unwind_plan.SetSourceName("msp430 default unwind plan");
342   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
343   unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
344   return true;
345 }
346 
347 bool ABISysV_msp430::RegisterIsVolatile(const RegisterInfo *reg_info) {
348   return !RegisterIsCalleeSaved(reg_info);
349 }
350 
351 bool ABISysV_msp430::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
352   int reg = ((reg_info->byte_offset) / 2);
353 
354   bool save = (reg >= 4) && (reg <= 10);
355   return save;
356 }
357 
358 void ABISysV_msp430::Initialize(void) {
359   PluginManager::RegisterPlugin(
360       GetPluginNameStatic(), "System V ABI for msp430 targets", CreateInstance);
361 }
362 
363 void ABISysV_msp430::Terminate(void) {
364   PluginManager::UnregisterPlugin(CreateInstance);
365 }
366