Skip to content

Commit

Permalink
[lldb] add architecture depended IR passes
Browse files Browse the repository at this point in the history
Function calls support in LLDB expressions for RISCV: 4 of 5

Adds architecture depended IR passes handler, that can apply architecture
specific IR passes before IRForTarget.
  • Loading branch information
dlav-sc committed Jul 17, 2024
1 parent 7074ef5 commit c4db74e
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 0 deletions.
12 changes: 12 additions & 0 deletions lldb/include/lldb/Core/Architecture.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

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

// Takes a Pass Manager and adds passes for this Architecture that should be
// run before IRForTarget
virtual std::unique_ptr<llvm::legacy::PassManager>
GetArchitectureCustomPasses(const ExecutionContext &exe_ctx,
const llvm::StringRef expr) const {
return nullptr;
}

static constexpr llvm::StringLiteral s_target_incompatibility_marker =
"target_incompatibility_detected";
};

} // namespace lldb_private
Expand Down
1 change: 1 addition & 0 deletions lldb/source/Plugins/Architecture/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ add_subdirectory(Arm)
add_subdirectory(Mips)
add_subdirectory(PPC64)
add_subdirectory(AArch64)
add_subdirectory(RISCV)
55 changes: 55 additions & 0 deletions lldb/source/Plugins/Architecture/RISCV/ArchitectureRISCV.cpp
Original file line number Diff line number Diff line change
@@ -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() {
PluginManager::RegisterPlugin(GetPluginNameStatic(),
"RISCV-specific algorithms",
&ArchitectureRISCV::Create);
}

void ArchitectureRISCV::Terminate() {
PluginManager::UnregisterPlugin(&ArchitectureRISCV::Create);
}

std::unique_ptr<Architecture> ArchitectureRISCV::Create(const ArchSpec &arch) {
if (!arch.GetTriple().isRISCV())
return nullptr;
return std::unique_ptr<Architecture>(new ArchitectureRISCV());
}

void ArchitectureRISCV::OverrideStopInfo(Thread &thread) const {}

std::unique_ptr<llvm::legacy::PassManager>
ArchitectureRISCV::GetArchitectureCustomPasses(
const ExecutionContext &exe_ctx, const llvm::StringRef expr) const {
// LLDB generates additional support functions like
// '_$__lldb_valid_pointer_check', that do not require custom passes
if (expr != "$__lldb_expr")
return nullptr;

std::unique_ptr<llvm::legacy::PassManager> custom_passes =
std::make_unique<llvm::legacy::PassManager>();
auto *P = createDirectToIndirectFCR(exe_ctx);
custom_passes->add(P);
return custom_passes;
}
34 changes: 34 additions & 0 deletions lldb/source/Plugins/Architecture/RISCV/ArchitectureRISCV.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//===-- ArchitectureRISCV.h -------------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#pragma once

#include "lldb/Core/Architecture.h"

namespace lldb_private {

class ArchitectureRISCV : public Architecture {
public:
static llvm::StringRef GetPluginNameStatic() { return "riscv"; }
static void Initialize();
static void Terminate();

llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }

void OverrideStopInfo(Thread &thread) const override;

std::unique_ptr<llvm::legacy::PassManager>
GetArchitectureCustomPasses(const ExecutionContext &exe_ctx,
const llvm::StringRef expr) const override;

private:
static std::unique_ptr<Architecture> Create(const ArchSpec &arch);
ArchitectureRISCV() = default;
};

} // namespace lldb_private
12 changes: 12 additions & 0 deletions lldb/source/Plugins/Architecture/RISCV/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
add_lldb_library(lldbPluginArchitectureRISCV PLUGIN
ArchitectureRISCV.cpp
DirectToIndirectFCR.cpp

LINK_LIBS
lldbPluginProcessUtility
lldbCore
lldbTarget
lldbUtility
LINK_COMPONENTS
Support
)
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/TargetParser/Triple.h"

#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/ErrorHandling.h"
Expand Down Expand Up @@ -1362,6 +1364,27 @@ lldb_private::Status ClangExpressionParser::DoPrepareForExecution(
custom_passes.EarlyPasses->run(*llvm_module_up);
}

std::unique_ptr<llvm::legacy::PassManager> arch_passes(nullptr);
if (lldb::TargetSP target_sp = exe_ctx.GetTargetSP()) {
Architecture *arch = target_sp->GetArchitecturePlugin();
if (arch) {
arch_passes =
arch->GetArchitectureCustomPasses(exe_ctx, m_expr.FunctionName());
}
}

if (arch_passes)
arch_passes->run(*llvm_module_up);

if (llvm_module_up->getNamedMetadata(
Architecture::s_target_incompatibility_marker)) {
err.SetErrorToGenericError();
err.SetErrorStringWithFormat(
"%s - Architecture passes failure on function %s\n. Function "
"contains unsupported function calls",
__FUNCTION__, m_expr.FunctionName());
}

execution_unit_sp = std::make_shared<IRExecutionUnit>(
m_llvm_context, // handed off here
llvm_module_up, // handed off here
Expand Down

0 comments on commit c4db74e

Please sign in to comment.