b/6115789
TODO(ppluzhnikov): revert this after cleanup.
(ppluzhnikov, google-local)
+
+csu/elf-init.c
+sysdeps/i386/start.S
+sysdeps/x86_64/start.S
+ For b/13901604, revert local changes to sysdeps/{i386,x86_64}/elf/start.S,
+ and initialize __google_auxv in __libc_csu_init instead.
+ (ppluzhnikov, google-local)
+
#include <stddef.h>
+# include <link.h> // For ElfW.
+
/* These magic symbols are provided by the linker. */
extern void (*__preinit_array_start []) (int, char **, char **)
for (i = 0; i < size; i++)
(*__preinit_array_start [i]) (argc, argv, envp);
}
+
+ extern ElfW(auxv_t) *__google_auxv; /* Defined in dl-init.c */
+ /* _dl_init() is never called for fully-static binary.
+ Initialize __google_auxv here. */
+ if (__google_auxv == NULL)
+ {
+ char **e;
+
+ for (e = envp; *e; ++e) /* Skip. */;
+ __google_auxv = (ElfW(auxv_t) *) ++e;
+ }
+
#endif
#ifndef NO_INITFINI
/* Clear the frame pointer. The ABI suggests this be done, to mark
the outermost frame obviously. */
xorl %ebp, %ebp
- call __google_init
/* Extract the arguments as encoded on the stack and set up
the arguments for `main': argc, argv. envp will be determined
ret
#endif
-/*
- %esp The stack contains the arguments and environment:
- 0(%esp) ra
- 1*4(%esp) argc
- 2*4(%esp) argv[0]
- ...
- (argc+2)*4(%esp) NULL
- (argc+3)*4(%esp) envp[0]
- ...
- (argc+2+env_count+1)*4(%esp) NULL
- (argc+2+env_count+2)*4(%esp) auxv[0]
- ...
-*/
-
-__google_init:
-#ifdef SHARED
- call 1b
- addl $_GLOBAL_OFFSET_TABLE_, %ebx
- leal __google_argc@GOTOFF(%ebx), %ecx
-#else
- leal __google_argc, %ecx
-#endif
- movl 4(%esp), %eax
- movl %eax, 0(%ecx)
- push %esp
- pop %eax
- addl $2*4, %eax
-#ifdef SHARED
- leal __google_argv@GOTOFF(%ebx), %ecx
-#else
- leal __google_argv, %ecx
-#endif
- movl %eax, 0(%ecx)
-/* The next loop could be omitted if we are to trust argc from the kernel. */
-1: cmpl $0, 0(%eax) /* while(argv[i++] != 0) skip; */
- je 2f
- addl $4, %eax
- jmp 1b
-2: addl $4, %eax
-#ifdef SHARED
- leal __google_envp@GOTOFF(%ebx), %ecx
-#else
- leal __google_envp, %ecx
-#endif
- movl %eax, 0(%ecx)
-3: cmpl $0, 0(%eax) /* while (envp[i++] != 0) skip; */
- je 4f
- addl $4, %eax
- jmp 3b
-4: addl $4, %eax
-#ifdef SHARED
- leal __google_auxv@GOTOFF(%ebx), %ecx
-#else
- leal __google_auxv, %ecx
-#endif
- movl %eax, 0(%ecx)
- ret
-
/* To fulfill the System V/i386 ABI we need this symbol. Yuck, it's so
meaningless since we don't support machines < 80386. */
.section .rodata
.long 0
.weak data_start
data_start = __data_start
-
-/* The {argc,argv,envp} variables are not exposed to keep the interface narrow
- (we don't need anything except auxv right now). If/when they are needed,
- simply mark them with ".globl". */
-__google_argc: .long 0
-__google_argv: .long 0
-__google_envp: .long 0
- .globl __google_auxv
-__google_auxv: .long 0
-
-
/* Clear the frame pointer. The ABI suggests this be done, to mark
the outermost frame obviously. */
xorl %ebp, %ebp
- call __google_init
/* Extract the arguments as encoded on the stack and set up
the arguments for __libc_start_main (int (*main) (int, char **, char **),
hlt /* Crash if somehow `exit' does return. */
cfi_endproc
-/*
- %rsp The stack contains the arguments and environment:
- 0(%rsp) ra
- 1*8(%rsp) argc
- 2*8(%rsp) argv[0]
- ...
- (argc+2)*8(%rsp) NULL
- (argc+3)*8(%rsp) envp[0]
- ...
- (argc+2+env_count+1)*8(%rsp) NULL
- (argc+2+env_count+2)*8(%rsp) auxv[0]
- ...
-*/
-__google_init:
- leaq __google_argc(%rip), %rbx /* %rbx = &__google_argc */
- movq 8(%rsp), %rax
- movq %rax, 0(%rbx)
- push %rsp
- pop %rax
- addq $2*8, %rax
- leaq __google_argv(%rip), %rbx
- movq %rax, 0(%rbx)
-/* The next loop could be omitted if we are to trust argc from the kernel. */
-1: cmpq $0, 0(%rax) /* while(argv[i++] != 0) skip; */
- je 2f
- addq $8, %rax
- jmp 1b
-2: addq $8, %rax
- leaq __google_envp(%rip), %rbx
- movq %rax, 0(%rbx)
-3: cmpq $0, 0(%rax) /* while (envp[i++] != 0) skip; */
- je 4f
- addq $8, %rax
- jmp 3b
-4: addq $8, %rax
- leaq __google_auxv(%rip), %rbx
- movq %rax, 0(%rbx)
- ret
-
-
/* Define a symbol for the first piece of initialized data. */
.data
.globl __data_start
.long 0
.weak data_start
data_start = __data_start
-
- .p2align 3
-/* The {argc,argv,envp} variables are not exposed to keep the interface narrow
- (we don't need anything except auxv right now). If/when they are needed,
- simply mark them with ".globl". */
-__google_argc: .quad 0
-__google_argv: .quad 0
-__google_envp: .quad 0
- .globl __google_auxv
-__google_auxv: .quad 0