mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-02 22:24:26 +00:00
Kernel: Exclude individual functions from coverage instrumentation
Sticking this to the function source has multiple benefits: - We instrument more code, by not excluding entire files. - NO_SANITIZE_COVERAGE can be used in Header files. - Keeping the info with the source code, means if a function or file is moved around, the NO_SANITIZE_COVERAGE moves with it.
This commit is contained in:
parent
ca89116a46
commit
fdc0328ce3
|
@ -186,6 +186,15 @@
|
|||
#endif
|
||||
#define RETURNS_NONNULL __attribute__((returns_nonnull))
|
||||
|
||||
#ifdef NO_SANITIZE_COVERAGE
|
||||
# undef NO_SANITIZE_COVERAGE
|
||||
#endif
|
||||
#if defined(AK_COMPILER_CLANG)
|
||||
# define NO_SANITIZE_COVERAGE __attribute__((no_sanitize("coverage")))
|
||||
#else
|
||||
# define NO_SANITIZE_COVERAGE __attribute__((no_sanitize_coverage))
|
||||
#endif
|
||||
|
||||
#ifdef NO_SANITIZE_ADDRESS
|
||||
# undef NO_SANITIZE_ADDRESS
|
||||
#endif
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Platform.h>
|
||||
#include <AK/Types.h>
|
||||
#include <Kernel/Arch/CPU.h>
|
||||
#include <Kernel/Arch/InterruptManagement.h>
|
||||
|
@ -165,7 +166,7 @@ Atomic<Graphics::Console*> g_boot_console;
|
|||
READONLY_AFTER_INIT static u8 s_command_line_buffer[512];
|
||||
#endif
|
||||
|
||||
extern "C" [[noreturn]] UNMAP_AFTER_INIT void init([[maybe_unused]] BootInfo const& boot_info)
|
||||
extern "C" [[noreturn]] UNMAP_AFTER_INIT NO_SANITIZE_COVERAGE void init([[maybe_unused]] BootInfo const& boot_info)
|
||||
{
|
||||
g_in_early_boot = true;
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ ALWAYS_INLINE void sti()
|
|||
asm volatile("sti" ::
|
||||
: "memory");
|
||||
}
|
||||
ALWAYS_INLINE FlatPtr cpu_flags()
|
||||
ALWAYS_INLINE NO_SANITIZE_COVERAGE FlatPtr cpu_flags()
|
||||
{
|
||||
FlatPtr flags;
|
||||
asm volatile(
|
||||
|
@ -52,7 +52,7 @@ ALWAYS_INLINE void write_gs_value(FlatPtr offset, T val)
|
|||
: "memory");
|
||||
}
|
||||
|
||||
ALWAYS_INLINE FlatPtr read_gs_ptr(FlatPtr offset)
|
||||
ALWAYS_INLINE NO_SANITIZE_COVERAGE FlatPtr read_gs_ptr(FlatPtr offset)
|
||||
{
|
||||
FlatPtr val;
|
||||
asm volatile(
|
||||
|
@ -69,7 +69,7 @@ ALWAYS_INLINE void write_gs_ptr(u32 offset, FlatPtr val)
|
|||
: "memory");
|
||||
}
|
||||
|
||||
ALWAYS_INLINE bool are_interrupts_enabled()
|
||||
ALWAYS_INLINE NO_SANITIZE_COVERAGE bool are_interrupts_enabled()
|
||||
{
|
||||
return (cpu_flags() & 0x200) != 0;
|
||||
}
|
||||
|
|
|
@ -5,13 +5,14 @@
|
|||
*/
|
||||
|
||||
#include <AK/Assertions.h>
|
||||
#include <AK/Platform.h>
|
||||
#include <Kernel/Arch/CPU.h>
|
||||
#include <Kernel/Library/Panic.h>
|
||||
#include <Kernel/Tasks/Process.h>
|
||||
|
||||
using namespace Kernel;
|
||||
|
||||
void __assertion_failed(char const* msg, char const* file, unsigned line, char const* func)
|
||||
NO_SANITIZE_COVERAGE void __assertion_failed(char const* msg, char const* file, unsigned line, char const* func)
|
||||
{
|
||||
asm volatile("cli");
|
||||
critical_dmesgln("ASSERTION FAILED: {}", msg);
|
||||
|
|
|
@ -1409,7 +1409,7 @@ extern "C" void enter_thread_context(Thread* from_thread, Thread* to_thread)
|
|||
asm volatile("frstor %0" ::"m"(to_thread->fpu_state()));
|
||||
}
|
||||
|
||||
extern "C" FlatPtr do_init_context(Thread* thread, u32 flags)
|
||||
extern "C" NO_SANITIZE_COVERAGE FlatPtr do_init_context(Thread* thread, u32 flags)
|
||||
{
|
||||
VERIFY_INTERRUPTS_DISABLED();
|
||||
thread->regs().set_flags(flags);
|
||||
|
@ -1461,7 +1461,7 @@ NAKED void thread_context_first_enter(void)
|
|||
" jmp common_trap_exit \n");
|
||||
}
|
||||
|
||||
NAKED void do_assume_context(Thread*, u32)
|
||||
NAKED NO_SANITIZE_COVERAGE void do_assume_context(Thread*, u32)
|
||||
{
|
||||
// clang-format off
|
||||
// FIXME: I hope (Thread* thread, u32 flags) aren't compiled away
|
||||
|
|
|
@ -156,7 +156,7 @@ public:
|
|||
};
|
||||
|
||||
template<typename T>
|
||||
ALWAYS_INLINE Thread* ProcessorBase<T>::current_thread()
|
||||
ALWAYS_INLINE NO_SANITIZE_COVERAGE Thread* ProcessorBase<T>::current_thread()
|
||||
{
|
||||
// If we were to use ProcessorBase::current here, we'd have to
|
||||
// disable interrupts to prevent a race where we may get pre-empted
|
||||
|
@ -224,7 +224,7 @@ ALWAYS_INLINE void ProcessorBase<T>::enter_critical()
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
ALWAYS_INLINE bool ProcessorBase<T>::are_interrupts_enabled()
|
||||
ALWAYS_INLINE NO_SANITIZE_COVERAGE bool ProcessorBase<T>::are_interrupts_enabled()
|
||||
{
|
||||
return Kernel::are_interrupts_enabled();
|
||||
}
|
||||
|
@ -297,7 +297,7 @@ ALWAYS_INLINE void ProcessorBase<T>::wait_check()
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
ALWAYS_INLINE FlatPtr ProcessorBase<T>::current_in_irq()
|
||||
ALWAYS_INLINE NO_SANITIZE_COVERAGE FlatPtr ProcessorBase<T>::current_in_irq()
|
||||
{
|
||||
return read_gs_ptr(__builtin_offsetof(Processor, m_in_irq));
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Platform.h>
|
||||
#include <Kernel/API/Syscall.h>
|
||||
#include <Kernel/Arch/Processor.h>
|
||||
#include <Kernel/Arch/TrapFrame.h>
|
||||
|
@ -18,7 +19,7 @@
|
|||
using namespace Kernel;
|
||||
|
||||
extern "C" void syscall_entry();
|
||||
extern "C" [[gnu::naked]] void syscall_entry()
|
||||
extern "C" NO_SANITIZE_COVERAGE [[gnu::naked]] void syscall_entry()
|
||||
{
|
||||
// clang-format off
|
||||
asm(
|
||||
|
|
|
@ -716,18 +716,15 @@ if (ENABLE_KERNEL_COVERAGE_COLLECTION)
|
|||
)
|
||||
|
||||
add_compile_options(-fsanitize-coverage=trace-pc)
|
||||
# To avoid __sanitizer_cov_trace_pc from causing an infinite recursion,
|
||||
# don't instrument any even transitively used code. You can either skip
|
||||
# individual function via the NO_SANITIZE_COVERAGE macro or by excluding
|
||||
# the whole file by adding it to KCOV_EXCLUDED_SOURCES.
|
||||
# Note that you can only add .cpp and not .h files to KCOV_EXCLUDED_SOURCES.
|
||||
set(KCOV_EXCLUDED_SOURCES
|
||||
# Make sure we don't instrument any code called from __sanitizer_cov_trace_pc
|
||||
# otherwise we'll end up with recursive calls to that function.
|
||||
../AK/Error.cpp
|
||||
../AK/Format.cpp
|
||||
../AK/StringBuilder.cpp
|
||||
../Kernel/Arch/x86_64/Processor.cpp
|
||||
# Skip core KCOV code.
|
||||
../Kernel/Devices/KCOVDevice.cpp
|
||||
../Kernel/Devices/KCOVInstance.cpp
|
||||
../Kernel/FileSystem/File.cpp
|
||||
../Kernel/FileSystem/OpenFileDescription.cpp
|
||||
../Kernel/init.cpp
|
||||
../Kernel/SanCov.cpp
|
||||
# GCC assumes that the caller saves registers for functions according
|
||||
# to the System V ABI and happily inserts coverage calls into the
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <AK/IntrusiveList.h>
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <AK/Platform.h>
|
||||
#include <AK/Time.h>
|
||||
#include <AK/Variant.h>
|
||||
#include <AK/Vector.h>
|
||||
|
@ -94,8 +95,8 @@ public:
|
|||
return m_is_joinable;
|
||||
}
|
||||
|
||||
Process& process() { return m_process; }
|
||||
Process const& process() const { return m_process; }
|
||||
NO_SANITIZE_COVERAGE Process& process() { return m_process; }
|
||||
NO_SANITIZE_COVERAGE Process const& process() const { return m_process; }
|
||||
|
||||
using Name = FixedStringBuffer<64>;
|
||||
SpinlockProtected<Name, LockRank::None> const& name() const
|
||||
|
|
Loading…
Reference in a new issue