dl-startup.h 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Architecture specific code used by dl-startup.c
  4. * Copyright (C) 2005 by Erik Andersen <andersen@codepoet.org>
  5. */
  6. __asm__ ("\
  7. .text\n\
  8. .globl _start\n\
  9. .type _start,@function\n\
  10. _start:\n\
  11. move.l %sp, -(%sp)\n\
  12. jbsr _dl_start\n\
  13. addq.l #4, %sp\n\
  14. /* FALLTHRU */\n\
  15. \n\
  16. .globl _dl_start_user\n\
  17. .type _dl_start_user,@function\n\
  18. _dl_start_user:\n\
  19. # Save the user entry point address in %a4.\n\
  20. move.l %d0, %a4\n\
  21. # See if we were run as a command with the executable file\n\
  22. # name as an extra leading argument.\n\
  23. move.l _dl_skip_args(%pc), %d0\n\
  24. # Pop the original argument count\n\
  25. move.l (%sp)+, %d1\n\
  26. # Subtract _dl_skip_args from it.\n\
  27. sub.l %d0, %d1\n\
  28. # Adjust the stack pointer to skip _dl_skip_args words.\n\
  29. lea (%sp, %d0*4), %sp\n\
  30. # Push back the modified argument count.\n\
  31. move.l %d1, -(%sp)\n\
  32. # Pass our finalizer function to the user in %a1.\n\
  33. lea _dl_fini(%pc), %a1\n\
  34. # Initialize %fp with the stack pointer.\n\
  35. move.l %sp, %fp\n\
  36. # Jump to the user's entry point.\n\
  37. jmp (%a4)\n\
  38. .size _dl_start_user, . - _dl_start_user\n\
  39. .previous");
  40. /* Get a pointer to the argv array. On many platforms this can be just
  41. * the address of the first argument, on other platforms we need to
  42. * do something a little more subtle here. */
  43. #define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long *) ARGS) + 1)
  44. /* Handle relocation of the symbols in the dynamic loader. */
  45. static __always_inline
  46. void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
  47. unsigned long symbol_addr, unsigned long load_addr, Elf32_Sym *symtab)
  48. {
  49. switch (ELF32_R_TYPE(rpnt->r_info))
  50. {
  51. case R_68K_8:
  52. *(char *) reloc_addr = symbol_addr + rpnt->r_addend;
  53. break;
  54. case R_68K_16:
  55. *(short *) reloc_addr = symbol_addr + rpnt->r_addend;
  56. break;
  57. case R_68K_32:
  58. *reloc_addr = symbol_addr + rpnt->r_addend;
  59. break;
  60. case R_68K_PC8:
  61. *(char *) reloc_addr = (symbol_addr + rpnt->r_addend
  62. - (unsigned int) reloc_addr);
  63. break;
  64. case R_68K_PC16:
  65. *(short *) reloc_addr = (symbol_addr + rpnt->r_addend
  66. - (unsigned int) reloc_addr);
  67. break;
  68. case R_68K_PC32:
  69. *reloc_addr = (symbol_addr + rpnt->r_addend
  70. - (unsigned int) reloc_addr);
  71. break;
  72. case R_68K_GLOB_DAT:
  73. case R_68K_JMP_SLOT:
  74. *reloc_addr = symbol_addr;
  75. break;
  76. case R_68K_RELATIVE:
  77. *reloc_addr = ((unsigned int) load_addr +
  78. (rpnt->r_addend ? : *reloc_addr));
  79. break;
  80. default:
  81. _dl_exit (1);
  82. }
  83. }