]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/ldso/ldso/i386/dl-sysdep.h
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / ldso / ldso / i386 / dl-sysdep.h
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Various assembly language/system dependent hacks that are required
4  * so that we can minimize the amount of platform specific code.
5  * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
6  */
7
8 /* Define this if the system uses RELOCA.  */
9 #undef ELF_USES_RELOCA
10 #include <elf.h>
11 /* Initialization sequence for the GOT.  */
12 #define INIT_GOT(GOT_BASE,MODULE)                                                       \
13 do {                                                                                                            \
14         GOT_BASE[2] = (unsigned long) _dl_linux_resolve;                \
15         GOT_BASE[1] = (unsigned long) MODULE;                                   \
16 } while(0)
17
18 /* Here we define the magic numbers that this dynamic loader should accept */
19 #define MAGIC1 EM_386
20 #undef  MAGIC2
21
22 /* Used for error messages */
23 #define ELF_TARGET "386"
24
25 struct elf_resolve;
26 extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
27
28 /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
29    TLS variable, so undefined references should not be allowed to
30    define the value.
31    ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
32    of the main executable's symbols, as for a COPY reloc.  */
33 #define elf_machine_type_class(type) \
34   ((((type) == R_386_JMP_SLOT || (type) == R_386_TLS_DTPMOD32                 \
35      || (type) == R_386_TLS_DTPOFF32 || (type) == R_386_TLS_TPOFF32           \
36      || (type) == R_386_TLS_TPOFF) * ELF_RTYPE_CLASS_PLT)                                 \
37    | (((type) == R_386_COPY) * ELF_RTYPE_CLASS_COPY))
38
39 /* Return the link-time address of _DYNAMIC.  Conveniently, this is the
40    first element of the GOT.  This must be inlined in a function which
41    uses global data.  */
42 static __always_inline Elf32_Addr elf_machine_dynamic (void) attribute_unused;
43 static __always_inline Elf32_Addr
44 elf_machine_dynamic (void)
45 {
46         register Elf32_Addr *got __asm__ ("%ebx");
47         return *got;
48 }
49
50
51 /* Return the run-time load address of the shared object.  */
52 static __always_inline Elf32_Addr elf_machine_load_address (void) attribute_unused;
53 static __always_inline Elf32_Addr
54 elf_machine_load_address (void)
55 {
56         /* It doesn't matter what variable this is, the reference never makes
57            it to assembly.  We need a dummy reference to some global variable
58            via the GOT to make sure the compiler initialized %ebx in time.  */
59         Elf32_Addr addr;
60         int tmp;
61         __asm__ ("leal _dl_start@GOTOFF(%%ebx), %0\n"
62              "subl _dl_start@GOT(%%ebx), %0"
63              : "=r" (addr) : "m" (tmp) : "cc");
64         return addr;
65 }
66
67 static __always_inline void
68 elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
69                       Elf32_Word relative_count)
70 {
71         Elf32_Rel * rpnt = (void *) rel_addr;
72         --rpnt;
73         do {
74                 Elf32_Addr *const reloc_addr = (void *) (load_off + (++rpnt)->r_offset);
75
76                 *reloc_addr += load_off;
77         } while (--relative_count);
78 }