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