[lldb][RISCV] function calls support in lldb expressions by dlav-sc · Pull Request #99336 · llvm/llvm-project (original) (raw)

@llvm/pr-subscribers-lldb

Author: None (dlav-sc)

Changes

To make function calls inside lldb expressions ABI support, JIT engine support are required. This patch augments corresponding functionality to RISCV ABI and implements RISCV relocation resolver in JIT, which allows to make function calls with integer and void function arguments and return value. Also it adds RISCV specific DirectToIndirectFunctionCallsReplacement IR pass, that allows to make assembly jumps at any 64bit address without RISCV large code model, which has not been implemented yet. This pass is needed, because jitted code contains more that +-2GB jumps, which are not available in RISCV without large code model now.

Fixed tests:

TestCallThatRestarts.ExprCommandThatRestartsTestCase
TestMainThreadExit.ThreadExitTestCase
TestSBValuePersist.SBValuePersistTestCase
TestThisClassTypeMixing.TestCase
Test11588.Issue11581TestCase
TestExprsChar.ExprCharTestCase
TestExpressions.TestExpressions
TestCallWithTimeout.ExprCommandWithTimeoutsTestCase
TestInlineNamespace.TestInlineNamespace
TestInlineNamespaceAlias.TestInlineNamespace
TestSetValues.SetValuesTestCase
TestValueAPIAddressOfVoidStar.ValueAPIVoidStarTestCase
TestXValuePrinting.ExprXValuePrintingTestCase
lldbsuite.test.lldbtest.TestRedefinitionsInInlines
lldbsuite.test.lldbtest.TestVirtualOverload
TestSetValues.SetValuesTestCase
TestExprs.BasicExprCommandsTestCase
TestExprHelpExamples.Radar9673644TestCase
TestExprEntryBP.ExprEntryBPTestCase
TestExprInsideLambdas.ExprInsideLambdaTestCase
TestConstStaticIntegralMemberInt128.TestCase
TestDWIMPrint.TestCase
TestCPPStaticMembers.TestCase
TestNestedPersistentTypes.NestedPersistentTypesTestCase
TestSaveJITObjects.SaveJITObjectsTestCase
TestNamespaceLookup.NamespaceLookupTestCase
TestCCallingConventions.TestCase
TestCppTypedef.TestCppTypedef
TestUnwindExpression.UnwindFromExpressionTest
TestCxxChar8_t.CxxChar8_tTestCase
TestCallCPPFunction.CallCPPFunctionTestCase
TestExprDoesntBlock.ExprDoesntDeadlockTestCase
TestEnumTypes.EnumTypesTestCase
TestAnonymous.AnonymousTestCase

Patch is 35.55 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/99336.diff

15 Files Affected:

diff --git a/lldb/include/lldb/Core/Architecture.h b/lldb/include/lldb/Core/Architecture.h index b6fc1a20e1e69..ca6a9207d8012 100644 --- a/lldb/include/lldb/Core/Architecture.h +++ b/lldb/include/lldb/Core/Architecture.h @@ -12,6 +12,7 @@ #include "lldb/Core/PluginInterface.h" #include "lldb/Target/DynamicRegisterInfo.h" #include "lldb/Target/MemoryTagManager.h" +#include "llvm/IR/LegacyPassManager.h"

namespace lldb_private {

@@ -129,6 +130,17 @@ class Architecture : public PluginInterface { RegisterContext &reg_context) const { return false; } +

};

} // namespace lldb_private diff --git a/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp b/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp index 6395f5bb5bd9b..f3edee1dd6dc1 100644 --- a/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp +++ b/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp @@ -10,7 +10,9 @@

#include #include +#include

+#include "llvm/ADT/STLExtras.h" #include "llvm/IR/DerivedTypes.h"

#include "lldb/Core/PluginManager.h" @@ -19,6 +21,7 @@ #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/RegisterValue.h"

#define DEFINE_REG_NAME(reg_num) ConstString(#reg_num).GetCString() @@ -163,11 +166,83 @@ TotalArgsSizeInWords(bool is_rv64, return total_size; }

+static bool UpdateRegister(RegisterContext *reg_ctx,

bool ABISysV_riscv::PrepareTrivialCall( @@ -221,14 +296,14 @@ bool ABISysV_riscv::PrepareTrivialCall( assert(prototype.getFunctionNumParams() == args.size());

const size_t num_args = args.size();

@@ -259,7 +334,7 @@ bool ABISysV_riscv::PrepareTrivialCall( ++reg_index; }

diff --git a/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.h b/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.h index d8cf008dbb0bf..04ec018c8a718 100644 --- a/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.h +++ b/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.h @@ -124,6 +124,9 @@ class ABISysV_riscv : public lldb_private::RegInfoBasedABI { using lldb_private::RegInfoBasedABI::RegInfoBasedABI; // Call CreateInstance // instead. bool m_is_rv64; // true if target is riscv64; false if target is riscv32

};

#endif // liblldb_ABISysV_riscv_h_ diff --git a/lldb/source/Plugins/Architecture/CMakeLists.txt b/lldb/source/Plugins/Architecture/CMakeLists.txt index 9ed8edf70af3f..78cdaa0bdf2d4 100644 --- a/lldb/source/Plugins/Architecture/CMakeLists.txt +++ b/lldb/source/Plugins/Architecture/CMakeLists.txt @@ -2,3 +2,4 @@ add_subdirectory(Arm) add_subdirectory(Mips) add_subdirectory(PPC64) add_subdirectory(AArch64) +add_subdirectory(RISCV) diff --git a/lldb/source/Plugins/Architecture/RISCV/ArchitectureRISCV.cpp b/lldb/source/Plugins/Architecture/RISCV/ArchitectureRISCV.cpp new file mode 100644 index 0000000000000..e4608b41bd787 --- /dev/null +++ b/lldb/source/Plugins/Architecture/RISCV/ArchitectureRISCV.cpp @@ -0,0 +1,55 @@ +//===-- ArchitectureRISCV.cpp----------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "Plugins/Architecture/RISCV/ArchitectureRISCV.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/ArchSpec.h" + +#include "llvm/IR/LegacyPassManager.h" + +#include "DirectToIndirectFCR.h" + +using namespace lldb_private; +using namespace lldb; + +LLDB_PLUGIN_DEFINE(ArchitectureRISCV) + +void ArchitectureRISCV::Initialize() {

+} + +void ArchitectureRISCV::Terminate() {

+#include "llvm/IR/Function.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/InstIterator.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Value.h" +#include "llvm/InitializePasses.h" +#include "llvm/Support/Casting.h" +#include "llvm/Transforms/Utils/BasicBlockUtils.h" + +#include "Plugins/Architecture/RISCV/DirectToIndirectFCR.h" + +#include "lldb/Core/Architecture.h" +#include "lldb/Core/Module.h" +#include "lldb/Symbol/Symtab.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/Log.h" + +#include + +using namespace llvm; +using namespace lldb_private; + +namespace { +std::string GetValueTypeStr(const llvm::Type *value_ty) {

+#include "llvm/Pass.h" + +namespace lldb_private { + +class ExecutionContext; + +// During the lldb expression execution lldb wraps a user expression, jittes +// fabricated code and then puts it into the stack memory. Thus, if user tried +// to make a function call there will be a jump from a stack address to a code +// sections's address. RISC-V Architecture doesn't have a large code model yet +// and can make only a +-2GiB jumps, but in 64-bit architecture a distance +// between stack addresses and code sections's addresses is longer. Therefore, +// relocations resolver obtains an invalid address. To avoid such problem, this +// pass should be used. It replaces function calls with appropriate function's +// addresses explicitly. By doing so it removes relocations related to function +// calls. This pass should be cosidered as temprorary solution until a large +// code model will be approved. +class DirectToIndirectFCR : public llvm::FunctionPass { +