dl-startup.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  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. "_start:\n"
  11. " mov r7, sp\n"
  12. " @ldr r0, [sp], #4\n"
  13. " mov r0, sp\n"
  14. " bl _dl_start\n"
  15. " mov r6, r0\n"
  16. " mov r0, r7\n"
  17. " mov pc, r6\n"
  18. " .size _start,.-_start\n"
  19. " .previous\n"
  20. );
  21. /* Get a pointer to the argv array. On many platforms this can be just
  22. * the address if the first argument, on other platforms we need to
  23. * do something a little more subtle here. */
  24. #define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*)ARGS)+1)
  25. /* Handle relocation of the symbols in the dynamic loader. */
  26. static inline
  27. void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
  28. unsigned long symbol_addr, unsigned long load_addr, Elf32_Sym *symtab)
  29. {
  30. switch (ELF32_R_TYPE(rpnt->r_info)) {
  31. case R_ARM_NONE:
  32. break;
  33. case R_ARM_ABS32:
  34. *reloc_addr += symbol_addr;
  35. break;
  36. case R_ARM_PC24:
  37. {
  38. unsigned long addend;
  39. long newvalue, topbits;
  40. addend = *reloc_addr & 0x00ffffff;
  41. if (addend & 0x00800000) addend |= 0xff000000;
  42. newvalue = symbol_addr - (unsigned long)reloc_addr + (addend << 2);
  43. topbits = newvalue & 0xfe000000;
  44. if (topbits != 0xfe000000 && topbits != 0x00000000)
  45. {
  46. #if 0
  47. // Don't bother with this during ldso initilization...
  48. newvalue = fix_bad_pc24(reloc_addr, symbol_addr)
  49. - (unsigned long)reloc_addr + (addend << 2);
  50. topbits = newvalue & 0xfe000000;
  51. if (unlikely(topbits != 0xfe000000 && topbits != 0x00000000))
  52. {
  53. SEND_STDERR("R_ARM_PC24 relocation out of range\n");
  54. _dl_exit(1);
  55. }
  56. #else
  57. SEND_STDERR("R_ARM_PC24 relocation out of range\n");
  58. _dl_exit(1);
  59. #endif
  60. }
  61. newvalue >>= 2;
  62. symbol_addr = (*reloc_addr & 0xff000000) | (newvalue & 0x00ffffff);
  63. *reloc_addr = symbol_addr;
  64. break;
  65. }
  66. case R_ARM_GLOB_DAT:
  67. case R_ARM_JUMP_SLOT:
  68. *reloc_addr = symbol_addr;
  69. break;
  70. case R_ARM_RELATIVE:
  71. *reloc_addr += load_addr;
  72. break;
  73. case R_ARM_COPY:
  74. break;
  75. default:
  76. SEND_STDERR("Unsupported relocation type\n");
  77. _dl_exit(1);
  78. }
  79. }
  80. /* Transfer control to the user's application, once the dynamic loader is
  81. * done. This routine has to exit the current function, then call the
  82. * _dl_elf_main function. */
  83. #define START() return _dl_elf_main;