m68k: add NPTL/TLS support
[uclibc-ng.git] / ldso / ldso / m68k / dl-sysdep.h
blob21937b25976931d2a330e2fd301d089d5a80c2ca
1 /*
2 * Various assembly language/system dependent hacks that are required
3 * so that we can minimize the amount of platform specific code.
4 * Copyright (C) 2005 by Erik Andersen <andersen@codepoet.org>
5 */
7 /* Define this if the system uses RELOCA. */
8 #define ELF_USES_RELOCA
9 #include <elf.h>
10 /* Initialization sequence for a GOT. */
11 #define INIT_GOT(GOT_BASE,MODULE) \
12 do { \
13 GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \
14 GOT_BASE[1] = (unsigned long) (MODULE); \
15 } while(0)
17 /* Here we define the magic numbers that this dynamic loader should accept */
18 #define MAGIC1 EM_68K
19 #undef MAGIC2
21 /* Used for error messages */
22 #define ELF_TARGET "m68k"
24 /* Need bootstrap relocations */
25 #define ARCH_NEEDS_BOOTSTRAP_RELOCS
27 struct elf_resolve;
28 extern unsigned long _dl_linux_resolver (struct elf_resolve *, int);
30 /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
31 TLS variable, so undefined references should not be allowed to
32 define the value.
33 ELF_RTYPE_CLASS_COPY iff TYPE should not be allowed to resolve to one
34 of the main executable's symbols, as for a COPY reloc. */
35 #define elf_machine_type_class(type) \
36 ((((type) == R_68K_JMP_SLOT \
37 || (type) == R_68K_TLS_DTPMOD32 \
38 || (type) == R_68K_TLS_DTPREL32 \
39 || (type) == R_68K_TLS_TPREL32) * ELF_RTYPE_CLASS_PLT) \
40 | (((type) == R_68K_COPY) * ELF_RTYPE_CLASS_COPY))
42 /* Return the link-time address of _DYNAMIC. Conveniently, this is the
43 first element of the GOT. This must be inlined in a function which
44 uses global data. */
45 static __always_inline Elf32_Addr
46 elf_machine_dynamic (void)
48 Elf32_Addr got;
50 __asm__ ("move.l _DYNAMIC@GOT.w(%%a5), %0"
51 : "=a" (got));
52 return got;
55 #ifdef __mcoldfire__
56 #define PCREL_OP(OP, SRC, DST, TMP, PC) \
57 "move.l #" SRC " - ., " TMP "\n\t" OP " (-8, " PC ", " TMP "), " DST
58 #else
59 #define PCREL_OP(OP, SRC, DST, TMP, PC) \
60 OP " " SRC "(" PC "), " DST
61 #endif
63 /* Return the run-time load address of the shared object. */
64 static __always_inline Elf32_Addr
65 elf_machine_load_address (void)
67 Elf32_Addr addr;
68 __asm__ (PCREL_OP ("lea", "_dl_start", "%0", "%0", "%%pc") "\n\t"
69 "sub.l _dl_start@GOT.w(%%a5), %0"
70 : "=a" (addr));
71 return addr;
74 static __always_inline void
75 elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
76 Elf32_Word relative_count)
78 Elf32_Rela * rpnt = (void *)rel_addr;
79 --rpnt;
80 do {
81 Elf32_Addr *const reloc_addr = (void *) (load_off + (++rpnt)->r_offset);
83 *reloc_addr = load_off + rpnt->r_addend;
84 } while (--relative_count);