bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: struct sigcontext in Hurd/x86_64


From: Sergey Bugaev
Subject: Re: struct sigcontext in Hurd/x86_64
Date: Fri, 12 May 2023 22:48:55 +0300

Hello,

On Fri, May 12, 2023 at 10:12 PM Bruno Haible <bruno@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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]