#endif
///--------------------------------------------------------------------------
-/// x86-specific hacking.
+/// Windows-specific hacking.
+
+#if ABI_WIN
#if CPUFAM_X86
+# define F(name) _##name
+#endif
+
+#endif
+
+///--------------------------------------------------------------------------
+/// x86- and amd64-specific hacking.
+///
+/// It's (slightly) easier to deal with both of these in one go.
+
+#if CPUFAM_X86 || CPUFAM_AMD64
// Set the function hooks.
#define FUNC_PREHOOK(_) .balign 16
// Maybe load GOT address into GOT.
.macro ldgot got=GOTREG
-#if WANT_PIC
+#if WANT_PIC && CPUFAM_X86
call _where_am_i.\got
add \got, offset _GLOBAL_OFFSET_TABLE_
#endif
// Maybe build a helper subroutine for `ldgot GOT'.
.macro gotaux got=GOTREG
-#if WANT_PIC
+#if WANT_PIC && CPUFAM_X86
.align 16
_where_am_i.\got :
mov \got, [esp]
// Load address of external symbol ADDR into REG, maybe using GOT.
.macro leaext reg, addr, got=GOTREG
#if WANT_PIC
+# if CPUFAM_X86
mov \reg, [\got + \addr@GOT]
+# endif
+# if CPUFAM_AMD64
+ mov \reg, \addr@GOTPCREL[rip]
+# endif
#else
+# if CPUFAM_X86
mov \reg, offset \addr
+# endif
+# if CPUFAM_AMD64
+ lea \reg, \addr[rip]
+# endif
#endif
.endm
// referring to ADDR, which is within our module, maybe using GOT.
#define INTADDR(...) INTADDR__0(__VA_ARGS__, GOTREG, dummy)
#define INTADDR__0(addr, got, ...) INTADDR__1(addr, got)
-#if WANT_PIC
+#if CPUFAM_AMD64
+# define INTADDR__1(addr, got) addr + rip
+#elif WANT_PIC
# define INTADDR__1(addr, got) got + addr@GOTOFF
#else
# define INTADDR__1(addr, got) addr
#endif
///--------------------------------------------------------------------------
+/// ARM-specific hacking.
+
+#if CPUFAM_ARM
+
+// Set the function hooks.
+#define FUNC_PREHOOK(_) .balign 4
+#define ENDFUNC_HOOK(name) .ltorg
+
+// Call external subroutine at ADDR, possibly via PLT.
+ .macro callext addr, cond=
+#if WANT_PIC
+ bl\cond \addr(PLT)
+#else
+ bl\cond \addr
+#endif
+ .endm
+
+// Do I need to arrange a spare GOT register?
+#if WANT_PIC
+# define NEED_GOT 1
+#endif
+#define GOTREG r9
+
+// Maybe load GOT address into GOT.
+ .macro ldgot got=r9
+#if WANT_PIC
+ ldr \got, =_GLOBAL_OFFSET_TABLE_ - . - 12
+ add \got, pc, \got
+#endif
+ .endm
+
+// Load address of external symbol ADDR into REG, maybe using GOT.
+ .macro leaext reg, addr, cond=, got=GOTREG
+#if WANT_PIC
+ ldr \reg, =\addr(GOT)
+ ldr \reg, [\got, \reg]
+#else
+ ldr \reg, =\addr
+#endif
+ .endm
+
+#endif
+
+///--------------------------------------------------------------------------
/// Final stuff.
// Default values for the various hooks.