Sergey Bugaev writes:

> On Fri, Nov 22, 2024 at 4:28 PM <jann...@gnu.org> wrote:
>> using the (amazing) command-line that glibc creates
>>
>> --8<---------------cut here---------------start------------->8---
>> $ x86_64-pc-gnu-gcc ../sysdeps/mach/hurd/x86_64/sigreturn.c -c

[..]
>
> You could now make use of this command line to see exactly how the
> preprocessor expands all the macros, by replacing -c with -E and -o
> .../build/signal/sigreturn.o with, say, /tmp/sigreturn.c.pp

Right, that's probably the proper way.

>> eh...hmm?  Last thing I tried was marking the THREAD_SETMEM calls with
>> NOPS
>>
>>   reply_port = THREAD_GETMEM (THREAD_SELF, reply_port);
>>   asm ("nop");
>>   THREAD_SETMEM (THREAD_SELF, reply_port, MACH_PORT_DEAD);
>>   asm ("nop"); asm ("nop");
>>   if (__glibc_likely (MACH_PORT_VALID (reply_port)))
>>     (void) __mach_port_mod_refs (__mach_task_self (), reply_port,
>>                                  MACH_PORT_RIGHT_RECEIVE, -1);
>>   asm ("nop"); asm ("nop"); asm ("nop");
>>   THREAD_SETMEM (THREAD_SELF, reply_port, sc_reply_port);
>>   asm ("nop"); asm ("nop"); asm ("nop"); asm ("nop");
>
> FWIW, an asm statement that's not marked as 'volatile' and doesn't
> have useful outputs can be eliminated by the compiler, but it doesn't
> seem to have happened here.

Ah, right.  Sure.  They better never implement that, or one of my best
debugging tricks breaks %-/

>> and I have attached the the objdump --reloc of this.  Can you make
>> anything of this?
>
> This version does seem to set reply_port:
>
>    1:   89 d5                   mov    %edx,%ebp
> <snip>
>   47:   90                      nop
>   48:   90                      nop
>   49:   90                      nop
>   4a:   64 89 2c 25 80 00 00    mov    %ebp,%fs:0x80
>   51:   00
>   52:   90                      nop
>   53:   90                      nop
>   54:   90                      nop
>   55:   90                      nop
>
> Perhaps the nops tickled the compiler a different way, and it chose
> not to mis-optimize? Does this version of sigreturn.o work?

YES!  I was puzzled by it too and I found that (only!) the trailing nop
has this effect.  So this extra nop at 47a:

    42    reply_port = THREAD_GETMEM (THREAD_SELF, reply_port);
    43    THREAD_SETMEM (THREAD_SELF, reply_port, MACH_PORT_DEAD);
    44    if (__glibc_likely (MACH_PORT_VALID (reply_port)))
    45      (void) __mach_port_mod_refs (__mach_task_self (), reply_port,
    46                                   MACH_PORT_RIGHT_RECEIVE, -1);
    47    THREAD_SETMEM (THREAD_SELF, reply_port, sc_reply_port);
    47a   asm ("nop");
    48  
    49    asm volatile (
    50                  /* Point the stack to the register dump.  */
    51                  "movq %0, %%rsp\n"
    52

makes the mov at 44 appear:

  3f:   e8 00 00 00 00          call   44 <__sigreturn2+0x44>
                        40: R_X86_64_PLT32      __mach_port_mod_refs-0x4
  44:   64 89 2c 25 80 00 00    mov    %ebp,%fs:0x80
  4b:   00 
  4c:   90                      nop

> See also: [0]; if this is indeed the same bug and you can reproduce it
> with just THREAD_SETMEM (and not THREAD_SELF->smth), it's a lot more
> serious than I thought.
>
> [0] 
> https://inbox.sourceware.org/libc-alpha/CAN9u=Heeem3L5ybS8CPHLWubFn_=1ucsn7affyzhp1-zmsg...@mail.gmail.com/T/

Sounds awfully familiar...so is this a compiler bug?  How should I go
forward here?  Could/should I do/try something like this?

# define THREAD_SETMEM(descr, member, value)                            \
  (*(__typeof (descr->member) __seg_fs *) offsetof (tcbhead_t, member) = 
value);\
  asm ("nop")

and if so, for which macros?

Greetings,
Janneke

-- 
Janneke Nieuwenhuizen <jann...@gnu.org>  | GNU LilyPond https://LilyPond.org
Freelance IT https://www.JoyOfSource.com | Avatar® https://AvatarAcademy.com

Reply via email to