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 {