2 * Various assembly language/system dependent hacks that are required
3 * so that we can minimize the amount of platform specific code.
6 /* Define this if the system uses RELOCA. */
7 #define ELF_USES_RELOCA
10 * Initialization sequence for a GOT.
12 #define INIT_GOT(GOT_BASE,MODULE) \
14 GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \
15 GOT_BASE[1] = (unsigned long) (MODULE); \
18 /* Here we define the magic numbers that this dynamic loader should accept */
22 /* Used for error messages */
23 #define ELF_TARGET "sh"
26 extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
28 static __always_inline unsigned int
29 _dl_urem(unsigned int n, unsigned int base)
37 "! get one bit from the msb of the numerator into the T\n\t" \
38 "! bit and divide it by whats in %2. Put the answer bit\n\t" \
39 "! into the T bit so it can come out again at the bottom\n\t" \
41 "rotcl %1 ; div1 %2, r0\n\t" \
42 "rotcl %1 ; div1 %2, r0\n\t" \
43 "rotcl %1 ; div1 %2, r0\n\t" \
44 "rotcl %1 ; div1 %2, r0\n\t" \
45 "rotcl %1 ; div1 %2, r0\n\t" \
46 "rotcl %1 ; div1 %2, r0\n\t" \
47 "rotcl %1 ; div1 %2, r0\n\t" \
48 "rotcl %1 ; div1 %2, r0\n\t" \
50 "rotcl %1 ; div1 %2, r0\n\t" \
51 "rotcl %1 ; div1 %2, r0\n\t" \
52 "rotcl %1 ; div1 %2, r0\n\t" \
53 "rotcl %1 ; div1 %2, r0\n\t" \
54 "rotcl %1 ; div1 %2, r0\n\t" \
55 "rotcl %1 ; div1 %2, r0\n\t" \
56 "rotcl %1 ; div1 %2, r0\n\t" \
57 "rotcl %1 ; div1 %2, r0\n\t" \
59 "rotcl %1 ; div1 %2, r0\n\t" \
60 "rotcl %1 ; div1 %2, r0\n\t" \
61 "rotcl %1 ; div1 %2, r0\n\t" \
62 "rotcl %1 ; div1 %2, r0\n\t" \
63 "rotcl %1 ; div1 %2, r0\n\t" \
64 "rotcl %1 ; div1 %2, r0\n\t" \
65 "rotcl %1 ; div1 %2, r0\n\t" \
66 "rotcl %1 ; div1 %2, r0\n\t" \
68 "rotcl %1 ; div1 %2, r0\n\t" \
69 "rotcl %1 ; div1 %2, r0\n\t" \
70 "rotcl %1 ; div1 %2, r0\n\t" \
71 "rotcl %1 ; div1 %2, r0\n\t" \
72 "rotcl %1 ; div1 %2, r0\n\t" \
73 "rotcl %1 ; div1 %2, r0\n\t" \
74 "rotcl %1 ; div1 %2, r0\n\t" \
75 "rotcl %1 ; div1 %2, r0\n\t" \
81 return n - (base * res);
84 #define do_rem(result, n, base) ((result) = _dl_urem((n), (base)))
86 /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
87 TLS variable, so undefined references should not be allowed to
89 ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
90 of the main executable's symbols, as for a COPY reloc. */
91 # define elf_machine_type_class(type) \
92 ((((type) == R_SH_JMP_SLOT || (type) == R_SH_TLS_DTPMOD32 \
93 || (type) == R_SH_TLS_DTPOFF32 || (type) == R_SH_TLS_TPOFF32) \
94 * ELF_RTYPE_CLASS_PLT) \
95 | (((type) == R_SH_COPY) * ELF_RTYPE_CLASS_COPY))
97 /* Return the link-time address of _DYNAMIC. Conveniently, this is the
98 first element of the GOT. This must be inlined in a function which
100 static __always_inline Elf32_Addr __attribute__ ((unused))
101 elf_machine_dynamic (void)
103 register Elf32_Addr *got;
104 __asm__ ("mov r12,%0" :"=r" (got));
108 /* Return the run-time load address of the shared object. */
109 static __always_inline Elf32_Addr __attribute__ ((unused))
110 elf_machine_load_address (void)
113 __asm__ ("mov.l 1f,r0\n\
116 mov.l @(r0,r12),r0\n\
120 1: .long _dl_start@GOT\n\
121 3: .long _dl_start@GOTOFF\n\
123 : "=r" (addr) : : "r0", "r1", "r2");
127 #define COPY_UNALIGNED_WORD(swp, twp, align) \
129 void *__s = (swp), *__t = (twp); \
130 unsigned char *__s1 = __s, *__t1 = __t; \
131 unsigned short *__s2 = __s, *__t2 = __t; \
132 unsigned long *__s4 = __s, *__t4 = __t; \
151 static __always_inline void
152 elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
153 Elf32_Word relative_count)
156 Elf32_Rela * rpnt = (void *)rel_addr;
159 Elf32_Addr *const reloc_addr = (void *) (load_off + rpnt->r_offset);
162 value = load_off + rpnt->r_addend;
164 COPY_UNALIGNED_WORD (reloc_addr, &value, (int) reloc_addr & 3);
167 COPY_UNALIGNED_WORD (&value, reloc_addr, (int) reloc_addr & 3);
169 } while (--relative_count);
170 #undef COPY_UNALIGNED_WORD