tools/nolibc: add auxiliary vector retrieval for mips
authorWilly Tarreau <w@1wt.eu>
Tue, 10 Jan 2023 07:24:30 +0000 (08:24 +0100)
committerPaul E. McKenney <paulmck@kernel.org>
Tue, 10 Jan 2023 21:33:56 +0000 (13:33 -0800)
In the _start block we now iterate over envp to find the auxiliary
vector after the NULL. The pointer is saved into an _auxv variable
that is marked as weak so that it's accessible from multiple units.

Signed-off-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
tools/include/nolibc/arch-mips.h

index 7d22f7bc38b307f8c0682a80cb033d673d19469d..bf83432d23ed3115c8a211a9820694adce1cc39e 100644 (file)
@@ -177,6 +177,7 @@ struct sys_stat_struct {
 })
 
 char **environ __attribute__((weak));
+const unsigned long *_auxv __attribute__((weak));
 
 /* startup code, note that it's called __start on MIPS */
 void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) __start(void)
@@ -196,6 +197,16 @@ void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) __start(void)
                "lui $a3, %hi(environ)\n"     // load environ into a3 (hi)
                "addiu $a3, %lo(environ)\n"   // load environ into a3 (lo)
                "sw $a2,($a3)\n"              // store envp(a2) into environ
+
+               "move $t0, $a2\n"             // iterate t0 over envp, look for NULL
+               "0:"                          // do {
+               "lw $a3, ($t0)\n"             //   a3=*(t0);
+               "bne $a3, $0, 0b\n"           // } while (a3);
+               "addiu $t0, $t0, 4\n"         // delayed slot: t0+=4;
+               "lui $a3, %hi(_auxv)\n"       // load _auxv into a3 (hi)
+               "addiu $a3, %lo(_auxv)\n"     // load _auxv into a3 (lo)
+               "sw $t0, ($a3)\n"             // store t0 into _auxv
+
                "li $t0, -8\n"
                "and $sp, $sp, $t0\n"   // sp must be 8-byte aligned
                "addiu $sp,$sp,-16\n"   // the callee expects to save a0..a3 there!