13#include <asm-generic/unistd.h>
23static inline uint32_t MakeMovImmInstr(uint8_t reg, int32_t val) {
25 DS2ASSERT(0 <= val && val <= 65535);
26 static const uint32_t base = 0xd2800000;
27 return base | (
static_cast<uint16_t
>(val) << 5) | reg;
30static inline uint32_t MakeMovNegImmInstr(uint8_t reg, int32_t val) {
32 DS2ASSERT(-65535 <= val && val <= 0);
33 static const uint32_t base = 0x92800000;
34 return base | (
static_cast<uint16_t
>(-val - 1) << 5) | reg;
37static inline uint32_t MakeLdrRelInstr(uint8_t reg, int32_t offset) {
39 DS2ASSERT(offset % 4 == 0);
40 static const uint32_t base = 0x58000000;
41 return base | (
static_cast<uint16_t
>(offset / 4) << 5) | reg;
44static inline uint32_t MakeSvcInstr(uint16_t idx) {
45 static const uint32_t base = 0xd4000001;
46 return base | (idx << 5);
49static inline uint32_t MakeBrkInstr(uint16_t idx) {
50 static const uint32_t base = 0xd4200000;
51 return base | (idx << 5);
55static inline void InsertBytes(ByteVector &codestr, T value) {
56 auto valueBytes =
reinterpret_cast<uint8_t *
>(&value);
57 codestr.insert(codestr.end(), valueBytes, valueBytes +
sizeof(T));
61static inline void PrepareMmapCode(
size_t size,
int protection,
62 ByteVector &codestr) {
63 static_assert(
sizeof(size) == 8,
"size_t should be 8-bytes long on ARM64");
65 for (uint32_t instr : {
66 MakeMovImmInstr(8, __NR_mmap),
67 MakeMovImmInstr(0, 0),
68 MakeLdrRelInstr(1, 7 *
sizeof(uint32_t)),
69 MakeMovImmInstr(2, protection),
70 MakeMovImmInstr(3, MAP_ANON | MAP_PRIVATE),
71 MakeMovNegImmInstr(4, -1),
72 MakeMovImmInstr(5, 0),
76 InsertBytes(codestr, instr);
80 InsertBytes(codestr, size);
83static inline void PrepareMunmapCode(uint64_t address,
size_t size,
84 ByteVector &codestr) {
85 static_assert(
sizeof(size) == 8,
"size_t should be 8-bytes long on ARM64");
87 for (uint32_t instr : {
88 MakeMovImmInstr(8, __NR_munmap),
89 MakeLdrRelInstr(0, 4 *
sizeof(uint32_t)),
90 MakeLdrRelInstr(1, 5 *
sizeof(uint32_t)),
94 InsertBytes(codestr, instr);
98 InsertBytes(codestr, address);
99 InsertBytes(codestr, size);