summaryrefslogtreecommitdiff
path: root/ldso/ldso/arm/dl-sysdep.h
diff options
context:
space:
mode:
Diffstat (limited to 'ldso/ldso/arm/dl-sysdep.h')
-rw-r--r--ldso/ldso/arm/dl-sysdep.h18
1 files changed, 18 insertions, 0 deletions
diff --git a/ldso/ldso/arm/dl-sysdep.h b/ldso/ldso/arm/dl-sysdep.h
index 794c86a0c..194fd2eb7 100644
--- a/ldso/ldso/arm/dl-sysdep.h
+++ b/ldso/ldso/arm/dl-sysdep.h
@@ -85,7 +85,25 @@ elf_machine_load_address (void)
extern void __dl_start asm ("_dl_start");
Elf32_Addr got_addr = (Elf32_Addr) &__dl_start;
Elf32_Addr pcrel_addr;
+#if !defined __thumb__
asm ("adr %0, _dl_start" : "=r" (pcrel_addr));
+#else
+ int tmp;
+ /* The above adr will not work on thumb because it
+ * is negative. The only safe way is to temporarily
+ * swap to arm.
+ */
+ asm( ".align 2\n"
+ " bx pc\n"
+ " nop \n"
+ " .arm \n"
+ " adr %0, _dl_start\n"
+ " .align 2\n"
+ " orr %1, pc, #1\n"
+ " bx %1\n"
+ " .force_thumb\n"
+ : "=r" (pcrel_addr), "=&r" (tmp));
+#endif
return pcrel_addr - got_addr;
}