]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/ldso/ldso/i386/dl-startup.h
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / ldso / ldso / i386 / dl-startup.h
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Architecture specific code used by dl-startup.c
4  * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
5  */
6 __asm__ (
7     "   .text\n"
8     "   .globl  _start\n"
9     "   .type   _start,@function\n"
10     "   .hidden _start\n"
11     "_start:\n"
12     "   call _dl_start\n"
13     "   # Save the user entry point address in %edi.\n"
14     "   movl %eax, %edi\n"
15     "   # Point %ebx at the GOT.\n"
16     "   call 1f\n"
17     "1: popl    %ebx\n"
18     "   addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx\n"
19     "   # See if we were run as a command with the executable file\n"
20     "   # name as an extra leading argument.\n"
21     "   movl _dl_skip_args@GOTOFF(%ebx), %eax\n"
22     "   # Pop the original argument count.\n"
23     "   popl %edx\n"
24     "   # Adjust the stack pointer to skip _dl_skip_args words.\n"
25     "   leal (%esp,%eax,4), %esp\n"
26     "   # Subtract _dl_skip_args from argc.\n"
27     "   subl %eax, %edx\n"
28     "   # Push argc back on the stack.\n"
29     "   push %edx\n"
30     "   # Pass our FINI ptr() to the user in %edx, as per ELF ABI.\n"
31     "   leal _dl_fini@GOTOFF(%ebx), %edx\n"
32     "   # Jump to the user's entry point.\n"
33     "   jmp *%edi\n"
34     "   .size   _start,.-_start\n"
35     "   .previous\n"
36 );
37
38 /* Get a pointer to the argv array.  On many platforms this can be just
39  * the address of the first argument, on other platforms we need to
40  * do something a little more subtle here.  */
41 #define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*) & ARGS)+1)
42
43 /* Handle relocation of the symbols in the dynamic loader. */
44 static __always_inline
45 void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
46         unsigned long symbol_addr, unsigned long load_addr, attribute_unused Elf32_Sym *symtab)
47 {
48         switch (ELF_R_TYPE(rpnt->r_info))
49         {
50                 case R_386_32:
51                         *reloc_addr += symbol_addr;
52                         break;
53                 case R_386_PC32:
54                         *reloc_addr += symbol_addr - (unsigned long) reloc_addr;
55                         break;
56                 case R_386_GLOB_DAT:
57                 case R_386_JMP_SLOT:
58                         *reloc_addr = symbol_addr;
59                         break;
60                 case R_386_RELATIVE:
61                         *reloc_addr += load_addr;
62                         break;
63                 default:
64                         _dl_exit(1);
65         }
66 }