From c8af0d3cea8cab9277651f8cabe54e2f1a3b167f Mon Sep 17 00:00:00 2001 From: David Spickett Date: Thu, 16 Mar 2023 11:32:35 +0000 Subject: [PATCH] [lldb] Add compile time checks for signal codes when on the matching platform This adds a new macro to the UnixSignals subclasses, ADD_SIGCODE. ADD_SIGCODE(4, ILL_ILLOPC, 1, "illegal opcode"); Adds a sigcode to signal 4. That code is ILL_ILLOPC and we expect its value to be 1. When compiling on a system that matches the class e.g. FreeBSD for FreeBSDSignals, the macro will check that that is true. When you're not on FreeBSD we just use the number 1, and ILL_ILLOPC won't be defined to anything because we don't include csignal. Example error: LinuxSignals.cpp:52:3: error: static_assert failed due to requirement 'ILL_COPROC == 9' "Value mismatch for signal code ILL_COPROC" Reviewed By: arichardson Differential Revision: https://reviews.llvm.org/D146222 --- lldb/include/lldb/Target/UnixSignals.h | 2 + .../Platform/FreeBSD/FreeBSDSignals.cpp | 65 ++++++++++------- .../Plugins/Platform/Linux/LinuxSignals.cpp | 71 ++++++++++++------- .../Plugins/Platform/NetBSD/NetBSDSignals.cpp | 53 ++++++++------ 4 files changed, 118 insertions(+), 73 deletions(-) diff --git a/lldb/include/lldb/Target/UnixSignals.h b/lldb/include/lldb/Target/UnixSignals.h index 1287e0007cc7..65eac7ebdd82 100644 --- a/lldb/include/lldb/Target/UnixSignals.h +++ b/lldb/include/lldb/Target/UnixSignals.h @@ -90,6 +90,8 @@ public: enum SignalCodePrintOption { None, Address, Bounds }; + // Instead of calling this directly, use a ADD_SIGCODE macro to get compile + // time checks when on the native platform. void AddSignalCode( int signo, int code, const char *description, SignalCodePrintOption print_option = SignalCodePrintOption::None); diff --git a/lldb/source/Plugins/Platform/FreeBSD/FreeBSDSignals.cpp b/lldb/source/Plugins/Platform/FreeBSD/FreeBSDSignals.cpp index c2997e024921..f597bed80dde 100644 --- a/lldb/source/Plugins/Platform/FreeBSD/FreeBSDSignals.cpp +++ b/lldb/source/Plugins/Platform/FreeBSD/FreeBSDSignals.cpp @@ -8,6 +8,17 @@ #include "FreeBSDSignals.h" +#ifdef __FreeBSD__ +#include + +#define ADD_SIGCODE(signal, name, value, ...) \ + static_assert(name == value, "Value mismatch for signal code " #name); \ + AddSignalCode(signal, value, __VA_ARGS__) +#else +#define ADD_SIGCODE(signal, name, value, ...) \ + AddSignalCode(signal, value, __VA_ARGS__) +#endif /* ifdef __FreeBSD__ */ + using namespace lldb_private; FreeBSDSignals::FreeBSDSignals() : UnixSignals() { Reset(); } @@ -17,39 +28,39 @@ void FreeBSDSignals::Reset() { // clang-format off // SIGILL - AddSignalCode(4, 1 /*ILL_ILLOPC*/, "illegal opcode"); - AddSignalCode(4, 2 /*ILL_ILLOPN*/, "illegal operand"); - AddSignalCode(4, 3 /*ILL_ILLADR*/, "illegal addressing mode"); - AddSignalCode(4, 4 /*ILL_ILLTRP*/, "illegal trap"); - AddSignalCode(4, 5 /*ILL_PRVOPC*/, "privileged opcode"); - AddSignalCode(4, 6 /*ILL_PRVREG*/, "privileged register"); - AddSignalCode(4, 7 /*ILL_COPROC*/, "coprocessor error"); - AddSignalCode(4, 8 /*ILL_BADSTK*/, "internal stack error"); + ADD_SIGCODE(4, ILL_ILLOPC, 1, "illegal opcode"); + ADD_SIGCODE(4, ILL_ILLOPN, 2, "illegal operand"); + ADD_SIGCODE(4, ILL_ILLADR, 3, "illegal addressing mode"); + ADD_SIGCODE(4, ILL_ILLTRP, 4, "illegal trap"); + ADD_SIGCODE(4, ILL_PRVOPC, 5, "privileged opcode"); + ADD_SIGCODE(4, ILL_PRVREG, 6, "privileged register"); + ADD_SIGCODE(4, ILL_COPROC, 7, "coprocessor error"); + ADD_SIGCODE(4, ILL_BADSTK, 8, "internal stack error"); // SIGFPE - AddSignalCode(8, 1 /*FPE_INTOVF*/, "integer overflow"); - AddSignalCode(8, 2 /*FPE_INTDIV*/, "integer divide by zero"); - AddSignalCode(8, 3 /*FPE_FLTDIV*/, "floating point divide by zero"); - AddSignalCode(8, 4 /*FPE_FLTOVF*/, "floating point overflow"); - AddSignalCode(8, 5 /*FPE_FLTUND*/, "floating point underflow"); - AddSignalCode(8, 6 /*FPE_FLTRES*/, "floating point inexact result"); - AddSignalCode(8, 7 /*FPE_FLTINV*/, "invalid floating point operation"); - AddSignalCode(8, 8 /*FPE_FLTSUB*/, "subscript out of range"); - AddSignalCode(8, 9 /*FPE_FLTIDO*/, "input denormal operation"); + ADD_SIGCODE(8, FPE_INTOVF, 1, "integer overflow"); + ADD_SIGCODE(8, FPE_INTDIV, 2, "integer divide by zero"); + ADD_SIGCODE(8, FPE_FLTDIV, 3, "floating point divide by zero"); + ADD_SIGCODE(8, FPE_FLTOVF, 4, "floating point overflow"); + ADD_SIGCODE(8, FPE_FLTUND, 5, "floating point underflow"); + ADD_SIGCODE(8, FPE_FLTRES, 6, "floating point inexact result"); + ADD_SIGCODE(8, FPE_FLTINV, 7, "invalid floating point operation"); + ADD_SIGCODE(8, FPE_FLTSUB, 8, "subscript out of range"); + ADD_SIGCODE(8, FPE_FLTIDO, 9, "input denormal operation"); // SIGBUS - AddSignalCode(10, 1 /*BUS_ADRALN*/, "invalid address alignment"); - AddSignalCode(10, 2 /*BUS_ADRERR*/, "nonexistent physical address"); - AddSignalCode(10, 3 /*BUS_OBJERR*/, "object-specific hardware error"); - AddSignalCode(10, 100 /*BUS_OOMERR*/, "no memory"); + ADD_SIGCODE(10, BUS_ADRALN, 1, "invalid address alignment"); + ADD_SIGCODE(10, BUS_ADRERR, 2, "nonexistent physical address"); + ADD_SIGCODE(10, BUS_OBJERR, 3, "object-specific hardware error"); + ADD_SIGCODE(10, BUS_OOMERR, 100, "no memory"); // SIGSEGV - AddSignalCode(11, 1 /*SEGV_MAPERR*/, "address not mapped to object", - SignalCodePrintOption::Address); - AddSignalCode(11, 2 /*SEGV_ACCERR*/, "invalid permissions for mapped object", - SignalCodePrintOption::Address); - AddSignalCode(11, 100 /*SEGV_PKUERR*/, "PKU violation", - SignalCodePrintOption::Address); + ADD_SIGCODE(11, SEGV_MAPERR, 1, "address not mapped to object", + SignalCodePrintOption::Address); + ADD_SIGCODE(11, SEGV_ACCERR, 2, "invalid permissions for mapped object", + SignalCodePrintOption::Address); + ADD_SIGCODE(11, SEGV_PKUERR, 100, "PKU violation", + SignalCodePrintOption::Address); // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION // ===== ============== ======== ====== ====== ======================== diff --git a/lldb/source/Plugins/Platform/Linux/LinuxSignals.cpp b/lldb/source/Plugins/Platform/Linux/LinuxSignals.cpp index fee7b89ef837..834a558e4d22 100644 --- a/lldb/source/Plugins/Platform/Linux/LinuxSignals.cpp +++ b/lldb/source/Plugins/Platform/Linux/LinuxSignals.cpp @@ -8,6 +8,27 @@ #include "LinuxSignals.h" +#ifdef __linux__ +#include + +#ifndef SEGV_BNDERR +#define SEGV_BNDERR 3 +#endif +#ifndef SEGV_MTEAERR +#define SEGV_MTEAERR 8 +#endif +#ifndef SEGV_MTESERR +#define SEGV_MTESERR 9 +#endif + +#define ADD_SIGCODE(signal, name, value, ...) \ + static_assert(name == value, "Value mismatch for signal code " #name); \ + AddSignalCode(signal, value, __VA_ARGS__) +#else +#define ADD_SIGCODE(signal, name, value, ...) \ + AddSignalCode(signal, value, __VA_ARGS__) +#endif /* ifdef __linux__ */ + using namespace lldb_private; LinuxSignals::LinuxSignals() : UnixSignals() { Reset(); } @@ -22,45 +43,45 @@ void LinuxSignals::Reset() { AddSignal(3, "SIGQUIT", false, true, true, "quit"); AddSignal(4, "SIGILL", false, true, true, "illegal instruction"); - AddSignalCode(4, 1 /*ILL_ILLOPC*/, "illegal opcode"); - AddSignalCode(4, 2 /*ILL_ILLOPN*/, "illegal operand"); - AddSignalCode(4, 3 /*ILL_ILLADR*/, "illegal addressing mode"); - AddSignalCode(4, 4 /*ILL_ILLTRP*/, "illegal trap"); - AddSignalCode(4, 5 /*ILL_PRVOPC*/, "privileged opcode"); - AddSignalCode(4, 6 /*ILL_PRVREG*/, "privileged register"); - AddSignalCode(4, 7 /*ILL_COPROC*/, "coprocessor error"); - AddSignalCode(4, 8 /*ILL_BADSTK*/, "internal stack error"); + ADD_SIGCODE(4, ILL_ILLOPC, 1, "illegal opcode"); + ADD_SIGCODE(4, ILL_ILLOPN, 2, "illegal operand"); + ADD_SIGCODE(4, ILL_ILLADR, 3, "illegal addressing mode"); + ADD_SIGCODE(4, ILL_ILLTRP, 4, "illegal trap"); + ADD_SIGCODE(4, ILL_PRVOPC, 5, "privileged opcode"); + ADD_SIGCODE(4, ILL_PRVREG, 6, "privileged register"); + ADD_SIGCODE(4, ILL_COPROC, 7, "coprocessor error"); + ADD_SIGCODE(4, ILL_BADSTK, 8, "internal stack error"); AddSignal(5, "SIGTRAP", true, true, true, "trace trap (not reset when caught)"); AddSignal(6, "SIGABRT", false, true, true, "abort()/IOT trap", "SIGIOT"); AddSignal(7, "SIGBUS", false, true, true, "bus error"); - AddSignalCode(7, 1 /*BUS_ADRALN*/, "illegal alignment"); - AddSignalCode(7, 2 /*BUS_ADRERR*/, "illegal address"); - AddSignalCode(7, 3 /*BUS_OBJERR*/, "hardware error"); + ADD_SIGCODE(7, BUS_ADRALN, 1, "illegal alignment"); + ADD_SIGCODE(7, BUS_ADRERR, 2, "illegal address"); + ADD_SIGCODE(7, BUS_OBJERR, 3, "hardware error"); AddSignal(8, "SIGFPE", false, true, true, "floating point exception"); - AddSignalCode(8, 1 /*FPE_INTDIV*/, "integer divide by zero"); - AddSignalCode(8, 2 /*FPE_INTOVF*/, "integer overflow"); - AddSignalCode(8, 3 /*FPE_FLTDIV*/, "floating point divide by zero"); - AddSignalCode(8, 4 /*FPE_FLTOVF*/, "floating point overflow"); - AddSignalCode(8, 5 /*FPE_FLTUND*/, "floating point underflow"); - AddSignalCode(8, 6 /*FPE_FLTRES*/, "floating point inexact result"); - AddSignalCode(8, 7 /*FPE_FLTINV*/, "floating point invalid operation"); - AddSignalCode(8, 8 /*FPE_FLTSUB*/, "subscript out of range"); + ADD_SIGCODE(8, FPE_INTDIV, 1, "integer divide by zero"); + ADD_SIGCODE(8, FPE_INTOVF, 2, "integer overflow"); + ADD_SIGCODE(8, FPE_FLTDIV, 3, "floating point divide by zero"); + ADD_SIGCODE(8, FPE_FLTOVF, 4, "floating point overflow"); + ADD_SIGCODE(8, FPE_FLTUND, 5, "floating point underflow"); + ADD_SIGCODE(8, FPE_FLTRES, 6, "floating point inexact result"); + ADD_SIGCODE(8, FPE_FLTINV, 7, "floating point invalid operation"); + ADD_SIGCODE(8, FPE_FLTSUB, 8, "subscript out of range"); AddSignal(9, "SIGKILL", false, true, true, "kill"); AddSignal(10, "SIGUSR1", false, true, true, "user defined signal 1"); AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation"); - AddSignalCode(11, 1 /*SEGV_MAPERR*/, "address not mapped to object", SignalCodePrintOption::Address); - AddSignalCode(11, 2 /*SEGV_ACCERR*/, "invalid permissions for mapped object", SignalCodePrintOption::Address); - AddSignalCode(11, 3 /*SEGV_BNDERR*/, "failed address bounds checks", SignalCodePrintOption::Bounds); - AddSignalCode(11, 8 /*SEGV_MTEAERR*/, "async tag check fault"); - AddSignalCode(11, 9 /*SEGV_MTESERR*/, "sync tag check fault", SignalCodePrintOption::Address); + ADD_SIGCODE(11, SEGV_MAPERR, 1, "address not mapped to object", SignalCodePrintOption::Address); + ADD_SIGCODE(11, SEGV_ACCERR, 2, "invalid permissions for mapped object", SignalCodePrintOption::Address); + ADD_SIGCODE(11, SEGV_BNDERR, 3, "failed address bounds checks", SignalCodePrintOption::Bounds); + ADD_SIGCODE(11, SEGV_MTEAERR, 8, "async tag check fault"); + ADD_SIGCODE(11, SEGV_MTESERR, 9, "sync tag check fault", SignalCodePrintOption::Address); // Some platforms will occasionally send nonstandard spurious SI_KERNEL // codes. One way to get this is via unaligned SIMD loads. Treat it as invalid address. - AddSignalCode(11, 0x80 /*SI_KERNEL*/, "invalid address", SignalCodePrintOption::Address); + ADD_SIGCODE(11, SI_KERNEL, 0x80, "invalid address", SignalCodePrintOption::Address); AddSignal(12, "SIGUSR2", false, true, true, "user defined signal 2"); AddSignal(13, "SIGPIPE", false, true, true, "write to pipe with reading end closed"); diff --git a/lldb/source/Plugins/Platform/NetBSD/NetBSDSignals.cpp b/lldb/source/Plugins/Platform/NetBSD/NetBSDSignals.cpp index 84a664c05558..285808e10c95 100644 --- a/lldb/source/Plugins/Platform/NetBSD/NetBSDSignals.cpp +++ b/lldb/source/Plugins/Platform/NetBSD/NetBSDSignals.cpp @@ -8,6 +8,17 @@ #include "NetBSDSignals.h" +#ifdef __NetBSD__ +#include + +#define ADD_SIGCODE(signal, name, value, ...) \ + static_assert(name == value, "Value mismatch for signal code " #name); \ + AddSignalCode(signal, value, __VA_ARGS__) +#else +#define ADD_SIGCODE(signal, name, value, ...) \ + AddSignalCode(signal, value, __VA_ARGS__) +#endif /* ifdef __NetBSD__ */ + using namespace lldb_private; NetBSDSignals::NetBSDSignals() : UnixSignals() { Reset(); } @@ -17,34 +28,34 @@ void NetBSDSignals::Reset() { // clang-format off // SIGILL - AddSignalCode(4, 1 /*ILL_ILLOPC*/, "illegal opcode"); - AddSignalCode(4, 2 /*ILL_ILLOPN*/, "illegal operand"); - AddSignalCode(4, 3 /*ILL_ILLADR*/, "illegal addressing mode"); - AddSignalCode(4, 4 /*ILL_ILLTRP*/, "illegal trap"); - AddSignalCode(4, 5 /*ILL_PRVOPC*/, "privileged opcode"); - AddSignalCode(4, 6 /*ILL_PRVREG*/, "privileged register"); - AddSignalCode(4, 7 /*ILL_COPROC*/, "coprocessor error"); - AddSignalCode(4, 8 /*ILL_BADSTK*/, "internal stack error"); + ADD_SIGCODE(4, ILL_ILLOPC, 1, "illegal opcode"); + ADD_SIGCODE(4, ILL_ILLOPN, 2, "illegal operand"); + ADD_SIGCODE(4, ILL_ILLADR, 3, "illegal addressing mode"); + ADD_SIGCODE(4, ILL_ILLTRP, 4, "illegal trap"); + ADD_SIGCODE(4, ILL_PRVOPC, 5, "privileged opcode"); + ADD_SIGCODE(4, ILL_PRVREG, 6, "privileged register"); + ADD_SIGCODE(4, ILL_COPROC, 7, "coprocessor error"); + ADD_SIGCODE(4, ILL_BADSTK, 8, "internal stack error"); // SIGFPE - AddSignalCode(8, 1 /*FPE_INTDIV*/, "integer divide by zero"); - AddSignalCode(8, 2 /*FPE_INTOVF*/, "integer overflow"); - AddSignalCode(8, 3 /*FPE_FLTDIV*/, "floating point divide by zero"); - AddSignalCode(8, 4 /*FPE_FLTOVF*/, "floating point overflow"); - AddSignalCode(8, 5 /*FPE_FLTUND*/, "floating point underflow"); - AddSignalCode(8, 6 /*FPE_FLTRES*/, "floating point inexact result"); - AddSignalCode(8, 7 /*FPE_FLTINV*/, "invalid floating point operation"); - AddSignalCode(8, 8 /*FPE_FLTSUB*/, "subscript out of range"); + ADD_SIGCODE(8, FPE_INTDIV, 1, "integer divide by zero"); + ADD_SIGCODE(8, FPE_INTOVF, 2, "integer overflow"); + ADD_SIGCODE(8, FPE_FLTDIV, 3, "floating point divide by zero"); + ADD_SIGCODE(8, FPE_FLTOVF, 4, "floating point overflow"); + ADD_SIGCODE(8, FPE_FLTUND, 5, "floating point underflow"); + ADD_SIGCODE(8, FPE_FLTRES, 6, "floating point inexact result"); + ADD_SIGCODE(8, FPE_FLTINV, 7, "invalid floating point operation"); + ADD_SIGCODE(8, FPE_FLTSUB, 8, "subscript out of range"); // SIGBUS - AddSignalCode(10, 1 /*BUS_ADRALN*/, "invalid address alignment"); - AddSignalCode(10, 2 /*BUS_ADRERR*/, "non-existent physical address"); - AddSignalCode(10, 3 /*BUS_OBJERR*/, "object specific hardware error"); + ADD_SIGCODE(10, BUS_ADRALN, 1, "invalid address alignment"); + ADD_SIGCODE(10, BUS_ADRERR, 2, "non-existent physical address"); + ADD_SIGCODE(10, BUS_OBJERR, 3, "object specific hardware error"); // SIGSEGV - AddSignalCode(11, 1 /*SEGV_MAPERR*/, "address not mapped to object", + ADD_SIGCODE(11, SEGV_MAPERR, 1, "address not mapped to object", SignalCodePrintOption::Address); - AddSignalCode(11, 2 /*SEGV_ACCERR*/, "invalid permissions for mapped object", + ADD_SIGCODE(11, SEGV_ACCERR, 2, "invalid permissions for mapped object", SignalCodePrintOption::Address); // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION -- 2.34.1