Hello, On Fri, May 12, 2023 at 10:12 PM Bruno Haible <br...@clisp.org> wrote: > * glibc/sysdeps/mach/hurd/x86_64/bits/sigcontext.h lines 57..79 > * glibc/sysdeps/mach/hurd/x86/trampoline.c lines 239..247. > This code copies the values from the stack into a 'struct sigcontext'. > But here the order of the registers is
No: trampoline.c copies the values of registers from the Mach thread state, as returned by thread_get_state (). There's no way that glibc could, from the userland, directly get at the values on the kernel stack. thread_get_state () returns the i386_thread_state structure defined in gnumach i386/include/mach/i386/thread_status.h: struct i386_thread_state { unsigned int gs; unsigned int fs; unsigned int es; unsigned int ds; #if defined(__x86_64__) && !defined(USER32) uint64_t r8; uint64_t r9; uint64_t r10; uint64_t r11; uint64_t r12; uint64_t r13; uint64_t r14; uint64_t r15; uint64_t rdi; uint64_t rsi; uint64_t rbp; uint64_t rsp; uint64_t rbx; uint64_t rdx; uint64_t rcx; uint64_t rax; uint64_t rip; ..more.. So struct sigcontext is supposed to mirror that arrangement. Mach fills in i386_thread_state from its internal struct i386_saved_state (defined in i386/i386/thread.h), and *that one* is arranged in the popa order: struct i386_saved_state { #ifdef __x86_64__ unsigned long fsbase; unsigned long gsbase; #endif unsigned long gs; unsigned long fs; unsigned long es; unsigned long ds; #ifdef __x86_64__ unsigned long r15; unsigned long r14; unsigned long r13; unsigned long r12; unsigned long r11; unsigned long r10; unsigned long r9; unsigned long r8; The conversion between i386_saved_state and i386_thread_state is not a direct memcpy, but a bunch of explicit assignments (see i386_thread_state:thread_getstatus): #if defined(__x86_64__) && !defined(USER32) state->r8 = saved_state->r8; state->r9 = saved_state->r9; state->r10 = saved_state->r10; state->r11 = saved_state->r11; state->r12 = saved_state->r12; state->r13 = saved_state->r13; state->r14 = saved_state->r14; state->r15 = saved_state->r15; state->rdi = saved_state->edi; state->rsi = saved_state->esi; state->rbp = saved_state->ebp; state->rbx = saved_state->ebx; state->rdx = saved_state->edx; state->rcx = saved_state->ecx; state->rax = saved_state->eax; state->rip = saved_state->eip; state->ursp = saved_state->uesp; state->rfl = saved_state->efl; state->rsp = 0; /* unused */ So there's no bug here. Sergey