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

Bug#634261: Analysis



I'm not sure how _IO_stdin_used comes into play here, but the failure 
with this test case is actually happens because stdout itself is not 
8-bytes aligned, as it should be. It looks like for the 
normally-linked binary stdout is just set to the address of 
_IO_2_1_stdout_, as one would expect from looking at libio/stdio.c in 
libc source code, which contains:

_IO_FILE *stdin = (FILE *) &_IO_2_1_stdin_;
_IO_FILE *stdout = (FILE *) &_IO_2_1_stdout_;
_IO_FILE *stderr = (FILE *) &_IO_2_1_stderr_;

Demo:

jurij@debian:~/libc/eglibc-2.13/tmp$ cat foo.c
#include <stdio.h>
#include <stdlib.h>

int main() {
  printf("stdout=%p &_IO_2_1_stdout_=%p\n", stdout, &_IO_2_1_stdout_);
  setbuf(stdout, 0);
  return 0;
}
jurij@debian:~/libc/eglibc-2.13/tmp$ gcc -o foo foo.c
jurij@debian:~/libc/eglibc-2.13/tmp$ ./foo
stdout=0x207e0 &_IO_2_1_stdout_=0x207e0

However, when using the version script, stdout is altered to point to 
a unaligned location:

jurij@debian:~/libc/eglibc-2.13/tmp$ gcc -o foo foo.c -Wl,--version-script,ver
jurij@debian:~/libc/eglibc-2.13/tmp$ ./foo 
stdout=0xf7d97114 &_IO_2_1_stdout_=0x207c0
Bus error

The value is modified by the dynamic linker somewhere between the 
_init and _start:

urij@debian:~/libc/eglibc-2.13/tmp$ gdb foo
GNU gdb (GDB) 7.3-debian
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show 
copying"
and "show warranty" for details.
This GDB was configured as "sparc-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/jurij/libc/eglibc-2.13/tmp/foo...(no 
debugging symbols found)...done.
(gdb) break _init
Breakpoint 1 at 0x1032c
(gdb) break _start
Breakpoint 2 at 0x10380
(gdb) run
Starting program: /home/jurij/libc/eglibc-2.13/tmp/foo 

Breakpoint 1, _init (argc=-134233040, argv=0x1, envp=0xffffd814) at 
../sysdeps/unix/sysv/linux/init-first.c:52
52	{
(gdb) print stdout
$1 = (struct _IO_FILE *) 0x207c0
(gdb) print &_IO_2_1_stdout_
$2 = (struct _IO_FILE_plus *) 0xf7fc2d40
(gdb) c
Continuing.

Breakpoint 2, 0x00010380 in _start ()
(gdb) print stdout
$3 = (struct _IO_FILE *) 0xf7fc3114
(gdb) print &_IO_2_1_stdout_
$4 = (struct _IO_FILE_plus *) 0xf7fc2d40
(gdb) 

On amd64 stdout is set to the address of _IO_2_1_stdout_ even with the 
version script:

jurij@paddy:~/tmp$ gcc -o foo foo.c -Wl,--version-script,ver
jurij@paddy:~/tmp$ ./foo
stdout=0x600a40 &_IO_2_1_stdout_=0x600a40

Best regards
-- 
Jurij Smakov                                           jurij@wooyd.org
Key: http://www.wooyd.org/pgpkey/                      KeyID: C99E03CC



Reply to: