mirror of
https://github.com/thead-yocto-mirror/meta-openembedded
synced 2026-09-16 12:12:16 +02:00
Note: the adbd makefile can't be upstreamed to debian, because there is already an open PR upstream: https://salsa.debian.org/android-tools-team/android-platform-tools/-/merge_requests/4/diffs Signed-off-by: Etienne Cordonnier <ecordonnier@snap.com> Signed-off-by: Khem Raj <raj.khem@gmail.com>
652 lines
21 KiB
Diff
652 lines
21 KiB
Diff
From: Guo Ren <guoren@linux.alibaba.com>
|
|
Date: Wed, 29 Jun 2022 16:46:46 +0800
|
|
Subject: Add riscv64 support
|
|
|
|
This patch contains the dwarf unwind support for 64bit risc-v.
|
|
|
|
* DwarfCfa.cpp (cfa_def_cfa_register): setup register if CFA_REG is
|
|
not setup for riscv64
|
|
* Elf.cpp (GetRelPc): convert offset to virtual address for riscv64.
|
|
* ElfInterface.cpp (GetVirtAddrFromOffset): New for riscv64.
|
|
* RegsRiscv64.cpp (StepIfSignalHandler): Fix signal frame check.
|
|
libunwindstack/include/unwindstack/
|
|
* ElfInterface.h (GetVirtAddrFromOffset): New for riscv64.
|
|
libunwindstack/tests/
|
|
* DwarfCfaTest.cpp (cfa_def_cfa_register): ok for riscv64.
|
|
* RegsStepIfSignalHandlerTest.cpp (riscv64_step_if_signal_handler): Fix
|
|
testcase for riscv64
|
|
|
|
Test: Builds.
|
|
Test: All unit tests pass.
|
|
|
|
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
|
|
Signed-off-by: Lifang Xia <lifang_xia@linux.alibaba.com>
|
|
Signed-off-by: Mao Han <han_mao@linux.alibaba.com>
|
|
Change-Id: Ib21ddf23cc83f332af202df7bffcaceec16063e0
|
|
---
|
|
system/core/libunwindstack/Android.bp | 1 +
|
|
system/core/libunwindstack/Elf.cpp | 2 +
|
|
system/core/libunwindstack/Regs.cpp | 10 ++
|
|
system/core/libunwindstack/RegsRiscv64.cpp | 156 +++++++++++++++++++++
|
|
.../core/libunwindstack/include/unwindstack/Elf.h | 5 +
|
|
.../include/unwindstack/MachineRiscv64.h | 59 ++++++++
|
|
.../include/unwindstack/RegsGetLocal.h | 43 ++++++
|
|
.../include/unwindstack/RegsRiscv64.h | 59 ++++++++
|
|
.../include/unwindstack/UcontextRiscv64.h | 80 +++++++++++
|
|
.../include/unwindstack/UserRiscv64.h | 37 +++++
|
|
system/core/libunwindstack/tools/unwind.cpp | 3 +
|
|
.../core/libunwindstack/tools/unwind_symbols.cpp | 3 +
|
|
12 files changed, 458 insertions(+)
|
|
create mode 100644 system/core/libunwindstack/RegsRiscv64.cpp
|
|
create mode 100644 system/core/libunwindstack/include/unwindstack/MachineRiscv64.h
|
|
create mode 100644 system/core/libunwindstack/include/unwindstack/RegsRiscv64.h
|
|
create mode 100644 system/core/libunwindstack/include/unwindstack/UcontextRiscv64.h
|
|
create mode 100644 system/core/libunwindstack/include/unwindstack/UserRiscv64.h
|
|
|
|
diff --git a/system/core/libunwindstack/Android.bp b/system/core/libunwindstack/Android.bp
|
|
index 3695f72..f1f9c68 100644
|
|
--- a/system/core/libunwindstack/Android.bp
|
|
+++ b/system/core/libunwindstack/Android.bp
|
|
@@ -70,6 +70,7 @@ cc_library {
|
|
"RegsArm64.cpp",
|
|
"RegsX86.cpp",
|
|
"RegsX86_64.cpp",
|
|
+ "RegsRiscv64.cpp",
|
|
"RegsMips.cpp",
|
|
"RegsMips64.cpp",
|
|
"Unwinder.cpp",
|
|
diff --git a/system/core/libunwindstack/Elf.cpp b/system/core/libunwindstack/Elf.cpp
|
|
index f01b092..3c2088b 100644
|
|
--- a/system/core/libunwindstack/Elf.cpp
|
|
+++ b/system/core/libunwindstack/Elf.cpp
|
|
@@ -290,6 +290,8 @@ ElfInterface* Elf::CreateInterfaceFromMemory(Memory* memory) {
|
|
arch_ = ARCH_X86_64;
|
|
} else if (e_machine == EM_MIPS) {
|
|
arch_ = ARCH_MIPS64;
|
|
+ } else if (e_machine == EM_RISCV) {
|
|
+ arch_ = ARCH_RISCV64;
|
|
} else {
|
|
// Unsupported.
|
|
ALOGI("64 bit elf that is neither aarch64 nor x86_64 nor mips64: e_machine = %d\n",
|
|
diff --git a/system/core/libunwindstack/Regs.cpp b/system/core/libunwindstack/Regs.cpp
|
|
index c7dec52..447a554 100644
|
|
--- a/system/core/libunwindstack/Regs.cpp
|
|
+++ b/system/core/libunwindstack/Regs.cpp
|
|
@@ -27,12 +27,14 @@
|
|
#include <unwindstack/RegsArm64.h>
|
|
#include <unwindstack/RegsMips.h>
|
|
#include <unwindstack/RegsMips64.h>
|
|
+#include <unwindstack/RegsRiscv64.h>
|
|
#include <unwindstack/RegsX86.h>
|
|
#include <unwindstack/RegsX86_64.h>
|
|
#include <unwindstack/UserArm.h>
|
|
#include <unwindstack/UserArm64.h>
|
|
#include <unwindstack/UserMips.h>
|
|
#include <unwindstack/UserMips64.h>
|
|
+#include <unwindstack/UserRiscv64.h>
|
|
#include <unwindstack/UserX86.h>
|
|
#include <unwindstack/UserX86_64.h>
|
|
|
|
@@ -67,6 +69,8 @@ Regs* Regs::RemoteGet(pid_t pid) {
|
|
return RegsMips::Read(buffer.data());
|
|
case sizeof(mips64_user_regs):
|
|
return RegsMips64::Read(buffer.data());
|
|
+ case sizeof(riscv64_user_regs):
|
|
+ return RegsRiscv64::Read(buffer.data());
|
|
}
|
|
return nullptr;
|
|
}
|
|
@@ -85,6 +89,8 @@ Regs* Regs::CreateFromUcontext(ArchEnum arch, void* ucontext) {
|
|
return RegsMips::CreateFromUcontext(ucontext);
|
|
case ARCH_MIPS64:
|
|
return RegsMips64::CreateFromUcontext(ucontext);
|
|
+ case ARCH_RISCV64:
|
|
+ return RegsRiscv64::CreateFromUcontext(ucontext);
|
|
case ARCH_UNKNOWN:
|
|
default:
|
|
return nullptr;
|
|
@@ -104,6 +110,8 @@ ArchEnum Regs::CurrentArch() {
|
|
return ARCH_MIPS;
|
|
#elif defined(__mips__) && defined(__LP64__)
|
|
return ARCH_MIPS64;
|
|
+#elif defined(__riscv)
|
|
+ return ARCH_RISCV64;
|
|
#else
|
|
abort();
|
|
#endif
|
|
@@ -123,6 +131,8 @@ Regs* Regs::CreateFromLocal() {
|
|
regs = new RegsMips();
|
|
#elif defined(__mips__) && defined(__LP64__)
|
|
regs = new RegsMips64();
|
|
+#elif defined(__riscv)
|
|
+ regs = new RegsRiscv64();
|
|
#else
|
|
abort();
|
|
#endif
|
|
diff --git a/system/core/libunwindstack/RegsRiscv64.cpp b/system/core/libunwindstack/RegsRiscv64.cpp
|
|
new file mode 100644
|
|
index 0000000..887762a
|
|
--- /dev/null
|
|
+++ b/system/core/libunwindstack/RegsRiscv64.cpp
|
|
@@ -0,0 +1,156 @@
|
|
+/*
|
|
+ * Copyright (C) 2022 The Android Open Source Project
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
|
+ * you may not use this file except in compliance with the License.
|
|
+ * You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
|
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
+ * See the License for the specific language governing permissions and
|
|
+ * limitations under the License.
|
|
+ */
|
|
+
|
|
+#include <stdint.h>
|
|
+#include <string.h>
|
|
+
|
|
+#include <functional>
|
|
+
|
|
+#include <unwindstack/Elf.h>
|
|
+#include <unwindstack/MachineRiscv64.h>
|
|
+#include <unwindstack/MapInfo.h>
|
|
+#include <unwindstack/Memory.h>
|
|
+#include <unwindstack/RegsRiscv64.h>
|
|
+#include <unwindstack/UcontextRiscv64.h>
|
|
+#include <unwindstack/UserRiscv64.h>
|
|
+
|
|
+namespace unwindstack {
|
|
+
|
|
+RegsRiscv64::RegsRiscv64()
|
|
+ : RegsImpl<uint64_t>(RISCV64_REG_MAX, Location(LOCATION_REGISTER, RISCV64_REG_RA)) {}
|
|
+
|
|
+ArchEnum RegsRiscv64::Arch() {
|
|
+ return ARCH_RISCV64;
|
|
+}
|
|
+
|
|
+uint64_t RegsRiscv64::pc() {
|
|
+ return regs_[RISCV64_REG_PC];
|
|
+}
|
|
+
|
|
+uint64_t RegsRiscv64::sp() {
|
|
+ return regs_[RISCV64_REG_SP];
|
|
+}
|
|
+
|
|
+void RegsRiscv64::set_pc(uint64_t pc) {
|
|
+ regs_[RISCV64_REG_PC] = pc;
|
|
+}
|
|
+
|
|
+void RegsRiscv64::set_sp(uint64_t sp) {
|
|
+ regs_[RISCV64_REG_SP] = sp;
|
|
+}
|
|
+
|
|
+uint64_t RegsRiscv64::GetPcAdjustment(uint64_t rel_pc, Elf*) {
|
|
+ if (rel_pc < 8) {
|
|
+ return 0;
|
|
+ }
|
|
+ // For now, just assume no compact branches
|
|
+ return 8;
|
|
+}
|
|
+
|
|
+bool RegsRiscv64::SetPcFromReturnAddress(Memory*) {
|
|
+ uint64_t ra = regs_[RISCV64_REG_RA];
|
|
+ if (regs_[RISCV64_REG_PC] == ra) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ regs_[RISCV64_REG_PC] = ra;
|
|
+ return true;
|
|
+}
|
|
+
|
|
+void RegsRiscv64::IterateRegisters(std::function<void(const char*, uint64_t)> fn) {
|
|
+ fn("pc", regs_[RISCV64_REG_PC]);
|
|
+ fn("ra", regs_[RISCV64_REG_RA]);
|
|
+ fn("sp", regs_[RISCV64_REG_SP]);
|
|
+ fn("gp", regs_[RISCV64_REG_GP]);
|
|
+ fn("tp", regs_[RISCV64_REG_TP]);
|
|
+ fn("t0", regs_[RISCV64_REG_T0]);
|
|
+ fn("t1", regs_[RISCV64_REG_T1]);
|
|
+ fn("t2", regs_[RISCV64_REG_T2]);
|
|
+ fn("t3", regs_[RISCV64_REG_T3]);
|
|
+ fn("t4", regs_[RISCV64_REG_T4]);
|
|
+ fn("t5", regs_[RISCV64_REG_T5]);
|
|
+ fn("t6", regs_[RISCV64_REG_T6]);
|
|
+ fn("s0", regs_[RISCV64_REG_S0]);
|
|
+ fn("s1", regs_[RISCV64_REG_S1]);
|
|
+ fn("s2", regs_[RISCV64_REG_S2]);
|
|
+ fn("s3", regs_[RISCV64_REG_S3]);
|
|
+ fn("s4", regs_[RISCV64_REG_S4]);
|
|
+ fn("s5", regs_[RISCV64_REG_S5]);
|
|
+ fn("s6", regs_[RISCV64_REG_S6]);
|
|
+ fn("s7", regs_[RISCV64_REG_S7]);
|
|
+ fn("s8", regs_[RISCV64_REG_S8]);
|
|
+ fn("s9", regs_[RISCV64_REG_S9]);
|
|
+ fn("s10", regs_[RISCV64_REG_S10]);
|
|
+ fn("s11", regs_[RISCV64_REG_S11]);
|
|
+ fn("a0", regs_[RISCV64_REG_A0]);
|
|
+ fn("a1", regs_[RISCV64_REG_A1]);
|
|
+ fn("a2", regs_[RISCV64_REG_A2]);
|
|
+ fn("a3", regs_[RISCV64_REG_A3]);
|
|
+ fn("a4", regs_[RISCV64_REG_A4]);
|
|
+ fn("a5", regs_[RISCV64_REG_A5]);
|
|
+ fn("a6", regs_[RISCV64_REG_A6]);
|
|
+ fn("a7", regs_[RISCV64_REG_A7]);
|
|
+}
|
|
+
|
|
+Regs* RegsRiscv64::Read(void* remote_data) {
|
|
+ riscv64_user_regs* user = reinterpret_cast<riscv64_user_regs*>(remote_data);
|
|
+
|
|
+ RegsRiscv64* regs = new RegsRiscv64();
|
|
+ memcpy(regs->RawData(), &user->regs[0], RISCV64_REG_MAX * sizeof(uint64_t));
|
|
+ // uint64_t* reg_data = reinterpret_cast<uint64_t*>(regs->RawData());
|
|
+ return regs;
|
|
+}
|
|
+
|
|
+Regs* RegsRiscv64::CreateFromUcontext(void* ucontext) {
|
|
+ riscv64_ucontext_t* riscv64_ucontext = reinterpret_cast<riscv64_ucontext_t*>(ucontext);
|
|
+
|
|
+ RegsRiscv64* regs = new RegsRiscv64();
|
|
+ memcpy(regs->RawData(), &riscv64_ucontext->uc_mcontext.__gregs[0],
|
|
+ RISCV64_REG_MAX * sizeof(uint64_t));
|
|
+ return regs;
|
|
+}
|
|
+
|
|
+bool RegsRiscv64::StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) {
|
|
+ uint64_t data;
|
|
+ Memory* elf_memory = elf->memory();
|
|
+ // Read from elf memory since it is usually more expensive to read from
|
|
+ // process memory.
|
|
+ if (!elf_memory->ReadFully(elf_offset, &data, sizeof(data))) {
|
|
+ return false;
|
|
+ }
|
|
+ // Look for the kernel sigreturn function.
|
|
+ // __kernel_rt_sigreturn:
|
|
+ // li a7, __NR_rt_sigreturn
|
|
+ // scall
|
|
+
|
|
+ const uint8_t li_scall[] = {0x93, 0x08, 0xb0, 0x08, 0x73, 0x00, 0x00, 0x00};
|
|
+ if (memcmp(&data, &li_scall, 8) != 0) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ // SP + sizeof(siginfo_t) + uc_mcontext offset + PC offset.
|
|
+ if (!process_memory->ReadFully(regs_[RISCV64_REG_SP] + 0x80 + 0xb0 + 0x00, regs_.data(),
|
|
+ sizeof(uint64_t) * (RISCV64_REG_MAX))) {
|
|
+ return false;
|
|
+ }
|
|
+ return true;
|
|
+}
|
|
+
|
|
+Regs* RegsRiscv64::Clone() {
|
|
+ return new RegsRiscv64(*this);
|
|
+}
|
|
+
|
|
+} // namespace unwindstack
|
|
diff --git a/system/core/libunwindstack/include/unwindstack/Elf.h b/system/core/libunwindstack/include/unwindstack/Elf.h
|
|
index 472ed92..88fa0ff 100644
|
|
--- a/system/core/libunwindstack/include/unwindstack/Elf.h
|
|
+++ b/system/core/libunwindstack/include/unwindstack/Elf.h
|
|
@@ -32,6 +32,10 @@
|
|
#define EM_AARCH64 183
|
|
#endif
|
|
|
|
+#if !defined(EM_RISCV)
|
|
+#define EM_RISCV 243
|
|
+#endif
|
|
+
|
|
namespace unwindstack {
|
|
|
|
// Forward declaration.
|
|
@@ -46,6 +50,7 @@ enum ArchEnum : uint8_t {
|
|
ARCH_X86_64,
|
|
ARCH_MIPS,
|
|
ARCH_MIPS64,
|
|
+ ARCH_RISCV64,
|
|
};
|
|
|
|
class Elf {
|
|
diff --git a/system/core/libunwindstack/include/unwindstack/MachineRiscv64.h b/system/core/libunwindstack/include/unwindstack/MachineRiscv64.h
|
|
new file mode 100644
|
|
index 0000000..397e680
|
|
--- /dev/null
|
|
+++ b/system/core/libunwindstack/include/unwindstack/MachineRiscv64.h
|
|
@@ -0,0 +1,59 @@
|
|
+/*
|
|
+ * Copyright (C) 2022 The Android Open Source Project
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
|
+ * you may not use this file except in compliance with the License.
|
|
+ * You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
|
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
+ * See the License for the specific language governing permissions and
|
|
+ * limitations under the License.
|
|
+ */
|
|
+
|
|
+#pragma once
|
|
+
|
|
+#include <stdint.h>
|
|
+
|
|
+namespace unwindstack {
|
|
+
|
|
+enum Riscv64Reg : uint16_t {
|
|
+ RISCV64_REG_PC,
|
|
+ RISCV64_REG_RA,
|
|
+ RISCV64_REG_SP,
|
|
+ RISCV64_REG_GP,
|
|
+ RISCV64_REG_TP,
|
|
+ RISCV64_REG_T0,
|
|
+ RISCV64_REG_T1,
|
|
+ RISCV64_REG_T2,
|
|
+ RISCV64_REG_S0,
|
|
+ RISCV64_REG_S1,
|
|
+ RISCV64_REG_A0,
|
|
+ RISCV64_REG_A1,
|
|
+ RISCV64_REG_A2,
|
|
+ RISCV64_REG_A3,
|
|
+ RISCV64_REG_A4,
|
|
+ RISCV64_REG_A5,
|
|
+ RISCV64_REG_A6,
|
|
+ RISCV64_REG_A7,
|
|
+ RISCV64_REG_S2,
|
|
+ RISCV64_REG_S3,
|
|
+ RISCV64_REG_S4,
|
|
+ RISCV64_REG_S5,
|
|
+ RISCV64_REG_S6,
|
|
+ RISCV64_REG_S7,
|
|
+ RISCV64_REG_S8,
|
|
+ RISCV64_REG_S9,
|
|
+ RISCV64_REG_S10,
|
|
+ RISCV64_REG_S11,
|
|
+ RISCV64_REG_T3,
|
|
+ RISCV64_REG_T4,
|
|
+ RISCV64_REG_T5,
|
|
+ RISCV64_REG_T6,
|
|
+ RISCV64_REG_MAX,
|
|
+};
|
|
+
|
|
+} // namespace unwindstack
|
|
diff --git a/system/core/libunwindstack/include/unwindstack/RegsGetLocal.h b/system/core/libunwindstack/include/unwindstack/RegsGetLocal.h
|
|
index f0b5e3a..698eba2 100644
|
|
--- a/system/core/libunwindstack/include/unwindstack/RegsGetLocal.h
|
|
+++ b/system/core/libunwindstack/include/unwindstack/RegsGetLocal.h
|
|
@@ -81,6 +81,49 @@ inline __attribute__((__always_inline__)) void AsmGetRegs(void* reg_data) {
|
|
: "x12", "x13", "memory");
|
|
}
|
|
|
|
+#elif defined(__riscv)
|
|
+
|
|
+inline __attribute__((__always_inline__)) void AsmGetRegs(void* reg_data) {
|
|
+ asm volatile(
|
|
+ "1:\n"
|
|
+ "sd ra, 8(%[base])\n"
|
|
+ "sd sp, 16(%[base])\n"
|
|
+ "sd gp, 24(%[base])\n"
|
|
+ "sd tp, 32(%[base])\n"
|
|
+ "sd t0, 40(%[base])\n"
|
|
+ "sd t1, 48(%[base])\n"
|
|
+ "sd t2, 56(%[base])\n"
|
|
+ "sd s0, 64(%[base])\n"
|
|
+ "sd s1, 72(%[base])\n"
|
|
+ "sd a0, 80(%[base])\n"
|
|
+ "sd a1, 88(%[base])\n"
|
|
+ "sd a2, 96(%[base])\n"
|
|
+ "sd a3, 104(%[base])\n"
|
|
+ "sd a4, 112(%[base])\n"
|
|
+ "sd a5, 120(%[base])\n"
|
|
+ "sd a6, 128(%[base])\n"
|
|
+ "sd a7, 136(%[base])\n"
|
|
+ "sd s2, 144(%[base])\n"
|
|
+ "sd s3, 152(%[base])\n"
|
|
+ "sd s4, 160(%[base])\n"
|
|
+ "sd s5, 168(%[base])\n"
|
|
+ "sd s6, 176(%[base])\n"
|
|
+ "sd s7, 184(%[base])\n"
|
|
+ "sd s8, 192(%[base])\n"
|
|
+ "sd s9, 200(%[base])\n"
|
|
+ "sd s10, 208(%[base])\n"
|
|
+ "sd s11, 216(%[base])\n"
|
|
+ "sd t3, 224(%[base])\n"
|
|
+ "sd t4, 232(%[base])\n"
|
|
+ "sd t5, 240(%[base])\n"
|
|
+ "sd t6, 248(%[base])\n"
|
|
+ "la t1, 1b\n"
|
|
+ "sd t1, 0(%[base])\n"
|
|
+ : [base] "+r"(reg_data)
|
|
+ :
|
|
+ : "t1", "memory");
|
|
+}
|
|
+
|
|
#elif defined(__i386__) || defined(__x86_64__) || defined(__mips__)
|
|
|
|
extern "C" void AsmGetRegs(void* regs);
|
|
diff --git a/system/core/libunwindstack/include/unwindstack/RegsRiscv64.h b/system/core/libunwindstack/include/unwindstack/RegsRiscv64.h
|
|
new file mode 100644
|
|
index 0000000..eb09397
|
|
--- /dev/null
|
|
+++ b/system/core/libunwindstack/include/unwindstack/RegsRiscv64.h
|
|
@@ -0,0 +1,59 @@
|
|
+/*
|
|
+ * Copyright (C) 2022 The Android Open Source Project
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
|
+ * you may not use this file except in compliance with the License.
|
|
+ * You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
|
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
+ * See the License for the specific language governing permissions and
|
|
+ * limitations under the License.
|
|
+ */
|
|
+
|
|
+#pragma once
|
|
+
|
|
+#include <stdint.h>
|
|
+
|
|
+#include <functional>
|
|
+
|
|
+#include <unwindstack/Elf.h>
|
|
+#include <unwindstack/Regs.h>
|
|
+
|
|
+namespace unwindstack {
|
|
+
|
|
+// Forward declarations.
|
|
+class Memory;
|
|
+
|
|
+class RegsRiscv64 : public RegsImpl<uint64_t> {
|
|
+ public:
|
|
+ RegsRiscv64();
|
|
+ virtual ~RegsRiscv64() = default;
|
|
+
|
|
+ ArchEnum Arch() override final;
|
|
+
|
|
+ uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) override;
|
|
+
|
|
+ bool SetPcFromReturnAddress(Memory* process_memory) override;
|
|
+
|
|
+ bool StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) override;
|
|
+
|
|
+ void IterateRegisters(std::function<void(const char*, uint64_t)>) override final;
|
|
+
|
|
+ uint64_t pc() override;
|
|
+ uint64_t sp() override;
|
|
+
|
|
+ void set_pc(uint64_t pc) override;
|
|
+ void set_sp(uint64_t sp) override;
|
|
+
|
|
+ Regs* Clone() override final;
|
|
+
|
|
+ static Regs* Read(void* data);
|
|
+
|
|
+ static Regs* CreateFromUcontext(void* ucontext);
|
|
+};
|
|
+
|
|
+} // namespace unwindstack
|
|
diff --git a/system/core/libunwindstack/include/unwindstack/UcontextRiscv64.h b/system/core/libunwindstack/include/unwindstack/UcontextRiscv64.h
|
|
new file mode 100644
|
|
index 0000000..c6c82b1
|
|
--- /dev/null
|
|
+++ b/system/core/libunwindstack/include/unwindstack/UcontextRiscv64.h
|
|
@@ -0,0 +1,80 @@
|
|
+/*
|
|
+ * Copyright (C) 2014 The Android Open Source Project
|
|
+ * All rights reserved.
|
|
+ *
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ * * Redistributions of source code must retain the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ * * Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in
|
|
+ * the documentation and/or other materials provided with the
|
|
+ * distribution.
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
|
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
|
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
+ * SUCH DAMAGE.
|
|
+ */
|
|
+
|
|
+#pragma once
|
|
+
|
|
+#include <sys/cdefs.h>
|
|
+
|
|
+typedef uint64_t __riscv_mc_gp_state[32]; // unsigned long
|
|
+
|
|
+struct __riscv_mc_f_ext_state {
|
|
+ uint32_t __f[32];
|
|
+ uint32_t __fcsr;
|
|
+};
|
|
+
|
|
+struct __riscv_mc_d_ext_state {
|
|
+ uint64_t __f[32];
|
|
+ uint32_t __fcsr;
|
|
+};
|
|
+
|
|
+struct __riscv_mc_q_ext_state {
|
|
+ uint64_t __f[64] __attribute__((__aligned__(16)));
|
|
+ uint32_t __fcsr;
|
|
+ uint32_t __reserved[3];
|
|
+};
|
|
+
|
|
+union __riscv_mc_fp_state {
|
|
+ struct __riscv_mc_f_ext_state __f;
|
|
+ struct __riscv_mc_d_ext_state __d;
|
|
+ struct __riscv_mc_q_ext_state __q;
|
|
+};
|
|
+
|
|
+struct __riscv_stack_t {
|
|
+ uint64_t ss_sp;
|
|
+ int32_t ss_flags;
|
|
+ uint64_t ss_size;
|
|
+};
|
|
+
|
|
+struct riscv64_sigset_t {
|
|
+ uint64_t sig; // unsigned long
|
|
+};
|
|
+
|
|
+struct riscv64_mcontext_t {
|
|
+ __riscv_mc_gp_state __gregs;
|
|
+ union __riscv_mc_fp_state __fpregs;
|
|
+};
|
|
+
|
|
+struct riscv64_ucontext_t {
|
|
+ uint64_t uc_flags; // unsigned long
|
|
+ struct riscv64_ucontext_t* uc_link;
|
|
+ __riscv_stack_t uc_stack;
|
|
+ riscv64_sigset_t uc_sigmask;
|
|
+ /* The kernel adds extra padding here to allow sigset_t to grow. */
|
|
+ int8_t __padding[128 - sizeof(riscv64_sigset_t)]; // char
|
|
+ riscv64_mcontext_t uc_mcontext;
|
|
+};
|
|
diff --git a/system/core/libunwindstack/include/unwindstack/UserRiscv64.h b/system/core/libunwindstack/include/unwindstack/UserRiscv64.h
|
|
new file mode 100644
|
|
index 0000000..1e91228
|
|
--- /dev/null
|
|
+++ b/system/core/libunwindstack/include/unwindstack/UserRiscv64.h
|
|
@@ -0,0 +1,37 @@
|
|
+/*
|
|
+ * Copyright (C) 2016 The Android Open Source Project
|
|
+ * All rights reserved.
|
|
+ *
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ * * Redistributions of source code must retain the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ * * Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in
|
|
+ * the documentation and/or other materials provided with the
|
|
+ * distribution.
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
|
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
|
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
+ * SUCH DAMAGE.
|
|
+ */
|
|
+
|
|
+#pragma once
|
|
+
|
|
+namespace unwindstack {
|
|
+
|
|
+struct riscv64_user_regs {
|
|
+ uint64_t regs[32];
|
|
+};
|
|
+
|
|
+} // namespace unwindstack
|
|
diff --git a/system/core/libunwindstack/tools/unwind.cpp b/system/core/libunwindstack/tools/unwind.cpp
|
|
index 1812e50..ae20891 100644
|
|
--- a/system/core/libunwindstack/tools/unwind.cpp
|
|
+++ b/system/core/libunwindstack/tools/unwind.cpp
|
|
@@ -83,6 +83,9 @@ void DoUnwind(pid_t pid) {
|
|
case unwindstack::ARCH_MIPS64:
|
|
printf("mips64");
|
|
break;
|
|
+ case unwindstack::ARCH_RISCV64:
|
|
+ printf("riscv64");
|
|
+ break;
|
|
default:
|
|
printf("unknown\n");
|
|
return;
|
|
diff --git a/system/core/libunwindstack/tools/unwind_symbols.cpp b/system/core/libunwindstack/tools/unwind_symbols.cpp
|
|
index 8df2284..976db56 100644
|
|
--- a/system/core/libunwindstack/tools/unwind_symbols.cpp
|
|
+++ b/system/core/libunwindstack/tools/unwind_symbols.cpp
|
|
@@ -77,6 +77,9 @@ int main(int argc, char** argv) {
|
|
case EM_AARCH64:
|
|
printf("ABI: arm64\n");
|
|
break;
|
|
+ case EM_RISCV:
|
|
+ printf("ABI: riscv64\n");
|
|
+ break;
|
|
case EM_386:
|
|
printf("ABI: x86\n");
|
|
break;
|