mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-23 03:10:05 +00:00
Hurd: Avoid init-first.c miscompilation.
This commit is contained in:
parent
5aa3a74a59
commit
18bad2ae1b
@ -1,5 +1,12 @@
|
||||
2012-05-10 Thomas Schwinge <thomas@schwinge.name>
|
||||
|
||||
* sysdeps/mach/hurd/i386/init-first.c (init): Use
|
||||
__builtin_frame_address instead of making assumptions about the
|
||||
location of the return address relative to DATA. Force early load of
|
||||
the return address.
|
||||
(_dl_init_first, doinit1 in doinit in _hurd_stack_setup): Don't use
|
||||
__builtin_frame_address.
|
||||
|
||||
dup3 for GNU Hurd.
|
||||
* include/unistd.h: Declare __dup3 and use libc_hidden_proto on it.
|
||||
* sysdeps/mach/hurd/dup3.c: New file, copy from dup2.c. Evolve it to
|
||||
|
@ -244,9 +244,16 @@ init (int *data)
|
||||
/* Push the user code address on the top of the new stack. It will
|
||||
be the return address for `init1'; we will jump there with NEWSP
|
||||
as the stack pointer. */
|
||||
*--newsp = data[-1];
|
||||
((void **) data)[-1] = switch_stacks;
|
||||
/* Force NEWSP into %ecx and &init1 into %eax, which are not restored
|
||||
/* The following expression would typically be written as
|
||||
``__builtin_return_address (0)''. But, for example, GCC 4.4.6 doesn't
|
||||
recognize that this read operation may alias the following write
|
||||
operation, and thus is free to reorder the two, clobbering the
|
||||
original return address. */
|
||||
*--newsp = *((int *) __builtin_frame_address (0) + 1);
|
||||
/* GCC 4.4.6 also wants us to force loading *NEWSP already here. */
|
||||
asm volatile ("# %0" : : "X" (*newsp));
|
||||
*((void **) __builtin_frame_address (0) + 1) = &switch_stacks;
|
||||
/* Force NEWSP into %eax and &init1 into %ecx, which are not restored
|
||||
by function return. */
|
||||
asm volatile ("# a %0 c %1" : : "a" (newsp), "c" (&init1));
|
||||
}
|
||||
@ -273,8 +280,15 @@ init (int *data)
|
||||
|
||||
/* The argument data is just above the stack frame we will unwind by
|
||||
returning. Mutate our own return address to run the code below. */
|
||||
usercode = data[-1];
|
||||
data[-1] = (int) &call_init1;
|
||||
/* The following expression would typically be written as
|
||||
``__builtin_return_address (0)''. But, for example, GCC 4.4.6 doesn't
|
||||
recognize that this read operation may alias the following write
|
||||
operation, and thus is free to reorder the two, clobbering the
|
||||
original return address. */
|
||||
usercode = *((int *) __builtin_frame_address (0) + 1);
|
||||
/* GCC 4.4.6 also wants us to force loading USERCODE already here. */
|
||||
asm volatile ("# %0" : : "X" (usercode));
|
||||
*((void **) __builtin_frame_address (0) + 1) = &call_init1;
|
||||
/* Force USERCODE into %eax and &init1 into %ecx, which are not
|
||||
restored by function return. */
|
||||
asm volatile ("# a %0 c %1" : : "a" (usercode), "c" (&init1));
|
||||
@ -322,11 +336,12 @@ first_init (void)
|
||||
stack set up just as the user will see it, so it can switch stacks. */
|
||||
|
||||
void
|
||||
_dl_init_first (void)
|
||||
_dl_init_first (int argc, ...)
|
||||
{
|
||||
first_init ();
|
||||
|
||||
init ((int *) __builtin_frame_address (0) + 2);
|
||||
/* If we use ``__builtin_frame_address (0) + 2'' here, GCC gets confused. */
|
||||
init (&argc);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -360,9 +375,11 @@ _hurd_stack_setup (void)
|
||||
void doinit (intptr_t *data)
|
||||
{
|
||||
/* This function gets called with the argument data at TOS. */
|
||||
void doinit1 (void)
|
||||
void doinit1 (int argc, ...)
|
||||
{
|
||||
init ((int *) __builtin_frame_address (0) + 2);
|
||||
/* If we use ``__builtin_frame_address (0) + 2'' here, GCC gets
|
||||
confused. */
|
||||
init ((int *) &argc);
|
||||
}
|
||||
|
||||
/* Push the user return address after the argument data, and then
|
||||
|
Loading…
Reference in New Issue
Block a user