summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Ferris <cferris@google.com>2024-03-06 20:52:21 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2024-03-06 20:52:21 +0000
commit3f39dce166f9427b91651484004ca785b0b67ad7 (patch)
treec289046d9143a2d23e80ae59e95467f78d60757f
parentf1cb1ab9af03d1eda35dbe4d6d5923490c133a4b (diff)
parent838034d87b252c55182913b848dc2edac4fd5bbf (diff)
downloadunwinding-3f39dce166f9427b91651484004ca785b0b67ad7.tar.gz
Merge "Update riscv64 handling." into main
-rw-r--r--libunwindstack/LogAndroid.cpp8
-rw-r--r--libunwindstack/LogStdout.cpp8
-rw-r--r--libunwindstack/RegsRiscv64.cpp23
-rw-r--r--libunwindstack/include/unwindstack/Log.h1
-rw-r--r--libunwindstack/tests/RegsTest.cpp16
5 files changed, 49 insertions, 7 deletions
diff --git a/libunwindstack/LogAndroid.cpp b/libunwindstack/LogAndroid.cpp
index 6fb613f..2f5b00e 100644
--- a/libunwindstack/LogAndroid.cpp
+++ b/libunwindstack/LogAndroid.cpp
@@ -66,6 +66,14 @@ void Error(const char* format, ...) {
va_end(args);
}
+void Fatal(const char* format, ...) {
+ va_list args;
+ va_start(args, format);
+ LogWithPriority(ANDROID_LOG_FATAL, 0, format, args);
+ va_end(args);
+ abort();
+}
+
#if defined(__BIONIC__)
void AsyncSafe(const char* format, ...) {
va_list args;
diff --git a/libunwindstack/LogStdout.cpp b/libunwindstack/LogStdout.cpp
index bb5c2dd..e54bd11 100644
--- a/libunwindstack/LogStdout.cpp
+++ b/libunwindstack/LogStdout.cpp
@@ -61,6 +61,14 @@ void Error(const char* format, ...) {
va_end(args);
}
+void Fatal(const char* format, ...) {
+ va_list args;
+ va_start(args, format);
+ PrintToStdout(0, format, args);
+ va_end(args);
+ abort();
+}
+
void AsyncSafe(const char* format, ...) {
va_list args;
va_start(args, format);
diff --git a/libunwindstack/RegsRiscv64.cpp b/libunwindstack/RegsRiscv64.cpp
index a69b07f..532b3b1 100644
--- a/libunwindstack/RegsRiscv64.cpp
+++ b/libunwindstack/RegsRiscv64.cpp
@@ -24,6 +24,7 @@
#include <vector>
#include <unwindstack/Elf.h>
+#include <unwindstack/Log.h>
#include <unwindstack/MachineRiscv64.h>
#include <unwindstack/MapInfo.h>
#include <unwindstack/Memory.h>
@@ -35,30 +36,38 @@ namespace unwindstack {
uint64_t RegsRiscv64::GetVlenbFromLocal() {
#if defined(__riscv)
- // Assumes that all cpus have the same value.
uint64_t vlenb;
asm volatile("csrr %0, 0xc22\n" : "=r"(vlenb)::);
return vlenb;
#else
- return 0;
+ Log::Fatal("%s:%d: On non-riscv device, attempt to get vlenb locally.", __FILE__, __LINE__);
#endif
}
+#if defined(__riscv)
+uint64_t RegsRiscv64::GetVlenbFromRemote(pid_t) {
+ // All riscv cores in a cpu are required to have the same vlenb value.
+ // Note: If a device exists with multiple cpus, but all of the cpus do not
+ // have the same vlenb, then this method will need to be modified.
+ return GetVlenbFromLocal();
+}
+#else
uint64_t RegsRiscv64::GetVlenbFromRemote(pid_t pid) {
if (pid == 0) {
- return GetVlenbFromLocal();
+ Log::Fatal("%s:%d: Attempt to get vlenb remotely from non-riscv device without pid.", __FILE__,
+ __LINE__);
}
- // We only care about these values, no need to get the other vector registers.
+ // We only care about the state values, no need to get anything else.
struct riscv64_v_regset_state regs;
struct iovec io = {.iov_base = &regs, .iov_len = sizeof(regs)};
if (ptrace(PTRACE_GETREGSET, pid, NT_RISCV_VECTOR, reinterpret_cast<void*>(&io)) == -1) {
- // TODO: Workaround due to some devices not properly returning these values.
- // This code assumes that all cores on the device have the same vlenb.
- return GetVlenbFromLocal();
+ Log::Error("Failed to get vlenb from target process %d: %d", pid, errno);
+ return 0;
}
return regs.vlenb;
}
+#endif
RegsRiscv64::RegsRiscv64()
: RegsImpl<uint64_t>(RISCV64_REG_COUNT, Location(LOCATION_REGISTER, RISCV64_REG_RA)) {}
diff --git a/libunwindstack/include/unwindstack/Log.h b/libunwindstack/include/unwindstack/Log.h
index 34eb218..be681c0 100644
--- a/libunwindstack/include/unwindstack/Log.h
+++ b/libunwindstack/include/unwindstack/Log.h
@@ -27,6 +27,7 @@ namespace unwindstack {
namespace Log {
+[[noreturn]] void Fatal(const char* format, ...) __printflike(1, 2);
void Error(const char* format, ...) __printflike(1, 2);
void Info(const char* format, ...) __printflike(1, 2);
void Info(uint8_t indent, const char* format, ...) __printflike(2, 3);
diff --git a/libunwindstack/tests/RegsTest.cpp b/libunwindstack/tests/RegsTest.cpp
index 6fb625d..10605ab 100644
--- a/libunwindstack/tests/RegsTest.cpp
+++ b/libunwindstack/tests/RegsTest.cpp
@@ -18,6 +18,7 @@
#include <memory>
+#include <android-base/silent_death_test.h>
#include <gtest/gtest.h>
#include <unwindstack/Elf.h>
@@ -229,6 +230,21 @@ TEST_F(RegsTest, riscv_convert) {
EXPECT_EQ(RISCV64_REG_COUNT, regs.Convert(RISCV64_REG_VLENB));
}
+#if defined(__riscv)
+TEST_F(RegsTest, riscv_get_vlenb) {
+ RegsRiscv64 regs;
+ EXPECT_NE(0U, regs.GetVlenbFromLocal());
+ EXPECT_NE(0U, regs.GetVlenbFromRemote(0));
+}
+#else
+using RegsDeathTest = SilentDeathTest;
+TEST_F(RegsDeathTest, riscv_get_vlenb) {
+ RegsRiscv64 regs;
+ ASSERT_DEATH(regs.GetVlenbFromLocal(), "");
+ ASSERT_DEATH(regs.GetVlenbFromRemote(0), "");
+}
+#endif
+
TEST_F(RegsTest, x86_verify_sp_pc) {
RegsX86 x86;
uint32_t* regs = reinterpret_cast<uint32_t*>(x86.RawData());