[lldb] Add compile time checks for signal codes when on the matching platform
authorDavid Spickett <david.spickett@linaro.org>
Thu, 16 Mar 2023 11:32:35 +0000 (11:32 +0000)
committerDavid Spickett <david.spickett@linaro.org>
Tue, 21 Mar 2023 11:45:13 +0000 (11:45 +0000)
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
lldb/source/Plugins/Platform/FreeBSD/FreeBSDSignals.cpp
lldb/source/Plugins/Platform/Linux/LinuxSignals.cpp
lldb/source/Plugins/Platform/NetBSD/NetBSDSignals.cpp

index 1287e00..65eac7e 100644 (file)
@@ -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);
index c2997e0..f597bed 100644 (file)
@@ -8,6 +8,17 @@
 
 #include "FreeBSDSignals.h"
 
+#ifdef __FreeBSD__
+#include <csignal>
+
+#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
   //        ===== ============== ======== ====== ====== ========================
index fee7b89..834a558 100644 (file)
@@ -8,6 +8,27 @@
 
 #include "LinuxSignals.h"
 
+#ifdef __linux__
+#include <csignal>
+
+#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");
index 84a664c..285808e 100644 (file)
@@ -8,6 +8,17 @@
 
 #include "NetBSDSignals.h"
 
+#ifdef __NetBSD__
+#include <csignal>
+
+#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