dl-sysdep.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /*
  2. * Copyright (C) 2016 Andes Technology, Inc.
  3. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  4. */
  5. /* Define this if the system uses RELOCA. */
  6. #define ELF_USES_RELOCA
  7. #include <elf.h>
  8. /* Initialization sequence for the GOT. */
  9. #define INIT_GOT(GOT_BASE,MODULE) \
  10. { \
  11. GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \
  12. GOT_BASE[1] = (unsigned long) MODULE; \
  13. }
  14. static __inline__ unsigned long nds32_modulus(unsigned long m, unsigned long p)
  15. {
  16. unsigned long i,t,inc;
  17. i=p; t=0;
  18. while (!(i&(1<<31))) {
  19. i<<=1;
  20. t++;
  21. }
  22. t--;
  23. for (inc=t;inc>2;inc--) {
  24. i=p<<inc;
  25. if (i&(1<<31))
  26. break;
  27. while (m>=i) {
  28. m-=i;
  29. i<<=1;
  30. if (i&(1<<31))
  31. break;
  32. if (i<p)
  33. break;
  34. }
  35. }
  36. while (m>=p) {
  37. m-=p;
  38. }
  39. return m;
  40. }
  41. #define do_rem(result, n, base) ((result) = nds32_modulus(n, base))
  42. /* Here we define the magic numbers that this dynamic loader should accept */
  43. #define MAGIC1 EM_NDS32
  44. #undef MAGIC2
  45. /* Used for error messages */
  46. #define ELF_TARGET "NDS32"
  47. struct elf_resolve;
  48. unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
  49. /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
  50. PLT entries should not be allowed to define the value.
  51. ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
  52. of the main executable's symbols, as for a COPY reloc. */
  53. #define elf_machine_type_class(type) \
  54. ((((type) == R_NDS32_JMP_SLOT || (type) == R_NDS32_TLS_TPOFF \
  55. || (type) == R_NDS32_TLS_DESC) * ELF_RTYPE_CLASS_PLT) \
  56. | (((type) == R_NDS32_COPY) * ELF_RTYPE_CLASS_COPY))
  57. /* Return the link-time address of _DYNAMIC. Conveniently, this is the
  58. first element of the GOT. We used to use the PIC register to do this
  59. without a constant pool reference, but GCC 4.2 will use a pseudo-register
  60. for the PIC base, so it may not be in r10. */
  61. static __inline__ Elf32_Addr __attribute__ ((unused))
  62. elf_machine_dynamic (void)
  63. {
  64. Elf32_Addr link_addr;
  65. __asm__ ( "l.w %0, _GLOBAL_OFFSET_TABLE_@GOTOFF": "=r" (link_addr) );
  66. return link_addr;
  67. }
  68. /* Return the run-time load address of the shared object. */
  69. static __inline__ Elf32_Addr __attribute__ ((unused))
  70. elf_machine_load_address (void)
  71. {
  72. /* It doesn't matter what variable this is, the reference never makes
  73. it to assembly. We need a dummy reference to some global variable
  74. via the GOT to make sure the compiler initialized %ebx in time. */
  75. Elf32_Addr addr;
  76. __asm__ ("la %0, _DYNAMIC@GOTOFF\n" : "=r" (addr) );
  77. return addr - elf_machine_dynamic();
  78. }
  79. static __inline__ void
  80. elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
  81. Elf32_Word relative_count)
  82. {
  83. Elf32_Rela * rpnt = (void *) rel_addr;
  84. --rpnt;
  85. do {
  86. Elf32_Addr *const reloc_addr = (void *) (load_off + (++rpnt)->r_offset);
  87. *reloc_addr = load_off + rpnt->r_addend;
  88. } while (--relative_count);
  89. }