Sergey Bugaev writes:
> On Fri, Nov 22, 2024 at 4:28 PM <[email protected]> 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 <[email protected]> | GNU LilyPond https://LilyPond.org
Freelance IT https://www.JoyOfSource.com | Avatar® https://AvatarAcademy.com