summaryrefslogtreecommitdiff
path: root/ldso/ldso/cris/dl-sysdep.h
diff options
context:
space:
mode:
Diffstat (limited to 'ldso/ldso/cris/dl-sysdep.h')
-rw-r--r--ldso/ldso/cris/dl-sysdep.h46
1 files changed, 45 insertions, 1 deletions
diff --git a/ldso/ldso/cris/dl-sysdep.h b/ldso/ldso/cris/dl-sysdep.h
index ab089072f..d12644a2d 100644
--- a/ldso/ldso/cris/dl-sysdep.h
+++ b/ldso/ldso/cris/dl-sysdep.h
@@ -1,6 +1,6 @@
/* CRIS can never use Elf32_Rel relocations. */
#define ELF_USES_RELOCA
-
+#include <elf.h>
/* Initialization sequence for the GOT. */
#define INIT_GOT(GOT_BASE,MODULE) \
{ \
@@ -75,3 +75,47 @@ cris_mod(unsigned long m, unsigned long p)
((((((type) == R_CRIS_JUMP_SLOT)) \
|| ((type) == R_CRIS_GLOB_DAT)) * ELF_RTYPE_CLASS_PLT) \
| (((type) == R_CRIS_COPY) * ELF_RTYPE_CLASS_COPY))
+
+static inline Elf32_Addr
+elf_machine_dynamic (void)
+{
+ /* Don't just set this to an asm variable "r0" since that's not logical
+ (like, the variable is uninitialized and the register is fixed) and
+ may make GCC trip over itself doing register allocation. Yes, I'm
+ paranoid. Why do you ask? */
+ Elf32_Addr *got;
+
+ __asm__ ("move.d $r0,%0" : "=rm" (got));
+ return *got;
+}
+
+/* Return the run-time load address of the shared object. We do it like
+ m68k and i386, by taking an arbitrary local symbol, forcing a GOT entry
+ for it, and peeking into the GOT table, which is set to the link-time
+ file-relative symbol value (regardless of whether the target is REL or
+ RELA). We subtract this link-time file-relative value from the "local"
+ value we calculate from GOT position and GOT offset. FIXME: Perhaps
+ there's some other symbol we could use, that we don't *have* to force a
+ GOT entry for. */
+
+static inline Elf32_Addr
+elf_machine_load_address (void)
+{
+ Elf32_Addr gotaddr_diff;
+ __asm__ ("sub.d [$r0+_dl_boot:GOT16],$r0,%0\n\t"
+ "add.d _dl_boot:GOTOFF,%0" : "=r" (gotaddr_diff));
+ return gotaddr_diff;
+}
+
+static inline void
+elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
+ Elf32_Word relative_count)
+{
+ Elf32_Rela * rpnt = (void *) (rel_addr + load_off);
+ --rpnt;
+ do {
+ Elf32_Addr *const reloc_addr = (void *) (load_off + (++rpnt)->r_offset);
+
+ *reloc_addr = load_off + rpnt->r_addend;
+ } while (--relative_count);
+}