aboutsummaryrefslogtreecommitdiff
path: root/lib/arm64/jump-patch.h
blob: 0a276ba549b2427133f41d82bf11c18115532678 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#pragma once
#include "arm64/assemble.h"
#define MAX_JUMP_PATCH_SIZE 20

static inline int jump_patch_size(uintptr_t pc, uintptr_t dpc,
                                  UNUSED struct arch_dis_ctx arch,
                                  bool force) {
    intptr_t diff = (dpc & ~0xfff) - (pc & ~0xfff);
    if (!(diff >= -0x100000000 && diff < 0x100000000))
        return force ? (size_of_MOVi64(dpc) + 4) : -1;
    else if (!(dpc & 0xfff))
        return 8;
    else
        return 12;
}

static inline void make_jump_patch(void **codep, uintptr_t pc, uintptr_t dpc,
                                   struct arch_dis_ctx arch) {
    int reg = arm64_get_unwritten_temp_reg(&arch);
    intptr_t diff = (dpc & ~0xfff) - (pc & ~0xfff);
    if (!(diff >= -0x100000000 && diff < 0x100000000))
        MOVi64(codep, reg, dpc);
    else
        ADRP_ADD(codep, reg, pc, dpc);
    BR(codep, reg);
}