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> ®s) 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