From 9797af0ad4ee1cfecbd6aa339fc43f30472aaa19 Mon Sep 17 00:00:00 2001 From: Yutetsu TAKATSUKASA Date: Sat, 8 May 2021 07:16:40 +0900 Subject: [PATCH] Introduce a macro VL_ATTR_NO_SANITIZE_ALIGN to suppress unaligned access check in ubsan (#2929) * Add VL_ATTR_NO_SANITIZE_ALIGN macro to disable alignment check of ubsan * Mark a function VL_ATTR_NO_SANITIZE_ALIGN because the function is intentionally using unaligned access for the sake of performance. Co-authored-by: Wilson Snyder --- include/verilated_vcd_c.cpp | 12 ++++++++++-- include/verilatedos.h | 9 +++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/include/verilated_vcd_c.cpp b/include/verilated_vcd_c.cpp index e11ed947d..bfc185c34 100644 --- a/include/verilated_vcd_c.cpp +++ b/include/verilated_vcd_c.cpp @@ -586,8 +586,10 @@ void VerilatedVcd::declTriArray(vluint32_t code, const char* name, bool array, i //============================================================================= // Trace rendering prinitives -void VerilatedVcd::finishLine(vluint32_t code, char* writep) { - const char* const suffixp = m_suffixesp + code * VL_TRACE_SUFFIX_ENTRY_SIZE; +static inline void +VerilatedVcdCCopyAndAppendNewLine(char* writep, const char* suffixp) VL_ATTR_NO_SANITIZE_ALIGN; + +static inline void VerilatedVcdCCopyAndAppendNewLine(char* writep, const char* suffixp) { // Copy the whole suffix (this avoid having hard to predict branches which // helps a lot). Note: The maximum length of the suffix is // VL_TRACE_MAX_VCD_CODE_SIZE + 2 == 7, but we unroll this here for speed. @@ -605,6 +607,12 @@ void VerilatedVcd::finishLine(vluint32_t code, char* writep) { writep[5] = suffixp[5]; writep[6] = '\n'; // The 6th index is always '\n' if it's relevant, no need to fetch it. #endif +} + +void VerilatedVcd::finishLine(vluint32_t code, char* writep) { + const char* const suffixp = m_suffixesp + code * VL_TRACE_SUFFIX_ENTRY_SIZE; + VerilatedVcdCCopyAndAppendNewLine(writep, suffixp); + // Now write back the write pointer incremented by the actual size of the // suffix, which was stored in the last byte of the suffix buffer entry. m_writep = writep + suffixp[VL_TRACE_SUFFIX_ENTRY_SIZE - 1]; diff --git a/include/verilatedos.h b/include/verilatedos.h index 21cc1447f..4b1b0874d 100644 --- a/include/verilatedos.h +++ b/include/verilatedos.h @@ -43,6 +43,12 @@ # define VL_ATTR_COLD __attribute__((cold)) # define VL_ATTR_HOT __attribute__((hot)) # define VL_ATTR_NORETURN __attribute__((noreturn)) +// clang and gcc-8.0+ support no_sanitize("string") style attribute +# if defined(__clang__) || (__GNUC__ >= 8) +# define VL_ATTR_NO_SANITIZE_ALIGN __attribute__((no_sanitize("alignment"))) +#else // The entire undefined sanitizer has to be disabled for older gcc +# define VL_ATTR_NO_SANITIZE_ALIGN __attribute__((no_sanitize_undefined)) +#endif # define VL_ATTR_PRINTF(fmtArgNum) __attribute__((format(printf, (fmtArgNum), (fmtArgNum) + 1))) # define VL_ATTR_PURE __attribute__((pure)) # define VL_ATTR_UNUSED __attribute__((unused)) @@ -85,6 +91,9 @@ #ifndef VL_ATTR_NORETURN # define VL_ATTR_NORETURN ///< Attribute that function does not ever return #endif +#ifndef VL_ATTR_NO_SANITIZE_ALIGN +# define VL_ATTR_NO_SANITIZE_ALIGN ///< Attribute that the function contains intended unaligned access +#endif #ifndef VL_ATTR_PRINTF # define VL_ATTR_PRINTF(fmtArgNum) ///< Attribute for function with printf format checking #endif