git: 2068608ebdbf - stable/13 - kdump: Decode Linux l_sigset_t.

From: Dmitry Chagin <dchagin_at_FreeBSD.org>
Date: Wed, 06 Jul 2022 11:04:04 UTC
The branch stable/13 has been updated by dchagin:

URL: https://cgit.FreeBSD.org/src/commit/?id=2068608ebdbfaa40ff763af0526e8ee0fb9f3120

commit 2068608ebdbfaa40ff763af0526e8ee0fb9f3120
Author:     Dmitry Chagin <dchagin@FreeBSD.org>
AuthorDate: 2022-06-22 11:15:20 +0000
Commit:     Dmitry Chagin <dchagin@FreeBSD.org>
CommitDate: 2022-07-06 11:02:13 +0000

    kdump: Decode Linux l_sigset_t.
    
    Reviewed by:            markj
    Differential revision:  https://reviews.freebsd.org/D35153
    MFC after:              2 weeks
    
    (cherry picked from commit 3606a213bfa42e1970197ba9b3494c88d5827259)
---
 usr.bin/kdump/kdump.c |  5 ++++-
 usr.bin/kdump/kdump.h |  1 +
 usr.bin/kdump/linux.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c
index 8ed33783e7c7..f3e6787edbe0 100644
--- a/usr.bin/kdump/kdump.c
+++ b/usr.bin/kdump/kdump.c
@@ -2061,7 +2061,10 @@ ktrstruct(char *buf, size_t buflen)
 		ktrbitset(name, set, datalen);
 		free(set);
 	} else {
-		printf("unknown structure\n");
+#ifdef SYSDECODE_HAVE_LINUX
+		if (ktrstruct_linux(name, data, datalen) == false)
+#endif
+			printf("unknown structure\n");
 	}
 	return;
 invalid:
diff --git a/usr.bin/kdump/kdump.h b/usr.bin/kdump/kdump.h
index dc0515397f48..29bdb1dfbbaf 100644
--- a/usr.bin/kdump/kdump.h
+++ b/usr.bin/kdump/kdump.h
@@ -77,6 +77,7 @@ bool	print_mask_arg_part(bool (*decoder)(FILE *, int, int *),
 	    int value, int *rem);
 
 #ifdef SYSDECODE_HAVE_LINUX
+bool ktrstruct_linux(const char *name, const char *data, size_t datalen);
 void ktrsyscall_linux(struct ktr_syscall *ktr, register_t **resip,
     int *resnarg, char *resc);
 #ifdef __amd64__
diff --git a/usr.bin/kdump/linux.c b/usr.bin/kdump/linux.c
index e584b54db36c..ed057a6b8ef6 100644
--- a/usr.bin/kdump/linux.c
+++ b/usr.bin/kdump/linux.c
@@ -31,7 +31,11 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/uio.h>
 #include <sys/ktrace.h>
+#include <err.h>
+#include <errno.h>
 #include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
 #include <sysdecode.h>
 
 #include "kdump.h"
@@ -45,6 +49,8 @@ __FBSDID("$FreeBSD$");
 #include <i386/linux/linux_syscall.h>
 #endif
 
+#include <compat/linux/linux.h>
+
 static void
 print_linux_signal(int signo)
 {
@@ -183,3 +189,41 @@ ktrsyscall_linux32(struct ktr_syscall *ktr, register_t **resip,
 	*resnarg = narg;
 }
 #endif /* __amd64__ */
+
+static void
+ktrsigset(const char *name, const l_sigset_t *mask, size_t sz)
+{
+	unsigned long i, c;
+
+	printf("%s [ ", name);
+	c = 0;
+	for (i = 1; i <= sz * CHAR_BIT; i++) {
+		if (!LINUX_SIGISMEMBER(*mask, i))
+			continue;
+		if (c != 0)
+			printf(", ");
+		printf("%s", sysdecode_linux_signal(i));
+		c++;
+	}
+	if (c == 0)
+		printf("empty ]\n");
+	else
+		printf(" ]\n");
+}
+
+bool
+ktrstruct_linux(const char *name, const char *data, size_t datalen)
+{
+	l_sigset_t mask;
+
+	if (strcmp(name, "l_sigset_t") == 0) {
+		/* Old Linux sigset_t is one word size. */
+		if (datalen < sizeof(int) || datalen > sizeof(l_sigset_t))
+			return (false);
+		memcpy(&mask, data, datalen);
+		ktrsigset(name, &mask, datalen);
+	} else
+		return (false);
+
+	return (true);
+}