Skip to content

Commit

Permalink
[LLDB] [LoongArch] Add minimal LoongArch support
Browse files Browse the repository at this point in the history
Add as little code as possible to allow compiling lldb on LoongArch.
Actual functionality will be implemented later.

Reviewed By: SixWeining, DavidSpickett

Differential Revision: https://reviews.llvm.org/D136578
  • Loading branch information
Tiezhu Yang authored and DavidSpickett committed Oct 25, 2022
1 parent 76745d2 commit a3be778
Show file tree
Hide file tree
Showing 6 changed files with 293 additions and 0 deletions.
1 change: 1 addition & 0 deletions lldb/source/Plugins/Process/Linux/CMakeLists.txt
Expand Up @@ -8,6 +8,7 @@ add_lldb_library(lldbPluginProcessLinux
NativeRegisterContextLinux.cpp
NativeRegisterContextLinux_arm.cpp
NativeRegisterContextLinux_arm64.cpp
NativeRegisterContextLinux_loongarch64.cpp
NativeRegisterContextLinux_ppc64le.cpp
NativeRegisterContextLinux_riscv64.cpp
NativeRegisterContextLinux_s390x.cpp
Expand Down
@@ -0,0 +1,92 @@
//===-- NativeRegisterContextLinux_loongarch64.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
//
//===----------------------------------------------------------------------===//

#if defined(__loongarch__) && __loongarch_grlen == 64

#include "NativeRegisterContextLinux_loongarch64.h"

#include "lldb/Host/HostInfo.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Status.h"

#include "Plugins/Process/Linux/NativeProcessLinux.h"
#include "Plugins/Process/Linux/Procfs.h"

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_linux;

std::unique_ptr<NativeRegisterContextLinux>
NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
const ArchSpec &target_arch, NativeThreadLinux &native_thread) {
switch (target_arch.GetMachine()) {
case llvm::Triple::loongarch64: {
Flags opt_regsets;
auto register_info_up = std::make_unique<RegisterInfoPOSIX_loongarch64>(
target_arch, opt_regsets);
return std::make_unique<NativeRegisterContextLinux_loongarch64>(
target_arch, native_thread, std::move(register_info_up));
}
default:
llvm_unreachable("have no register context for architecture");
}
}

llvm::Expected<ArchSpec>
NativeRegisterContextLinux::DetermineArchitecture(lldb::tid_t tid) {
return HostInfo::GetArchitecture();
}

NativeRegisterContextLinux_loongarch64::NativeRegisterContextLinux_loongarch64(
const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
std::unique_ptr<RegisterInfoPOSIX_loongarch64> register_info_up)
: NativeRegisterContextRegisterInfo(native_thread,
register_info_up.release()),
NativeRegisterContextLinux(native_thread) {
::memset(&m_fpr, 0, sizeof(m_fpr));
::memset(&m_gpr, 0, sizeof(m_gpr));
}

const RegisterInfoPOSIX_loongarch64 &
NativeRegisterContextLinux_loongarch64::GetRegisterInfo() const {
return static_cast<const RegisterInfoPOSIX_loongarch64 &>(
NativeRegisterContextRegisterInfo::GetRegisterInfoInterface());
}

uint32_t NativeRegisterContextLinux_loongarch64::GetRegisterSetCount() const {
return GetRegisterInfo().GetRegisterSetCount();
}

const RegisterSet *NativeRegisterContextLinux_loongarch64::GetRegisterSet(
uint32_t set_index) const {
return GetRegisterInfo().GetRegisterSet(set_index);
}

Status NativeRegisterContextLinux_loongarch64::ReadRegister(
const RegisterInfo *reg_info, RegisterValue &reg_value) {
return Status("Failed to read register value");
}

Status NativeRegisterContextLinux_loongarch64::WriteRegister(
const RegisterInfo *reg_info, const RegisterValue &reg_value) {
return Status("Failed to write register value");
}

Status NativeRegisterContextLinux_loongarch64::ReadAllRegisterValues(
lldb::WritableDataBufferSP &data_sp) {
return Status("Failed to read all register values");
}

Status NativeRegisterContextLinux_loongarch64::WriteAllRegisterValues(
const lldb::DataBufferSP &data_sp) {
return Status("Failed to write all register values");
}

#endif // defined(__loongarch__) && __loongarch_grlen == 64
@@ -0,0 +1,67 @@
//===-- NativeRegisterContextLinux_loongarch64.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
//
//===----------------------------------------------------------------------===//

#if defined(__loongarch__) && __loongarch_grlen == 64

#ifndef lldb_NativeRegisterContextLinux_loongarch64_h
#define lldb_NativeRegisterContextLinux_loongarch64_h

#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
#include "Plugins/Process/Utility/RegisterInfoPOSIX_loongarch64.h"

#include <asm/ptrace.h>

namespace lldb_private {
namespace process_linux {

class NativeProcessLinux;

class NativeRegisterContextLinux_loongarch64
: public NativeRegisterContextLinux {
public:
NativeRegisterContextLinux_loongarch64(
const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
std::unique_ptr<RegisterInfoPOSIX_loongarch64> register_info_up);

uint32_t GetRegisterSetCount() const override;

const RegisterSet *GetRegisterSet(uint32_t set_index) const override;

Status ReadRegister(const RegisterInfo *reg_info,
RegisterValue &reg_value) override;

Status WriteRegister(const RegisterInfo *reg_info,
const RegisterValue &reg_value) override;

Status ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override;

Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;

protected:
void *GetGPRBuffer() override { return &m_gpr; }

void *GetFPRBuffer() override { return &m_fpr; }

size_t GetGPRSize() const override { return GetRegisterInfo().GetGPRSize(); }

size_t GetFPRSize() override { return GetRegisterInfo().GetFPRSize(); }

private:
RegisterInfoPOSIX_loongarch64::GPR m_gpr;

RegisterInfoPOSIX_loongarch64::FPR m_fpr;

const RegisterInfoPOSIX_loongarch64 &GetRegisterInfo() const;
};

} // namespace process_linux
} // namespace lldb_private

#endif // #ifndef lldb_NativeRegisterContextLinux_loongarch64_h

#endif // defined(__loongarch__) && __loongarch_grlen == 64
1 change: 1 addition & 0 deletions lldb/source/Plugins/Process/Utility/CMakeLists.txt
Expand Up @@ -49,6 +49,7 @@ add_lldb_library(lldbPluginProcessUtility
RegisterContextWindows_x86_64.cpp
RegisterInfoPOSIX_arm.cpp
RegisterInfoPOSIX_arm64.cpp
RegisterInfoPOSIX_loongarch64.cpp
RegisterInfoPOSIX_ppc64le.cpp
RegisterInfoPOSIX_riscv64.cpp
StopInfoMachException.cpp
Expand Down
@@ -0,0 +1,68 @@
//===-- RegisterInfoPOSIX_loongarch64.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 <cassert>
#include <lldb/Utility/Flags.h>
#include <stddef.h>

#include "lldb/lldb-defines.h"
#include "llvm/Support/Compiler.h"

#include "RegisterInfoPOSIX_loongarch64.h"

const lldb_private::RegisterInfo *
RegisterInfoPOSIX_loongarch64::GetRegisterInfoPtr(
const lldb_private::ArchSpec &target_arch) {
switch (target_arch.GetMachine()) {
default:
assert(false && "Unhandled target architecture.");
return nullptr;
}
}

uint32_t RegisterInfoPOSIX_loongarch64::GetRegisterInfoCount(
const lldb_private::ArchSpec &target_arch) {
switch (target_arch.GetMachine()) {
default:
assert(false && "Unhandled target architecture.");
return 0;
}
}

RegisterInfoPOSIX_loongarch64::RegisterInfoPOSIX_loongarch64(
const lldb_private::ArchSpec &target_arch, lldb_private::Flags flags)
: lldb_private::RegisterInfoAndSetInterface(target_arch),
m_register_info_p(GetRegisterInfoPtr(target_arch)),
m_register_info_count(GetRegisterInfoCount(target_arch)) {}

uint32_t RegisterInfoPOSIX_loongarch64::GetRegisterCount() const { return 0; }

size_t RegisterInfoPOSIX_loongarch64::GetGPRSize() const {
return sizeof(struct RegisterInfoPOSIX_loongarch64::GPR);
}

size_t RegisterInfoPOSIX_loongarch64::GetFPRSize() const {
return sizeof(struct RegisterInfoPOSIX_loongarch64::FPR);
}

const lldb_private::RegisterInfo *
RegisterInfoPOSIX_loongarch64::GetRegisterInfo() const {
return m_register_info_p;
}

size_t RegisterInfoPOSIX_loongarch64::GetRegisterSetCount() const { return 0; }

size_t RegisterInfoPOSIX_loongarch64::GetRegisterSetFromRegisterIndex(
uint32_t reg_index) const {
return LLDB_INVALID_REGNUM;
}

const lldb_private::RegisterSet *
RegisterInfoPOSIX_loongarch64::GetRegisterSet(size_t set_index) const {
return nullptr;
}
@@ -0,0 +1,64 @@
//===-- RegisterInfoPOSIX_loongarch64.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
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_LOONGARCH64_H
#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_LOONGARCH64_H

#include "RegisterInfoAndSetInterface.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/lldb-private.h"
#include <map>

class RegisterInfoPOSIX_loongarch64
: public lldb_private::RegisterInfoAndSetInterface {
public:
static const lldb_private::RegisterInfo *
GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch);
static uint32_t
GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch);

public:
struct GPR {
uint64_t gpr[32];

uint64_t orig_a0;
uint64_t csr_era;
uint64_t csr_badv;
uint64_t reserved[10];
};

struct FPR {
uint64_t fpr[32];
uint64_t fcc;
uint32_t fcsr;
};

RegisterInfoPOSIX_loongarch64(const lldb_private::ArchSpec &target_arch,
lldb_private::Flags flags);

size_t GetGPRSize() const override;

size_t GetFPRSize() const override;

const lldb_private::RegisterInfo *GetRegisterInfo() const override;

uint32_t GetRegisterCount() const override;

const lldb_private::RegisterSet *
GetRegisterSet(size_t reg_set) const override;

size_t GetRegisterSetCount() const override;

size_t GetRegisterSetFromRegisterIndex(uint32_t reg_index) const override;

private:
const lldb_private::RegisterInfo *m_register_info_p;
uint32_t m_register_info_count;
};

#endif

0 comments on commit a3be778

Please sign in to comment.