1 //===-- ABISysV_riscv.h -----------------------------------------*- 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 #ifndef liblldb_ABISysV_riscv_h_
10 #define liblldb_ABISysV_riscv_h_
11 
12 // Other libraries and framework includes
13 #include "llvm/TargetParser/Triple.h"
14 
15 // Project includes
16 #include "lldb/Target/ABI.h"
17 #include "lldb/Target/Process.h"
18 #include "lldb/Utility/Flags.h"
19 #include "lldb/lldb-private.h"
20 
21 class ABISysV_riscv : public lldb_private::RegInfoBasedABI {
22 public:
23   ~ABISysV_riscv() override = default;
24 
GetRedZoneSize()25   size_t GetRedZoneSize() const override { return 0; }
26 
27   bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp,
28                           lldb::addr_t functionAddress,
29                           lldb::addr_t returnAddress,
30                           llvm::ArrayRef<lldb::addr_t> args) const override;
31 
32   // Special thread plan for GDB style non-jit function calls.
33   bool
34   PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp,
35                      lldb::addr_t functionAddress, lldb::addr_t returnAddress,
36                      llvm::Type &prototype,
37                      llvm::ArrayRef<ABI::CallArgument> args) const override;
38 
39   bool GetArgumentValues(lldb_private::Thread &thread,
40                          lldb_private::ValueList &values) const override;
41 
42   lldb_private::Status
43   SetReturnValueObject(lldb::StackFrameSP &frame_sp,
44                        lldb::ValueObjectSP &new_value) override;
45 
46   lldb::ValueObjectSP
47   GetReturnValueObjectImpl(lldb_private::Thread &thread,
48                            lldb_private::CompilerType &type) const override;
49 
50   // Specialized to work with llvm IR types.
51   lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread,
52                                                llvm::Type &type) const override;
53 
54   bool
55   CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
56 
57   bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
58 
59   bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
60 
CallFrameAddressIsValid(lldb::addr_t cfa)61   bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
62     // The CFA must be 128 bit aligned, unless the E ABI is used
63     lldb_private::ArchSpec arch = GetProcessSP()->GetTarget().GetArchitecture();
64     lldb_private::Flags arch_flags = arch.GetFlags();
65     if (arch_flags.Test(lldb_private::ArchSpec::eRISCV_rve))
66       return (cfa & 0x3ull) == 0;
67     return (cfa & 0xfull) == 0;
68   }
69 
SetIsRV64(bool is_rv64)70   void SetIsRV64(bool is_rv64) { m_is_rv64 = is_rv64; }
71 
CodeAddressIsValid(lldb::addr_t pc)72   bool CodeAddressIsValid(lldb::addr_t pc) override {
73     // Calls can use the least significant bit to store auxiliary information,
74     // so no strict check is done for alignment.
75 
76     lldb_private::ArchSpec arch = GetProcessSP()->GetTarget().GetArchitecture();
77 
78     // <addr> & 2 set is a fault if C extension is not used.
79     lldb_private::Flags arch_flags(arch.GetFlags());
80     if (!arch_flags.Test(lldb_private::ArchSpec::eRISCV_rvc) && (pc & 2))
81       return false;
82 
83     // Make sure 64 bit addr_t only has lower 32 bits set on riscv32
84     llvm::Triple::ArchType machine = arch.GetMachine();
85     if (llvm::Triple::riscv32 == machine)
86       return (pc <= UINT32_MAX);
87 
88     return true;
89   }
90 
91   const lldb_private::RegisterInfo *
92   GetRegisterInfoArray(uint32_t &count) override;
93 
94   //------------------------------------------------------------------
95   // Static Functions
96   //------------------------------------------------------------------
97 
98   static void Initialize();
99 
100   static void Terminate();
101 
102   static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp,
103                                     const lldb_private::ArchSpec &arch);
104 
GetPluginNameStatic()105   static llvm::StringRef GetPluginNameStatic() { return "sysv-riscv"; }
106 
107   //------------------------------------------------------------------
108   // PluginInterface protocol
109   //------------------------------------------------------------------
110 
GetPluginName()111   llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
112 
113 protected:
114   void AugmentRegisterInfo(
115       std::vector<lldb_private::DynamicRegisterInfo::Register> &regs) override;
116 
117   bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
118 
119 private:
120   lldb::ValueObjectSP
121   GetReturnValueObjectSimple(lldb_private::Thread &thread,
122                              lldb_private::CompilerType &ast_type) const;
123 
124   using lldb_private::RegInfoBasedABI::RegInfoBasedABI; // Call CreateInstance
125                                                         // instead.
126   bool m_is_rv64; // true if target is riscv64; false if target is riscv32
127 };
128 
129 #endif // liblldb_ABISysV_riscv_h_
130