From b4b833031c9786791880ec54d493929276e4b4ea Mon Sep 17 00:00:00 2001
From: Diego Nehab <1635557+diegonehab@users.noreply.github.com>
Date: Wed, 5 Mar 2025 16:59:19 +0000
Subject: [PATCH] refactor: use attribute((format(printf, 1, 2)))
---
src/assert-printf.h | 20 ++++++-
src/dump.h | 28 ----------
src/i-accept-scoped-notes.h | 30 +++++++----
src/i-state-access.h | 66 +++++++++++++----------
src/i-uarch-state-access.h | 36 ++++++++-----
src/interpret.cpp | 104 ++++++++++++++++++------------------
src/machine.cpp | 74 ++++++++++++-------------
src/merkle-tree-hash.cpp | 2 +-
src/uarch-solidity-compat.h | 8 +--
uarch/uarch-runtime.h | 3 ++
10 files changed, 198 insertions(+), 173 deletions(-)
delete mode 100644 src/dump.h
diff --git a/src/assert-printf.h b/src/assert-printf.h
index 1bf16b67..0f0f5b41 100644
--- a/src/assert-printf.h
+++ b/src/assert-printf.h
@@ -14,8 +14,8 @@
// with this program (see COPYING). If not, see .
//
-#ifndef PRINTF_ASSERT_H
-#define PRINTF_ASSERT_H
+#ifndef ASSERT_PRINTF_H
+#define ASSERT_PRINTF_H
/// \file
/// \brief Microarchitecture-dependent includes for printf and assert
@@ -27,4 +27,20 @@
#include
#endif
+#include
+#include
+
+static inline void d_vprintf(const char *fmt, va_list ap) {
+ std::ignore = vfprintf(stderr, fmt, ap);
+}
+
+// Better to use C-style variadic function that checks for format!
+// NOLINTNEXTLINE(cert-dcl50-cpp)
+__attribute__((__format__(__printf__, 1, 2))) static inline void d_printf(const char *fmt, ...) {
+ va_list ap;
+ va_start(ap, fmt);
+ d_vprintf(fmt, ap);
+ va_end(ap);
+}
+
#endif
diff --git a/src/dump.h b/src/dump.h
deleted file mode 100644
index 4cfc8e2c..00000000
--- a/src/dump.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright Cartesi and individual authors (see AUTHORS)
-// SPDX-License-Identifier: LGPL-3.0-or-later
-//
-// This program is free software: you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License as published by the Free
-// Software Foundation, either version 3 of the License, or (at your option) any
-// later version.
-//
-// This program is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-// PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License along
-// with this program (see COPYING). If not, see .
-//
-#ifndef DUMP_H
-#define DUMP_H
-
-#include
-
-#include "assert-printf.h"
-
-template
-static inline auto D_PRINTF(const char (&fmt)[N], ARGS... args) {
- std::ignore = fprintf(stderr, fmt, args...);
-}
-
-#endif // DUMP_H
diff --git a/src/i-accept-scoped-notes.h b/src/i-accept-scoped-notes.h
index affc19c3..1c122026 100644
--- a/src/i-accept-scoped-notes.h
+++ b/src/i-accept-scoped-notes.h
@@ -20,10 +20,11 @@
/// \file
/// \brief Accept scoped notes interface
+#include
#include
#include
-#include "dump.h"
+#include "assert-printf.h"
#include "i-state-access.h"
#include "i-uarch-state-access.h"
#include "meta.h"
@@ -48,32 +49,43 @@ class i_accept_scoped_notes { // CRTP
}
public:
- /// \brief Works as printf if we are dumping scoped notes, otherwise does nothing
- template
- static void DSN_PRINTF([[maybe_unused]] const char (&fmt)[N], [[maybe_unused]] ARGS... args) {
+ /// \brief Works as vprintf if we are dumping scoped notes, otherwise does nothing
+ static void dsn_vprintf([[maybe_unused]] const char *fmt, [[maybe_unused]] va_list ap) {
#ifdef DUMP_SCOPED_NOTE
if constexpr (is_an_i_state_access_v) {
- DERIVED::DSA_PRINTF(fmt, args...);
+ DERIVED::dsa_vprintf(fmt, ap);
} else if (is_an_i_uarch_state_access_v) {
- DERIVED::DUSA_PRINTF(fmt, args...);
+ DERIVED::dusa_vprintf(fmt, ap);
} else {
- D_PRINTF(fmt, args...);
+ d_vprintf(fmt, ap);
}
#endif
}
+ /// \brief Works as printf if we are dumping scoped notes, otherwise does nothing
+ // Better to use C-style variadic function that checks for format!
+ // NOLINTNEXTLINE(cert-dcl50-cpp)
+ __attribute__((__format__(__printf__, 1, 2))) static void dsn_printf([[maybe_unused]] const char *fmt, ...) {
+#ifdef DUMP_SCOPED_NOTE
+ va_list ap;
+ va_start(ap, fmt);
+ dsn_vprintf(fmt, ap);
+ va_end(ap);
+#endif
+ }
+
/// \brief Adds a begin bracket annotation to the log
/// \param text String with the text for the annotation
void push_begin_bracket(const char *text) const {
derived().do_push_begin_bracket(text);
- DSN_PRINTF("----> begin %s (%s)\n", text, derived().get_name());
+ dsn_printf("----> begin %s (%s)\n", text, derived().get_name());
}
/// \brief Adds an end bracket annotation to the log
/// \param text String with the text for the annotation
void push_end_bracket(const char *text) const {
derived().do_push_end_bracket(text);
- DSN_PRINTF("<---- end %s (%s)\n", text, derived().get_name());
+ dsn_printf("<---- end %s (%s)\n", text, derived().get_name());
}
/// \brief Adds annotations to the state, bracketing a scope
diff --git a/src/i-state-access.h b/src/i-state-access.h
index 139d24aa..c9cbb1a0 100644
--- a/src/i-state-access.h
+++ b/src/i-state-access.h
@@ -21,11 +21,12 @@
/// \brief State access interface
#include
+#include
#include
#include
#include
-#include "dump.h"
+#include "assert-printf.h"
#include "i-prefer-shadow-state.h"
#include "meta.h"
#include "poor-type-name.h"
@@ -47,7 +48,7 @@ using i_state_access_fast_addr_t = typename i_state_access_fast_addr) { \
const auto val = derived().do_read_##REG(); \
- DSA_PRINTF("%s::read_" #REG "() = %" PRIu64 "(0x%" PRIx64 ")\n", get_name(), val, val); \
+ dsa_printf("%s::read_" #REG "() = %" PRIu64 "(0x%" PRIx64 ")\n", get_name(), val, val); \
return val; \
} else { \
return prefer_read_shadow_state(shadow_state_what::REG); \
@@ -58,7 +59,7 @@ using i_state_access_fast_addr_t = typename i_state_access_fast_addr) { \
derived().do_write_##REG(val); \
- DSA_PRINTF("%s::write_" #REG "(%" PRIu64 "(0x%" PRIx64 "))\n", get_name(), val, val); \
+ dsa_printf("%s::write_" #REG "(%" PRIu64 "(0x%" PRIx64 "))\n", get_name(), val, val); \
} else { \
prefer_write_shadow_state(shadow_state_what::REG, val); \
} \
@@ -104,24 +105,35 @@ class i_state_access { // CRTP
uint64_t prefer_read_shadow_state(shadow_state_what what) const {
const auto val = derived().read_shadow_state(what);
[[maybe_unused]] const auto *const what_name = shadow_state_get_what_name(what);
- DSA_PRINTF("%s::read_shadow_state(%s) = %" PRIu64 "(0x%" PRIx64 ")\n", get_name(), what_name, val, val);
+ dsa_printf("%s::read_shadow_state(%s) = %" PRIu64 "(0x%" PRIx64 ")\n", get_name(), what_name, val, val);
return val;
}
void prefer_write_shadow_state(shadow_state_what what, uint64_t val) const {
derived().write_shadow_state(what, val);
[[maybe_unused]] const auto *const what_name = shadow_state_get_what_name(what);
- DSA_PRINTF("%s::write_shadow_state(%s, %" PRIu64 "(0x%" PRIx64 "))\n", get_name(), what_name, val, val);
+ dsa_printf("%s::write_shadow_state(%s, %" PRIu64 "(0x%" PRIx64 "))\n", get_name(), what_name, val, val);
}
public:
using fast_addr = i_state_access_fast_addr_t;
+ /// \brief Works as vprintf if we are dumping state accesses, otherwise does nothing
+ static void dsa_vprintf([[maybe_unused]] const char *fmt, [[maybe_unused]] va_list ap) {
+#ifdef DUMP_STATE_ACCESS
+ d_vprintf(fmt, ap);
+#endif
+ }
+
/// \brief Works as printf if we are dumping state accesses, otherwise does nothing
- template
- static void DSA_PRINTF([[maybe_unused]] const char (&fmt)[N], [[maybe_unused]] ARGS... args) {
+ // Better to use C-style variadic function that checks for format!
+ // NOLINTNEXTLINE(cert-dcl50-cpp)
+ __attribute__((__format__(__printf__, 1, 2))) static void dsa_printf([[maybe_unused]] const char *fmt, ...) {
#ifdef DUMP_STATE_ACCESS
- D_PRINTF(fmt, args...);
+ va_list ap;
+ va_start(ap, fmt);
+ dsa_vprintf(fmt, ap);
+ va_end(ap);
#endif
}
@@ -131,7 +143,7 @@ class i_state_access { // CRTP
uint64_t read_x(int i) const {
if constexpr (!is_an_i_prefer_shadow_state_v) {
const auto val = derived().do_read_x(i);
- DSA_PRINTF("%s::read_x(%d) = %" PRIu64 "(0x%" PRIx64 ")\n", get_name(), i, val, val);
+ dsa_printf("%s::read_x(%d) = %" PRIu64 "(0x%" PRIx64 ")\n", get_name(), i, val, val);
return val;
} else {
return prefer_read_shadow_state(shadow_state_get_what(shadow_state_what::x0, i));
@@ -146,7 +158,7 @@ class i_state_access { // CRTP
void write_x(int i, uint64_t val) const {
if constexpr (!is_an_i_prefer_shadow_state_v) {
derived().do_write_x(i, val);
- DSA_PRINTF("%s::write_x(%d, %" PRIu64 "(0x%" PRIx64 "))\n", get_name(), i, val, val);
+ dsa_printf("%s::write_x(%d, %" PRIu64 "(0x%" PRIx64 "))\n", get_name(), i, val, val);
} else {
prefer_write_shadow_state(shadow_state_get_what(shadow_state_what::x0, i), val);
}
@@ -158,7 +170,7 @@ class i_state_access { // CRTP
uint64_t read_f(int i) const {
if constexpr (!is_an_i_prefer_shadow_state_v) {
const auto val = derived().do_read_f(i);
- DSA_PRINTF("%s::read_f(%d) = %" PRIu64 "(0x%" PRIx64 ")\n", get_name(), i, val, val);
+ dsa_printf("%s::read_f(%d) = %" PRIu64 "(0x%" PRIx64 ")\n", get_name(), i, val, val);
return val;
} else {
return prefer_read_shadow_state(shadow_state_get_what(shadow_state_what::f0, i));
@@ -171,7 +183,7 @@ class i_state_access { // CRTP
void write_f(int i, uint64_t val) const {
if constexpr (!is_an_i_prefer_shadow_state_v) {
derived().do_write_f(i, val);
- DSA_PRINTF("%s::write_f(%d, %" PRIu64 "(%" PRIx64 "))\n", get_name(), i, val, val);
+ dsa_printf("%s::write_f(%d, %" PRIu64 "(%" PRIx64 "))\n", get_name(), i, val, val);
} else {
prefer_write_shadow_state(shadow_state_get_what(shadow_state_what::f0, i), val);
}
@@ -269,7 +281,7 @@ class i_state_access { // CRTP
/// \param index Index of PMA
address_range &read_pma(uint64_t index) const {
auto &ar = derived().do_read_pma(index);
- DSA_PRINTF("%s::read_address_range(%" PRIu64 ") = {%s, 0x%" PRIx64 ", 0x%" PRIx64 "}\n", get_name(), index,
+ dsa_printf("%s::read_address_range(%" PRIu64 ") = {%s, 0x%" PRIx64 ", 0x%" PRIx64 "}\n", get_name(), index,
pmas_get_DID_name(ar.get_driver_id()), ar.get_start(), ar.get_length());
return ar;
}
@@ -281,8 +293,8 @@ class i_state_access { // CRTP
fast_addr get_faddr(uint64_t paddr, uint64_t pma_index) const {
const auto val = derived().do_get_faddr(paddr, pma_index);
[[maybe_unused]] const auto fast_addr_name = std::is_same_v ? "phys_addr" : "fast_addr";
- DSA_PRINTF("%s::get_faddr(%" PRIu64 "(0x%" PRIx64 ")) = %s{%" PRIu64 "(0x%" PRIx64 ")}\n", get_name(), paddr,
- paddr, fast_addr_name, val, val);
+ dsa_printf("%s::get_faddr(%" PRIu64 "(0x%" PRIx64 ")) = %s{%" PRIu64 "(0x%" PRIx64 ")}\n", get_name(), paddr,
+ paddr, fast_addr_name, static_cast(val), static_cast(val));
return val;
}
@@ -331,9 +343,9 @@ class i_state_access { // CRTP
static_assert(std::is_integral_v && sizeof(T) <= sizeof(uint64_t), "unsupported type");
derived().template do_read_memory_word(faddr, pma_index, pval);
[[maybe_unused]] const auto fast_addr_name = std::is_same_v ? "phys_addr" : "fast_addr";
- DSA_PRINTF("%s::read_memory_word<%s,%s>(%s{0x%" PRIx64 "}, %" PRIu64 ") = %" PRIu64 "(0x%" PRIx64 ")\n",
- get_name(), poor_type_name_v, poor_type_name_v, fast_addr_name, faddr, pma_index,
- static_cast(*pval), static_cast(*pval));
+ dsa_printf("%s::read_memory_word<%s,%s>(%s{0x%" PRIx64 "}, %" PRIu64 ") = %" PRIu64 "(0x%" PRIx64 ")\n",
+ get_name(), poor_type_name_v, poor_type_name_v, fast_addr_name, static_cast(faddr),
+ pma_index, static_cast(*pval), static_cast(*pval));
}
/// \brief Writes a word to memory.
@@ -348,9 +360,9 @@ class i_state_access { // CRTP
static_assert(std::is_integral_v && sizeof(T) <= sizeof(uint64_t), "unsupported type");
derived().template do_write_memory_word(faddr, pma_index, val);
[[maybe_unused]] const auto fast_addr_name = std::is_same_v ? "phys_addr" : "fast_addr";
- DSA_PRINTF("%s::write_memory_word<%s,%s>(%s{0x%" PRIx64 "}, %" PRIu64 ", %" PRIu64 "(0x%" PRIx64 "))\n",
- get_name(), poor_type_name_v, poor_type_name_v, fast_addr_name, faddr, pma_index,
- static_cast(val), static_cast(val));
+ dsa_printf("%s::write_memory_word<%s,%s>(%s{0x%" PRIx64 "}, %" PRIu64 ", %" PRIu64 "(0x%" PRIx64 "))\n",
+ get_name(), poor_type_name_v, poor_type_name_v, fast_addr_name, static_cast(faddr),
+ pma_index, static_cast(val), static_cast(val));
}
/// \brief Reads TLB's vaddr_page
@@ -360,7 +372,7 @@ class i_state_access { // CRTP
template
uint64_t read_tlb_vaddr_page(uint64_t slot_index) const {
const auto val = derived().template do_read_tlb_vaddr_page(slot_index);
- DSA_PRINTF("%s::read_tlb_vaddr_page<%" PRIu64 ">(%" PRIu64 ") = 0x%" PRIx64 "\n", get_name(), SET, slot_index,
+ dsa_printf("%s::read_tlb_vaddr_page<%" PRIu64 ">(%" PRIu64 ") = 0x%" PRIx64 "\n", get_name(), SET, slot_index,
val);
return val;
}
@@ -373,8 +385,8 @@ class i_state_access { // CRTP
fast_addr read_tlb_vp_offset(uint64_t slot_index) const {
[[maybe_unused]] const auto fast_addr_name = std::is_same_v ? "phys_addr" : "fast_addr";
const auto val = derived().template do_read_tlb_vp_offset(slot_index);
- DSA_PRINTF("%s::read_tlb_vp_offset<%" PRIu64 ">(%" PRIu64 ") = %s{0x%" PRIx64 "}\n", get_name(), SET,
- slot_index, fast_addr_name, val);
+ dsa_printf("%s::read_tlb_vp_offset<%" PRIu64 ">(%" PRIu64 ") = %s{0x%" PRIx64 "}\n", get_name(), SET,
+ slot_index, fast_addr_name, static_cast(val));
return val;
}
@@ -385,7 +397,7 @@ class i_state_access { // CRTP
template
uint64_t read_tlb_pma_index(uint64_t slot_index) const {
const auto val = derived().template do_read_tlb_pma_index(slot_index);
- DSA_PRINTF("%s::read_tlb_pma_index<%" PRIu64 ">(%" PRIu64 ") = %" PRIu64 "(0x%" PRIx64 ")\n", get_name(), SET,
+ dsa_printf("%s::read_tlb_pma_index<%" PRIu64 ">(%" PRIu64 ") = %" PRIu64 "(0x%" PRIx64 ")\n", get_name(), SET,
slot_index, val, val);
return val;
}
@@ -402,8 +414,8 @@ class i_state_access { // CRTP
void write_tlb(uint64_t slot_index, uint64_t vaddr_page, fast_addr vp_offset, uint64_t pma_index) const {
derived().template do_write_tlb(slot_index, vaddr_page, vp_offset, pma_index);
[[maybe_unused]] const auto fast_addr_name = std::is_same_v ? "phys_addr" : "fast_addr";
- DSA_PRINTF("%s::write_tlb<%" PRIu64 ">(%" PRIu64 ", 0x%" PRIx64 ", %s{0x%" PRIx64 "}, %" PRIu64 ")\n",
- get_name(), SET, slot_index, vaddr_page, fast_addr_name, vp_offset, pma_index);
+ dsa_printf("%s::write_tlb<%" PRIu64 ">(%" PRIu64 ", 0x%" PRIx64 ", %s{0x%" PRIx64 "}, %" PRIu64 ")\n",
+ get_name(), SET, slot_index, vaddr_page, fast_addr_name, static_cast(vp_offset), pma_index);
}
/// \brief Marks a page as dirty
diff --git a/src/i-uarch-state-access.h b/src/i-uarch-state-access.h
index fd58933b..3e290c76 100644
--- a/src/i-uarch-state-access.h
+++ b/src/i-uarch-state-access.h
@@ -18,9 +18,10 @@
#define I_UARCH_STATE_ACCESS_H
#include
+#include
#include
-#include "dump.h"
+#include "assert-printf.h"
#include "i-prefer-shadow-uarch-state.h"
#include "meta.h"
#include "tlb.h"
@@ -30,7 +31,7 @@
uint64_t read_##REG() const { \
if constexpr (!is_an_i_prefer_shadow_uarch_state_v) { \
const auto val = derived().do_read_##REG(); \
- DUSA_PRINTF("%s::read_" #REG "() = %" PRIu64 "(0x%" PRIx64 ")\n", get_name(), val, val); \
+ dusa_printf("%s::read_" #REG "() = %" PRIu64 "(0x%" PRIx64 ")\n", get_name(), val, val); \
return val; \
} else { \
return prefer_read_shadow_uarch_state(shadow_uarch_state_what::REG); \
@@ -41,7 +42,7 @@
void write_##REG(uint64_t val) const { \
if constexpr (!is_an_i_prefer_shadow_uarch_state_v) { \
derived().do_write_##REG(val); \
- DUSA_PRINTF("%s::write_" #REG "(%" PRIu64 "(0x%" PRIx64 "))\n", get_name(), val, val); \
+ dusa_printf("%s::write_" #REG "(%" PRIu64 "(0x%" PRIx64 "))\n", get_name(), val, val); \
} else { \
prefer_write_shadow_uarch_state(shadow_uarch_state_what::REG, val); \
} \
@@ -67,29 +68,40 @@ class i_uarch_state_access { // CRTP
uint64_t prefer_read_shadow_uarch_state(shadow_uarch_state_what what) const {
const auto val = derived().read_shadow_uarch_state(what);
[[maybe_unused]] const auto *const what_name = shadow_uarch_state_get_what_name(what);
- DUSA_PRINTF("%s::read_shadow_uarch_state(%s) = %" PRIu64 "(0x%" PRIx64 ")\n", get_name(), what_name, val, val);
+ dusa_printf("%s::read_shadow_uarch_state(%s) = %" PRIu64 "(0x%" PRIx64 ")\n", get_name(), what_name, val, val);
return val;
}
void prefer_write_shadow_uarch_state(shadow_uarch_state_what what, uint64_t val) const {
derived().write_shadow_uarch_state(what, val);
[[maybe_unused]] const auto *const what_name = shadow_uarch_state_get_what_name(what);
- DUSA_PRINTF("%s::write_shadow_uarch_state(%s, %" PRIu64 "(0x%" PRIx64 "))\n", get_name(), what_name, val, val);
+ dusa_printf("%s::write_shadow_uarch_state(%s, %" PRIu64 "(0x%" PRIx64 "))\n", get_name(), what_name, val, val);
}
public:
+ /// \brief Works as vprintf if we are dumping uarch state accesses, otherwise does nothing
+ static void dusa_vprintf([[maybe_unused]] const char *fmt, [[maybe_unused]] va_list ap) {
+#ifdef DUMP_UARCH_STATE_ACCESS
+ d_vprintf(fmt, ap);
+#endif
+ }
+
/// \brief Works as printf if we are dumping uarch state accesses, otherwise does nothing
- template
- static void DUSA_PRINTF([[maybe_unused]] const char (&fmt)[N], [[maybe_unused]] ARGS... args) {
+ // Better to use C-style variadic function that checks for format!
+ // NOLINTNEXTLINE(cert-dcl50-cpp)
+ __attribute__((__format__(__printf__, 1, 2))) static void dusa_printf([[maybe_unused]] const char *fmt, ...) {
#ifdef DUMP_UARCH_STATE_ACCESS
- D_PRINTF(fmt, args...);
+ va_list ap;
+ va_start(ap, fmt);
+ dusa_vprintf(fmt, ap);
+ va_end(ap);
#endif
}
uint64_t read_uarch_x(int i) const {
if constexpr (!is_an_i_prefer_shadow_uarch_state_v) {
const auto val = derived().do_read_uarch_x(i);
- DUSA_PRINTF("%s::read_uarch_x(%d) = %" PRIu64 "(0x%" PRIx64 ")\n", get_name(), i, val, val);
+ dusa_printf("%s::read_uarch_x(%d) = %" PRIu64 "(0x%" PRIx64 ")\n", get_name(), i, val, val);
return val;
} else {
return prefer_read_shadow_uarch_state(shadow_uarch_state_get_what(shadow_uarch_state_what::uarch_x0, i));
@@ -99,7 +111,7 @@ class i_uarch_state_access { // CRTP
void write_uarch_x(int i, uint64_t val) const {
if constexpr (!is_an_i_prefer_shadow_uarch_state_v) {
derived().do_write_uarch_x(i, val);
- DUSA_PRINTF("%s::write_uarch_x(%d, %" PRIu64 ")\n", get_name(), i, val);
+ dusa_printf("%s::write_uarch_x(%d, %" PRIu64 ")\n", get_name(), i, val);
} else {
prefer_write_shadow_uarch_state(shadow_uarch_state_get_what(shadow_uarch_state_what::uarch_x0, i), val);
}
@@ -117,14 +129,14 @@ class i_uarch_state_access { // CRTP
uint64_t read_word(uint64_t paddr) const {
const auto val = derived().do_read_word(paddr);
- DUSA_PRINTF("%s::read_word(phys_addr{0x%" PRIx64 "}) = %" PRIu64 "(0x%" PRIx64 ")\n", get_name(), paddr, val,
+ dusa_printf("%s::read_word(phys_addr{0x%" PRIx64 "}) = %" PRIu64 "(0x%" PRIx64 ")\n", get_name(), paddr, val,
val);
return val;
}
void write_word(uint64_t paddr, uint64_t val) const {
derived().do_write_word(paddr, val);
- DUSA_PRINTF("%s::write_word(phys_addr{0x%" PRIx64 "}, %" PRIu64 "(0x%" PRIx64 "))\n", get_name(), paddr, val,
+ dusa_printf("%s::write_word(phys_addr{0x%" PRIx64 "}, %" PRIu64 "(0x%" PRIx64 "))\n", get_name(), paddr, val,
val);
}
diff --git a/src/interpret.cpp b/src/interpret.cpp
index 49094f48..11c5a6f3 100644
--- a/src/interpret.cpp
+++ b/src/interpret.cpp
@@ -92,17 +92,15 @@
#ifdef MICROARCHITECTURE
#include "machine-uarch-bridge-state-access.h"
-#include "uarch-runtime.h"
#else
#include "record-step-state-access.h"
#include "replay-step-state-access.h"
#include "state-access.h"
-#include
#endif // MICROARCHITECTURE
+#include "assert-printf.h"
#include "compiler-defines.h"
#include "device-state-access.h"
-#include "dump.h"
#include "find-pma.h"
#include "i-accept-counters.h"
#include "i-interactive-state-access.h"
@@ -182,94 +180,94 @@ static void dump_exception_or_interrupt(uint64_t cause, uint64_t a7) {
if ((cause & MCAUSE_INTERRUPT_FLAG) != 0) {
switch (cause & ~MCAUSE_INTERRUPT_FLAG) {
case 0:
- D_PRINTF("reserved software interrupt", "");
+ d_printf("reserved software interrupt");
break;
case 1:
- D_PRINTF("supervisor software interrupt", "");
+ d_printf("supervisor software interrupt");
break;
case 2:
- D_PRINTF("reserved software interrupt", "");
+ d_printf("reserved software interrupt");
break;
case 3:
- D_PRINTF("machine software interrupt", "");
+ d_printf("machine software interrupt");
break;
case 4:
- D_PRINTF("reserved timer interrupt", "");
+ d_printf("reserved timer interrupt");
break;
case 5:
- D_PRINTF("supervisor timer interrupt", "");
+ d_printf("supervisor timer interrupt");
break;
case 6:
- D_PRINTF("reserved timer interrupt", "");
+ d_printf("reserved timer interrupt");
break;
case 7:
- D_PRINTF("machine timer interrupt", "");
+ d_printf("machine timer interrupt");
break;
case 8:
- D_PRINTF("reserved external interrupt", "");
+ d_printf("reserved external interrupt");
break;
case 9:
- D_PRINTF("supervisor external interrupt", "");
+ d_printf("supervisor external interrupt");
break;
case 10:
- D_PRINTF("reserved external interrupt", "");
+ d_printf("reserved external interrupt");
break;
case 11:
- D_PRINTF("machine external interrupt", "");
+ d_printf("machine external interrupt");
break;
default:
- D_PRINTF("unknown interrupt", "");
+ d_printf("unknown interrupt");
break;
}
} else {
switch (cause) {
case 0:
- D_PRINTF("instruction address misaligned", "");
+ d_printf("instruction address misaligned");
break;
case 1:
- D_PRINTF("instruction access fault", "");
+ d_printf("instruction access fault");
break;
case 2:
- D_PRINTF("illegal instruction", "");
+ d_printf("illegal instruction");
break;
case 3:
- D_PRINTF("breakpoint", "");
+ d_printf("breakpoint");
break;
case 4:
- D_PRINTF("load address misaligned", "");
+ d_printf("load address misaligned");
break;
case 5:
- D_PRINTF("load access fault", "");
+ d_printf("load access fault");
break;
case 6:
- D_PRINTF("store/amo address misaligned", "");
+ d_printf("store/amo address misaligned");
break;
case 7:
- D_PRINTF("store/amo access fault", "");
+ d_printf("store/amo access fault");
break;
case 8:
- D_PRINTF("ecall %d from u-mode", static_cast(a7));
+ d_printf("ecall %d from u-mode", static_cast(a7));
break;
case 9:
- D_PRINTF("ecall %s(%d) from s-mode", sbi_ecall_name(a7), static_cast(a7));
+ d_printf("ecall %s(%d) from s-mode", sbi_ecall_name(a7), static_cast(a7));
break;
case 10:
- D_PRINTF("ecall %d reserved", static_cast(a7));
+ d_printf("ecall %d reserved", static_cast(a7));
break;
case 11:
- D_PRINTF("ecall %s(%d) from m-mode", sbi_ecall_name(a7), static_cast(a7));
+ d_printf("ecall %s(%d) from m-mode", sbi_ecall_name(a7), static_cast(a7));
break;
case 12:
- D_PRINTF("instruction page fault", "");
+ d_printf("instruction page fault");
break;
case 13:
- D_PRINTF("load page fault", "");
+ d_printf("load page fault");
break;
case 15:
- D_PRINTF("store/amo page fault", "");
+ d_printf("store/amo page fault");
break;
default:
- D_PRINTF("reserved", "");
+ d_printf("reserved");
break;
}
}
@@ -319,22 +317,22 @@ static void dump_regs(STATE_ACCESS &a) {
f[i] = a.read_f(i);
}
// Now print them
- D_PRINTF("pc = " PRIxREG " ", pc);
+ d_printf("pc = " PRIxREG " ", pc);
for (int i = 1; i < X_REG_COUNT; i++) {
const char sep = ((i & (cols - 1)) == (cols - 1)) ? '\n' : ' ';
- D_PRINTF("%-4s= " PRIxREG "%c", reg_name[i], x[i], sep);
+ d_printf("%-4s= " PRIxREG "%c", reg_name[i], x[i], sep);
}
for (int i = 0; i < F_REG_COUNT; i++) {
const char sep = ((i & (cols - 1)) == (cols - 1)) ? '\n' : ' ';
- D_PRINTF("%-4s= " PRIxREG "%c", f_reg_name[i], f[i], sep);
- }
- D_PRINTF("prv=%s", prv_get_name(iprv));
- D_PRINTF(" mstatus=" PRIxREG "\n", mstatus);
- D_PRINTF(" cycles=" PRIuREG, mcycle);
- D_PRINTF(" insns=" PRIuREG "\n", mcycle - icycleinstret);
- D_PRINTF("mideleg=" PRIxREG, mideleg);
- D_PRINTF(" mie=" PRIxREG, mie);
- D_PRINTF(" mip=" PRIxREG "\n", mip);
+ d_printf("%-4s= " PRIxREG "%c", f_reg_name[i], f[i], sep);
+ }
+ d_printf("prv=%s", prv_get_name(iprv));
+ d_printf(" mstatus=" PRIxREG "\n", mstatus);
+ d_printf(" cycles=" PRIuREG, mcycle);
+ d_printf(" insns=" PRIuREG "\n", mcycle - icycleinstret);
+ d_printf("mideleg=" PRIxREG, mideleg);
+ d_printf(" mie=" PRIxREG, mie);
+ d_printf(" mip=" PRIxREG "\n", mip);
#undef PRIxREG
#undef PRIuREG
}
@@ -420,10 +418,10 @@ static NO_INLINE uint64_t raise_exception(const STATE_ACCESS a, uint64_t pc, uin
if (flag) {
[[maybe_unused]] auto dnote = a.make_scoped_note("dump_exception");
const auto a7 = a.read_x(17);
- D_PRINTF("raise_exception: cause=0x%016" PRIx64, cause);
- D_PRINTF(" tval=0x%016" PRIx64 " (", tval);
+ d_printf("raise_exception: cause=0x%016" PRIx64, cause);
+ d_printf(" tval=0x%016" PRIx64 " (", tval);
dump_exception_or_interrupt(cause, a7);
- D_PRINTF(")\n", "");
+ d_printf(")\n");
#ifdef DUMP_REGS
dump_regs(a);
#endif
@@ -1148,11 +1146,11 @@ static auto dump_insn([[maybe_unused]] const STATE_ACCESS a, [[maybe_unused]] ui
[[maybe_unused]] auto note = a.make_scoped_note("dump_insn");
uint64_t ppc = pc;
if (!translate_virtual_address(a, &ppc, pc, PTE_XWR_X_SHIFT)) {
- D_PRINTF("v %08" PRIx64, ppc);
+ d_printf("v %08" PRIx64, ppc);
} else {
- D_PRINTF("p %08" PRIx64, ppc);
+ d_printf("p %08" PRIx64, ppc);
}
- D_PRINTF(": %08" PRIx32 " %s\n", insn, name);
+ d_printf(": %08" PRIx32 " %s\n", insn, name);
#endif
return a.make_scoped_note(name);
}
@@ -2089,7 +2087,7 @@ static NO_INLINE uint64_t read_csr(const STATE_ACCESS a, uint64_t mcycle, CSR_ad
default:
// Invalid CSRs
#ifdef DUMP_INVALID_CSR
- D_PRINTF("csr_read: invalid CSR=0x%x\n", static_cast(csraddr));
+ d_printf("csr_read: invalid CSR=0x%x\n", static_cast(csraddr));
#endif
return read_csr_fail(status);
}
@@ -2437,9 +2435,9 @@ static inline execute_status write_csr_fcsr(const STATE_ACCESS a, uint64_t val)
template
static NO_INLINE execute_status write_csr(const STATE_ACCESS a, uint64_t mcycle, CSR_address csraddr, uint64_t val) {
#if defined(DUMP_CSR)
- D_PRINTF("csr_write: csr=0x%03x val=0x", static_cast(csraddr));
+ d_printf("csr_write: csr=0x%03x val=0x", static_cast(csraddr));
print_uint64_t(val);
- D_PRINTF("\n");
+ d_printf("\n");
#endif
if (unlikely(csr_is_read_only(csraddr))) {
return execute_status::failure;
@@ -2582,7 +2580,7 @@ static NO_INLINE execute_status write_csr(const STATE_ACCESS a, uint64_t mcycle,
default:
// Invalid CSRs
#ifdef DUMP_INVALID_CSR
- D_PRINTF("csr_write: invalid CSR=0x%x\n", static_cast(csraddr));
+ d_printf("csr_write: invalid CSR=0x%x\n", static_cast(csraddr));
#endif
return execute_status::failure;
}
diff --git a/src/machine.cpp b/src/machine.cpp
index 265c9d4e..7bde91f7 100644
--- a/src/machine.cpp
+++ b/src/machine.cpp
@@ -951,10 +951,10 @@ void machine::store(const std::string &dir) const {
void machine::dump_insn_hist() {
#ifdef DUMP_INSN_HIST
- D_PRINTF("\nInstruction Histogram:\n", "");
+ d_printf("\nInstruction Histogram:\n");
for (const auto &[key, val] : m_counters) {
if (key.starts_with("insn.")) {
- D_PRINTF("%s: %" PRIu64 "\n", key.c_str(), val);
+ d_printf("%s: %" PRIu64 "\n", key.c_str(), val);
}
}
#endif
@@ -967,41 +967,41 @@ void machine::dump_stats() {
return static_cast(b) / (a + b);
};
- D_PRINTF("\nMachine Counters:\n", "");
- D_PRINTF("inner loops: %" PRIu64 "\n", m_counters["stats.inner_loop"]);
- D_PRINTF("outers loops: %" PRIu64 "\n", m_counters["stats.outer_loop"]);
- D_PRINTF("supervisor ints: %" PRIu64 "\n", m_counters["stats.sv_int"]);
- D_PRINTF("supervisor ex: %" PRIu64 "\n", m_counters["stats.sv_ex"]);
- D_PRINTF("machine ints: %" PRIu64 "\n", m_counters["stats.m_int"]);
- D_PRINTF("machine ex: %" PRIu64 "\n", m_counters["stats.m_ex"]);
- D_PRINTF("atomic mem ops: %" PRIu64 "\n", m_counters["stats.atomic_mop"]);
- D_PRINTF("fence: %" PRIu64 "\n", m_counters["stats.fence"]);
- D_PRINTF("fence.i: %" PRIu64 "\n", m_counters["stats.fence_i"]);
- D_PRINTF("fence.vma: %" PRIu64 "\n", m_counters["stats.fence_vma"]);
- D_PRINTF("max asid: %" PRIu64 "\n", m_counters["stats.max_asid"]);
- D_PRINTF("User mode: %" PRIu64 "\n", m_counters["stats.prv.U"]);
- D_PRINTF("Supervisor mode: %" PRIu64 "\n", m_counters["stats.prv.S"]);
- D_PRINTF("Machine mode: %" PRIu64 "\n", m_counters["stats.prv.M"]);
- D_PRINTF("tlb code hit ratio: %.4f\n", hr(m_counters["stats.tlb.cmiss"], m_counters["stats.tlb.chit"]));
- D_PRINTF("tlb read hit ratio: %.4f\n", hr(m_counters["stats.tlb.rmiss"], m_counters["stats.tlb.rhit"]));
- D_PRINTF("tlb write hit ratio: %.4f\n", hr(m_counters["stats.tlb.wmiss"], m_counters["stats.tlb.whit"]));
- D_PRINTF("tlb.chit: %" PRIu64 "\n", m_counters["stats.tlb.chit"]);
- D_PRINTF("tlb.cmiss: %" PRIu64 "\n", m_counters["stats.tlb.cmiss"]);
- D_PRINTF("tlb.rhit: %" PRIu64 "\n", m_counters["stats.tlb.rhit"]);
- D_PRINTF("tlb.rmiss: %" PRIu64 "\n", m_counters["stats.tlb.rmiss"]);
- D_PRINTF("tlb.whit: %" PRIu64 "\n", m_counters["stats.tlb.whit"]);
- D_PRINTF("tlb.wmiss: %" PRIu64 "\n", m_counters["stats.tlb.wmiss"]);
- D_PRINTF("tlb.flush_all: %" PRIu64 "\n", m_counters["stats.tlb.flush_all"]);
- D_PRINTF("tlb.flush_read: %" PRIu64 "\n", m_counters["stats.tlb.flush_read"]);
- D_PRINTF("tlb.flush_write: %" PRIu64 "\n", m_counters["stats.tlb.flush_write"]);
- D_PRINTF("tlb.flush_vaddr: %" PRIu64 "\n", m_counters["stats.tlb.flush_vaddr"]);
- D_PRINTF("tlb.flush_satp: %" PRIu64 "\n", m_counters["stats.tlb.flush_satp"]);
- D_PRINTF("tlb.flush_mstatus: %" PRIu64 "\n", m_counters["stats.tlb.flush_mstatus"]);
- D_PRINTF("tlb.flush_set_prv: %" PRIu64 "\n", m_counters["stats.tlb.flush_set_prv"]);
- D_PRINTF("tlb.flush_fence_vma_all: %" PRIu64 "\n", m_counters["stats.tlb.flush_fence_vma_all"]);
- D_PRINTF("tlb.flush_fence_vma_asid: %" PRIu64 "\n", m_counters["stats.tlb.flush_fence_vma_asid"]);
- D_PRINTF("tlb.flush_fence_vma_vaddr: %" PRIu64 "\n", m_counters["stats.tlb.flush_fence_vma_vaddr"]);
- D_PRINTF("tlb.flush_fence_vma_asid_vaddr: %" PRIu64 "\n", m_counters["stats.tlb.flush_fence_vma_asid_vaddr"]);
+ d_printf("\nMachine Counters:\n");
+ d_printf("inner loops: %" PRIu64 "\n", m_counters["stats.inner_loop"]);
+ d_printf("outers loops: %" PRIu64 "\n", m_counters["stats.outer_loop"]);
+ d_printf("supervisor ints: %" PRIu64 "\n", m_counters["stats.sv_int"]);
+ d_printf("supervisor ex: %" PRIu64 "\n", m_counters["stats.sv_ex"]);
+ d_printf("machine ints: %" PRIu64 "\n", m_counters["stats.m_int"]);
+ d_printf("machine ex: %" PRIu64 "\n", m_counters["stats.m_ex"]);
+ d_printf("atomic mem ops: %" PRIu64 "\n", m_counters["stats.atomic_mop"]);
+ d_printf("fence: %" PRIu64 "\n", m_counters["stats.fence"]);
+ d_printf("fence.i: %" PRIu64 "\n", m_counters["stats.fence_i"]);
+ d_printf("fence.vma: %" PRIu64 "\n", m_counters["stats.fence_vma"]);
+ d_printf("max asid: %" PRIu64 "\n", m_counters["stats.max_asid"]);
+ d_printf("User mode: %" PRIu64 "\n", m_counters["stats.prv.U"]);
+ d_printf("Supervisor mode: %" PRIu64 "\n", m_counters["stats.prv.S"]);
+ d_printf("Machine mode: %" PRIu64 "\n", m_counters["stats.prv.M"]);
+ d_printf("tlb code hit ratio: %.4f\n", hr(m_counters["stats.tlb.cmiss"], m_counters["stats.tlb.chit"]));
+ d_printf("tlb read hit ratio: %.4f\n", hr(m_counters["stats.tlb.rmiss"], m_counters["stats.tlb.rhit"]));
+ d_printf("tlb write hit ratio: %.4f\n", hr(m_counters["stats.tlb.wmiss"], m_counters["stats.tlb.whit"]));
+ d_printf("tlb.chit: %" PRIu64 "\n", m_counters["stats.tlb.chit"]);
+ d_printf("tlb.cmiss: %" PRIu64 "\n", m_counters["stats.tlb.cmiss"]);
+ d_printf("tlb.rhit: %" PRIu64 "\n", m_counters["stats.tlb.rhit"]);
+ d_printf("tlb.rmiss: %" PRIu64 "\n", m_counters["stats.tlb.rmiss"]);
+ d_printf("tlb.whit: %" PRIu64 "\n", m_counters["stats.tlb.whit"]);
+ d_printf("tlb.wmiss: %" PRIu64 "\n", m_counters["stats.tlb.wmiss"]);
+ d_printf("tlb.flush_all: %" PRIu64 "\n", m_counters["stats.tlb.flush_all"]);
+ d_printf("tlb.flush_read: %" PRIu64 "\n", m_counters["stats.tlb.flush_read"]);
+ d_printf("tlb.flush_write: %" PRIu64 "\n", m_counters["stats.tlb.flush_write"]);
+ d_printf("tlb.flush_vaddr: %" PRIu64 "\n", m_counters["stats.tlb.flush_vaddr"]);
+ d_printf("tlb.flush_satp: %" PRIu64 "\n", m_counters["stats.tlb.flush_satp"]);
+ d_printf("tlb.flush_mstatus: %" PRIu64 "\n", m_counters["stats.tlb.flush_mstatus"]);
+ d_printf("tlb.flush_set_prv: %" PRIu64 "\n", m_counters["stats.tlb.flush_set_prv"]);
+ d_printf("tlb.flush_fence_vma_all: %" PRIu64 "\n", m_counters["stats.tlb.flush_fence_vma_all"]);
+ d_printf("tlb.flush_fence_vma_asid: %" PRIu64 "\n", m_counters["stats.tlb.flush_fence_vma_asid"]);
+ d_printf("tlb.flush_fence_vma_vaddr: %" PRIu64 "\n", m_counters["stats.tlb.flush_fence_vma_vaddr"]);
+ d_printf("tlb.flush_fence_vma_asid_vaddr: %" PRIu64 "\n", m_counters["stats.tlb.flush_fence_vma_asid_vaddr"]);
#undef TLB_HIT_RATIO
#endif
}
diff --git a/src/merkle-tree-hash.cpp b/src/merkle-tree-hash.cpp
index 06f695a1..101235b4 100644
--- a/src/merkle-tree-hash.cpp
+++ b/src/merkle-tree-hash.cpp
@@ -103,7 +103,7 @@ static std::optional read_hash(FILE *f) {
/// \param fmt Format string
/// \param ... Arguments, if any
// NOLINTNEXTLINE(cert-dcl50-cpp): this vararg is safe because the compiler can check the format
-__attribute__((format(printf, 1, 2))) static void error(const char *fmt, ...) {
+__attribute__((__format__(__printf__, 1, 2))) static void error(const char *fmt, ...) {
va_list ap{};
va_start(ap, fmt);
std::ignore = vfprintf(stderr, fmt, ap);
diff --git a/src/uarch-solidity-compat.h b/src/uarch-solidity-compat.h
index fd155905..3cd66e0b 100644
--- a/src/uarch-solidity-compat.h
+++ b/src/uarch-solidity-compat.h
@@ -23,7 +23,7 @@
#include
#ifdef DUMP_UARCH_INSN
-#include "dump.h"
+#include "assert-printf.h"
#include
#endif
@@ -231,9 +231,9 @@ template
static auto dumpInsn([[maybe_unused]] const UarchState a, [[maybe_unused]] uint64 pc, [[maybe_unused]] uint32 insn,
[[maybe_unused]] const char *name) {
#ifdef DUMP_UARCH_INSN
- D_PRINTF("ua %08" PRIx64, pc);
- D_PRINTF(": %08" PRIx32 " ", insn);
- D_PRINTF("%s\n", name);
+ d_printf("ua %08" PRIx64, pc);
+ d_printf(": %08" PRIx32 " ", insn);
+ d_printf("%s\n", name);
#endif
return a.make_scoped_note(name);
}
diff --git a/uarch/uarch-runtime.h b/uarch/uarch-runtime.h
index 30fc0517..a59b6009 100644
--- a/uarch/uarch-runtime.h
+++ b/uarch/uarch-runtime.h
@@ -40,6 +40,9 @@
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define fprintf(f, ...) printf(__VA_ARGS__)
+// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
+#define vfprintf(f, fmt, ap) vprintf(fmt, ap)
+
extern "C" NO_RETURN void abort();
namespace cartesi {