On Wed, Apr 19, 2023 at 11:52 PM Sergey Bugaev <buga...@gmail.com> wrote: > On Wed, Apr 19, 2023 at 10:48 PM Luca Dariz <l...@orpolo.org> wrote: > > * i386/i386/pcb.c: switch FSBASE/GSBASE on context switch and > > implement accessors in thread setstatus/getstatus > > * i386/i386/thread.h: add new state to thread saved state > > * kern/thread.c: add i386_FSGS_BASE_STATE handler > > Hi Luca -- this is great! > > I will build gnumach with your changes and see if that works with my > latest build of x86_64-gnu glibc.
Well, too bad -- as is, we don't even get to actually doing the thread_set_state () RPC. We do reach the call to __thread_set_state (), but then it uses __mig_memcpy (), which is just 'return memcpy (...)'. And (because of the static build?), that memcpy () is the full real ifunc-selected memcpy. So it jumps to the memcpy@plt, which jumps to *(mem...@got.plt), which is supposed to jump into the rtld and then run the ifunc resolver and do its smarts and eventually jump to the right memcpy... But of course none of that is happening because we haven't really started running any of rtld proper yet, we're still inside _hurd_stack_setup (). So there was no-one to apply the relocations to our .got.plt yet, and they point to who knows where. (In practice, back to the PLT.) Why had this worked for me when I was running it on Linux? Most likely I have skipped over the whole __thread_set_state () call and not just the 'syscall'. Why was this not an issue for us on i386? Two reasons: * i386_set_gdt () doesn't need memcpy; * memcpy is not ifunc-resolved in static i386 We can't run libc_start_main () (which is what calls ARCH_INIT_CPU_FEATURES and then _dl_relocate_static_pie) before we get our argv/envp and our new stack, but to do that we need MIG, and MIG will memcpy... So how do we get out of this chicken-and-egg situation? Well, like this of course: leaq __memcpy_sse2_unaligned(%rip), %rax movq %rax, memcpy@GOTPCREL(%rip) Call that either a terrible hack or a brilliant solution :) :) :) and I'm sure H.J. Lu over on libc-alpha will appreciate it when I send the patch. But -- it works! I can get through memcpy now, and __thread_set_state () succeeds and writes $fs_base as seen from GDB! So, great work on this! Now, this exposed some of my own bugs in glibc... and after quickly fixing them, I'm now stuck at trying to allocate memory. Specifically, I'd like to have memory at 0x200000000000 and some further, but gnumach is not letting me! -- because that's more than VM_MAX_USER_ADDRESS, which is defined to VM_MAX_ADDRESS, which is then defined to 0xc0000000, same as on i386. That's of course too small. Can we bump this substantially? Sergey