The branch main has been updated by bapt: URL: https://cgit.FreeBSD.org/src/commit/?id=748402ebf2d7a08b13d0b21694afdaad55cfa9cd
commit 748402ebf2d7a08b13d0b21694afdaad55cfa9cd Author: Baptiste Daroussin <[email protected]> AuthorDate: 2026-05-06 13:11:16 +0000 Commit: Baptiste Daroussin <[email protected]> CommitDate: 2026-05-06 14:16:54 +0000 devmatch: read linker.hints from all module paths Previously, devmatch would stop at the first linker.hints file found in kern.module_path. This meant modules installed in /boot/modules/ were invisible to devmatch if /boot/kernel/ contained a linker.hints file (which it always does). Merge hints from all directories in kern.module_path. This allows third-party or out-of-tree kernel modules in /boot/modules/ to be auto-loaded by devmatch just like built-in modules. Reviewed by: imp Differential Revivion: https://reviews.freebsd.org/D56847 --- sbin/devmatch/devmatch.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/sbin/devmatch/devmatch.c b/sbin/devmatch/devmatch.c index 62bfc2c521ed..6c6c5f3bcf79 100644 --- a/sbin/devmatch/devmatch.c +++ b/sbin/devmatch/devmatch.c @@ -102,6 +102,9 @@ read_linker_hints(void) size_t buflen, len; if (linker_hints == NULL) { + void *all_hints = NULL; + size_t all_len = 0; + if (sysctlbyname("kern.module_path", NULL, &buflen, NULL, 0) < 0) errx(1, "Can't find kernel module path."); modpath = malloc(buflen); @@ -111,13 +114,39 @@ read_linker_hints(void) errx(1, "Can't find kernel module path."); p = modpath; while ((q = strsep(&p, ";")) != NULL) { + void *h; + snprintf(fn, sizeof(fn), "%s/linker.hints", q); - hints = read_hints(fn, &len); - if (hints == NULL) + h = read_hints(fn, &len); + if (h == NULL) continue; - break; + if (len < sizeof(int) || + *(int *)(intptr_t)h != LINKER_HINTS_VERSION) { + free(h); + continue; + } + if (all_hints == NULL) { + all_hints = h; + all_len = len; + } else { + void *merged; + + merged = realloc(all_hints, all_len + len - sizeof(int)); + if (merged == NULL) { + free(h); + continue; + } + all_hints = merged; + memcpy((char *)all_hints + all_len, + (char *)h + sizeof(int), + len - sizeof(int)); + all_len += len - sizeof(int); + free(h); + } } - if (q == NULL) { + hints = all_hints; + len = all_len; + if (hints == NULL) { if (quiet_flag) exit(EX_UNAVAILABLE); else
