[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
This commit is contained in:
David Spickett
2023-03-16 11:32:35 +00:00
parent af99aa0ff7
commit c8af0d3cea
4 changed files with 118 additions and 73 deletions

View 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);

View 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
// ===== ============== ======== ====== ====== ========================

View 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");

View 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