? dmidecode-m-option-2.diff
? dmidecode-m-option.diff
Index: Makefile
===================================================================
RCS file: /cvs/ports/sysutils/dmidecode/Makefile,v
diff -u -p -u -p -r1.19 Makefile
--- Makefile	25 Apr 2024 11:53:34 -0000	1.19
+++ Makefile	12 Oct 2025 08:15:56 -0000
@@ -1,10 +1,9 @@
-# builds on aarch64 but for !x86 it requires code to lookup the entry
-# point from EFI and only FreeBSD/Linux implementations are present.
 ONLY_FOR_ARCHS=	amd64 i386
 
 COMMENT=	dump DMI/SMBIOS contents in human-readable format
 DISTNAME=	dmidecode-3.6
 EXTRACT_SUFX=	.tar.xz
+REVISION=	1
 
 CATEGORIES=	sysutils
 
Index: patches/patch-dmidecode_c
===================================================================
RCS file: patches/patch-dmidecode_c
diff -N patches/patch-dmidecode_c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-dmidecode_c	12 Oct 2025 08:15:56 -0000
@@ -0,0 +1,59 @@
+Index: dmidecode.c
+--- dmidecode.c.orig
++++ dmidecode.c
+@@ -6176,6 +6176,7 @@ int main(int argc, char * const argv[])
+ 	size_t size;
+ 	int efi;
+ 	u8 *buf = NULL;
++	uint64_t scan_base = 0xF0000ULL;
+ 
+ 	/*
+ 	 * We don't want stdout and stderr to be mixed up if both are
+@@ -6194,6 +6195,9 @@ int main(int argc, char * const argv[])
+ 	opt.devmem = DEFAULT_MEM_DEV;
+ 	opt.flags = 0;
+ 	opt.handle = ~0U;
++	#ifdef __OpenBSD__
++		opt.flags |= FLAG_NO_SYSFS;
++	#endif
+ 
+ 	if (parse_command_line(argc, argv)<0)
+ 	{
+@@ -6220,8 +6224,12 @@ int main(int argc, char * const argv[])
+ 	}
+ 
+ 	if (!(opt.flags & FLAG_QUIET))
++	{
+ 		pr_comment("dmidecode %s", VERSION);
+-
++			#ifdef __OpenBSD__
++				pr_info("Defaulting to --no-sysfs on OpenBSD.");
++			#endif
++	}
+ 	/* Read from dump if so instructed */
+ 	size = 0x20;
+ 	if (opt.flags & FLAG_FROM_DUMP)
+@@ -6326,10 +6334,21 @@ int main(int argc, char * const argv[])
+ 
+ memory_scan:
+ #if defined __i386__ || defined __x86_64__
++	/* Fallback to memory scan (x86, x86_64) */
+ 	if (!(opt.flags & FLAG_QUIET))
+ 		pr_info("Scanning %s for entry point.", opt.devmem);
+-	/* Fallback to memory scan (x86, x86_64) */
+-	if ((buf = mem_chunk(0xF0000, 0x10000, opt.devmem)) == NULL)
++
++	/* Use memory base address if provided */
++	if (opt.flags & FLAG_MEM_BASE)
++	{
++		scan_base = opt.mem_base;
++		if (!(opt.flags & FLAG_QUIET))
++			pr_info("Scanning from memory base 0x%llx.", scan_base);
++	}
++	else
++		scan_base = 0xF0000;
++
++	if ((buf = mem_chunk(scan_base, 0x10000, opt.devmem)) == NULL)
+ 	{
+ 		ret = 1;
+ 		goto exit_free;
Index: patches/patch-dmiopt_c
===================================================================
RCS file: patches/patch-dmiopt_c
diff -N patches/patch-dmiopt_c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-dmiopt_c	12 Oct 2025 08:15:56 -0000
@@ -0,0 +1,72 @@
+Index: dmiopt.c
+--- dmiopt.c.orig
++++ dmiopt.c
+@@ -30,10 +30,10 @@
+ #include "util.h"
+ #include "dmidecode.h"
+ #include "dmiopt.h"
++#include "dmioutput.h"
+ 
+-
+ /* Options are global */
+-struct opt opt;
++struct opt opt = {0};
+ 
+ 
+ /*
+@@ -266,11 +266,12 @@ int parse_command_line(int argc, char * const argv[])
+ {
+ 	int option;
+ 	unsigned int i;
+-	const char *optstring = "d:hqs:t:uH:V";
++	const char *optstring = "d:hqm:Qs:t:uB:F:H:O:SLTV";
+ 	struct option longopts[] = {
+ 		{ "dev-mem", required_argument, NULL, 'd' },
+ 		{ "help", no_argument, NULL, 'h' },
+ 		{ "quiet", no_argument, NULL, 'q' },
++		{ "mem-base", required_argument, NULL, 'm' },
+ 		{ "no-quirks", no_argument, NULL, 'Q' },
+ 		{ "string", required_argument, NULL, 's' },
+ 		{ "type", required_argument, NULL, 't' },
+@@ -303,6 +304,14 @@ int parse_command_line(int argc, char * const argv[])
+ 			case 'h':
+ 				opt.flags |= FLAG_HELP;
+ 				break;
++			case 'm':
++				if (sscanf(optarg, "0x%llx", &opt.mem_base) != 1)
++				{
++					pr_info("Memory base address in format 0x<address> required: %s\n", optarg);
++					return -1;
++				} else
++					opt.flags |= FLAG_MEM_BASE;
++				break;
+ 			case 'q':
+ 				opt.flags |= FLAG_QUIET;
+ 				break;
+@@ -387,18 +396,19 @@ void print_help(void)
+ 		"Options are:\n"
+ 		" -d, --dev-mem FILE     Read memory from device FILE (default: " DEFAULT_MEM_DEV ")\n"
+ 		" -h, --help             Display this help text and exit\n"
++		" -m, --mem-base 0xADDR  Memory-scan for Entrypoint from base ADDR\n"
+ 		" -q, --quiet            Less verbose output\n"
+-		"     --no-quirks        Decode everything without quirks\n"
++		" -Q, --no-quirks        Decode everything without quirks\n"
+ 		" -s, --string KEYWORD   Only display the value of the given DMI string\n"
+-		"     --list-strings     List available string keywords and exit\n"
++		" -L, --list-strings     List available string keywords and exit\n"
+ 		" -t, --type TYPE        Only display the entries of given type\n"
+-		"     --list-types       List available type keywords and exit\n"
++		" -T, --list-types       List available type keywords and exit\n"
+ 		" -H, --handle HANDLE    Only display the entry of given handle\n"
+ 		" -u, --dump             Do not decode the entries\n"
+-		"     --dump-bin FILE    Dump the DMI data to a binary file\n"
+-		"     --from-dump FILE   Read the DMI data from a binary file\n"
+-		"     --no-sysfs         Do not attempt to read DMI data from sysfs files\n"
+-		"     --oem-string N     Only display the value of the given OEM string\n"
++		" -B, --dump-bin FILE    Dump the DMI data to a binary file\n"
++		" -F, --from-dump FILE   Read the DMI data from a binary file\n"
++		" -S, --no-sysfs         Do not attempt to read DMI data from sysfs files\n"
++		" -O, --oem-string N     Only display the value of the given OEM string\n"
+ 		" -V, --version          Display the version and exit\n";
+ 
+ 	printf("%s", help);
Index: patches/patch-dmiopt_h
===================================================================
RCS file: patches/patch-dmiopt_h
diff -N patches/patch-dmiopt_h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-dmiopt_h	12 Oct 2025 08:15:56 -0000
@@ -0,0 +1,19 @@
+Index: dmiopt.h
+--- dmiopt.h.orig
++++ dmiopt.h
+@@ -32,6 +32,7 @@ struct opt
+ {
+ 	const char *devmem;
+ 	unsigned int flags;
++	uint64_t mem_base;
+ 	u8 *type;
+ 	const struct string_keyword *string;
+ 	char *dumpfile;
+@@ -48,6 +49,7 @@ extern struct opt opt;
+ #define FLAG_NO_SYSFS           (1 << 6)
+ #define FLAG_NO_QUIRKS          (1 << 7)
+ #define FLAG_LIST               (1 << 8)
++#define FLAG_MEM_BASE           (1 << 9)
+ 
+ int parse_command_line(int argc, char * const argv[]);
+ void print_help(void);
Index: patches/patch-man_dmidecode_8
===================================================================
RCS file: patches/patch-man_dmidecode_8
diff -N patches/patch-man_dmidecode_8
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-man_dmidecode_8	12 Oct 2025 08:15:56 -0000
@@ -0,0 +1,70 @@
+Index: man/dmidecode.8
+--- man/dmidecode.8.orig
++++ man/dmidecode.8
+@@ -70,7 +70,7 @@ Read memory from device \fIFILE\fP (default: \fI/dev/m
+ Be less verbose. Unknown, inactive and \s-1OEM\s0-specific entries are not
+ displayed. Meta-data and handle references are hidden.
+ .TP
+-.BR "  " "  " "--no-quirks"
++.BR "-Q" ", " "--no-quirks"
+ Decode everything exactly as it is in the table, without trying to fix up
+ common mistakes or hide irrelevant fields.
+ This mode is primarily aimed at firmware developers.
+@@ -127,7 +127,7 @@ typically from files under
+ .IR /sys/devices/virtual/dmi/id .
+ Most of these files are even readable by regular users.
+ .TP
+-.BR "  " "  " "--list-strings"
++.BR "-L" ", " "--list-strings"
+ List available string keywords, which can then be passed to the \fB--string\fP
+ option.
+ .TP
+@@ -154,7 +154,7 @@ is printed and
+ .B dmidecode
+ exits with an error.
+ .TP
+-.BR "  " "  " "--list-types"
++.BR "-T" ", " "--list-types"
+ List available type keywords, which can then be passed to the \fB--type\fP
+ option.
+ .TP
+@@ -162,27 +162,35 @@ option.
+ Only display the entry whose handle matches \fIHANDLE\fP.
+ \fIHANDLE\fP is a 16-bit integer.
+ .TP
++.BR "-m" ", " "--mem-base \fIADDRESS\fP"
++If memory-scanning (default: /dev/mem, see -d option above) is used,
++scan a 64kB range starting at \fIADDRESS\fP rather than the Legacy BIOS
++range 0xF0000 to 0xFFFFF. \fIADDRESS\fP format: 0xnnnnnnnnnnnnnnnn ,
++a 64-bit integer. Leading zeros may be omitted.
++Useful for legacy-free systems that do not have EFI or sysfs structures,
++which are tried first.
++.TP
+ .BR "-u" ", " "--dump"
+ Do not decode the entries, dump their contents as hexadecimal instead.
+ Note that this is still a text output, no binary data will be thrown upon
+ you. The strings attached to each entry are displayed as both
+ hexadecimal and \s-1ASCII\s0. This option is mainly useful for debugging.
+ .TP
+-.BR "  " "  " "--dump-bin \fIFILE\fP"
++.BR "-B" ", " "--dump-bin \fIFILE\fP"
+ Do not decode the entries, instead dump the DMI data to a file in binary
+ form. The generated file is suitable to pass to \fB--from-dump\fP
+ later.
+ \fIFILE\fP must not exist.
+ .TP
+-.BR "  " "  " "--from-dump \fIFILE\fP"
++.BR "-F" ", " "--from-dump \fIFILE\fP"
+ Read the DMI data from a binary file previously generated using
+ \fB--dump-bin\fP.
+ .TP
+-.BR "  " "  " "--no-sysfs"
++.BR "-S" ",  " "--no-sysfs"
+ Do not attempt to read DMI data from sysfs files. This is mainly useful for
+ debugging.
+ .TP
+-.BR "  " "  " "--oem-string \fIN\fP"
++.BR "-O" ", " "--oem-string \fIN\fP"
+ Only display the value of the \s-1OEM\s0 string number \fIN\fP. The first
+ \s-1OEM\s0 string has number \fB1\fP. With special value \fBcount\fP, return the
+ number of OEM strings instead.
Index: patches/patch-types_h
===================================================================
RCS file: patches/patch-types_h
diff -N patches/patch-types_h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-types_h	12 Oct 2025 08:15:56 -0000
@@ -0,0 +1,86 @@
+Index: types.h
+--- types.h.orig
++++ types.h
+@@ -2,6 +2,8 @@
+ #define TYPES_H
+ 
+ #include "config.h"
++#include <stdint.h>
++#include <string.h>
+ 
+ typedef unsigned char u8;
+ typedef unsigned short u16;
+@@ -30,30 +32,58 @@ typedef struct {
+ } u64;
+ #endif
+ 
+-#if defined(ALIGNMENT_WORKAROUND) || defined(BIGENDIAN)
+-static inline u64 U64(u32 low, u32 high)
++static inline u64
++U64_make(u32 low, u32 high)
+ {
+-	u64 self;
+-
+-	self.l = low;
+-	self.h = high;
+-
+-	return self;
++	u64 v;
++	v.l = low;
++	v.h = high;
++	return v;
+ }
+-#endif
+ 
+ /*
+  * Per SMBIOS v2.8.0 and later, all structures assume a little-endian
+  * ordering convention.
+  */
+ #if defined(ALIGNMENT_WORKAROUND) || defined(BIGENDIAN)
+-#define WORD(x) (u16)((x)[0] + ((x)[1] << 8))
++
++/* Slow but portable, safe on strict-alignment CPUs */
++#define WORD(x)  (u16)((x)[0] + ((x)[1] << 8))
+ #define DWORD(x) (u32)((x)[0] + ((x)[1] << 8) + ((x)[2] << 16) + ((x)[3] << 24))
+-#define QWORD(x) (U64(DWORD(x), DWORD(x + 4)))
+-#else /* ALIGNMENT_WORKAROUND || BIGENDIAN */
+-#define WORD(x) (u16)(*(const u16 *)(x))
+-#define DWORD(x) (u32)(*(const u32 *)(x))
+-#define QWORD(x) (*(const u64 *)(x))
++#define QWORD(x) (U64_make(DWORD(x), DWORD(x + 4)))
++
++#else /* little-endian, unaligned OK */
++
++/* Safe unaligned accessors without strict-aliasing warnings */
++static inline uint16_t
++get_u16(const void *p)
++{
++	uint16_t v;
++	memcpy(&v, p, sizeof(v));
++	return v;
++}
++
++static inline uint32_t
++get_u32(const void *p)
++{
++	uint32_t v;
++	memcpy(&v, p, sizeof(v));
++	return v;
++}
++
++static inline u64
++get_u64(const void *p)
++{
++	uint32_t low, high;
++	memcpy(&low, p, 4);
++	memcpy(&high, (const u8 *)p + 4, 4);
++	return U64_make(low, high);
++}
++
++#define WORD(x)   get_u16(x)
++#define DWORD(x)  get_u32(x)
++#define QWORD(x)  get_u64(x)
++
+ #endif /* ALIGNMENT_WORKAROUND || BIGENDIAN */
+ 
+ #endif
Index: pkg/PLIST
===================================================================
RCS file: /cvs/ports/sysutils/dmidecode/pkg/PLIST,v
diff -u -p -u -p -r1.7 PLIST
--- pkg/PLIST	25 Apr 2024 11:53:34 -0000	1.7
+++ pkg/PLIST	12 Oct 2025 08:15:56 -0000
@@ -11,3 +11,4 @@ share/doc/dmidecode/
 share/doc/dmidecode/AUTHORS
 share/doc/dmidecode/NEWS
 share/doc/dmidecode/README
+share/doc/pkg-readmes/${PKGSTEM}
Index: pkg/README
===================================================================
RCS file: pkg/README
diff -N pkg/README
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ pkg/README	12 Oct 2025 08:15:56 -0000
@@ -0,0 +1,29 @@
++-------------------------------------------------------------------------------
+| Running ${PKGSTEM} on OpenBSD
++-------------------------------------------------------------------------------
+
+On OpenBSD, dmidecode falls back to scanning /dev/mem for the SMBIOS
+Entry Point.
+
+By default, only the 'Legacy BIOS' region starting at 0xF0000 is
+scanned.
+
+On legacy-free systems, this region may not contain SMBIOS information,
+leading to a failure to find the correct Entry Point.
+
+The kernel-detected SMBIOS Entry Point can be shown by:
+
+$ grep bios /var/run/dmesg.boot
+
+and passed to dmidecode using the -m/--mem-base command-line option:
+
+$ doas dmidecode -m 0xa4df8000
+
+The sysctl kern.allowkmem=1 needs to be set to allow access to
+/dev/mem.
+
+The package builds on aarch64 but for !x86 it requires code to
+lookup the entry point from EFI, and only FreeBSD/Linux implementations
+are present.
+
+On OpenBSD, the -S/--no-sysfs option has been  enabled by default.
