summaryrefslogtreecommitdiff
path: root/usr/src/test
diff options
context:
space:
mode:
authorRobert Mustacchi <rm@fingolfin.org>2021-07-31 18:32:39 -0700
committerRobert Mustacchi <rm@fingolfin.org>2021-11-11 14:12:38 -0800
commit8e458de0baeb1fee50643403223bc7e909a48464 (patch)
tree56fb55c9127badcfdd124858bc930e1f7ba693a5 /usr/src/test
parent1dee82f4f45d5f7651c78ce447f9829386d9d9c5 (diff)
downloadillumos-gate-8e458de0baeb1fee50643403223bc7e909a48464.tar.gz
13925 core files should include DWARF
Reviewed by: Rich Lowe <richlowe@richlowe.net> Reviewed by: C Fraire <cfraire@me.com> Reviewed by: Adam Leventhal <adam.leventhal@gmail.com> Approved by: Dan McDonald <danmcd@joyent.com>
Diffstat (limited to 'usr/src/test')
-rw-r--r--usr/src/test/os-tests/runfiles/default.run5
-rw-r--r--usr/src/test/os-tests/tests/Makefile1
-rw-r--r--usr/src/test/os-tests/tests/cores/Makefile22
-rw-r--r--usr/src/test/os-tests/tests/cores/Makefile.com17
-rw-r--r--usr/src/test/os-tests/tests/cores/Makefile.targ48
-rw-r--r--usr/src/test/os-tests/tests/cores/dumper/Makefile57
-rw-r--r--usr/src/test/os-tests/tests/cores/dumper/dumper.c64
-rw-r--r--usr/src/test/os-tests/tests/cores/libdumper/Makefile41
-rw-r--r--usr/src/test/os-tests/tests/cores/libdumper/Makefile.com44
-rw-r--r--usr/src/test/os-tests/tests/cores/libdumper/amd64/Makefile19
-rw-r--r--usr/src/test/os-tests/tests/cores/libdumper/common/libdumper.c36
-rw-r--r--usr/src/test/os-tests/tests/cores/libdumper/common/mapfile-vers44
-rw-r--r--usr/src/test/os-tests/tests/cores/libdumper/i386/Makefile18
-rw-r--r--usr/src/test/os-tests/tests/cores/scripts/Makefile36
-rw-r--r--usr/src/test/os-tests/tests/cores/scripts/core_prereqs.ksh31
-rw-r--r--usr/src/test/os-tests/tests/cores/scripts/coretests.ksh135
-rw-r--r--usr/src/test/os-tests/tests/cores/secmapper/Makefile48
-rw-r--r--usr/src/test/os-tests/tests/cores/secmapper/secmapper.c434
18 files changed, 1100 insertions, 0 deletions
diff --git a/usr/src/test/os-tests/runfiles/default.run b/usr/src/test/os-tests/runfiles/default.run
index 4824a8328b..426433b7a5 100644
--- a/usr/src/test/os-tests/runfiles/default.run
+++ b/usr/src/test/os-tests/runfiles/default.run
@@ -126,3 +126,8 @@ post = ksensor_fini
[/opt/os-tests/tests/stackalign]
tests = ['stackalign.32', 'stackalign.64']
+
+[/opt/os-tests/tests/cores]
+user = root
+pre = core_prereqs
+tests = ['coretests']
diff --git a/usr/src/test/os-tests/tests/Makefile b/usr/src/test/os-tests/tests/Makefile
index fdb8fe302c..059fc2ddd8 100644
--- a/usr/src/test/os-tests/tests/Makefile
+++ b/usr/src/test/os-tests/tests/Makefile
@@ -19,6 +19,7 @@
SUBDIRS_i386 = i386 imc
SUBDIRS = \
+ cores \
ddi_ufm \
file-locking \
ksensor \
diff --git a/usr/src/test/os-tests/tests/cores/Makefile b/usr/src/test/os-tests/tests/cores/Makefile
new file mode 100644
index 0000000000..dccb694ae9
--- /dev/null
+++ b/usr/src/test/os-tests/tests/cores/Makefile
@@ -0,0 +1,22 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2021 Oxide Computer Company
+#
+
+.PARALLEL: $(SUBDIRS)
+
+SUBDIRS = libdumper dumper scripts secmapper
+
+include $(SRC)/test/Makefile.com
+
+dumper: libdumper
diff --git a/usr/src/test/os-tests/tests/cores/Makefile.com b/usr/src/test/os-tests/tests/cores/Makefile.com
new file mode 100644
index 0000000000..daf8207a43
--- /dev/null
+++ b/usr/src/test/os-tests/tests/cores/Makefile.com
@@ -0,0 +1,17 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2021 Oxide Computer Company
+#
+
+ROOTOPTDIR = $(ROOT)/opt/os-tests/tests
+ROOTOPTCORE = $(ROOTOPTDIR)/cores
diff --git a/usr/src/test/os-tests/tests/cores/Makefile.targ b/usr/src/test/os-tests/tests/cores/Makefile.targ
new file mode 100644
index 0000000000..9511df96ff
--- /dev/null
+++ b/usr/src/test/os-tests/tests/cores/Makefile.targ
@@ -0,0 +1,48 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2021 Oxide Computer Company
+#
+
+$(ROOTOPTDIR):
+ $(INS.dir)
+
+$(ROOTOPTCORE): $(ROOTOPTDIR)
+ $(INS.dir)
+
+$(ROOTOPTCORE)/%: %
+ $(INS.file)
+
+$(ROOTOPTCORE)/%: %.ksh
+ $(INS.rename)
+
+%.32.o: %.c
+ $(COMPILE.c) $< -o $@
+ $(POST_PROCESS_O)
+
+%.64.o: %.c
+ $(COMPILE64.c) $< -o $@
+ $(POST_PROCESS_O)
+
+%.64: %.64.o
+ $(LINK64.c) -o $@ $< $(LDLIBS64)
+ $(POST_PROCESS)
+
+%.32: %.32.o
+ $(LINK.c) -o $@ $< $(LDLIBS)
+ $(POST_PROCESS)
+
+clobber: clean
+ $(RM) $(PROGS32) $(PROGS64)
+
+clean:
+ $(RM) $(ALLOBJS)
diff --git a/usr/src/test/os-tests/tests/cores/dumper/Makefile b/usr/src/test/os-tests/tests/cores/dumper/Makefile
new file mode 100644
index 0000000000..4e193e1193
--- /dev/null
+++ b/usr/src/test/os-tests/tests/cores/dumper/Makefile
@@ -0,0 +1,57 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2021 Oxide Computer Company
+#
+
+PROGS = dumper
+
+PROGS32 = $(PROGS:%=%.32)
+PROGS64 = $(PROGS:%=%.64)
+ALLOBJS = $(PROGS32:%=%.o) $(PROGS64:%=%.o)
+
+include $(SRC)/cmd/Makefile.cmd
+include $(SRC)/cmd/Makefile.ctf
+include ../Makefile.com
+
+ROOTOPTPROGS = $(PROGS32:%=$(ROOTOPTCORE)/%) \
+ $(PROGS64:%=$(ROOTOPTCORE)/%)
+
+LDLIBS += -lproc -L$(ROOTOPTCORE) -ldumper -R\$$ORIGIN
+LDLIBS64 += -lproc -L$(ROOTOPTCORE)/$(MACH64) -ldumper -R\$$ORIGIN/$(MACH64)
+
+#
+# We need to explicitly set the objects for some of our programs with
+# CTF so that way we can make sure that we have what we need.
+#
+dumper.32 := OBJS = dumper.32.o
+dumper.64 := OBJS = dumper.32.o
+
+#
+# This is admittedly, a bit gross. In particular we need to make sure
+# that we have debug information in the following programs.
+#
+STRIP_STABS = /bin/true
+
+.KEEP_STATE:
+
+all: $(PROGS32) $(PROGS64)
+
+install: $(ROOTOPTPROGS)
+
+clean:
+
+$(ROOTOPTPROGS): $(PROGS32) $(PROGS64) $(ROOTOPTCORE)
+
+FRC:
+
+include ../Makefile.targ
diff --git a/usr/src/test/os-tests/tests/cores/dumper/dumper.c b/usr/src/test/os-tests/tests/cores/dumper/dumper.c
new file mode 100644
index 0000000000..9539220139
--- /dev/null
+++ b/usr/src/test/os-tests/tests/cores/dumper/dumper.c
@@ -0,0 +1,64 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2021 Oxide Computer Company
+ */
+
+/*
+ * This program is meant to be a victim process. It will set up its core content
+ * and location into the specific place we indicate in its arguments and then
+ * sleep until we gcore and ABRT it.
+ */
+
+#include <err.h>
+#include <stdlib.h>
+#include <sys/corectl.h>
+#include <libproc.h>
+#include <signal.h>
+
+extern int which_ff(uint32_t, uint32_t);
+
+int
+main(int argc, char *argv[])
+{
+ pid_t me = getpid();
+ core_content_t content;
+ sigset_t set = { 0 };
+
+ if (argc != 3) {
+ errx(EXIT_FAILURE, "<content> <dump path>");
+ }
+
+ if (proc_str2content(argv[1], &content) != 0) {
+ err(EXIT_FAILURE, "failed to parse content %s", argv[1]);
+ }
+
+ if (core_set_process_content(&content, me) != 0) {
+ err(EXIT_FAILURE, "failed to set core content to %s", argv[1]);
+ }
+
+ if (core_set_process_path(argv[2], strlen(argv[2]) + 1, me) != 0) {
+ err(EXIT_FAILURE, "failed to set core path to %s", argv[2]);
+ }
+
+ /*
+ * Call our library function to make sure it's present before we go and
+ * sleep.
+ */
+ (void) which_ff(6, 10);
+
+ for (;;) {
+ (void) sigsuspend(&set);
+ }
+
+ return (0);
+}
diff --git a/usr/src/test/os-tests/tests/cores/libdumper/Makefile b/usr/src/test/os-tests/tests/cores/libdumper/Makefile
new file mode 100644
index 0000000000..b807402808
--- /dev/null
+++ b/usr/src/test/os-tests/tests/cores/libdumper/Makefile
@@ -0,0 +1,41 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2021 Oxide Computer Company
+#
+
+include $(SRC)/lib/Makefile.lib
+
+SUBDIRS = $(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
+
+all := TARGET = all
+clean := TARGET = clean
+clobber := TARGET = clobber
+install := TARGET = install
+
+.KEEP_STATE:
+
+all clean clobber: $(SUBDIRS)
+
+install: $(SUBDIRS)
+
+install_h:
+
+check: $(CHECKHDRS)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include $(SRC)/lib/Makefile.targ
diff --git a/usr/src/test/os-tests/tests/cores/libdumper/Makefile.com b/usr/src/test/os-tests/tests/cores/libdumper/Makefile.com
new file mode 100644
index 0000000000..3a985d3965
--- /dev/null
+++ b/usr/src/test/os-tests/tests/cores/libdumper/Makefile.com
@@ -0,0 +1,44 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2021 Oxide Computer Company
+#
+
+LIBRARY = libdumper.a
+VERS = .1
+OBJECTS = libdumper.o
+
+include $(SRC)/lib/Makefile.lib
+include ../../Makefile.com
+
+ROOTLIBDIR = $(ROOTOPTCORE)
+ROOTLIBDIR64 = $(ROOTOPTCORE)/$(MACH64)
+
+LIBS = $(DYNLIB)
+LDLIBS += -lc
+SRCDIR = ../common
+
+#
+# This program needs to deliver DWARF data for debug purposes. Therefore
+# we override the strip to make sure that we can get that.
+#
+STRIP_STABS = /bin/true
+
+
+$(ROOTLIBDIR64): $(ROOTLIBDIR)
+ $(INS.dir)
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+include $(SRC)/lib/Makefile.targ
diff --git a/usr/src/test/os-tests/tests/cores/libdumper/amd64/Makefile b/usr/src/test/os-tests/tests/cores/libdumper/amd64/Makefile
new file mode 100644
index 0000000000..09690cb7b3
--- /dev/null
+++ b/usr/src/test/os-tests/tests/cores/libdumper/amd64/Makefile
@@ -0,0 +1,19 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2021 Oxide Computer Company
+#
+
+include ../Makefile.com
+include $(SRC)/lib/Makefile.lib.64
+
+install: all $(ROOTLIBDIR64) .WAIT $(ROOTLIBS64) $(ROOTLINKS64)
diff --git a/usr/src/test/os-tests/tests/cores/libdumper/common/libdumper.c b/usr/src/test/os-tests/tests/cores/libdumper/common/libdumper.c
new file mode 100644
index 0000000000..027095a471
--- /dev/null
+++ b/usr/src/test/os-tests/tests/cores/libdumper/common/libdumper.c
@@ -0,0 +1,36 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2021 Oxide Computer Company
+ */
+
+/*
+ * This is a dummy library that basically ensures we have yet another thing with
+ * CTF and DWARF data when we're testing core dumps.
+ */
+
+#include <err.h>
+#include <inttypes.h>
+#include <stdlib.h>
+
+const char *message_in_a_bottle = "Here's something that hopefully is rodata";
+
+int
+which_ff(uint32_t a, uint32_t b)
+{
+ if (a == 6 && b == 7) {
+ warnx("some debates are best left to forums");
+ abort();
+ }
+
+ return (0);
+}
diff --git a/usr/src/test/os-tests/tests/cores/libdumper/common/mapfile-vers b/usr/src/test/os-tests/tests/cores/libdumper/common/mapfile-vers
new file mode 100644
index 0000000000..e02f876869
--- /dev/null
+++ b/usr/src/test/os-tests/tests/cores/libdumper/common/mapfile-vers
@@ -0,0 +1,44 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2021 Oxide Computer Company
+#
+
+#
+# MAPFILE HEADER START
+#
+# WARNING: STOP NOW. DO NOT MODIFY THIS FILE.
+# Object versioning must comply with the rules detailed in
+#
+# usr/src/lib/README.mapfiles
+#
+# You should not be making modifications here until you've read the most current
+# copy of that file. If you need help, contact a gatekeeper for guidance.
+#
+# MAPFILE HEADER END
+#
+
+$mapfile_version 2
+
+SYMBOL_VERSION ILLUMOSprivate {
+ global:
+ message_in_a_bottle {
+ ASSERT = {
+ TYPE = OBJECT;
+ SIZE = addrsize;
+ };
+ };
+
+ which_ff;
+ local:
+ *;
+};
diff --git a/usr/src/test/os-tests/tests/cores/libdumper/i386/Makefile b/usr/src/test/os-tests/tests/cores/libdumper/i386/Makefile
new file mode 100644
index 0000000000..0af99e030c
--- /dev/null
+++ b/usr/src/test/os-tests/tests/cores/libdumper/i386/Makefile
@@ -0,0 +1,18 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2021 Oxide computer Company
+#
+
+include ../Makefile.com
+
+install: all $(ROOTLIBS) $(ROOTLINKS)
diff --git a/usr/src/test/os-tests/tests/cores/scripts/Makefile b/usr/src/test/os-tests/tests/cores/scripts/Makefile
new file mode 100644
index 0000000000..2e222b41c2
--- /dev/null
+++ b/usr/src/test/os-tests/tests/cores/scripts/Makefile
@@ -0,0 +1,36 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2021 Oxide Computer Company
+#
+
+SCRIPTS = core_prereqs coretests
+
+include $(SRC)/cmd/Makefile.cmd
+include $(SRC)/cmd/Makefile.ctf
+include ../Makefile.com
+
+ROOTOPTPROGS = $(SCRIPTS:%=$(ROOTOPTCORE)/%)
+
+.KEEP_STATE:
+
+all: $(PROGS32) $(PROGS64)
+
+install: $(ROOTOPTPROGS)
+
+$(ROOTOPTPROGS): $(ROOTOPTCORE)
+
+clean:
+
+FRC:
+
+include ../Makefile.targ
diff --git a/usr/src/test/os-tests/tests/cores/scripts/core_prereqs.ksh b/usr/src/test/os-tests/tests/cores/scripts/core_prereqs.ksh
new file mode 100644
index 0000000000..490c47e205
--- /dev/null
+++ b/usr/src/test/os-tests/tests/cores/scripts/core_prereqs.ksh
@@ -0,0 +1,31 @@
+#!/usr/bin/ksh
+#
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2021 Oxide Computer Company
+#
+
+#
+# The core tests require that we have per-process core dumps enabled.
+# This script is used as the pre-requisite in the test runner to verify
+# that fact.
+#
+
+set -o pipefail
+
+if coreadm | grep -q 'per-process core dumps: enabled'; then
+ exit 0
+fi
+
+echo "per -process core dumps are not enabled, skipping test" >&2
+exit 1
diff --git a/usr/src/test/os-tests/tests/cores/scripts/coretests.ksh b/usr/src/test/os-tests/tests/cores/scripts/coretests.ksh
new file mode 100644
index 0000000000..9e7f524070
--- /dev/null
+++ b/usr/src/test/os-tests/tests/cores/scripts/coretests.ksh
@@ -0,0 +1,135 @@
+#!/usr/bin/ksh
+#
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2021 Oxide Computer Company
+#
+
+#
+# The goal of this test suite is to test certain aspects of core dump
+# generation and different core contents being specified. The
+# 'dumper.32' and 'dumper.64' programs are designed to be told what to
+# set a core content and path to, after which point we use both gcore
+# and the kernel to generate a core dump for the file and verify that it
+# has what we expect. The verification is done by the secmapper program.
+#
+
+unalias -a
+set -o pipefail
+
+core_arg0="$(basename $0)"
+core_dir="$(dirname $0)"
+core_dumper32="$core_dir/dumper.32"
+core_dumper64="$core_dir/dumper.64"
+core_checker="$core_dir/secmapper"
+
+core_tmpdir="/tmp/coretest.$$"
+core_exit=0
+
+#
+# This array describes the different types of core contents that we're
+# going to try and generate and check against.
+#
+core_contents="none
+ctf
+debug
+symtab
+ctf+debug+symtab
+anon+data+ctf+debug+symtab
+default
+default-ctf-debug-symtab
+default+debug
+default-symtab"
+
+warn()
+{
+ typeset msg="$*"
+ echo "TEST FAILED: $msg" >&2
+ core_exit=1
+}
+
+core_dump_one()
+{
+ typeset prog="$1"
+ typeset pbase=$(basename $prog)
+ typeset cont="$2"
+ typeset kpath="$3"
+ typeset gpath="$4"
+ typeset pid=
+
+ $prog "$cont" "$kpath" &
+ pid=$!
+ if (( $? != 0 )); then
+ warn "failed to spawn $core_dumper32: $cont $kpath"
+ return 1
+ fi
+
+ #
+ # This is racy, but probably should be a reasonable amount of
+ # time for dumper to be ready.
+ #
+ for ((i = 0; i < 10; i++)) {
+ if pstack $pid | grep -q 'fsigsuspend'; then
+ break
+ fi
+ }
+
+ if ! gcore -o "$gpath" -c "$cont" $pid >/dev/null; then
+ warn "failed to gcore $pid: $prog $cont $kpath"
+ fi
+
+ kill -ABRT $pid
+ fg %1
+
+ #
+ # Since we have the pid, go through and check this now.
+ #
+ if $core_checker $core_tmpdir/*.kernel.$c.$pid $c; then
+ printf "TEST PASSED: kernel %s %s\n" "$pbase" "$c"
+ else
+ warn "checker failed for kernel $c"
+ fi
+
+ if $core_checker $core_tmpdir/*.gcore.$c.$pid $c; then
+ printf "TEST PASSED: gcore %s %s\n" "$pbase" "$c"
+ else
+ warn "checker failed for gcore of $c"
+ fi
+}
+
+if [[ ! -x "$core_dumper32" || ! -x "$core_dumper64" || \
+ ! -f "$core_checker" ]]; then
+ warn "missing expected files"
+ exit $core_exit
+fi
+
+if ! mkdir "$core_tmpdir"; then
+ warn "failed to create temporary directory: $core_tmpdir"
+ exit $core_exit
+fi
+
+for c in $core_contents; do
+ kpattern="$core_tmpdir/%f.kernel.$c.%p"
+ gpattern="$core_tmpdir/%f.gcore.$c"
+
+ core_dump_one "$core_dumper32" "$c" "$kpattern" "$gpattern"
+ core_dump_one "$core_dumper64" "$c" "$kpattern" "$gpattern"
+
+done
+
+if (( core_exit == 0 )); then
+ printf "All tests passed successfully\n"
+fi
+
+rm -rf $core_tmpdir
+exit $core_exit
diff --git a/usr/src/test/os-tests/tests/cores/secmapper/Makefile b/usr/src/test/os-tests/tests/cores/secmapper/Makefile
new file mode 100644
index 0000000000..84a28a56b8
--- /dev/null
+++ b/usr/src/test/os-tests/tests/cores/secmapper/Makefile
@@ -0,0 +1,48 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2021 Oxide Computer Company
+#
+
+PROG = secmapper
+OBJS = secmapper.o
+
+#
+# These are so the common makefile targets will clean things up.
+#
+ALLOBJS = $(OBJS)
+PROGS64 = $(PROG)
+
+include $(SRC)/cmd/Makefile.cmd
+include $(SRC)/cmd/Makefile.cmd.64
+include ../Makefile.com
+
+ROOTOPTPROGS = $(PROG:%=$(ROOTOPTCORE)/%)
+
+LDLIBS += -lproc -lelf
+CSTD = $(GNU_C99)
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(LINK.c) -o $(PROG) $(OBJS) $(LDLIBS)
+ $(POST_PROCESS)
+
+install: $(ROOTOPTPROGS)
+
+$(ROOTOPTPROGS): $(PROG)
+
+FRC:
+
+include ../Makefile.targ
diff --git a/usr/src/test/os-tests/tests/cores/secmapper/secmapper.c b/usr/src/test/os-tests/tests/cores/secmapper/secmapper.c
new file mode 100644
index 0000000000..87800a5352
--- /dev/null
+++ b/usr/src/test/os-tests/tests/cores/secmapper/secmapper.c
@@ -0,0 +1,434 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2021 Oxide Computer Company
+ */
+
+/*
+ * Check that a given core dump generated as part of our test framework has the
+ * sections that we'd expect. We have here the dumper binary. In that, we expect
+ * to find the following libraries and sections:
+ *
+ * a.out: symtab, ctf, .debug_* (dwarf)
+ * ld.so.1: symtab
+ * libc.so: symtab, ctf
+ * libproc.so: symtab, ctf
+ * libdumper.so: symtab, ctf, .debug_* (dwarf)
+ *
+ * Note, there will also be additional libraries and things here can change over
+ * time (e.g. deps of libproc, etc.), but we try to ignore them generally
+ * speaking if we can know enough to do so.
+ */
+
+#include <err.h>
+#include <stdlib.h>
+#include <libproc.h>
+#include <gelf.h>
+#include <libelf.h>
+#include <limits.h>
+#include <string.h>
+#include <libgen.h>
+
+typedef enum {
+ SECMAP_CTF,
+ SECMAP_SYMTAB,
+ SECMAP_DEBUG,
+ SECMAP_MAX
+} secmap_type_t;
+
+typedef struct secmap_data {
+ core_content_t sd_content;
+ const char *sd_name;
+} secmap_data_t;
+
+secmap_data_t secmap_data[SECMAP_MAX] = {
+ { CC_CONTENT_CTF, ".SUNW_ctf" },
+ { CC_CONTENT_SYMTAB, ".symtab" },
+ { CC_CONTENT_DEBUG, ".debug_" }
+};
+
+typedef struct {
+ uint64_t sm_addr;
+ char sm_obj[PATH_MAX];
+ size_t sm_nfound[SECMAP_MAX];
+ Elf *sm_elf;
+ GElf_Ehdr sm_ehdr;
+ boolean_t sm_ctf;
+ boolean_t sm_debug;
+ boolean_t sm_symtab;
+} secmap_t;
+
+static secmap_t *secmaps;
+static size_t secmap_count;
+static core_content_t secmap_content;
+
+static int secmap_exit = EXIT_SUCCESS;
+
+static void
+secmap_fail(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vwarnx(fmt, ap);
+ va_end(ap);
+ secmap_exit = EXIT_FAILURE;
+}
+
+
+static void
+check_content(core_content_t content, struct ps_prochandle *Pr)
+{
+ secmap_content = Pcontent(Pr);
+
+ if (secmap_content == CC_CONTENT_INVALID) {
+ secmap_fail("TEST FAILED: failed to get core content");
+ return;
+ }
+
+ if (secmap_content != content) {
+ secmap_fail("TEST FAILED: core file contains different "
+ "content than expected, found 0x%x, expected 0x%x",
+ secmap_content, content);
+ }
+}
+
+static secmap_t *
+secmap_find(uint64_t addr)
+{
+ for (size_t i = 0; i < secmap_count; i++) {
+ if (secmaps[i].sm_addr == addr) {
+ return (&secmaps[i]);
+ }
+ }
+
+ return (NULL);
+}
+
+static void
+secmap_matches_content(secmap_type_t type)
+{
+ boolean_t exist = (secmap_data[type].sd_content & secmap_content) != 0;
+ boolean_t found = B_FALSE;
+
+ /*
+ * Dumping CTF data implies that some symbol tables will exist for CTF.
+ */
+ if (type == SECMAP_SYMTAB && (secmap_content & CC_CONTENT_CTF) != 0) {
+ exist = B_TRUE;
+ }
+
+ for (size_t i = 0; i < secmap_count; i++) {
+ if (secmaps[i].sm_nfound[type] != 0) {
+ found = B_TRUE;
+ }
+ }
+
+ if (exist != found) {
+ secmap_fail("content type mismatch for %s: expected %s, but "
+ "found %s", secmap_data[type].sd_name,
+ exist ? "some" : "none",
+ found ? "some" : "none");
+ }
+}
+
+static secmap_t *
+secmap_alloc(struct ps_prochandle *Pr, uint64_t addr)
+{
+ int fd;
+ secmap_t *sm;
+ char *base;
+
+ sm = recallocarray(secmaps, secmap_count, secmap_count + 1,
+ sizeof (secmap_t));
+ if (sm == NULL) {
+ err(EXIT_FAILURE, "TEST FAILED: failed to allocate memory for "
+ "secmap %zu", secmap_count + 1);
+ }
+
+ secmaps = sm;
+ sm = &secmaps[secmap_count];
+ sm->sm_addr = addr;
+ secmap_count++;
+
+ /*
+ * We also have some tests that we don't expect to have anything here
+ * because we only include the relevant sections. Experimentally, we
+ * know that libproc needs both anon and data mappings for this to work.
+ * So if we don't have both, then we'll not warn on that.
+ */
+ if (Pobjname(Pr, addr, sm->sm_obj, sizeof (sm->sm_obj)) == NULL) {
+ core_content_t need = CC_CONTENT_ANON | CC_CONTENT_DATA;
+
+ if ((secmap_content & need) == need) {
+ secmap_fail("TEST FAILURE: object at address 0x%lx "
+ "has no name", addr);
+ }
+
+ return (sm);
+ }
+
+ /*
+ * Since we have a name, we should be able to open this elf object and
+ * identify it as well.
+ */
+ fd = open(sm->sm_obj, O_RDONLY);
+ if (fd < 0) {
+ err(EXIT_FAILURE, "failed to open object %s", sm->sm_obj);
+ }
+
+ sm->sm_elf = elf_begin(fd, ELF_C_READ, NULL);
+ if (sm->sm_elf == NULL) {
+ err(EXIT_FAILURE, "failed to find open elf object %s: %s",
+ sm->sm_obj, elf_errmsg(elf_errno()));
+ }
+
+ if (gelf_getehdr(sm->sm_elf, &sm->sm_ehdr) == NULL) {
+ err(EXIT_FAILURE, "failed to get ehdr for %s: %s",
+ sm->sm_obj, elf_errmsg(elf_errno()));
+ }
+
+ base = basename(sm->sm_obj);
+ if (strcmp(base, "dumper.32") == 0 || strcmp(base, "dumper.64") == 0) {
+ sm->sm_debug = sm->sm_symtab = sm->sm_ctf = B_TRUE;
+ } else if (strcmp(base, "libc.so.1") == 0) {
+ sm->sm_symtab = sm->sm_ctf = B_TRUE;
+ } else if (strcmp(base, "ld.so.1") == 0) {
+ sm->sm_symtab = B_TRUE;
+ } else if (strcmp(base, "libproc.so.1") == 0) {
+ sm->sm_symtab = sm->sm_ctf = B_TRUE;
+ } else if (strcmp(base, "libdumper.so.1") == 0) {
+ sm->sm_debug = sm->sm_symtab = sm->sm_ctf = B_TRUE;
+ } else {
+ sm->sm_symtab = B_TRUE;
+ }
+
+ return (sm);
+}
+
+static void
+secmap_data_cmp(secmap_t *sm, const char *sname, Elf_Scn *scn, GElf_Shdr *shdr)
+{
+ for (Elf_Scn *comp_scn = elf_nextscn(sm->sm_elf, NULL);
+ comp_scn != NULL; comp_scn = elf_nextscn(sm->sm_elf, comp_scn)) {
+ GElf_Shdr comp_shdr;
+ const char *comp_name;
+ Elf_Data *src_data, *comp_data;
+
+ if (gelf_getshdr(comp_scn, &comp_shdr) == NULL) {
+ secmap_fail("failed to load section header from %s "
+ "during data comparison", sm->sm_obj);
+ return;
+ }
+
+ comp_name = elf_strptr(sm->sm_elf, sm->sm_ehdr.e_shstrndx,
+ comp_shdr.sh_name);
+ if (comp_name == NULL) {
+ secmap_fail("failed to load section name from %s "
+ "with index %lu", sm->sm_obj, comp_shdr.sh_name);
+ return;
+ }
+
+ if (strcmp(comp_name, sname) != 0)
+ continue;
+
+ if (comp_shdr.sh_type != shdr->sh_type ||
+ comp_shdr.sh_addralign != shdr->sh_addralign ||
+ comp_shdr.sh_size != shdr->sh_size ||
+ comp_shdr.sh_entsize != shdr->sh_entsize) {
+ continue;
+ }
+
+ if ((src_data = elf_getdata(scn, NULL)) == NULL) {
+ secmap_fail("failed to load section data from "
+ "source to compare to %s %s", sm->sm_obj, sname);
+ return;
+ }
+
+ if ((comp_data = elf_getdata(comp_scn, NULL)) == NULL) {
+ secmap_fail("failed to load section data from "
+ "source to compare to %s %s", sm->sm_obj, sname);
+ return;
+ }
+
+ if (comp_data->d_size != src_data->d_size) {
+ secmap_fail("data size mismatch for %s: %s, core: "
+ "%zu, file: %zu", sm->sm_obj, sname,
+ src_data->d_size, comp_data->d_size);
+ return;
+ }
+
+ if (memcmp(comp_data->d_buf, src_data->d_buf,
+ comp_data->d_size) != 0) {
+ secmap_fail("data mismatch between core and source "
+ "in %s: %s", sm->sm_obj, sname);
+ return;
+ }
+
+ return;
+ }
+
+ secmap_fail("failed to find matching section for %s in %s",
+ sname, sm->sm_obj);
+}
+
+static void
+secmap_file_check(secmap_t *sm)
+{
+ if (sm->sm_ctf && (secmap_content & CC_CONTENT_CTF) != 0 &&
+ sm->sm_nfound[SECMAP_CTF] == 0) {
+ secmap_fail("expected object %s to have CTF, but it doesn't",
+ sm->sm_obj);
+ }
+
+ if (sm->sm_symtab && (secmap_content & CC_CONTENT_SYMTAB) != 0 &&
+ sm->sm_nfound[SECMAP_SYMTAB] == 0) {
+ secmap_fail("expected object %s to have a symbol table, "
+ "but it doesn't", sm->sm_obj);
+ }
+
+ if (sm->sm_debug && (secmap_content & CC_CONTENT_DEBUG) != 0 &&
+ sm->sm_nfound[SECMAP_DEBUG] == 0) {
+ secmap_fail("expected object %s to have debug sections, "
+ "but it doesn't", sm->sm_obj);
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ core_content_t content;
+ struct ps_prochandle *Pr;
+ int perr, fd;
+ Elf *elf;
+ Elf_Scn *scn;
+ GElf_Ehdr ehdr;
+
+ if (argc != 3) {
+ warnx("missing required file and core content");
+ (void) fprintf(stderr, "Usage: secmapper file content\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (elf_version(EV_CURRENT) == EV_NONE) {
+ errx(EXIT_FAILURE, "failed to init libelf");
+ }
+
+ Pr = Pgrab_core(argv[1], NULL, PGRAB_RDONLY, &perr);
+ if (Pr == NULL) {
+ errx(EXIT_FAILURE, "failed to open %s: %s", argv[1],
+ Pgrab_error(perr));
+ }
+
+ if ((fd = open(argv[1], O_RDONLY)) < 0) {
+ err(EXIT_FAILURE, "failed to open %s\n", argv[1]);
+ }
+
+ if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
+ errx(EXIT_FAILURE, "failed to open elf file %s: %s", argv[1],
+ elf_errmsg(elf_errno()));
+ }
+
+ if (proc_str2content(argv[2], &content) != 0) {
+ err(EXIT_FAILURE, "failed to parse content %s", argv[2]);
+ }
+
+ if (gelf_getehdr(elf, &ehdr) == NULL) {
+ errx(EXIT_FAILURE, "failed to get edr: %s",
+ elf_errmsg(elf_errno()));
+ }
+
+ /*
+ * Before we go futher, make sure that we have the content in this file
+ * that we expect.
+ */
+ check_content(content, Pr);
+
+ for (scn = elf_nextscn(elf, NULL); scn != NULL;
+ scn = elf_nextscn(elf, scn)) {
+ const char *sname;
+ GElf_Shdr shdr;
+ size_t index;
+ secmap_t *secmap;
+
+ index = elf_ndxscn(scn);
+ if (gelf_getshdr(scn, &shdr) == NULL) {
+ errx(EXIT_FAILURE, "failed to get section header for "
+ "shdr %zu: %s", index, elf_errmsg(elf_errno()));
+ }
+
+ /*
+ * Skip the strtab.
+ */
+ if (shdr.sh_type == SHT_STRTAB) {
+ continue;
+ }
+
+ sname = elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name);
+ if (sname == NULL) {
+ secmap_fail("TEST FAILURE: string name missing for "
+ "shdr %zu", index);
+ continue;
+ }
+
+ /*
+ * Find or cons up a new secmap for this object.
+ */
+ secmap = secmap_find(shdr.sh_addr);
+ if (secmap == NULL) {
+ secmap = secmap_alloc(Pr, shdr.sh_addr);
+ }
+
+ if (strcmp(sname, ".symtab") == 0) {
+ secmap->sm_nfound[SECMAP_SYMTAB]++;
+ } else if (strcmp(sname, ".SUNW_ctf") == 0) {
+ secmap->sm_nfound[SECMAP_CTF]++;
+ } else if (strncmp(sname, ".debug_", strlen(".debug_")) == 0) {
+ secmap->sm_nfound[SECMAP_DEBUG]++;
+ } else {
+ continue;
+ }
+
+ /*
+ * For one of our three primary sections, make sure that the
+ * data that is in the core file that we find in it actually
+ * matches the underlying object. That is, if the secmap
+ * actually has something here.
+ */
+ if (secmap->sm_elf != NULL) {
+ secmap_data_cmp(secmap, sname, scn, &shdr);
+ }
+ }
+
+ /*
+ * Now that we have iterated over all of these sections, check and make
+ * sure certain things are true of them. In particular, go through some
+ * of the various types of data and make sure it exists at all or
+ * doesn't based on our core content.
+ */
+ secmap_matches_content(SECMAP_CTF);
+ secmap_matches_content(SECMAP_SYMTAB);
+ secmap_matches_content(SECMAP_DEBUG);
+
+ /*
+ * Finally, if we have enough information to know that we've found
+ * a file that we know it should at least have a given type of data,
+ * check for it. Here, it is OK for data to be present we don't expect
+ * (assuming the core content allows it). This makes this test less
+ * prone to broader changes in the system.
+ */
+ for (size_t i = 0; i < secmap_count; i++) {
+ secmap_file_check(&secmaps[i]);
+ }
+
+ return (secmap_exit);
+}