dl-startup.h 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  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. /* Get a pointer to the argv array. On many platforms this can be just
  38. * the address of the first argument, on other platforms we need to
  39. * do something a little more subtle here. */
  40. #define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*) & ARGS)+1)
  41. /* Handle relocation of the symbols in the dynamic loader. */
  42. static __always_inline
  43. void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
  44. unsigned long symbol_addr, unsigned long load_addr, attribute_unused Elf32_Sym *symtab)
  45. {
  46. switch (ELF_R_TYPE(rpnt->r_info))
  47. {
  48. case R_386_32:
  49. *reloc_addr += symbol_addr;
  50. break;
  51. case R_386_PC32:
  52. *reloc_addr += symbol_addr - (unsigned long) reloc_addr;
  53. break;
  54. case R_386_GLOB_DAT:
  55. case R_386_JMP_SLOT:
  56. *reloc_addr = symbol_addr;
  57. break;
  58. case R_386_RELATIVE:
  59. *reloc_addr += load_addr;
  60. break;
  61. default:
  62. _dl_exit(1);
  63. }
  64. }