From 657585026a375d2cb2d06ab400f9deb487d89a17 Mon Sep 17 00:00:00 2001
From: dzwdz
Date: Sat, 17 Jun 2023 17:53:23 +0200
Subject: libc: expand psdata into a proper struct, include executable base

this is very useful for debugging userland programs using the qemu gdb stub
---
 src/user/lib/_start2.c       | 17 +++++++----------
 src/user/lib/include/_proc.h | 17 ++++++++++++-----
 src/user/lib/stdlib.c        |  8 +++++---
 3 files changed, 24 insertions(+), 18 deletions(-)

(limited to 'src/user/lib')

diff --git a/src/user/lib/_start2.c b/src/user/lib/_start2.c
index f55feab..b4eb76a 100644
--- a/src/user/lib/_start2.c
+++ b/src/user/lib/_start2.c
@@ -26,20 +26,17 @@ _Noreturn void _start2(struct execdata *ed) {
 	elf_selfreloc();
 
 	/* done first so it isn't allocated elsewhere by accident */
-	_sys_memflag(_libc_psdata, 1, MEMFLAG_PRESENT);
-	if (ed->argv[0]) {
-		strcpy(_libc_psdata, ed->argv[0]);
-	} else {
-		strcpy(_libc_psdata, "?");
-	}
+	_sys_memflag(_psdata_loc, 1, MEMFLAG_PRESENT);
+	_psdata_loc->base = __executable_start;
+	/* sets ->desc */
+	progname = shortname(ed->argv[0]);
+	setprogname(progname);
+
+	_klogf("_start2 %s %p", progname, __executable_start);
 
 	_sys_intr_set(intr_trampoline);
 	intr_set(intr_default);
 	__setinitialcwd(ed->cwd);
 
-	progname = shortname(ed->argv[0]);
-	setprogname(progname);
-	_klogf("_start2 %s %p", progname, __executable_start);
-
 	exit(main(ed->argc, ed->argv, ed->envp));
 }
diff --git a/src/user/lib/include/_proc.h b/src/user/lib/include/_proc.h
index c8fd70b..5f9c321 100644
--- a/src/user/lib/include/_proc.h
+++ b/src/user/lib/include/_proc.h
@@ -1,7 +1,14 @@
 #pragma once
 
-/* That page contains a null-terminated string that describes the process
- * for tools such as ps. It's first allocated in the bootstrap process, and
- * then it's freed on every exec() - just to be immediately reallocated by
- * _start2(). */
-static char *const _libc_psdata = (void*)0x10000;
+struct _psdata {
+	/* Description of the process, see setprogname.
+	 * Assumed to be null terminated. */
+	char desc[1024];
+
+	/* Base offset where the executable was loaded. */
+	void *base;
+};
+
+/* First allocated in bootstrap.
+ * Freed on every exec(), just to be immediately reallocated by _start2(). */
+static struct _psdata *const _psdata_loc = (void*)0x10000;
diff --git a/src/user/lib/stdlib.c b/src/user/lib/stdlib.c
index 13745d1..1739230 100644
--- a/src/user/lib/stdlib.c
+++ b/src/user/lib/stdlib.c
@@ -16,18 +16,20 @@ const char *getprogname(void) {
 }
 void setprogname(const char *pg) {
 	progname = pg;
+	setproctitle(NULL);
 }
 
 void setproctitle(const char *fmt, ...) {
+	// TODO bounds checking
 	if (!fmt) {
-		strcpy(_libc_psdata, progname);
+		strcpy(_psdata_loc->desc, progname);
 		return;
 	}
-	sprintf(_libc_psdata, "%s: ", progname);
+	sprintf(_psdata_loc->desc, "%s: ", progname);
 
 	va_list argp;
 	va_start(argp, fmt);
-	vsnprintf(_libc_psdata + strlen(_libc_psdata), 128, fmt, argp);
+	vsnprintf(_psdata_loc->desc + strlen(_psdata_loc->desc), 128, fmt, argp);
 	va_end(argp);
 }
 
-- 
cgit v1.2.3