]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/source/Plugins/ABI/SysV-arc/ABISysV_arc.cpp
Merge ^/head r357662 through r357854.
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / source / Plugins / ABI / SysV-arc / ABISysV_arc.cpp
1 //===-- ABISysV_arc.cpp ---------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "ABISysV_arc.h"
10
11 // C Includes
12 // C++ Includes
13 #include <array>
14 #include <limits>
15 #include <type_traits>
16
17 // Other libraries and framework includes
18 #include "llvm/ADT/Triple.h"
19 #include "llvm/IR/DerivedTypes.h"
20 #include "llvm/Support/MathExtras.h"
21
22 #include "lldb/Core/Module.h"
23 #include "lldb/Core/PluginManager.h"
24 #include "lldb/Core/Value.h"
25 #include "lldb/Core/ValueObjectConstResult.h"
26 #include "lldb/Core/ValueObjectMemory.h"
27 #include "lldb/Core/ValueObjectRegister.h"
28 #include "lldb/Symbol/UnwindPlan.h"
29 #include "lldb/Target/Process.h"
30 #include "lldb/Target/RegisterContext.h"
31 #include "lldb/Target/StackFrame.h"
32 #include "lldb/Target/Target.h"
33 #include "lldb/Target/Thread.h"
34 #include "lldb/Utility/ConstString.h"
35 #include "lldb/Utility/RegisterValue.h"
36 #include "lldb/Utility/Status.h"
37
38 #define DEFINE_REG_NAME(reg_num)      ConstString(#reg_num).GetCString()
39 #define DEFINE_REG_NAME_STR(reg_name) ConstString(reg_name).GetCString()
40
41 // The ABI is not a source of such information as size, offset, encoding, etc.
42 // of a register. Just provides correct dwarf and eh_frame numbers.
43
44 #define DEFINE_GENERIC_REGISTER_STUB(dwarf_num, str_name, generic_num)        \
45   {                                                                           \
46     DEFINE_REG_NAME(dwarf_num), DEFINE_REG_NAME_STR(str_name),                \
47     0, 0, eEncodingInvalid, eFormatDefault,                                   \
48     { dwarf_num, dwarf_num, generic_num, LLDB_INVALID_REGNUM, dwarf_num },    \
49     nullptr, nullptr, nullptr, 0                                              \
50   }
51
52 #define DEFINE_REGISTER_STUB(dwarf_num, str_name) \
53   DEFINE_GENERIC_REGISTER_STUB(dwarf_num, str_name, LLDB_INVALID_REGNUM)
54
55 using namespace lldb;
56 using namespace lldb_private;
57
58 namespace {
59 namespace dwarf {
60 enum regnums {
61   r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16,
62   r17, r18, r19, r20, r21, r22, r23, r24, r25, r26,
63   r27, fp = r27, r28, sp = r28, r29, r30, r31, blink = r31,
64   r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45, r46,
65   r47, r48, r49, r50, r51, r52, r53, r54, r55, r56, r57, r58, r59, r60,
66   /*reserved,*/ /*limm indicator,*/ r63 = 63, pc = 70, status32 = 74
67 };
68
69 static const std::array<RegisterInfo, 64> g_register_infos = { {
70     DEFINE_GENERIC_REGISTER_STUB(r0, nullptr, LLDB_REGNUM_GENERIC_ARG1),
71     DEFINE_GENERIC_REGISTER_STUB(r1, nullptr, LLDB_REGNUM_GENERIC_ARG2),
72     DEFINE_GENERIC_REGISTER_STUB(r2, nullptr, LLDB_REGNUM_GENERIC_ARG3),
73     DEFINE_GENERIC_REGISTER_STUB(r3, nullptr, LLDB_REGNUM_GENERIC_ARG4),
74     DEFINE_GENERIC_REGISTER_STUB(r4, nullptr, LLDB_REGNUM_GENERIC_ARG5),
75     DEFINE_GENERIC_REGISTER_STUB(r5, nullptr, LLDB_REGNUM_GENERIC_ARG6),
76     DEFINE_GENERIC_REGISTER_STUB(r6, nullptr, LLDB_REGNUM_GENERIC_ARG7),
77     DEFINE_GENERIC_REGISTER_STUB(r7, nullptr, LLDB_REGNUM_GENERIC_ARG8),
78     DEFINE_REGISTER_STUB(r8, nullptr),
79     DEFINE_REGISTER_STUB(r9, nullptr),
80     DEFINE_REGISTER_STUB(r10, nullptr),
81     DEFINE_REGISTER_STUB(r11, nullptr),
82     DEFINE_REGISTER_STUB(r12, nullptr),
83     DEFINE_REGISTER_STUB(r13, nullptr),
84     DEFINE_REGISTER_STUB(r14, nullptr),
85     DEFINE_REGISTER_STUB(r15, nullptr),
86     DEFINE_REGISTER_STUB(r16, nullptr),
87     DEFINE_REGISTER_STUB(r17, nullptr),
88     DEFINE_REGISTER_STUB(r18, nullptr),
89     DEFINE_REGISTER_STUB(r19, nullptr),
90     DEFINE_REGISTER_STUB(r20, nullptr),
91     DEFINE_REGISTER_STUB(r21, nullptr),
92     DEFINE_REGISTER_STUB(r22, nullptr),
93     DEFINE_REGISTER_STUB(r23, nullptr),
94     DEFINE_REGISTER_STUB(r24, nullptr),
95     DEFINE_REGISTER_STUB(r25, nullptr),
96     DEFINE_REGISTER_STUB(r26, "gp"),
97     DEFINE_GENERIC_REGISTER_STUB(r27, "fp", LLDB_REGNUM_GENERIC_FP),
98     DEFINE_GENERIC_REGISTER_STUB(r28, "sp", LLDB_REGNUM_GENERIC_SP),
99     DEFINE_REGISTER_STUB(r29, "ilink"),
100     DEFINE_REGISTER_STUB(r30, nullptr),
101     DEFINE_GENERIC_REGISTER_STUB(r31, "blink", LLDB_REGNUM_GENERIC_RA),
102     DEFINE_REGISTER_STUB(r32, nullptr),
103     DEFINE_REGISTER_STUB(r33, nullptr),
104     DEFINE_REGISTER_STUB(r34, nullptr),
105     DEFINE_REGISTER_STUB(r35, nullptr),
106     DEFINE_REGISTER_STUB(r36, nullptr),
107     DEFINE_REGISTER_STUB(r37, nullptr),
108     DEFINE_REGISTER_STUB(r38, nullptr),
109     DEFINE_REGISTER_STUB(r39, nullptr),
110     DEFINE_REGISTER_STUB(r40, nullptr),
111     DEFINE_REGISTER_STUB(r41, nullptr),
112     DEFINE_REGISTER_STUB(r42, nullptr),
113     DEFINE_REGISTER_STUB(r43, nullptr),
114     DEFINE_REGISTER_STUB(r44, nullptr),
115     DEFINE_REGISTER_STUB(r45, nullptr),
116     DEFINE_REGISTER_STUB(r46, nullptr),
117     DEFINE_REGISTER_STUB(r47, nullptr),
118     DEFINE_REGISTER_STUB(r48, nullptr),
119     DEFINE_REGISTER_STUB(r49, nullptr),
120     DEFINE_REGISTER_STUB(r50, nullptr),
121     DEFINE_REGISTER_STUB(r51, nullptr),
122     DEFINE_REGISTER_STUB(r52, nullptr),
123     DEFINE_REGISTER_STUB(r53, nullptr),
124     DEFINE_REGISTER_STUB(r54, nullptr),
125     DEFINE_REGISTER_STUB(r55, nullptr),
126     DEFINE_REGISTER_STUB(r56, nullptr),
127     DEFINE_REGISTER_STUB(r57, nullptr),
128     DEFINE_REGISTER_STUB(r58, "accl"),
129     DEFINE_REGISTER_STUB(r59, "acch"),
130     DEFINE_REGISTER_STUB(r60, "lp_count"),
131     DEFINE_REGISTER_STUB(r63, "pcl"),
132     DEFINE_GENERIC_REGISTER_STUB(pc, nullptr, LLDB_REGNUM_GENERIC_PC),
133     DEFINE_GENERIC_REGISTER_STUB(status32, nullptr, LLDB_REGNUM_GENERIC_FLAGS)} };
134 } // namespace dwarf
135 } // namespace
136
137 const RegisterInfo *ABISysV_arc::GetRegisterInfoArray(uint32_t &count) {
138   count = dwarf::g_register_infos.size();
139   return dwarf::g_register_infos.data();
140 }
141
142 size_t ABISysV_arc::GetRedZoneSize() const { return 0; }
143
144 bool ABISysV_arc::IsRegisterFileReduced(RegisterContext &reg_ctx) const {
145   if (!m_is_reg_file_reduced) {
146     const auto *const rf_build_reg = reg_ctx.GetRegisterInfoByName("rf_build");
147     
148     const auto reg_value = reg_ctx.ReadRegisterAsUnsigned(rf_build_reg,
149                                                           /*fail_value*/ 0);
150     // RF_BUILD "Number of Entries" bit.
151     const uint32_t rf_entries_bit = 1U << 9U;
152     m_is_reg_file_reduced = (reg_value | rf_entries_bit) != 0;
153   }
154
155   return m_is_reg_file_reduced.getValueOr(false);
156 }
157
158 //------------------------------------------------------------------
159 // Static Functions
160 //------------------------------------------------------------------
161
162 ABISP ABISysV_arc::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) {
163   return llvm::Triple::arc == arch.GetTriple().getArch() ?
164       ABISP(new ABISysV_arc(std::move(process_sp), MakeMCRegisterInfo(arch))) :
165       ABISP();
166 }
167
168 namespace {
169 const size_t word_size = 4U;
170 const size_t reg_size = word_size;
171
172 inline size_t AugmentArgSize(size_t size_in_bytes) {
173   return llvm::alignTo(size_in_bytes, word_size);
174 }
175
176 size_t TotalArgsSizeInWords(const llvm::ArrayRef<ABI::CallArgument> &args) {
177   size_t total_size = 0;
178   for (const auto &arg : args)
179     total_size +=
180         (ABI::CallArgument::TargetValue == arg.type ? AugmentArgSize(arg.size)
181                                                     : reg_size) /
182         word_size;
183
184   return total_size;
185 }
186 } // namespace
187
188 bool ABISysV_arc::PrepareTrivialCall(Thread &thread, addr_t sp,
189                                      addr_t func_addr, addr_t return_addr,
190                                      llvm::ArrayRef<addr_t> args) const {
191   // We don't use the traditional trivial call specialized for jit.
192   return false;
193 }
194
195 bool ABISysV_arc::PrepareTrivialCall(Thread &thread, addr_t sp, addr_t pc,
196     addr_t ra, llvm::Type &prototype,
197     llvm::ArrayRef<ABI::CallArgument> args) const {
198   auto reg_ctx = thread.GetRegisterContext();
199   if (!reg_ctx)
200     return false;
201
202   uint32_t pc_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
203       eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
204   if (pc_reg == LLDB_INVALID_REGNUM)
205     return false;
206
207   uint32_t ra_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
208       eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
209   if (ra_reg == LLDB_INVALID_REGNUM)
210     return false;
211
212   uint32_t sp_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
213       eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
214   if (sp_reg == LLDB_INVALID_REGNUM)
215     return false;
216
217   Status error;
218   ProcessSP process = thread.GetProcess();
219   if (!process)
220     return false;
221
222   // Push host data onto target.
223   for (const auto &arg : args) {
224     // Skip over target values.
225     if (arg.type == ABI::CallArgument::TargetValue)
226       continue;
227
228     // Create space on the stack for this data 4-byte aligned.
229     sp -= AugmentArgSize(arg.size);
230
231     if (process->WriteMemory(sp, arg.data_up.get(), arg.size, error) < arg.size
232         || error.Fail())
233       return false;
234
235     // Update the argument with the target pointer.
236     *const_cast<addr_t *>(&arg.value) = sp;
237   }
238
239   // Make sure number of parameters matches prototype.
240   assert(!prototype.isFunctionVarArg());
241   assert(prototype.getFunctionNumParams() == args.size());
242   
243   const size_t regs_for_args_count = IsRegisterFileReduced(*reg_ctx) ? 4U : 8U;
244
245   // Number of arguments passed on stack.
246   auto args_size = TotalArgsSizeInWords(args);
247   auto on_stack =
248       args_size <= regs_for_args_count ? 0 : args_size - regs_for_args_count;
249   auto offset = on_stack * word_size;
250
251   uint8_t reg_value[reg_size];
252   size_t reg_index = LLDB_REGNUM_GENERIC_ARG1;
253
254   for (const auto &arg : args) {
255     auto value = reinterpret_cast<const uint8_t *>(&arg.value);
256     auto size =
257         ABI::CallArgument::TargetValue == arg.type ? arg.size : reg_size;
258
259     // Pass arguments via registers.
260     while (size > 0 && reg_index < regs_for_args_count) {
261       size_t byte_index = 0;
262       auto end = size < reg_size ? size : reg_size;
263
264       while (byte_index < end) {
265         reg_value[byte_index++] = *(value++);
266         --size;
267       }
268
269       while (byte_index < reg_size) {
270         reg_value[byte_index++] = 0;
271       }
272
273       RegisterValue reg_val_obj(reg_value, reg_size, eByteOrderLittle);
274       if (!reg_ctx->WriteRegister(
275             reg_ctx->GetRegisterInfo(eRegisterKindGeneric, reg_index),
276             reg_val_obj))
277         return false;
278
279       // NOTE: It's unsafe to iterate through LLDB_REGNUM_GENERICs.
280       ++reg_index;
281     }
282
283     if (reg_index < regs_for_args_count || size == 0)
284       continue;
285
286     // Remaining arguments are passed on the stack.
287     if (process->WriteMemory(sp - offset, value, size, error) < size ||
288         !error.Success())
289       return false;
290
291     offset -= AugmentArgSize(size);
292   }
293
294   // Set stack pointer immediately below arguments.
295   sp -= on_stack * word_size;
296
297   // Update registers with current function call state.
298   reg_ctx->WriteRegisterFromUnsigned(pc_reg, pc);
299   reg_ctx->WriteRegisterFromUnsigned(ra_reg, ra);
300   reg_ctx->WriteRegisterFromUnsigned(sp_reg, sp);
301
302   return true;
303 }
304
305 bool ABISysV_arc::GetArgumentValues(Thread &thread, ValueList &values) const {
306   return false;
307 }
308
309 Status ABISysV_arc::SetReturnValueObject(StackFrameSP &frame_sp,
310                                          ValueObjectSP &new_value_sp) {
311   Status result;
312   if (!new_value_sp) {
313     result.SetErrorString("Empty value object for return value.");
314     return result;
315   }
316
317   CompilerType compiler_type = new_value_sp->GetCompilerType();
318   if (!compiler_type) {
319     result.SetErrorString("Null clang type for return value.");
320     return result;
321   }
322
323   auto &reg_ctx = *frame_sp->GetThread()->GetRegisterContext();
324
325   bool is_signed = false;
326   if (!compiler_type.IsIntegerOrEnumerationType(is_signed) &&
327       !compiler_type.IsPointerType()) {
328     result.SetErrorString("We don't support returning other types at present");
329     return result;
330   }
331
332   DataExtractor data;
333   size_t num_bytes = new_value_sp->GetData(data, result);
334
335   if (result.Fail()) {
336     result.SetErrorStringWithFormat(
337         "Couldn't convert return value to raw data: %s", result.AsCString());
338     return result;
339   }
340
341   if (num_bytes <= 2 * reg_size) {
342     offset_t offset = 0;
343     uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
344
345     auto reg_info =
346         reg_ctx.GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
347     if (!reg_ctx.WriteRegisterFromUnsigned(reg_info, raw_value)) {
348       result.SetErrorStringWithFormat("Couldn't write value to register %s",
349                                       reg_info->name);
350       return result;
351     }
352
353     if (num_bytes <= reg_size)
354       return result; // Successfully written.
355
356     raw_value >>= 32;
357     reg_info =
358         reg_ctx.GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
359     if (!reg_ctx.WriteRegisterFromUnsigned(reg_info, raw_value)) {
360       result.SetErrorStringWithFormat("Couldn't write value to register %s",
361                                       reg_info->name);
362     }
363
364     return result;
365   }
366
367   result.SetErrorString(
368       "We don't support returning large integer values at present.");
369   return result;
370 }
371
372 namespace {
373 template <typename T>
374 void SetInteger(Scalar &scalar, uint64_t raw_value, bool is_signed) {
375   raw_value &= std::numeric_limits<T>::max();
376   if (is_signed)
377     scalar = static_cast<typename std::make_signed<T>::type>(raw_value);
378   else
379     scalar = static_cast<T>(raw_value);
380 }
381
382 bool SetSizedInteger(Scalar &scalar, uint64_t raw_value, uint8_t size_in_bytes,
383                      bool is_signed) {
384   switch (size_in_bytes) {
385   default:
386     return false;
387
388   case sizeof(uint64_t):
389     SetInteger<uint64_t>(scalar, raw_value, is_signed);
390     break;
391
392   case sizeof(uint32_t):
393     SetInteger<uint32_t>(scalar, raw_value, is_signed);
394     break;
395
396   case sizeof(uint16_t):
397     SetInteger<uint16_t>(scalar, raw_value, is_signed);
398     break;
399
400   case sizeof(uint8_t):
401     SetInteger<uint8_t>(scalar, raw_value, is_signed);
402     break;
403   }
404
405   return true;
406 }
407
408 bool SetSizedFloat(Scalar &scalar, uint64_t raw_value, uint8_t size_in_bytes) {
409   switch (size_in_bytes) {
410   default:
411     return false;
412
413   case sizeof(uint64_t):
414     scalar = *reinterpret_cast<double *>(&raw_value);
415     break;
416
417   case sizeof(uint32_t):
418     scalar = *reinterpret_cast<float *>(&raw_value);
419     break;
420   }
421
422   return true;
423 }
424
425 uint64_t ReadRawValue(const RegisterContextSP &reg_ctx, uint8_t size_in_bytes) {
426   auto reg_info_r0 =
427       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
428
429   // Extract the register context so we can read arguments from registers.
430   uint64_t raw_value =
431       reg_ctx->ReadRegisterAsUnsigned(reg_info_r0, 0) & UINT32_MAX;
432
433   if (sizeof(uint64_t) == size_in_bytes)
434     raw_value |= (reg_ctx->ReadRegisterAsUnsigned(
435                       reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
436                                                LLDB_REGNUM_GENERIC_ARG2), 0) &
437                   UINT64_MAX) << 32U;
438
439   return raw_value;
440 }
441 } // namespace
442
443 ValueObjectSP
444 ABISysV_arc::GetReturnValueObjectSimple(Thread &thread,
445                                         CompilerType &compiler_type) const {
446   if (!compiler_type)
447     return ValueObjectSP();
448
449   auto reg_ctx = thread.GetRegisterContext();
450   if (!reg_ctx)
451     return ValueObjectSP();
452
453   Value value;
454   value.SetCompilerType(compiler_type);
455
456   const uint32_t type_flags = compiler_type.GetTypeInfo();
457   // Integer return type.
458   if (type_flags & eTypeIsInteger) {
459     const size_t byte_size = compiler_type.GetByteSize(nullptr).getValueOr(0);
460     auto raw_value = ReadRawValue(reg_ctx, byte_size);
461
462     const bool is_signed = (type_flags & eTypeIsSigned) != 0;
463     if (!SetSizedInteger(value.GetScalar(), raw_value, byte_size, is_signed))
464       return ValueObjectSP();
465
466     value.SetValueType(Value::eValueTypeScalar);
467   }
468   // Pointer return type.
469   else if (type_flags & eTypeIsPointer) {
470     auto reg_info_r0 = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
471                                                 LLDB_REGNUM_GENERIC_ARG1);
472     value.GetScalar() = reg_ctx->ReadRegisterAsUnsigned(reg_info_r0, 0);
473
474     value.SetValueType(Value::eValueTypeScalar);
475   }
476   // Floating point return type.
477   else if (type_flags & eTypeIsFloat) {
478     uint32_t float_count = 0;
479     bool is_complex = false;
480
481     if (compiler_type.IsFloatingPointType(float_count, is_complex) &&
482         1 == float_count && !is_complex) {
483       const size_t byte_size = compiler_type.GetByteSize(nullptr).getValueOr(0);
484       auto raw_value = ReadRawValue(reg_ctx, byte_size);
485
486       if (!SetSizedFloat(value.GetScalar(), raw_value, byte_size))
487         return ValueObjectSP();
488     }
489   }
490   // Unsupported return type.
491   else
492     return ValueObjectSP();
493
494   return ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
495                                         value, ConstString(""));
496 }
497
498 ValueObjectSP ABISysV_arc::GetReturnValueObjectImpl(
499     Thread &thread, CompilerType &return_compiler_type) const {
500   ValueObjectSP return_valobj_sp;
501
502   if (!return_compiler_type)
503     return return_valobj_sp;
504
505   ExecutionContext exe_ctx(thread.shared_from_this());
506   return GetReturnValueObjectSimple(thread, return_compiler_type);
507 }
508
509 ValueObjectSP ABISysV_arc::GetReturnValueObjectImpl(Thread &thread,
510                                                     llvm::Type &retType) const {
511   auto reg_ctx = thread.GetRegisterContext();
512   if (!reg_ctx)
513     return ValueObjectSP();
514
515   Value value;
516   // Void return type.
517   if (retType.isVoidTy()) {
518     value.GetScalar() = 0;
519   }
520   // Integer return type.
521   else if (retType.isIntegerTy()) {
522     size_t byte_size = retType.getPrimitiveSizeInBits();
523     if (1 != byte_size) // For boolian type.
524       byte_size /= CHAR_BIT;
525
526     auto raw_value = ReadRawValue(reg_ctx, byte_size);
527
528     const bool is_signed = false; // IR Type doesn't provide this info.
529     if (!SetSizedInteger(value.GetScalar(), raw_value, byte_size, is_signed))
530       return ValueObjectSP();
531   }
532   // Pointer return type.
533   else if (retType.isPointerTy()) {
534     auto reg_info_r0 = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
535                                                 LLDB_REGNUM_GENERIC_ARG1);
536     value.GetScalar() = reg_ctx->ReadRegisterAsUnsigned(reg_info_r0, 0);
537     value.SetValueType(Value::eValueTypeScalar);
538   }
539   // Floating point return type.
540   else if (retType.isFloatingPointTy()) {
541     const size_t byte_size = retType.getPrimitiveSizeInBits() / CHAR_BIT;
542     auto raw_value = ReadRawValue(reg_ctx, byte_size);
543
544     if (!SetSizedFloat(value.GetScalar(), raw_value, byte_size))
545       return ValueObjectSP();
546   }
547   // Unsupported return type.
548   else
549     return ValueObjectSP();
550
551   return ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
552                                         value, ConstString(""));
553 }
554
555 bool ABISysV_arc::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
556   unwind_plan.Clear();
557   unwind_plan.SetRegisterKind(eRegisterKindDWARF);
558
559   UnwindPlan::RowSP row(new UnwindPlan::Row);
560
561   // Our Call Frame Address is the stack pointer value.
562   row->GetCFAValue().SetIsRegisterPlusOffset(dwarf::sp, 0);
563
564   // The previous PC is in the BLINK.
565   row->SetRegisterLocationToRegister(dwarf::pc, dwarf::blink, true);
566   unwind_plan.AppendRow(row);
567
568   // All other registers are the same.
569   unwind_plan.SetSourceName("arc at-func-entry default");
570   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
571
572   return true;
573 }
574
575 bool ABISysV_arc::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
576   return false;
577 }
578
579 bool ABISysV_arc::RegisterIsVolatile(const RegisterInfo *reg_info) {
580   if (nullptr == reg_info)
581     return false;
582
583   // Volatile registers are: r0..r12.
584   uint32_t regnum = reg_info->kinds[eRegisterKindDWARF];
585   if (regnum <= 12)
586     return true;
587
588   static const std::string ra_reg_name = "blink";
589   return ra_reg_name == reg_info->name;
590 }
591
592 void ABISysV_arc::Initialize() {
593   PluginManager::RegisterPlugin(GetPluginNameStatic(),
594                                 "System V ABI for ARC targets", CreateInstance);
595 }
596
597 void ABISysV_arc::Terminate() {
598   PluginManager::UnregisterPlugin(CreateInstance);
599 }
600
601 ConstString ABISysV_arc::GetPluginNameStatic() {
602   static ConstString g_name("sysv-arc");
603   return g_name;
604 }
605
606 //------------------------------------------------------------------
607 // PluginInterface protocol
608 //------------------------------------------------------------------
609
610 ConstString ABISysV_arc::GetPluginName() {
611   return GetPluginNameStatic();
612 }
613
614 uint32_t ABISysV_arc::GetPluginVersion() { return 1; }