aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2018-01-29 17:51:06 +0100
committerSverker Eriksson <[email protected]>2018-01-29 17:51:06 +0100
commit627a958104c50c9cb4a5022b29239b7d63fb5d76 (patch)
tree6cf86f9af7e585263c39ce08c0695d781dda0de7
parent84db627b0d7bbb581da1ddc192e5c85155a76a1f (diff)
downloadotp-627a958104c50c9cb4a5022b29239b7d63fb5d76.tar.gz
otp-627a958104c50c9cb4a5022b29239b7d63fb5d76.tar.bz2
otp-627a958104c50c9cb4a5022b29239b7d63fb5d76.zip
erts: Refactor hipe x86_64 trampolines
-rw-r--r--erts/emulator/hipe/hipe_amd64.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/erts/emulator/hipe/hipe_amd64.c b/erts/emulator/hipe/hipe_amd64.c
index bdeae23c7c..f23f341e6d 100644
--- a/erts/emulator/hipe/hipe_amd64.c
+++ b/erts/emulator/hipe/hipe_amd64.c
@@ -39,6 +39,8 @@
#undef ERL_FUN_SIZE
#include "hipe_literals.h"
+static void patch_trampoline(void *trampoline, void *destAddress);
+
const Uint sse2_fnegate_mask[2] = {0x8000000000000000,0};
void hipe_patch_load_fe(Uint64 *address, Uint64 value)
@@ -75,13 +77,12 @@ int hipe_patch_call(void *callAddress, void *destAddress, void *trampoline)
Sint64 destOffset = (Sint64)destAddress - (Sint64)callAddress - 4;
if ((destOffset < -0x80000000L) || (destOffset >= 0x80000000L)) {
- destOffset = ((Sint64)trampoline - 2) - (Sint64)callAddress - 4;
+ destOffset = (Sint64)trampoline - (Sint64)callAddress - 4;
if ((destOffset < -0x80000000L) || (destOffset >= 0x80000000L))
return -1;
- *(void**)trampoline = destAddress;
- hipe_flush_icache_word(trampoline);
+ patch_trampoline(trampoline, destAddress);
}
*(Uint32*)callAddress = (Uint32)destOffset;
@@ -139,15 +140,25 @@ static void generate_trampolines(unsigned char *address,
for(i = 0; i < nrcallees; ++i) {
trampoline[0] = 0x48; /* movabsq $..., %rax; */
trampoline[1] = 0xb8;
- *((Uint64*)(trampoline+2)) = 0; /* callee's address */
+ *(void**)(trampoline+2) = NULL; /* callee's address */
trampoline[10] = 0xff; /* jmpq *%rax */
trampoline[11] = 0xe0;
- trampvec[i] = trampoline+2;
+ trampvec[i] = trampoline;
trampoline += TRAMPOLINE_BYTES;
}
hipe_flush_icache_range(address, nrcallees*TRAMPOLINE_BYTES);
}
+static void patch_trampoline(void *trampoline, void *destAddress)
+{
+ unsigned char *tp = (unsigned char*) trampoline;
+
+ ASSERT(tp[0] == 0x48 && tp[1] == 0xb8);
+
+ *(void**)(tp+2) = destAddress; /* callee's address */
+ hipe_flush_icache_word(tp+2);
+}
+
void *hipe_alloc_code(Uint nrbytes, Eterm callees, Eterm *trampolines, Process *p)
{
int nrcallees;