git: 501a337902f8 - stable/13 - Add support for module_verbose

From: Warner Losh <imp_at_FreeBSD.org>
Date: Tue, 24 Jan 2023 22:10:19 UTC
The branch stable/13 has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=501a337902f80cee1c84554e5222172dc809ac4b

commit 501a337902f80cee1c84554e5222172dc809ac4b
Author:     Simon J. Gerraty <sjg@FreeBSD.org>
AuthorDate: 2022-02-13 20:45:57 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2023-01-24 21:49:20 +0000

    Add support for module_verbose
    
    Set module_verbose to control the printing of information
    about loaded modules and kernel:
    
    0       MODULE_VERBOSE_SILENT   None
    1       MODULE_VERBOSE_SIZE     Pathname and size
    2       MODULE_VERBOSE_TWIDDLE  as for 1 but also twiddle for progress
    3       MODULE_VERBOSE_FULL     extra detail
    
    When the loader is verifying modules we already have a
    running indication of progress and module_verbose=0 makes sense.
    
    Reviewed by:    rpokala
    Differential Revision:  https://reviews.freebsd.org/D34245
    
    (cherry picked from commit ec042f46e9bbd195e1f7c8151df5d280a2a4d069)
---
 stand/common/bootstrap.h    |   8 ++++
 stand/common/console.c      |  29 ++++++++++-
 stand/common/load_elf.c     | 114 ++++++++++++++++++++++----------------------
 stand/common/load_elf_obj.c |   9 ++--
 4 files changed, 98 insertions(+), 62 deletions(-)

diff --git a/stand/common/bootstrap.h b/stand/common/bootstrap.h
index 42b2c73f5774..9c62a49b0da7 100644
--- a/stand/common/bootstrap.h
+++ b/stand/common/bootstrap.h
@@ -124,6 +124,14 @@ void cons_probe(void);
 bool		cons_update_mode(bool);
 void		autoload_font(bool);
 
+extern int module_verbose;
+enum {
+	MODULE_VERBOSE_SILENT,		/* say nothing */
+	MODULE_VERBOSE_SIZE,		/* print name and size */
+	MODULE_VERBOSE_TWIDDLE,		/* show progress */
+	MODULE_VERBOSE_FULL,		/* all we have */
+};
+
 /*
  * Plug-and-play enumerator/configurator interface.
  */
diff --git a/stand/common/console.c b/stand/common/console.c
index ff864276f96c..08d0dc40e3a9 100644
--- a/stand/common/console.c
+++ b/stand/common/console.c
@@ -41,6 +41,28 @@ static int	cons_check(const char *string);
 static int	cons_change(const char *string);
 static int	twiddle_set(struct env_var *ev, int flags, const void *value);
 
+#ifndef MODULE_VERBOSE
+# define MODULE_VERBOSE MODULE_VERBOSE_TWIDDLE
+#endif
+int module_verbose = MODULE_VERBOSE;
+
+static int
+module_verbose_set(struct env_var *ev, int flags, const void *value)
+{
+	u_long v;
+	char *eptr;
+
+	v = strtoul(value, &eptr, 0);
+	if (*(const char *)value == 0 || *eptr != 0) {
+		printf("invalid module_verbose '%s'\n", (const char *)value);
+		return (CMD_ERROR);
+	}
+	module_verbose = (int)v;
+	env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
+
+	return (CMD_OK);
+}
+
 /*
  * Detect possible console(s) to use.  If preferred console(s) have been
  * specified, mark them as active. Else, mark the first probed console
@@ -52,10 +74,15 @@ cons_probe(void)
 	int	cons;
 	int	active;
 	char	*prefconsole;
+	char	module_verbose_buf[8];
 
 	TSENTER();
 
-	/* We want a callback to install the new value when this var changes. */
+	/* We want a callback to install the new value when these vars change. */
+	snprintf(module_verbose_buf, sizeof(module_verbose_buf), "%d",
+	    module_verbose);
+	env_setenv("module_verbose", EV_VOLATILE, module_verbose_buf,
+	    module_verbose_set, env_nounset);
 	env_setenv("twiddle_divisor", EV_VOLATILE, "16", twiddle_set,
 	    env_nounset);
 
diff --git a/stand/common/load_elf.c b/stand/common/load_elf.c
index f3192c1c94fa..99ebace012ea 100644
--- a/stand/common/load_elf.c
+++ b/stand/common/load_elf.c
@@ -462,13 +462,17 @@ __elfN(loadfile_raw)(char *filename, uint64_t dest,
 	else
 		fp->f_type = strdup("elf multiboot kernel");
 
-#ifdef ELF_VERBOSE
-	if (ef.kernel)
-		printf("%s entry at 0x%jx\n", filename,
-		    (uintmax_t)ehdr->e_entry);
-#else
-	printf("%s ", filename);
-#endif
+	if (module_verbose >= MODULE_VERBOSE_FULL) {
+		if (ef.kernel)
+			printf("%s entry at 0x%jx\n", filename,
+			    (uintmax_t)ehdr->e_entry);
+	} else if (module_verbose > MODULE_VERBOSE_SILENT)
+		printf("%s ", filename);
+
+	if (module_verbose < MODULE_VERBOSE_TWIDDLE) {
+		/* A hack for now; we do not want twiddling */
+		twiddle_divisor(UINT_MAX);
+	}
 
 	fp->f_size = __elfN(loadimage)(fp, &ef, dest);
 	if (fp->f_size == 0 || fp->f_addr == 0)
@@ -579,9 +583,10 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, uint64_t off)
 			off += 0x01000000;
 		}
 		ehdr->e_entry += off;
-#ifdef ELF_VERBOSE
-		printf("Converted entry 0x%jx\n", (uintmax_t)ehdr->e_entry);
-#endif
+		if (module_verbose >= MODULE_VERBOSE_FULL)
+			printf("Converted entry 0x%jx\n",
+			    (uintmax_t)ehdr->e_entry);
+
 #elif defined(__arm__) && !defined(EFI)
 		/*
 		 * The elf headers in arm kernels specify virtual addresses in
@@ -603,10 +608,9 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, uint64_t off)
 		 */
 		off -= ehdr->e_entry & ~PAGE_MASK;
 		ehdr->e_entry += off;
-#ifdef ELF_VERBOSE
-		printf("ehdr->e_entry 0x%jx, va<->pa off %llx\n",
-		    (uintmax_t)ehdr->e_entry, off);
-#endif
+		if (module_verbose >= MODULE_VERBOSE_FULL)
+			printf("ehdr->e_entry 0x%jx, va<->pa off %llx\n",
+			    (uintmax_t)ehdr->e_entry, off);
 #else
 		off = 0;	/* other archs use direct mapped kernels */
 #endif
@@ -631,22 +635,22 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, uint64_t off)
 		if (phdr[i].p_type != PT_LOAD)
 			continue;
 
-#ifdef ELF_VERBOSE
-		printf("Segment: 0x%lx@0x%lx -> 0x%lx-0x%lx",
-		    (long)phdr[i].p_filesz, (long)phdr[i].p_offset,
-		    (long)(phdr[i].p_vaddr + off),
-		    (long)(phdr[i].p_vaddr + off + phdr[i].p_memsz - 1));
-#else
-		if ((phdr[i].p_flags & PF_W) == 0) {
-			printf("text=0x%lx ", (long)phdr[i].p_filesz);
-		} else {
-			printf("data=0x%lx", (long)phdr[i].p_filesz);
-			if (phdr[i].p_filesz < phdr[i].p_memsz)
-				printf("+0x%lx", (long)(phdr[i].p_memsz -
-				    phdr[i].p_filesz));
-			printf(" ");
+		if (module_verbose >= MODULE_VERBOSE_FULL) {
+			printf("Segment: 0x%lx@0x%lx -> 0x%lx-0x%lx",
+			    (long)phdr[i].p_filesz, (long)phdr[i].p_offset,
+			    (long)(phdr[i].p_vaddr + off),
+			    (long)(phdr[i].p_vaddr + off + phdr[i].p_memsz - 1));
+		} else if (module_verbose > MODULE_VERBOSE_SILENT) {
+			if ((phdr[i].p_flags & PF_W) == 0) {
+				printf("text=0x%lx ", (long)phdr[i].p_filesz);
+			} else {
+				printf("data=0x%lx", (long)phdr[i].p_filesz);
+				if (phdr[i].p_filesz < phdr[i].p_memsz)
+					printf("+0x%lx", (long)(phdr[i].p_memsz -
+						phdr[i].p_filesz));
+				printf(" ");
+			}
 		}
-#endif
 		fpcopy = 0;
 		if (ef->firstlen > phdr[i].p_offset) {
 			fpcopy = ef->firstlen - phdr[i].p_offset;
@@ -665,18 +669,16 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, uint64_t off)
 		}
 		/* clear space from oversized segments; eg: bss */
 		if (phdr[i].p_filesz < phdr[i].p_memsz) {
-#ifdef ELF_VERBOSE
-			printf(" (bss: 0x%lx-0x%lx)",
-			    (long)(phdr[i].p_vaddr + off + phdr[i].p_filesz),
-			    (long)(phdr[i].p_vaddr + off + phdr[i].p_memsz -1));
-#endif
-
+			if (module_verbose >= MODULE_VERBOSE_FULL) {
+				printf(" (bss: 0x%lx-0x%lx)",
+				    (long)(phdr[i].p_vaddr + off + phdr[i].p_filesz),
+				    (long)(phdr[i].p_vaddr + off + phdr[i].p_memsz -1));
+			}	
 			kern_bzero(phdr[i].p_vaddr + off + phdr[i].p_filesz,
 			    phdr[i].p_memsz - phdr[i].p_filesz);
 		}
-#ifdef ELF_VERBOSE
-		printf("\n");
-#endif
+		if (module_verbose >= MODULE_VERBOSE_FULL)
+			printf("\n");
 
 		if (archsw.arch_loadseg != NULL)
 			archsw.arch_loadseg(ehdr, phdr + i, off);
@@ -766,12 +768,10 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, uint64_t off)
 		goto nosyms;
 
 	/* Ok, committed to a load. */
-#ifndef ELF_VERBOSE
-	printf("syms=[");
-#endif
+	if (module_verbose >= MODULE_VERBOSE_FULL)
+		printf("syms=[");
 	ssym = lastaddr;
 	for (i = symtabindex; i >= 0; i = symstrindex) {
-#ifdef ELF_VERBOSE
 		char	*secname;
 
 		switch(shdr[i].sh_type) {
@@ -785,23 +785,21 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, uint64_t off)
 			secname = "WHOA!!";
 			break;
 		}
-#endif
 		size = shdr[i].sh_size;
 
 		archsw.arch_copyin(&size, lastaddr, sizeof(size));
 		lastaddr += sizeof(size);
 
-#ifdef ELF_VERBOSE
-		printf("\n%s: 0x%jx@0x%jx -> 0x%jx-0x%jx", secname,
-		    (uintmax_t)shdr[i].sh_size, (uintmax_t)shdr[i].sh_offset,
-		    (uintmax_t)lastaddr,
-		    (uintmax_t)(lastaddr + shdr[i].sh_size));
-#else
-		if (i == symstrindex)
-			printf("+");
-		printf("0x%lx+0x%lx", (long)sizeof(size), (long)size);
-#endif
-
+		if (module_verbose >= MODULE_VERBOSE_FULL) {
+			printf("\n%s: 0x%jx@0x%jx -> 0x%jx-0x%jx", secname,
+			    (uintmax_t)shdr[i].sh_size, (uintmax_t)shdr[i].sh_offset,
+			    (uintmax_t)lastaddr,
+			    (uintmax_t)(lastaddr + shdr[i].sh_size));
+		} else if (module_verbose > MODULE_VERBOSE_SILENT) {
+			if (i == symstrindex)
+				printf("+");
+			printf("0x%lx+0x%lx", (long)sizeof(size), (long)size);
+		}
 		if (VECTX_LSEEK(VECTX_HANDLE(ef), (off_t)shdr[i].sh_offset, SEEK_SET) == -1) {
 			printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
 			   "_loadimage: could not seek for symbols - skipped!");
@@ -828,15 +826,15 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, uint64_t off)
 			symstrindex = -1;
 	}
 	esym = lastaddr;
-#ifndef ELF_VERBOSE
-	printf("]");
-#endif
+	if (module_verbose >= MODULE_VERBOSE_FULL)
+		printf("]");
 
 	file_addmetadata(fp, MODINFOMD_SSYM, sizeof(ssym), &ssym);
 	file_addmetadata(fp, MODINFOMD_ESYM, sizeof(esym), &esym);
 
 nosyms:
-	printf("\n");
+	if (module_verbose > MODULE_VERBOSE_SILENT)
+		printf("\n");
 
 	ret = lastaddr - firstaddr;
 	fp->f_addr = firstaddr;
diff --git a/stand/common/load_elf_obj.c b/stand/common/load_elf_obj.c
index f3c84cf31368..ed202e08b780 100644
--- a/stand/common/load_elf_obj.c
+++ b/stand/common/load_elf_obj.c
@@ -184,7 +184,8 @@ __elfN(obj_loadfile)(char *filename, uint64_t dest,
 	fp->f_name = strdup(filename);
 	fp->f_type = strdup(__elfN(obj_moduletype));
 
-	printf("%s ", filename);
+	if (module_verbose > MODULE_VERBOSE_SILENT)
+		printf("%s ", filename);
 
 	fp->f_size = __elfN(obj_loadimage)(fp, &ef, dest);
 	if (fp->f_size == 0 || fp->f_addr == 0)
@@ -378,10 +379,12 @@ __elfN(obj_loadimage)(struct preloaded_file *fp, elf_file_t ef, uint64_t off)
 	ret = lastaddr - firstaddr;
 	fp->f_addr = firstaddr;
 
-	printf("size 0x%lx at 0x%lx", (u_long)ret, (u_long)firstaddr);
+	if (module_verbose > MODULE_VERBOSE_SILENT)
+		printf("size 0x%lx at 0x%lx", (u_long)ret, (u_long)firstaddr);
 
 out:
-	printf("\n");
+	if (module_verbose > MODULE_VERBOSE_SILENT)
+		printf("\n");
 	return ret;
 }