[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 07/10] tcg: implement bulletproof JIT
From: |
Joelle van Dyne |
Subject: |
Re: [PATCH 07/10] tcg: implement bulletproof JIT |
Date: |
Wed, 14 Oct 2020 09:03:26 -0700 |
Hi Philippe,
Will work on splitting the patch for v2. Thanks for the tip on git.orderfile
Hi Balaton,
Reply inline.
-j
On Tue, Oct 13, 2020 at 7:58 AM BALATON Zoltan <balaton@eik.bme.hu> wrote:
>
> On Mon, 12 Oct 2020, Joelle van Dyne wrote:
> > From: osy <osy86@users.noreply.github.com>
> >
> > On iOS, we cannot allocate RWX pages without special entitlements. As a
> > workaround, we can a RX region and then mirror map it to a separate RX
>
> Missing a verb here: "we can a RX region"
Good catch.
>
> > region. Then we can write to one region and execute from the other one.
> >
> > To better keep track of pointers to RW/RX memory, we mark any tcg_insn_unit
> > pointers as `const` if they will never be written to. We also define a new
> > macro `TCG_CODE_PTR_RW` that returns a pointer to RW memory. Only the
> > difference between the two regions is stored in the TCG context.
>
> Maybe it's easier to review if constification is split off as separate
> patch before other changes.
Will do.
>
> > To ensure cache coherency, we flush the data cache in the RW mapping and
> > then invalidate the instruction cache in the RX mapping (where applicable).
> > Because data cache flush is OS defined on some architectures, we do not
> > provide implementations for non iOS platforms (ARM/x86).
> >
> > Signed-off-by: Joelle van Dyne <j@getutm.app>
> > ---
> > accel/tcg/cpu-exec.c | 7 +++-
> > accel/tcg/translate-all.c | 78 ++++++++++++++++++++++++++++++++++--
> > configure | 1 +
> > docs/devel/ios.rst | 40 ++++++++++++++++++
> > include/exec/exec-all.h | 8 ++++
> > include/tcg/tcg.h | 18 +++++++--
> > tcg/aarch64/tcg-target.c.inc | 48 +++++++++++++---------
> > tcg/aarch64/tcg-target.h | 13 +++++-
> > tcg/arm/tcg-target.c.inc | 33 ++++++++-------
> > tcg/arm/tcg-target.h | 9 ++++-
> > tcg/i386/tcg-target.c.inc | 28 ++++++-------
> > tcg/i386/tcg-target.h | 24 ++++++++++-
> > tcg/mips/tcg-target.c.inc | 64 +++++++++++++++++------------
> > tcg/mips/tcg-target.h | 8 +++-
> > tcg/ppc/tcg-target.c.inc | 55 ++++++++++++++++---------
> > tcg/ppc/tcg-target.h | 8 +++-
> > tcg/riscv/tcg-target.c.inc | 51 +++++++++++++----------
> > tcg/riscv/tcg-target.h | 9 ++++-
> > tcg/s390/tcg-target.c.inc | 25 ++++++------
> > tcg/s390/tcg-target.h | 13 +++++-
> > tcg/sparc/tcg-target.c.inc | 33 +++++++++------
> > tcg/sparc/tcg-target.h | 8 +++-
> > tcg/tcg-ldst.c.inc | 2 +-
> > tcg/tcg-pool.c.inc | 9 +++--
> > tcg/tcg.c | 60 +++++++++++++++++----------
> > tcg/tci/tcg-target.c.inc | 8 ++--
> > tcg/tci/tcg-target.h | 9 ++++-
> > 27 files changed, 481 insertions(+), 188 deletions(-)
> > create mode 100644 docs/devel/ios.rst
> >
> > diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
> > index 58aea605d8..821aefdea2 100644
> > --- a/accel/tcg/cpu-exec.c
> > +++ b/accel/tcg/cpu-exec.c
> > @@ -354,7 +354,12 @@ void tb_set_jmp_target(TranslationBlock *tb, int n,
> > uintptr_t addr)
> > if (TCG_TARGET_HAS_direct_jump) {
> > uintptr_t offset = tb->jmp_target_arg[n];
> > uintptr_t tc_ptr = (uintptr_t)tb->tc.ptr;
> > - tb_target_set_jmp_target(tc_ptr, tc_ptr + offset, addr);
> > +#if defined(CONFIG_IOS_JIT)
> > + uintptr_t wr_addr = tc_ptr + offset + tb->code_rw_mirror_diff;
> > +#else
> > + uintptr_t wr_addr = tc_ptr + offset;
> > +#endif
> > + tb_target_set_jmp_target(tc_ptr, tc_ptr + offset, addr, wr_addr);
> > } else {
> > tb->jmp_target_arg[n] = addr;
> > }
> > diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
> > index d76097296d..76d8dc3d7b 100644
> > --- a/accel/tcg/translate-all.c
> > +++ b/accel/tcg/translate-all.c
> > @@ -60,6 +60,22 @@
> > #include "sysemu/cpu-timers.h"
> > #include "sysemu/tcg.h"
> >
> > +#if defined(CONFIG_IOS_JIT)
> > +#include <mach/mach.h>
> > +extern kern_return_t mach_vm_remap(vm_map_t target_task,
> > + mach_vm_address_t *target_address,
> > + mach_vm_size_t size,
> > + mach_vm_offset_t mask,
> > + int flags,
> > + vm_map_t src_task,
> > + mach_vm_address_t src_address,
> > + boolean_t copy,
> > + vm_prot_t *cur_protection,
> > + vm_prot_t *max_protection,
> > + vm_inherit_t inheritance
> > + );
> > +#endif
> > +
> > /* #define DEBUG_TB_INVALIDATE */
> > /* #define DEBUG_TB_FLUSH */
> > /* make various TB consistency checks */
> > @@ -302,10 +318,13 @@ static target_long decode_sleb128(uint8_t **pp)
> >
> > static int encode_search(TranslationBlock *tb, uint8_t *block)
> > {
> > - uint8_t *highwater = tcg_ctx->code_gen_highwater;
> > - uint8_t *p = block;
> > + uint8_t *highwater;
> > + uint8_t *p;
> > int i, j, n;
> >
> > + highwater = (uint8_t *)TCG_CODE_PTR_RW(tcg_ctx,
> > + tcg_ctx->code_gen_highwater);
> > + p = (uint8_t *)TCG_CODE_PTR_RW(tcg_ctx, block);
>
> Why do you need explicit casts here? Can this be avoided by using
> appropriate type or within the macro (I haven't checked this at all just
> dislike casts as they can hide problems otherwise caught by the compiler).
There's the choice between tcg_insn_unit * and uint8_t *. Since it's
used much more widely in tcg-target.inc.c, it seemed like
tcg_insn_unit * was a better choice.
>
> Regards,
> BALATON Zoltan
>
> > for (i = 0, n = tb->icount; i < n; ++i) {
> > target_ulong prev;
> >
> > @@ -329,7 +348,7 @@ static int encode_search(TranslationBlock *tb, uint8_t
> > *block)
> > }
> > }
> >
> > - return p - block;
> > + return p - (uint8_t *)TCG_CODE_PTR_RW(tcg_ctx, block);
> > }
> >
> > /* The cpu state corresponding to 'searched_pc' is restored.
> > @@ -1067,7 +1086,11 @@ static inline void *alloc_code_gen_buffer(void)
> > #else
> > static inline void *alloc_code_gen_buffer(void)
> > {
> > +#if defined(CONFIG_IOS_JIT)
> > + int prot = PROT_READ | PROT_EXEC;
> > +#else
> > int prot = PROT_WRITE | PROT_READ | PROT_EXEC;
> > +#endif
> > int flags = MAP_PRIVATE | MAP_ANONYMOUS;
> > size_t size = tcg_ctx->code_gen_buffer_size;
> > void *buf;
> > @@ -1118,6 +1141,39 @@ static inline void *alloc_code_gen_buffer(void)
> > }
> > #endif /* USE_STATIC_CODE_GEN_BUFFER, WIN32, POSIX */
> >
> > +#if defined(CONFIG_IOS_JIT)
> > +static inline void *alloc_jit_rw_mirror(void *base, size_t size)
> > +{
> > + kern_return_t ret;
> > + mach_vm_address_t mirror;
> > + vm_prot_t cur_prot, max_prot;
> > +
> > + mirror = 0;
> > + ret = mach_vm_remap(mach_task_self(),
> > + &mirror,
> > + size,
> > + 0,
> > + VM_FLAGS_ANYWHERE | VM_FLAGS_RANDOM_ADDR,
> > + mach_task_self(),
> > + (mach_vm_address_t)base,
> > + false,
> > + &cur_prot,
> > + &max_prot,
> > + VM_INHERIT_NONE
> > + );
> > + if (ret != KERN_SUCCESS) {
> > + return NULL;
> > + }
> > +
> > + if (mprotect((void *)mirror, size, PROT_READ | PROT_WRITE) != 0) {
> > + munmap((void *)mirror, size);
> > + return NULL;
> > + }
> > +
> > + return (void *)mirror;
> > +}
> > +#endif /* CONFIG_IOS_JIT */
> > +
> > static inline void code_gen_alloc(size_t tb_size)
> > {
> > tcg_ctx->code_gen_buffer_size = size_code_gen_buffer(tb_size);
> > @@ -1126,6 +1182,19 @@ static inline void code_gen_alloc(size_t tb_size)
> > fprintf(stderr, "Could not allocate dynamic translator buffer\n");
> > exit(1);
> > }
> > +#if defined(CONFIG_IOS_JIT)
> > + void *mirror;
> > +
> > + /* For iOS JIT we need a mirror mapping for code execution */
> > + mirror = alloc_jit_rw_mirror(tcg_ctx->code_gen_buffer,
> > + tcg_ctx->code_gen_buffer_size
> > + );
> > + if (mirror == NULL) {
> > + fprintf(stderr, "Could not remap code buffer mirror\n");
> > + exit(1);
> > + }
> > + tcg_ctx->code_rw_mirror_diff = mirror - tcg_ctx->code_gen_buffer;
> > +#endif /* CONFIG_IOS_JIT */
> > }
> >
> > static bool tb_cmp(const void *ap, const void *bp)
> > @@ -1721,6 +1790,9 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
> > cpu_loop_exit(cpu);
> > }
> >
> > +#if defined(CONFIG_IOS_JIT)
> > + tb->code_rw_mirror_diff = tcg_ctx->code_rw_mirror_diff;
> > +#endif
> > gen_code_buf = tcg_ctx->code_gen_ptr;
> > tb->tc.ptr = gen_code_buf;
> > tb->pc = pc;
> > diff --git a/configure b/configure
> > index 16c66b437c..c5a6584683 100755
> > --- a/configure
> > +++ b/configure
> > @@ -6220,6 +6220,7 @@ fi
> >
> > if test "$ios" = "yes" ; then
> > echo "CONFIG_IOS=y" >> $config_host_mak
> > + echo "CONFIG_IOS_JIT=y" >> $config_host_mak
> > fi
> >
> > if test "$solaris" = "yes" ; then
> > diff --git a/docs/devel/ios.rst b/docs/devel/ios.rst
> > new file mode 100644
> > index 0000000000..dba9fdd868
> > --- /dev/null
> > +++ b/docs/devel/ios.rst
> > @@ -0,0 +1,40 @@
> > +===========
> > +iOS Support
> > +===========
> > +
> > +To run qemu on the iOS platform, some modifications were required. Most of
> > the
> > +modifications are conditioned on the ``CONFIG_IOS`` and ``CONFIG_IOS_JIT``
> > +configuration variables.
> > +
> > +Build support
> > +-------------
> > +
> > +For the code to compile, certain changes in the block driver and the slirp
> > +driver had to be made. There is no ``system()`` call, so code requiring it
> > had
> > +to be disabled.
> > +
> > +``ucontext`` support is broken on iOS. The implementation from
> > ``libucontext``
> > +is used instead.
> > +
> > +Because ``fork()`` is not allowed on iOS apps, the option to build qemu
> > and the
> > +utilities as shared libraries is added. Note that because qemu does not
> > perform
> > +resource cleanup in most cases (open files, allocated memory, etc), it is
> > +advisable that the user implements a proxy layer for syscalls so resources
> > can
> > +be kept track by the app that uses qemu as a shared library.
> > +
> > +JIT support
> > +-----------
> > +
> > +On iOS, allocating RWX pages require special entitlements not usually
> > granted to
> > +apps. However, it is possible to use `bulletproof JIT`_ with a development
> > +certificate. This means that we need to allocate one chunk of memory with
> > RX
> > +permissions and then mirror map the same memory with RW permissions. We
> > generate
> > +code to the mirror mapping and execute the original mapping.
> > +
> > +With ``CONFIG_IOS_JIT`` defined, we store inside the TCG context the
> > difference
> > +between the two mappings. Then, we make sure that any writes to JIT memory
> > is
> > +done to the pointer + the difference (in order to get a pointer to the
> > mirror
> > +mapped space). Additionally, we make sure to flush the data cache before we
> > +invalidate the instruction cache so the changes are seen in both mappings.
> > +
> > +.. _bulletproof JIT:
> > https://www.blackhat.com/docs/us-16/materials/us-16-Krstic.pdf
> > diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
> > index 66f9b4cca6..2db155a772 100644
> > --- a/include/exec/exec-all.h
> > +++ b/include/exec/exec-all.h
> > @@ -483,6 +483,14 @@ struct TranslationBlock {
> > uintptr_t jmp_list_head;
> > uintptr_t jmp_list_next[2];
> > uintptr_t jmp_dest[2];
> > +
> > +#if defined(CONFIG_IOS_JIT)
> > + /*
> > + * Store difference to writable mirror
> > + * We need this when patching the jump instructions
> > + */
> > + ptrdiff_t code_rw_mirror_diff;
> > +#endif
> > };
> >
> > extern bool parallel_cpus;
> > diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
> > index 8804a8c4a2..40d1a7a85e 100644
> > --- a/include/tcg/tcg.h
> > +++ b/include/tcg/tcg.h
> > @@ -261,7 +261,7 @@ struct TCGLabel {
> > unsigned refs : 16;
> > union {
> > uintptr_t value;
> > - tcg_insn_unit *value_ptr;
> > + const tcg_insn_unit *value_ptr;
> > } u;
> > QSIMPLEQ_HEAD(, TCGRelocation) relocs;
> > QSIMPLEQ_ENTRY(TCGLabel) next;
> > @@ -593,7 +593,7 @@ struct TCGContext {
> > int nb_ops;
> >
> > /* goto_tb support */
> > - tcg_insn_unit *code_buf;
> > + const tcg_insn_unit *code_buf;
> > uint16_t *tb_jmp_reset_offset; /* tb->jmp_reset_offset */
> > uintptr_t *tb_jmp_insn_offset; /* tb->jmp_target_arg if direct_jump */
> > uintptr_t *tb_jmp_target_addr; /* tb->jmp_target_arg if !direct_jump */
> > @@ -627,6 +627,9 @@ struct TCGContext {
> > size_t code_gen_buffer_size;
> > void *code_gen_ptr;
> > void *data_gen_ptr;
> > +#if defined(CONFIG_IOS_JIT)
> > + ptrdiff_t code_rw_mirror_diff;
> > +#endif
> >
> > /* Threshold to flush the translated code buffer. */
> > void *code_gen_highwater;
> > @@ -677,6 +680,13 @@ struct TCGContext {
> > target_ulong gen_insn_data[TCG_MAX_INSNS][TARGET_INSN_START_WORDS];
> > };
> >
> > +#if defined(CONFIG_IOS_JIT)
> > +# define TCG_CODE_PTR_RW(s, code_ptr) \
> > + (tcg_insn_unit *)((uintptr_t)(code_ptr) + (s)->code_rw_mirror_diff)
> > +#else
> > +# define TCG_CODE_PTR_RW(s, code_ptr) (code_ptr)
> > +#endif
> > +
> > extern TCGContext tcg_init_ctx;
> > extern __thread TCGContext *tcg_ctx;
> > extern TCGv_env cpu_env;
> > @@ -1099,7 +1109,7 @@ static inline TCGLabel *arg_label(TCGArg i)
> > * correct result.
> > */
> >
> > -static inline ptrdiff_t tcg_ptr_byte_diff(void *a, void *b)
> > +static inline ptrdiff_t tcg_ptr_byte_diff(const void *a, const void *b)
> > {
> > return a - b;
> > }
> > @@ -1113,7 +1123,7 @@ static inline ptrdiff_t tcg_ptr_byte_diff(void *a,
> > void *b)
> > * to the destination address.
> > */
> >
> > -static inline ptrdiff_t tcg_pcrel_diff(TCGContext *s, void *target)
> > +static inline ptrdiff_t tcg_pcrel_diff(TCGContext *s, const void *target)
> > {
> > return tcg_ptr_byte_diff(target, s->code_ptr);
> > }
> > diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
> > index 26f71cb599..9cfa2703b3 100644
> > --- a/tcg/aarch64/tcg-target.c.inc
> > +++ b/tcg/aarch64/tcg-target.c.inc
> > @@ -78,38 +78,44 @@ static const int tcg_target_call_oarg_regs[1] = {
> > #define TCG_REG_GUEST_BASE TCG_REG_X28
> > #endif
> >
> > -static inline bool reloc_pc26(tcg_insn_unit *code_ptr, tcg_insn_unit
> > *target)
> > +static inline bool reloc_pc26(TCGContext *s,
> > + tcg_insn_unit *code_ptr,
> > + const tcg_insn_unit *target)
> > {
> > ptrdiff_t offset = target - code_ptr;
> > if (offset == sextract64(offset, 0, 26)) {
> > /* read instruction, mask away previous PC_REL26 parameter contents,
> > set the proper offset, then write back the instruction. */
> > - *code_ptr = deposit32(*code_ptr, 0, 26, offset);
> > + *TCG_CODE_PTR_RW(s, code_ptr) =
> > + deposit32(*TCG_CODE_PTR_RW(s, code_ptr), 0, 26, offset);
> > return true;
> > }
> > return false;
> > }
> >
> > -static inline bool reloc_pc19(tcg_insn_unit *code_ptr, tcg_insn_unit
> > *target)
> > +static inline bool reloc_pc19(TCGContext *s,
> > + tcg_insn_unit *code_ptr,
> > + const tcg_insn_unit *target)
> > {
> > ptrdiff_t offset = target - code_ptr;
> > if (offset == sextract64(offset, 0, 19)) {
> > - *code_ptr = deposit32(*code_ptr, 5, 19, offset);
> > + *TCG_CODE_PTR_RW(s, code_ptr) =
> > + deposit32(*TCG_CODE_PTR_RW(s, code_ptr), 5, 19, offset);
> > return true;
> > }
> > return false;
> > }
> >
> > -static inline bool patch_reloc(tcg_insn_unit *code_ptr, int type,
> > +static inline bool patch_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int
> > type,
> > intptr_t value, intptr_t addend)
> > {
> > tcg_debug_assert(addend == 0);
> > switch (type) {
> > case R_AARCH64_JUMP26:
> > case R_AARCH64_CALL26:
> > - return reloc_pc26(code_ptr, (tcg_insn_unit *)value);
> > + return reloc_pc26(s, code_ptr, (tcg_insn_unit *)value);
> > case R_AARCH64_CONDBR19:
> > - return reloc_pc19(code_ptr, (tcg_insn_unit *)value);
> > + return reloc_pc19(s, code_ptr, (tcg_insn_unit *)value);
> > default:
> > g_assert_not_reached();
> > }
> > @@ -1306,14 +1312,14 @@ static void tcg_out_cmp(TCGContext *s, TCGType ext,
> > TCGReg a,
> > }
> > }
> >
> > -static inline void tcg_out_goto(TCGContext *s, tcg_insn_unit *target)
> > +static inline void tcg_out_goto(TCGContext *s, const tcg_insn_unit *target)
> > {
> > ptrdiff_t offset = target - s->code_ptr;
> > tcg_debug_assert(offset == sextract64(offset, 0, 26));
> > tcg_out_insn(s, 3206, B, offset);
> > }
> >
> > -static inline void tcg_out_goto_long(TCGContext *s, tcg_insn_unit *target)
> > +static inline void tcg_out_goto_long(TCGContext *s, const tcg_insn_unit
> > *target)
> > {
> > ptrdiff_t offset = target - s->code_ptr;
> > if (offset == sextract64(offset, 0, 26)) {
> > @@ -1329,7 +1335,7 @@ static inline void tcg_out_callr(TCGContext *s,
> > TCGReg reg)
> > tcg_out_insn(s, 3207, BLR, reg);
> > }
> >
> > -static inline void tcg_out_call(TCGContext *s, tcg_insn_unit *target)
> > +static inline void tcg_out_call(TCGContext *s, const tcg_insn_unit *target)
> > {
> > ptrdiff_t offset = target - s->code_ptr;
> > if (offset == sextract64(offset, 0, 26)) {
> > @@ -1341,7 +1347,7 @@ static inline void tcg_out_call(TCGContext *s,
> > tcg_insn_unit *target)
> > }
> >
> > void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
> > - uintptr_t addr)
> > + uintptr_t addr, uintptr_t wr_addr)
> > {
> > tcg_insn_unit i1, i2;
> > TCGType rt = TCG_TYPE_I64;
> > @@ -1362,7 +1368,10 @@ void tb_target_set_jmp_target(uintptr_t tc_ptr,
> > uintptr_t jmp_addr,
> > i2 = I3401_ADDI | rt << 31 | (addr & 0xfff) << 10 | rd << 5 | rd;
> > }
> > pair = (uint64_t)i2 << 32 | i1;
> > - qatomic_set((uint64_t *)jmp_addr, pair);
> > + qatomic_set((uint64_t *)wr_addr, pair);
> > +#if defined(CONFIG_IOS_JIT)
> > + flush_dcache_range(wr_addr, wr_addr + 8);
> > +#endif
> > flush_icache_range(jmp_addr, jmp_addr + 8);
> > }
> >
> > @@ -1568,7 +1577,7 @@ static void * const qemu_st_helpers[16] = {
> > [MO_BEQ] = helper_be_stq_mmu,
> > };
> >
> > -static inline void tcg_out_adr(TCGContext *s, TCGReg rd, void *target)
> > +static inline void tcg_out_adr(TCGContext *s, TCGReg rd, const void
> > *target)
> > {
> > ptrdiff_t offset = tcg_pcrel_diff(s, target);
> > tcg_debug_assert(offset == sextract64(offset, 0, 21));
> > @@ -1581,7 +1590,7 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s,
> > TCGLabelQemuLdst *lb)
> > MemOp opc = get_memop(oi);
> > MemOp size = opc & MO_SIZE;
> >
> > - if (!reloc_pc19(lb->label_ptr[0], s->code_ptr)) {
> > + if (!reloc_pc19(s, lb->label_ptr[0], s->code_ptr)) {
> > return false;
> > }
> >
> > @@ -1606,7 +1615,7 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s,
> > TCGLabelQemuLdst *lb)
> > MemOp opc = get_memop(oi);
> > MemOp size = opc & MO_SIZE;
> >
> > - if (!reloc_pc19(lb->label_ptr[0], s->code_ptr)) {
> > + if (!reloc_pc19(s, lb->label_ptr[0], s->code_ptr)) {
> > return false;
> > }
> >
> > @@ -1622,7 +1631,8 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s,
> > TCGLabelQemuLdst *lb)
> >
> > static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
> > TCGType ext, TCGReg data_reg, TCGReg
> > addr_reg,
> > - tcg_insn_unit *raddr, tcg_insn_unit
> > *label_ptr)
> > + const tcg_insn_unit *raddr,
> > + tcg_insn_unit *label_ptr)
> > {
> > TCGLabelQemuLdst *label = new_ldst_label(s);
> >
> > @@ -1849,7 +1859,7 @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg
> > data_reg, TCGReg addr_reg,
> > #endif /* CONFIG_SOFTMMU */
> > }
> >
> > -static tcg_insn_unit *tb_ret_addr;
> > +static const tcg_insn_unit *tb_ret_addr;
> >
> > static void tcg_out_op(TCGContext *s, TCGOpcode opc,
> > const TCGArg args[TCG_MAX_OP_ARGS],
> > @@ -2916,11 +2926,11 @@ static void tcg_target_qemu_prologue(TCGContext *s)
> > tcg_out_insn(s, 3207, RET, TCG_REG_LR);
> > }
> >
> > -static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
> > +static void tcg_out_nop_fill(TCGContext *s, tcg_insn_unit *p, int count)
> > {
> > int i;
> > for (i = 0; i < count; ++i) {
> > - p[i] = NOP;
> > + (TCG_CODE_PTR_RW(s, p))[i] = NOP;
> > }
> > }
> >
> > diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
> > index a2b22b4305..78c97460a1 100644
> > --- a/tcg/aarch64/tcg-target.h
> > +++ b/tcg/aarch64/tcg-target.h
> > @@ -150,6 +150,7 @@ typedef enum {
> >
> > #if defined(__APPLE__)
> > void sys_icache_invalidate(void *start, size_t len);
> > +void sys_dcache_flush(void *start, size_t len);
> > #endif
> >
> > static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
> > @@ -163,7 +164,17 @@ static inline void flush_icache_range(uintptr_t start,
> > uintptr_t stop)
> > #endif
> > }
> >
> > -void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t);
> > +void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
> > +#if defined(CONFIG_IOS_JIT)
> > +static inline void flush_dcache_range(uintptr_t start, uintptr_t stop)
> > +{
> > +#if defined(__APPLE__)
> > + sys_dcache_flush((char *)start, stop - start);
> > +#else
> > +#error "Missing function to flush data cache"
> > +#endif
> > +}
> > +#endif
> >
> > #ifdef CONFIG_SOFTMMU
> > #define TCG_TARGET_NEED_LDST_LABELS
> > diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
> > index 62c37a954b..d27ad851b5 100644
> > --- a/tcg/arm/tcg-target.c.inc
> > +++ b/tcg/arm/tcg-target.c.inc
> > @@ -187,17 +187,22 @@ static const uint8_t tcg_cond_to_arm_cond[] = {
> > [TCG_COND_GTU] = COND_HI,
> > };
> >
> > -static inline bool reloc_pc24(tcg_insn_unit *code_ptr, tcg_insn_unit
> > *target)
> > +static inline bool reloc_pc24(TCGContext *s,
> > + tcg_insn_unit *code_ptr,
> > + const tcg_insn_unit *target)
> > {
> > ptrdiff_t offset = (tcg_ptr_byte_diff(target, code_ptr) - 8) >> 2;
> > if (offset == sextract32(offset, 0, 24)) {
> > - *code_ptr = (*code_ptr & ~0xffffff) | (offset & 0xffffff);
> > + *TCG_CODE_PTR_RW(s, code_ptr) =
> > + (*TCG_CODE_PTR_RW(s, code_ptr) & ~0xffffff) | (offset &
> > 0xffffff);
> > return true;
> > }
> > return false;
> > }
> >
> > -static inline bool reloc_pc13(tcg_insn_unit *code_ptr, tcg_insn_unit
> > *target)
> > +static inline bool reloc_pc13(TCGContext *s,
> > + tcg_insn_unit *code_ptr,
> > + const tcg_insn_unit *target)
> > {
> > ptrdiff_t offset = tcg_ptr_byte_diff(target, code_ptr) - 8;
> >
> > @@ -209,21 +214,21 @@ static inline bool reloc_pc13(tcg_insn_unit
> > *code_ptr, tcg_insn_unit *target)
> > }
> > insn = deposit32(insn, 23, 1, u);
> > insn = deposit32(insn, 0, 12, offset);
> > - *code_ptr = insn;
> > + *TCG_CODE_PTR_RW(s, code_ptr) = insn;
> > return true;
> > }
> > return false;
> > }
> >
> > -static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
> > +static bool patch_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type,
> > intptr_t value, intptr_t addend)
> > {
> > tcg_debug_assert(addend == 0);
> >
> > if (type == R_ARM_PC24) {
> > - return reloc_pc24(code_ptr, (tcg_insn_unit *)value);
> > + return reloc_pc24(s, code_ptr, (tcg_insn_unit *)value);
> > } else if (type == R_ARM_PC13) {
> > - return reloc_pc13(code_ptr, (tcg_insn_unit *)value);
> > + return reloc_pc13(s, code_ptr, (tcg_insn_unit *)value);
> > } else {
> > g_assert_not_reached();
> > }
> > @@ -1019,7 +1024,7 @@ static inline void tcg_out_st8(TCGContext *s, int
> > cond,
> > * with the code buffer limited to 16MB we wouldn't need the long case.
> > * But we also use it for the tail-call to the qemu_ld/st helpers, which
> > does.
> > */
> > -static void tcg_out_goto(TCGContext *s, int cond, tcg_insn_unit *addr)
> > +static void tcg_out_goto(TCGContext *s, int cond, const tcg_insn_unit
> > *addr)
> > {
> > intptr_t addri = (intptr_t)addr;
> > ptrdiff_t disp = tcg_pcrel_diff(s, addr);
> > @@ -1033,7 +1038,7 @@ static void tcg_out_goto(TCGContext *s, int cond,
> > tcg_insn_unit *addr)
> >
> > /* The call case is mostly used for helpers - so it's not unreasonable
> > * for them to be beyond branch range */
> > -static void tcg_out_call(TCGContext *s, tcg_insn_unit *addr)
> > +static void tcg_out_call(TCGContext *s, const tcg_insn_unit *addr)
> > {
> > intptr_t addri = (intptr_t)addr;
> > ptrdiff_t disp = tcg_pcrel_diff(s, addr);
> > @@ -1326,7 +1331,7 @@ static TCGReg tcg_out_tlb_read(TCGContext *s, TCGReg
> > addrlo, TCGReg addrhi,
> > helper code. */
> > static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
> > TCGReg datalo, TCGReg datahi, TCGReg addrlo,
> > - TCGReg addrhi, tcg_insn_unit *raddr,
> > + TCGReg addrhi, const tcg_insn_unit *raddr,
> > tcg_insn_unit *label_ptr)
> > {
> > TCGLabelQemuLdst *label = new_ldst_label(s);
> > @@ -1348,7 +1353,7 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s,
> > TCGLabelQemuLdst *lb)
> > MemOp opc = get_memop(oi);
> > void *func;
> >
> > - if (!reloc_pc24(lb->label_ptr[0], s->code_ptr)) {
> > + if (!reloc_pc24(s, lb->label_ptr[0], s->code_ptr)) {
> > return false;
> > }
> >
> > @@ -1411,7 +1416,7 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s,
> > TCGLabelQemuLdst *lb)
> > TCGMemOpIdx oi = lb->oi;
> > MemOp opc = get_memop(oi);
> >
> > - if (!reloc_pc24(lb->label_ptr[0], s->code_ptr)) {
> > + if (!reloc_pc24(s, lb->label_ptr[0], s->code_ptr)) {
> > return false;
> > }
> >
> > @@ -2255,11 +2260,11 @@ static inline void tcg_out_movi(TCGContext *s,
> > TCGType type,
> > tcg_out_movi32(s, COND_AL, ret, arg);
> > }
> >
> > -static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
> > +static void tcg_out_nop_fill(TCGContext *s, tcg_insn_unit *p, int count)
> > {
> > int i;
> > for (i = 0; i < count; ++i) {
> > - p[i] = INSN_NOP;
> > + (TCG_CODE_PTR_RW(s, p))[i] = INSN_NOP;
> > }
> > }
> >
> > diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
> > index 17e771374d..d8d7e7e239 100644
> > --- a/tcg/arm/tcg-target.h
> > +++ b/tcg/arm/tcg-target.h
> > @@ -139,8 +139,15 @@ static inline void flush_icache_range(uintptr_t start,
> > uintptr_t stop)
> > __builtin___clear_cache((char *) start, (char *) stop);
> > }
> >
> > +#if defined(CONFIG_IOS_JIT)
> > +static inline void flush_dcache_range(uintptr_t start, uintptr_t stop)
> > +{
> > +#error "Unimplemented dcache flush function"
> > +}
> > +#endif
> > +
> > /* not defined -- call should be eliminated at compile time */
> > -void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t);
> > +void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
> >
> > #ifdef CONFIG_SOFTMMU
> > #define TCG_TARGET_NEED_LDST_LABELS
> > diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
> > index d8797ed398..e9c128d9e7 100644
> > --- a/tcg/i386/tcg-target.c.inc
> > +++ b/tcg/i386/tcg-target.c.inc
> > @@ -165,9 +165,9 @@ static bool have_lzcnt;
> > # define have_lzcnt 0
> > #endif
> >
> > -static tcg_insn_unit *tb_ret_addr;
> > +static const tcg_insn_unit *tb_ret_addr;
> >
> > -static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
> > +static bool patch_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type,
> > intptr_t value, intptr_t addend)
> > {
> > value += addend;
> > @@ -179,14 +179,14 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int
> > type,
> > }
> > /* FALLTHRU */
> > case R_386_32:
> > - tcg_patch32(code_ptr, value);
> > + tcg_patch32(s, code_ptr, value);
> > break;
> > case R_386_PC8:
> > value -= (uintptr_t)code_ptr;
> > if (value != (int8_t)value) {
> > return false;
> > }
> > - tcg_patch8(code_ptr, value);
> > + tcg_patch8(s, code_ptr, value);
> > break;
> > default:
> > tcg_abort();
> > @@ -1591,7 +1591,7 @@ static void tcg_out_clz(TCGContext *s, int rexw,
> > TCGReg dest, TCGReg arg1,
> > }
> > }
> >
> > -static void tcg_out_branch(TCGContext *s, int call, tcg_insn_unit *dest)
> > +static void tcg_out_branch(TCGContext *s, int call, const tcg_insn_unit
> > *dest)
> > {
> > intptr_t disp = tcg_pcrel_diff(s, dest) - 5;
> >
> > @@ -1610,12 +1610,12 @@ static void tcg_out_branch(TCGContext *s, int call,
> > tcg_insn_unit *dest)
> > }
> > }
> >
> > -static inline void tcg_out_call(TCGContext *s, tcg_insn_unit *dest)
> > +static inline void tcg_out_call(TCGContext *s, const tcg_insn_unit *dest)
> > {
> > tcg_out_branch(s, 1, dest);
> > }
> >
> > -static void tcg_out_jmp(TCGContext *s, tcg_insn_unit *dest)
> > +static void tcg_out_jmp(TCGContext *s, const tcg_insn_unit *dest)
> > {
> > tcg_out_branch(s, 0, dest);
> > }
> > @@ -1774,7 +1774,7 @@ static void add_qemu_ldst_label(TCGContext *s, bool
> > is_ld, bool is_64,
> > TCGMemOpIdx oi,
> > TCGReg datalo, TCGReg datahi,
> > TCGReg addrlo, TCGReg addrhi,
> > - tcg_insn_unit *raddr,
> > + const tcg_insn_unit *raddr,
> > tcg_insn_unit **label_ptr)
> > {
> > TCGLabelQemuLdst *label = new_ldst_label(s);
> > @@ -1805,9 +1805,9 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s,
> > TCGLabelQemuLdst *l)
> > int rexw = (l->type == TCG_TYPE_I64 ? P_REXW : 0);
> >
> > /* resolve label address */
> > - tcg_patch32(label_ptr[0], s->code_ptr - label_ptr[0] - 4);
> > + tcg_patch32(s, label_ptr[0], s->code_ptr - label_ptr[0] - 4);
> > if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
> > - tcg_patch32(label_ptr[1], s->code_ptr - label_ptr[1] - 4);
> > + tcg_patch32(s, label_ptr[1], s->code_ptr - label_ptr[1] - 4);
> > }
> >
> > if (TCG_TARGET_REG_BITS == 32) {
> > @@ -1890,9 +1890,9 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s,
> > TCGLabelQemuLdst *l)
> > TCGReg retaddr;
> >
> > /* resolve label address */
> > - tcg_patch32(label_ptr[0], s->code_ptr - label_ptr[0] - 4);
> > + tcg_patch32(s, label_ptr[0], s->code_ptr - label_ptr[0] - 4);
> > if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
> > - tcg_patch32(label_ptr[1], s->code_ptr - label_ptr[1] - 4);
> > + tcg_patch32(s, label_ptr[1], s->code_ptr - label_ptr[1] - 4);
> > }
> >
> > if (TCG_TARGET_REG_BITS == 32) {
> > @@ -3842,9 +3842,9 @@ static void tcg_target_qemu_prologue(TCGContext *s)
> > tcg_out_opc(s, OPC_RET, 0, 0, 0);
> > }
> >
> > -static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
> > +static void tcg_out_nop_fill(TCGContext *s, tcg_insn_unit *p, int count)
> > {
> > - memset(p, 0x90, count);
> > + memset(TCG_CODE_PTR_RW(s, p), 0x90, count);
> > }
> >
> > static void tcg_target_init(TCGContext *s)
> > diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
> > index abd4ac7fc0..cdc440ce36 100644
> > --- a/tcg/i386/tcg-target.h
> > +++ b/tcg/i386/tcg-target.h
> > @@ -206,16 +206,36 @@ extern bool have_avx2;
> > #define TCG_TARGET_extract_i64_valid(ofs, len) \
> > (((ofs) == 8 && (len) == 8) || ((ofs) + (len)) == 32)
> >
> > +#ifdef __APPLE__
> > +void sys_dcache_flush(void *start, size_t len);
> > +#endif
> > +
> > static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
> > {
> > }
> >
> > +#if defined(CONFIG_IOS_JIT)
> > +static inline void flush_dcache_range(uintptr_t start, uintptr_t stop)
> > +{
> > +#if defined(__APPLE__)
> > + sys_dcache_flush((char *)start, stop - start);
> > +#else
> > +#error "Missing function to flush data cache"
> > +#endif
> > +}
> > +#endif
> > +
> > static inline void tb_target_set_jmp_target(uintptr_t tc_ptr,
> > - uintptr_t jmp_addr, uintptr_t
> > addr)
> > + uintptr_t jmp_addr, uintptr_t
> > addr,
> > + uintptr_t wr_addr)
> > {
> > /* patch the branch destination */
> > - qatomic_set((int32_t *)jmp_addr, addr - (jmp_addr + 4));
> > + qatomic_set((int32_t *)wr_addr, addr - (jmp_addr + 4));
> > /* no need to flush icache explicitly */
> > +#if defined(CONFIG_IOS_JIT)
> > + /* we do need to flush mirror dcache */
> > + flush_dcache_range(wr_addr, wr_addr + 4);
> > +#endif
> > }
> >
> > /* This defines the natural memory order supported by this
> > diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
> > index 41be574e89..e798527437 100644
> > --- a/tcg/mips/tcg-target.c.inc
> > +++ b/tcg/mips/tcg-target.c.inc
> > @@ -139,12 +139,13 @@ static const TCGReg tcg_target_call_oarg_regs[2] = {
> > TCG_REG_V1
> > };
> >
> > -static tcg_insn_unit *tb_ret_addr;
> > -static tcg_insn_unit *bswap32_addr;
> > -static tcg_insn_unit *bswap32u_addr;
> > -static tcg_insn_unit *bswap64_addr;
> > +static const tcg_insn_unit *tb_ret_addr;
> > +static const tcg_insn_unit *bswap32_addr;
> > +static const tcg_insn_unit *bswap32u_addr;
> > +static const tcg_insn_unit *bswap64_addr;
> >
> > -static inline uint32_t reloc_pc16_val(tcg_insn_unit *pc, tcg_insn_unit
> > *target)
> > +static inline uint32_t reloc_pc16_val(const tcg_insn_unit *pc,
> > + const tcg_insn_unit *target)
> > {
> > /* Let the compiler perform the right-shift as part of the arithmetic.
> > */
> > ptrdiff_t disp = target - (pc + 1);
> > @@ -152,28 +153,35 @@ static inline uint32_t reloc_pc16_val(tcg_insn_unit
> > *pc, tcg_insn_unit *target)
> > return disp & 0xffff;
> > }
> >
> > -static inline void reloc_pc16(tcg_insn_unit *pc, tcg_insn_unit *target)
> > +static inline void reloc_pc16(TCGContext *s,
> > + tcg_insn_unit *pc,
> > + const tcg_insn_unit *target)
> > {
> > - *pc = deposit32(*pc, 0, 16, reloc_pc16_val(pc, target));
> > + *TCG_CODE_PTR_RW(s, pc) =
> > + deposit32(*TCG_CODE_PTR_RW(s, pc), 0, 16, reloc_pc16_val(pc,
> > target));
> > }
> >
> > -static inline uint32_t reloc_26_val(tcg_insn_unit *pc, tcg_insn_unit
> > *target)
> > +static inline uint32_t reloc_26_val(const tcg_insn_unit *pc,
> > + const tcg_insn_unit *target)
> > {
> > tcg_debug_assert((((uintptr_t)pc ^ (uintptr_t)target) & 0xf0000000) ==
> > 0);
> > return ((uintptr_t)target >> 2) & 0x3ffffff;
> > }
> >
> > -static inline void reloc_26(tcg_insn_unit *pc, tcg_insn_unit *target)
> > +static inline void reloc_26(TCGContext *s,
> > + tcg_insn_unit *pc,
> > + const tcg_insn_unit *target)
> > {
> > - *pc = deposit32(*pc, 0, 26, reloc_26_val(pc, target));
> > + *TCG_CODE_PTR_RW(s, pc) =
> > + deposit32(*TCG_CODE_PTR_RW(s, pc), 0, 26, reloc_26_val(pc,
> > target));
> > }
> >
> > -static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
> > +static bool patch_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type,
> > intptr_t value, intptr_t addend)
> > {
> > tcg_debug_assert(type == R_MIPS_PC16);
> > tcg_debug_assert(addend == 0);
> > - reloc_pc16(code_ptr, (tcg_insn_unit *)value);
> > + reloc_pc16(s, code_ptr, (tcg_insn_unit *)value);
> > return true;
> > }
> >
> > @@ -516,7 +524,7 @@ static void tcg_out_opc_sa64(TCGContext *s, MIPSInsn
> > opc1, MIPSInsn opc2,
> > * Type jump.
> > * Returns true if the branch was in range and the insn was emitted.
> > */
> > -static bool tcg_out_opc_jmp(TCGContext *s, MIPSInsn opc, void *target)
> > +static bool tcg_out_opc_jmp(TCGContext *s, MIPSInsn opc, const void
> > *target)
> > {
> > uintptr_t dest = (uintptr_t)target;
> > uintptr_t from = (uintptr_t)s->code_ptr + 4;
> > @@ -631,7 +639,7 @@ static inline void tcg_out_bswap16s(TCGContext *s,
> > TCGReg ret, TCGReg arg)
> > }
> > }
> >
> > -static void tcg_out_bswap_subr(TCGContext *s, tcg_insn_unit *sub)
> > +static void tcg_out_bswap_subr(TCGContext *s, const tcg_insn_unit *sub)
> > {
> > bool ok = tcg_out_opc_jmp(s, OPC_JAL, sub);
> > tcg_debug_assert(ok);
> > @@ -925,7 +933,7 @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond,
> > TCGReg arg1,
> >
> > tcg_out_opc_br(s, b_opc, arg1, arg2);
> > if (l->has_value) {
> > - reloc_pc16(s->code_ptr - 1, l->u.value_ptr);
> > + reloc_pc16(s, s->code_ptr - 1, l->u.value_ptr);
> > } else {
> > tcg_out_reloc(s, s->code_ptr - 1, R_MIPS_PC16, l, 0);
> > }
> > @@ -1079,7 +1087,7 @@ static void tcg_out_movcond(TCGContext *s, TCGCond
> > cond, TCGReg ret,
> > }
> > }
> >
> > -static void tcg_out_call_int(TCGContext *s, tcg_insn_unit *arg, bool tail)
> > +static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool
> > tail)
> > {
> > /* Note that the ABI requires the called function's address to be
> > loaded into T9, even if a direct branch is in range. */
> > @@ -1097,7 +1105,7 @@ static void tcg_out_call_int(TCGContext *s,
> > tcg_insn_unit *arg, bool tail)
> > }
> > }
> >
> > -static void tcg_out_call(TCGContext *s, tcg_insn_unit *arg)
> > +static void tcg_out_call(TCGContext *s, const tcg_insn_unit *arg)
> > {
> > tcg_out_call_int(s, arg, false);
> > tcg_out_nop(s);
> > @@ -1289,7 +1297,8 @@ static void add_qemu_ldst_label(TCGContext *s, int
> > is_ld, TCGMemOpIdx oi,
> > TCGType ext,
> > TCGReg datalo, TCGReg datahi,
> > TCGReg addrlo, TCGReg addrhi,
> > - void *raddr, tcg_insn_unit *label_ptr[2])
> > + const tcg_insn_unit *raddr,
> > + tcg_insn_unit *label_ptr[2])
> > {
> > TCGLabelQemuLdst *label = new_ldst_label(s);
> >
> > @@ -1315,9 +1324,9 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s,
> > TCGLabelQemuLdst *l)
> > int i;
> >
> > /* resolve label address */
> > - reloc_pc16(l->label_ptr[0], s->code_ptr);
> > + reloc_pc16(s, l->label_ptr[0], s->code_ptr);
> > if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
> > - reloc_pc16(l->label_ptr[1], s->code_ptr);
> > + reloc_pc16(s, l->label_ptr[1], s->code_ptr);
> > }
> >
> > i = 1;
> > @@ -1345,7 +1354,7 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s,
> > TCGLabelQemuLdst *l)
> > }
> >
> > tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
> > - reloc_pc16(s->code_ptr - 1, l->raddr);
> > + reloc_pc16(s, s->code_ptr - 1, l->raddr);
> >
> > /* delay slot */
> > if (TCG_TARGET_REG_BITS == 64 && l->type == TCG_TYPE_I32) {
> > @@ -1365,9 +1374,9 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s,
> > TCGLabelQemuLdst *l)
> > int i;
> >
> > /* resolve label address */
> > - reloc_pc16(l->label_ptr[0], s->code_ptr);
> > + reloc_pc16(s, l->label_ptr[0], s->code_ptr);
> > if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
> > - reloc_pc16(l->label_ptr[1], s->code_ptr);
> > + reloc_pc16(s, l->label_ptr[1], s->code_ptr);
> > }
> >
> > i = 1;
> > @@ -2430,7 +2439,7 @@ static void tcg_target_detect_isa(void)
> > sigaction(SIGILL, &sa_old, NULL);
> > }
> >
> > -static tcg_insn_unit *align_code_ptr(TCGContext *s)
> > +static const tcg_insn_unit *align_code_ptr(TCGContext *s)
> > {
> > uintptr_t p = (uintptr_t)s->code_ptr;
> > if (p & 15) {
> > @@ -2657,9 +2666,12 @@ static void tcg_target_init(TCGContext *s)
> > }
> >
> > void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
> > - uintptr_t addr)
> > + uintptr_t addr, uintptr_t wr_addr)
> > {
> > - qatomic_set((uint32_t *)jmp_addr, deposit32(OPC_J, 0, 26, addr >> 2));
> > + qatomic_set((uint32_t *)wr_addr, deposit32(OPC_J, 0, 26, addr >> 2));
> > +#if defined(CONFIG_IOS_JIT)
> > + flush_dcache_range(wr_addr, wr_addr + 4);
> > +#endif
> > flush_icache_range(jmp_addr, jmp_addr + 4);
> > }
> >
> > diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
> > index c6b091d849..80dcba5358 100644
> > --- a/tcg/mips/tcg-target.h
> > +++ b/tcg/mips/tcg-target.h
> > @@ -212,7 +212,13 @@ static inline void flush_icache_range(uintptr_t start,
> > uintptr_t stop)
> > cacheflush ((void *)start, stop-start, ICACHE);
> > }
> >
> > -void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t);
> > +void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
> > +#if defined(CONFIG_IOS_JIT)
> > +static inline void flush_dcache_range(uintptr_t start, uintptr_t stop)
> > +{
> > +#error "Unimplemented dcache flush function"
> > +}
> > +#endif
> >
> > #ifdef CONFIG_SOFTMMU
> > #define TCG_TARGET_NEED_LDST_LABELS
> > diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
> > index 18ee989f95..f5a44e9852 100644
> > --- a/tcg/ppc/tcg-target.c.inc
> > +++ b/tcg/ppc/tcg-target.c.inc
> > @@ -62,7 +62,7 @@
> > #define TCG_CT_CONST_MONE 0x2000
> > #define TCG_CT_CONST_WSZ 0x4000
> >
> > -static tcg_insn_unit *tb_ret_addr;
> > +static const tcg_insn_unit *tb_ret_addr;
> >
> > TCGPowerISA have_isa;
> > static bool have_isel;
> > @@ -184,35 +184,43 @@ static inline bool in_range_b(tcg_target_long target)
> > return target == sextract64(target, 0, 26);
> > }
> >
> > -static uint32_t reloc_pc24_val(tcg_insn_unit *pc, tcg_insn_unit *target)
> > +static uint32_t reloc_pc24_val(const tcg_insn_unit *pc,
> > + const tcg_insn_unit *target)
> > {
> > ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
> > tcg_debug_assert(in_range_b(disp));
> > return disp & 0x3fffffc;
> > }
> >
> > -static bool reloc_pc24(tcg_insn_unit *pc, tcg_insn_unit *target)
> > +static bool reloc_pc24(TCGContext *s,
> > + tcg_insn_unit *pc,
> > + const tcg_insn_unit *target)
> > {
> > ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
> > if (in_range_b(disp)) {
> > - *pc = (*pc & ~0x3fffffc) | (disp & 0x3fffffc);
> > + *TCG_CODE_PTR_RW(s, pc) =
> > + (*TCG_CODE_PTR_RW(s, pc) & ~0x3fffffc) | (disp & 0x3fffffc);
> > return true;
> > }
> > return false;
> > }
> >
> > -static uint16_t reloc_pc14_val(tcg_insn_unit *pc, tcg_insn_unit *target)
> > +static uint16_t reloc_pc14_val(const tcg_insn_unit *pc,
> > + const tcg_insn_unit *target)
> > {
> > ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
> > tcg_debug_assert(disp == (int16_t) disp);
> > return disp & 0xfffc;
> > }
> >
> > -static bool reloc_pc14(tcg_insn_unit *pc, tcg_insn_unit *target)
> > +static bool reloc_pc14(TCGContext *s,
> > + tcg_insn_unit *pc,
> > + const tcg_insn_unit *target)
> > {
> > ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
> > if (disp == (int16_t) disp) {
> > - *pc = (*pc & ~0xfffc) | (disp & 0xfffc);
> > + *TCG_CODE_PTR_RW(s, pc) =
> > + (*TCG_CODE_PTR_RW(s, pc) & ~0xfffc) | (disp & 0xfffc);
> > return true;
> > }
> > return false;
> > @@ -670,7 +678,7 @@ static const uint32_t tcg_to_isel[] = {
> > [TCG_COND_GTU] = ISEL | BC_(7, CR_GT),
> > };
> >
> > -static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
> > +static bool patch_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type,
> > intptr_t value, intptr_t addend)
> > {
> > tcg_insn_unit *target;
> > @@ -682,9 +690,9 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int
> > type,
> >
> > switch (type) {
> > case R_PPC_REL14:
> > - return reloc_pc14(code_ptr, target);
> > + return reloc_pc14(s, code_ptr, target);
> > case R_PPC_REL24:
> > - return reloc_pc24(code_ptr, target);
> > + return reloc_pc24(s, code_ptr, target);
> > case R_PPC_ADDR16:
> > /*
> > * We are (slightly) abusing this relocation type. In particular,
> > @@ -1106,7 +1114,7 @@ static void tcg_out_xori32(TCGContext *s, TCGReg dst,
> > TCGReg src, uint32_t c)
> > tcg_out_zori32(s, dst, src, c, XORI, XORIS);
> > }
> >
> > -static void tcg_out_b(TCGContext *s, int mask, tcg_insn_unit *target)
> > +static void tcg_out_b(TCGContext *s, int mask, const tcg_insn_unit *target)
> > {
> > ptrdiff_t disp = tcg_pcrel_diff(s, target);
> > if (in_range_b(disp)) {
> > @@ -1723,7 +1731,7 @@ static void tcg_out_mb(TCGContext *s, TCGArg a0)
> > }
> >
> > void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
> > - uintptr_t addr)
> > + uintptr_t addr, uintptr_t wr_addr)
> > {
> > if (TCG_TARGET_REG_BITS == 64) {
> > tcg_insn_unit i1, i2;
> > @@ -1752,17 +1760,23 @@ void tb_target_set_jmp_target(uintptr_t tc_ptr,
> > uintptr_t jmp_addr,
> >
> > /* As per the enclosing if, this is ppc64. Avoid the _Static_assert
> > within qatomic_set that would fail to build a ppc32 host. */
> > - qatomic_set__nocheck((uint64_t *)jmp_addr, pair);
> > + qatomic_set__nocheck((uint64_t *)wr_addr, pair);
> > +#if defined(CONFIG_IOS_JIT)
> > + flush_dcache_range(wr_addr, wr_addr + 8);
> > +#endif
> > flush_icache_range(jmp_addr, jmp_addr + 8);
> > } else {
> > intptr_t diff = addr - jmp_addr;
> > tcg_debug_assert(in_range_b(diff));
> > - qatomic_set((uint32_t *)jmp_addr, B | (diff & 0x3fffffc));
> > + qatomic_set((uint32_t *)wr_addr, B | (diff & 0x3fffffc));
> > +#if defined(CONFIG_IOS_JIT)
> > + flush_dcache_range(wr_addr, wr_addr + 8);
> > +#endif
> > flush_icache_range(jmp_addr, jmp_addr + 4);
> > }
> > }
> >
> > -static void tcg_out_call(TCGContext *s, tcg_insn_unit *target)
> > +static void tcg_out_call(TCGContext *s, const tcg_insn_unit *target)
> > {
> > #ifdef _CALL_AIX
> > /* Look through the descriptor. If the branch is in range, and we
> > @@ -1987,7 +2001,8 @@ static TCGReg tcg_out_tlb_read(TCGContext *s, MemOp
> > opc,
> > static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
> > TCGReg datalo_reg, TCGReg datahi_reg,
> > TCGReg addrlo_reg, TCGReg addrhi_reg,
> > - tcg_insn_unit *raddr, tcg_insn_unit *lptr)
> > + const tcg_insn_unit *raddr,
> > + tcg_insn_unit *lptr)
> > {
> > TCGLabelQemuLdst *label = new_ldst_label(s);
> >
> > @@ -2007,7 +2022,7 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s,
> > TCGLabelQemuLdst *lb)
> > MemOp opc = get_memop(oi);
> > TCGReg hi, lo, arg = TCG_REG_R3;
> >
> > - if (!reloc_pc14(lb->label_ptr[0], s->code_ptr)) {
> > + if (!reloc_pc14(s, lb->label_ptr[0], s->code_ptr)) {
> > return false;
> > }
> >
> > @@ -2055,7 +2070,7 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s,
> > TCGLabelQemuLdst *lb)
> > MemOp s_bits = opc & MO_SIZE;
> > TCGReg hi, lo, arg = TCG_REG_R3;
> >
> > - if (!reloc_pc14(lb->label_ptr[0], s->code_ptr)) {
> > + if (!reloc_pc14(s, lb->label_ptr[0], s->code_ptr)) {
> > return false;
> > }
> >
> > @@ -2252,11 +2267,11 @@ static void tcg_out_qemu_st(TCGContext *s, const
> > TCGArg *args, bool is_64)
> > #endif
> > }
> >
> > -static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
> > +static void tcg_out_nop_fill(TCGContext *s, tcg_insn_unit *p, int count)
> > {
> > int i;
> > for (i = 0; i < count; ++i) {
> > - p[i] = NOP;
> > + (TCG_CODE_PTR_RW(s, p))[i] = NOP;
> > }
> > }
> >
> > diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
> > index be10363956..23d7a337c9 100644
> > --- a/tcg/ppc/tcg-target.h
> > +++ b/tcg/ppc/tcg-target.h
> > @@ -176,7 +176,13 @@ extern bool have_vsx;
> > #define TCG_TARGET_HAS_cmpsel_vec 0
> >
> > void flush_icache_range(uintptr_t start, uintptr_t stop);
> > -void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t);
> > +void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
> > +#if defined(CONFIG_IOS_JIT)
> > +static inline void flush_dcache_range(uintptr_t start, uintptr_t stop)
> > +{
> > +#error "Unimplemented dcache flush function"
> > +}
> > +#endif
> >
> > #define TCG_TARGET_DEFAULT_MO (0)
> > #define TCG_TARGET_HAS_MEMORY_BSWAP 1
> > diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
> > index d536f3ccc1..2d96c83c4b 100644
> > --- a/tcg/riscv/tcg-target.c.inc
> > +++ b/tcg/riscv/tcg-target.c.inc
> > @@ -413,11 +413,11 @@ static void tcg_out_opc_jump(TCGContext *s, RISCVInsn
> > opc,
> > tcg_out32(s, encode_uj(opc, rd, imm));
> > }
> >
> > -static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
> > +static void tcg_out_nop_fill(TCGContext *s, tcg_insn_unit *p, int count)
> > {
> > int i;
> > for (i = 0; i < count; ++i) {
> > - p[i] = encode_i(OPC_ADDI, TCG_REG_ZERO, TCG_REG_ZERO, 0);
> > + (TCG_CODE_PTR_RW(s, p))[i] = encode_i(OPC_ADDI, TCG_REG_ZERO,
> > TCG_REG_ZERO, 0);
> > }
> > }
> >
> > @@ -425,46 +425,52 @@ static void tcg_out_nop_fill(tcg_insn_unit *p, int
> > count)
> > * Relocations
> > */
> >
> > -static bool reloc_sbimm12(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
> > +static bool reloc_sbimm12(TCGContext *s,
> > + tcg_insn_unit *code_ptr,
> > + const tcg_insn_unit *target)
> > {
> > intptr_t offset = (intptr_t)target - (intptr_t)code_ptr;
> >
> > if (offset == sextreg(offset, 1, 12) << 1) {
> > - code_ptr[0] |= encode_sbimm12(offset);
> > + (TCG_CODE_PTR_RW(s, code_ptr))[0] |= encode_sbimm12(offset);
> > return true;
> > }
> >
> > return false;
> > }
> >
> > -static bool reloc_jimm20(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
> > +static bool reloc_jimm20(TCGContext *s,
> > + tcg_insn_unit *code_ptr,
> > + const tcg_insn_unit *target)
> > {
> > intptr_t offset = (intptr_t)target - (intptr_t)code_ptr;
> >
> > if (offset == sextreg(offset, 1, 20) << 1) {
> > - code_ptr[0] |= encode_ujimm20(offset);
> > + (TCG_CODE_PTR_RW(s, code_ptr))[0] |= encode_ujimm20(offset);
> > return true;
> > }
> >
> > return false;
> > }
> >
> > -static bool reloc_call(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
> > +static bool reloc_call(TCGContext *s,
> > + tcg_insn_unit *code_ptr,
> > + const tcg_insn_unit *target)
> > {
> > intptr_t offset = (intptr_t)target - (intptr_t)code_ptr;
> > int32_t lo = sextreg(offset, 0, 12);
> > int32_t hi = offset - lo;
> >
> > if (offset == hi + lo) {
> > - code_ptr[0] |= encode_uimm20(hi);
> > - code_ptr[1] |= encode_imm12(lo);
> > + (TCG_CODE_PTR_RW(s, code_ptr))[0] |= encode_uimm20(hi);
> > + (TCG_CODE_PTR_RW(s, code_ptr))[1] |= encode_imm12(lo);
> > return true;
> > }
> >
> > return false;
> > }
> >
> > -static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
> > +static bool patch_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type,
> > intptr_t value, intptr_t addend)
> > {
> > uint32_t insn = *code_ptr;
> > @@ -478,7 +484,7 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int
> > type,
> > diff = value - (uintptr_t)code_ptr;
> > short_jmp = diff == sextreg(diff, 0, 12);
> > if (short_jmp) {
> > - return reloc_sbimm12(code_ptr, (tcg_insn_unit *)value);
> > + return reloc_sbimm12(s, code_ptr, (tcg_insn_unit *)value);
> > } else {
> > /* Invert the condition */
> > insn = insn ^ (1 << 12);
> > @@ -499,9 +505,9 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int
> > type,
> > }
> > break;
> > case R_RISCV_JAL:
> > - return reloc_jimm20(code_ptr, (tcg_insn_unit *)value);
> > + return reloc_jimm20(s, code_ptr, (tcg_insn_unit *)value);
> > case R_RISCV_CALL:
> > - return reloc_call(code_ptr, (tcg_insn_unit *)value);
> > + return reloc_call(s, code_ptr, (tcg_insn_unit *)value);
> > default:
> > tcg_abort();
> > }
> > @@ -557,7 +563,7 @@ static void tcg_out_movi(TCGContext *s, TCGType type,
> > TCGReg rd,
> > if (tmp == (int32_t)tmp) {
> > tcg_out_opc_upper(s, OPC_AUIPC, rd, 0);
> > tcg_out_opc_imm(s, OPC_ADDI, rd, rd, 0);
> > - ret = reloc_call(s->code_ptr - 2, (tcg_insn_unit *)val);
> > + ret = reloc_call(s, s->code_ptr - 2, (tcg_insn_unit *)val);
> > tcg_debug_assert(ret == true);
> > return;
> > }
> > @@ -854,14 +860,14 @@ static void tcg_out_setcond2(TCGContext *s, TCGCond
> > cond, TCGReg ret,
> > g_assert_not_reached();
> > }
> >
> > -static inline void tcg_out_goto(TCGContext *s, tcg_insn_unit *target)
> > +static inline void tcg_out_goto(TCGContext *s, const tcg_insn_unit *target)
> > {
> > ptrdiff_t offset = tcg_pcrel_diff(s, target);
> > tcg_debug_assert(offset == sextreg(offset, 1, 20) << 1);
> > tcg_out_opc_jump(s, OPC_JAL, TCG_REG_ZERO, offset);
> > }
> >
> > -static void tcg_out_call_int(TCGContext *s, tcg_insn_unit *arg, bool tail)
> > +static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool
> > tail)
> > {
> > TCGReg link = tail ? TCG_REG_ZERO : TCG_REG_RA;
> > ptrdiff_t offset = tcg_pcrel_diff(s, arg);
> > @@ -875,7 +881,7 @@ static void tcg_out_call_int(TCGContext *s,
> > tcg_insn_unit *arg, bool tail)
> > /* long jump: -2147483646 to 2147483648 */
> > tcg_out_opc_upper(s, OPC_AUIPC, TCG_REG_TMP0, 0);
> > tcg_out_opc_imm(s, OPC_JALR, link, TCG_REG_TMP0, 0);
> > - ret = reloc_call(s->code_ptr - 2, arg);\
> > + ret = reloc_call(s, s->code_ptr - 2, arg);\
> > tcg_debug_assert(ret == true);
> > } else if (TCG_TARGET_REG_BITS == 64) {
> > /* far jump: 64-bit */
> > @@ -888,7 +894,7 @@ static void tcg_out_call_int(TCGContext *s,
> > tcg_insn_unit *arg, bool tail)
> > }
> > }
> >
> > -static void tcg_out_call(TCGContext *s, tcg_insn_unit *arg)
> > +static void tcg_out_call(TCGContext *s, const tcg_insn_unit *arg)
> > {
> > tcg_out_call_int(s, arg, false);
> > }
> > @@ -1022,7 +1028,8 @@ static void add_qemu_ldst_label(TCGContext *s, int
> > is_ld, TCGMemOpIdx oi,
> > TCGType ext,
> > TCGReg datalo, TCGReg datahi,
> > TCGReg addrlo, TCGReg addrhi,
> > - void *raddr, tcg_insn_unit **label_ptr)
> > + const tcg_insn_unit *raddr,
> > + tcg_insn_unit **label_ptr)
> > {
> > TCGLabelQemuLdst *label = new_ldst_label(s);
> >
> > @@ -1052,7 +1059,7 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s,
> > TCGLabelQemuLdst *l)
> > }
> >
> > /* resolve label address */
> > - if (!patch_reloc(l->label_ptr[0], R_RISCV_BRANCH,
> > + if (!patch_reloc(s, l->label_ptr[0], R_RISCV_BRANCH,
> > (intptr_t) s->code_ptr, 0)) {
> > return false;
> > }
> > @@ -1087,7 +1094,7 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s,
> > TCGLabelQemuLdst *l)
> > }
> >
> > /* resolve label address */
> > - if (!patch_reloc(l->label_ptr[0], R_RISCV_BRANCH,
> > + if (!patch_reloc(s, l->label_ptr[0], R_RISCV_BRANCH,
> > (intptr_t) s->code_ptr, 0)) {
> > return false;
> > }
> > @@ -1274,7 +1281,7 @@ static void tcg_out_qemu_st(TCGContext *s, const
> > TCGArg *args, bool is_64)
> > #endif
> > }
> >
> > -static tcg_insn_unit *tb_ret_addr;
> > +static const tcg_insn_unit *tb_ret_addr;
> >
> > static void tcg_out_op(TCGContext *s, TCGOpcode opc,
> > const TCGArg *args, const int *const_args)
> > diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
> > index 032439d806..d42b361991 100644
> > --- a/tcg/riscv/tcg-target.h
> > +++ b/tcg/riscv/tcg-target.h
> > @@ -164,8 +164,15 @@ static inline void flush_icache_range(uintptr_t start,
> > uintptr_t stop)
> > __builtin___clear_cache((char *)start, (char *)stop);
> > }
> >
> > +#if defined(CONFIG_IOS_JIT)
> > +static inline void flush_dcache_range(uintptr_t start, uintptr_t stop)
> > +{
> > +#error "Unimplemented dcache flush function"
> > +}
> > +#endif
> > +
> > /* not defined -- call should be eliminated at compile time */
> > -void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t);
> > +void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
> >
> > #define TCG_TARGET_DEFAULT_MO (0)
> >
> > diff --git a/tcg/s390/tcg-target.c.inc b/tcg/s390/tcg-target.c.inc
> > index c5e096449b..49a96ca15f 100644
> > --- a/tcg/s390/tcg-target.c.inc
> > +++ b/tcg/s390/tcg-target.c.inc
> > @@ -363,10 +363,10 @@ static void * const qemu_st_helpers[16] = {
> > };
> > #endif
> >
> > -static tcg_insn_unit *tb_ret_addr;
> > +static const tcg_insn_unit *tb_ret_addr;
> > uint64_t s390_facilities;
> >
> > -static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
> > +static bool patch_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type,
> > intptr_t value, intptr_t addend)
> > {
> > intptr_t pcrel2;
> > @@ -378,13 +378,13 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int
> > type,
> > switch (type) {
> > case R_390_PC16DBL:
> > if (pcrel2 == (int16_t)pcrel2) {
> > - tcg_patch16(code_ptr, pcrel2);
> > + tcg_patch16(s, code_ptr, pcrel2);
> > return true;
> > }
> > break;
> > case R_390_PC32DBL:
> > if (pcrel2 == (int32_t)pcrel2) {
> > - tcg_patch32(code_ptr, pcrel2);
> > + tcg_patch32(s, code_ptr, pcrel2);
> > return true;
> > }
> > break;
> > @@ -392,7 +392,7 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int
> > type,
> > if (value == sextract64(value, 0, 20)) {
> > old = *(uint32_t *)code_ptr & 0xf00000ff;
> > old |= ((value & 0xfff) << 16) | ((value & 0xff000) >> 4);
> > - tcg_patch32(code_ptr, old);
> > + tcg_patch32(s, code_ptr, old);
> > return true;
> > }
> > break;
> > @@ -1302,7 +1302,7 @@ static void tgen_extract(TCGContext *s, TCGReg dest,
> > TCGReg src,
> > tcg_out_risbg(s, dest, src, 64 - len, 63, 64 - ofs, 1);
> > }
> >
> > -static void tgen_gotoi(TCGContext *s, int cc, tcg_insn_unit *dest)
> > +static void tgen_gotoi(TCGContext *s, int cc, const tcg_insn_unit *dest)
> > {
> > ptrdiff_t off = dest - s->code_ptr;
> > if (off == (int16_t)off) {
> > @@ -1415,7 +1415,7 @@ static void tgen_brcond(TCGContext *s, TCGType type,
> > TCGCond c,
> > tgen_branch(s, cc, l);
> > }
> >
> > -static void tcg_out_call(TCGContext *s, tcg_insn_unit *dest)
> > +static void tcg_out_call(TCGContext *s, const tcg_insn_unit *dest)
> > {
> > ptrdiff_t off = dest - s->code_ptr;
> > if (off == (int32_t)off) {
> > @@ -1593,7 +1593,8 @@ static TCGReg tcg_out_tlb_read(TCGContext *s, TCGReg
> > addr_reg, MemOp opc,
> >
> > static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
> > TCGReg data, TCGReg addr,
> > - tcg_insn_unit *raddr, tcg_insn_unit
> > *label_ptr)
> > + const tcg_insn_unit *raddr,
> > + tcg_insn_unit *label_ptr)
> > {
> > TCGLabelQemuLdst *label = new_ldst_label(s);
> >
> > @@ -1612,7 +1613,7 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s,
> > TCGLabelQemuLdst *lb)
> > TCGMemOpIdx oi = lb->oi;
> > MemOp opc = get_memop(oi);
> >
> > - if (!patch_reloc(lb->label_ptr[0], R_390_PC16DBL,
> > + if (!patch_reloc(s, lb->label_ptr[0], R_390_PC16DBL,
> > (intptr_t)s->code_ptr, 2)) {
> > return false;
> > }
> > @@ -1637,7 +1638,7 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s,
> > TCGLabelQemuLdst *lb)
> > TCGMemOpIdx oi = lb->oi;
> > MemOp opc = get_memop(oi);
> >
> > - if (!patch_reloc(lb->label_ptr[0], R_390_PC16DBL,
> > + if (!patch_reloc(s, lb->label_ptr[0], R_390_PC16DBL,
> > (intptr_t)s->code_ptr, 2)) {
> > return false;
> > }
> > @@ -2575,9 +2576,9 @@ static void tcg_target_qemu_prologue(TCGContext *s)
> > tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R14);
> > }
> >
> > -static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
> > +static void tcg_out_nop_fill(TCGContext *s, tcg_insn_unit *p, int count)
> > {
> > - memset(p, 0x07, count * sizeof(tcg_insn_unit));
> > + memset(TCG_CODE_PTR_RW(s, p), 0x07, count * sizeof(tcg_insn_unit));
> > }
> >
> > typedef struct {
> > diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
> > index 63c8797bd3..d67632512d 100644
> > --- a/tcg/s390/tcg-target.h
> > +++ b/tcg/s390/tcg-target.h
> > @@ -149,13 +149,24 @@ static inline void flush_icache_range(uintptr_t
> > start, uintptr_t stop)
> > {
> > }
> >
> > +#if defined(CONFIG_IOS_JIT)
> > +static inline void flush_dcache_range(uintptr_t start, uintptr_t stop)
> > +{
> > +#error "Unimplemented dcache flush function"
> > +}
> > +#endif
> > +
> > static inline void tb_target_set_jmp_target(uintptr_t tc_ptr,
> > - uintptr_t jmp_addr, uintptr_t
> > addr)
> > + uintptr_t jmp_addr, uintptr_t
> > addr,
> > + uintptr_t wr_addr)
> > {
> > /* patch the branch destination */
> > intptr_t disp = addr - (jmp_addr - 2);
> > qatomic_set((int32_t *)jmp_addr, disp / 2);
> > /* no need to flush icache explicitly */
> > +#if defined(CONFIG_IOS_JIT)
> > + flush_dcache_range(wr_addr, wr_addr + 4);
> > +#endif
> > }
> >
> > #ifdef CONFIG_SOFTMMU
> > diff --git a/tcg/sparc/tcg-target.c.inc b/tcg/sparc/tcg-target.c.inc
> > index 6775bd30fc..af97cbdeef 100644
> > --- a/tcg/sparc/tcg-target.c.inc
> > +++ b/tcg/sparc/tcg-target.c.inc
> > @@ -291,14 +291,14 @@ static inline int check_fit_i32(int32_t val, unsigned
> > int bits)
> > # define check_fit_ptr check_fit_i32
> > #endif
> >
> > -static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
> > +static bool patch_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type,
> > intptr_t value, intptr_t addend)
> > {
> > uint32_t insn = *code_ptr;
> > intptr_t pcrel;
> >
> > value += addend;
> > - pcrel = tcg_ptr_byte_diff((tcg_insn_unit *)value, code_ptr);
> > + pcrel = tcg_ptr_byte_diff((const tcg_insn_unit *)value, code_ptr);
> >
> > switch (type) {
> > case R_SPARC_WDISP16:
> > @@ -840,7 +840,7 @@ static void tcg_out_addsub2_i64(TCGContext *s, TCGReg
> > rl, TCGReg rh,
> > tcg_out_mov(s, TCG_TYPE_I64, rl, tmp);
> > }
> >
> > -static void tcg_out_call_nodelay(TCGContext *s, tcg_insn_unit *dest,
> > +static void tcg_out_call_nodelay(TCGContext *s, const tcg_insn_unit *dest,
> > bool in_prologue)
> > {
> > ptrdiff_t disp = tcg_pcrel_diff(s, dest);
> > @@ -855,7 +855,7 @@ static void tcg_out_call_nodelay(TCGContext *s,
> > tcg_insn_unit *dest,
> > }
> > }
> >
> > -static void tcg_out_call(TCGContext *s, tcg_insn_unit *dest)
> > +static void tcg_out_call(TCGContext *s, const tcg_insn_unit *dest)
> > {
> > tcg_out_call_nodelay(s, dest, false);
> > tcg_out_nop(s);
> > @@ -868,8 +868,8 @@ static void tcg_out_mb(TCGContext *s, TCGArg a0)
> > }
> >
> > #ifdef CONFIG_SOFTMMU
> > -static tcg_insn_unit *qemu_ld_trampoline[16];
> > -static tcg_insn_unit *qemu_st_trampoline[16];
> > +static const tcg_insn_unit *qemu_ld_trampoline[16];
> > +static const tcg_insn_unit *qemu_st_trampoline[16];
> >
> > static void emit_extend(TCGContext *s, TCGReg r, int op)
> > {
> > @@ -1048,11 +1048,11 @@ static void tcg_target_qemu_prologue(TCGContext *s)
> > #endif
> > }
> >
> > -static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
> > +static void tcg_out_nop_fill(TCGContext *s, tcg_insn_unit *p, int count)
> > {
> > int i;
> > for (i = 0; i < count; ++i) {
> > - p[i] = NOP;
> > + (TCG_CODE_PTR_RW(s, p))[i] = NOP;
> > }
> > }
> >
> > @@ -1163,7 +1163,7 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg
> > data, TCGReg addr,
> > #ifdef CONFIG_SOFTMMU
> > unsigned memi = get_mmuidx(oi);
> > TCGReg addrz, param;
> > - tcg_insn_unit *func;
> > + const tcg_insn_unit *func;
> > tcg_insn_unit *label_ptr;
> >
> > addrz = tcg_out_tlb_load(s, addr, memi, memop,
> > @@ -1226,7 +1226,8 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg
> > data, TCGReg addr,
> > }
> > }
> >
> > - *label_ptr |= INSN_OFF19(tcg_ptr_byte_diff(s->code_ptr, label_ptr));
> > + *TCG_CODE_PTR_RW(s, label_ptr) |=
> > + INSN_OFF19(tcg_ptr_byte_diff(s->code_ptr, label_ptr));
> > #else
> > if (SPARC64 && TARGET_LONG_BITS == 32) {
> > tcg_out_arithi(s, TCG_REG_T1, addr, 0, SHIFT_SRL);
> > @@ -1822,7 +1823,7 @@ void tcg_register_jit(void *buf, size_t buf_size)
> > }
> >
> > void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
> > - uintptr_t addr)
> > + uintptr_t addr, uintptr_t wr_addr)
> > {
> > intptr_t tb_disp = addr - tc_ptr;
> > intptr_t br_disp = addr - jmp_addr;
> > @@ -1834,8 +1835,11 @@ void tb_target_set_jmp_target(uintptr_t tc_ptr,
> > uintptr_t jmp_addr,
> > tcg_debug_assert(br_disp == (int32_t)br_disp);
> >
> > if (!USE_REG_TB) {
> > - qatomic_set((uint32_t *)jmp_addr,
> > + qatomic_set((uint32_t *)wr_addr,
> > deposit32(CALL, 0, 30, br_disp >> 2));
> > +#if defined(CONFIG_IOS_JIT)
> > + flush_dcache_range(wr_addr, wr_addr + 4);
> > +#endif
> > flush_icache_range(jmp_addr, jmp_addr + 4);
> > return;
> > }
> > @@ -1859,6 +1863,9 @@ void tb_target_set_jmp_target(uintptr_t tc_ptr,
> > uintptr_t jmp_addr,
> > | INSN_IMM13((tb_disp & 0x3ff) | -0x400));
> > }
> >
> > - qatomic_set((uint64_t *)jmp_addr, deposit64(i2, 32, 32, i1));
> > + qatomic_set((uint64_t *)wr_addr, deposit64(i2, 32, 32, i1));
> > +#if defined(CONFIG_IOS_JIT)
> > + flush_dcache_range(wr_addr, wr_addr + 8);
> > +#endif
> > flush_icache_range(jmp_addr, jmp_addr + 8);
> > }
> > diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
> > index 633841ebf2..d102e13692 100644
> > --- a/tcg/sparc/tcg-target.h
> > +++ b/tcg/sparc/tcg-target.h
> > @@ -176,7 +176,13 @@ static inline void flush_icache_range(uintptr_t start,
> > uintptr_t stop)
> > }
> > }
> >
> > -void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t);
> > +void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
> > +#if defined(CONFIG_IOS_JIT)
> > +static inline void flush_dcache_range(uintptr_t start, uintptr_t stop)
> > +{
> > +#error "Unimplemented dcache flush function"
> > +}
> > +#endif
> >
> > #define TCG_TARGET_NEED_POOL_LABELS
> >
> > diff --git a/tcg/tcg-ldst.c.inc b/tcg/tcg-ldst.c.inc
> > index 05f9b3ccd6..eaba08700e 100644
> > --- a/tcg/tcg-ldst.c.inc
> > +++ b/tcg/tcg-ldst.c.inc
> > @@ -28,7 +28,7 @@ typedef struct TCGLabelQemuLdst {
> > TCGReg addrhi_reg; /* reg index for high word of guest virtual
> > addr */
> > TCGReg datalo_reg; /* reg index for low word to be loaded or
> > stored */
> > TCGReg datahi_reg; /* reg index for high word to be loaded or
> > stored */
> > - tcg_insn_unit *raddr; /* gen code addr of the next IR of qemu_ld/st
> > IR */
> > + const tcg_insn_unit *raddr; /* gen code addr of the next IR of
> > qemu_ld/st */
> > tcg_insn_unit *label_ptr[2]; /* label pointers to be updated */
> > QSIMPLEQ_ENTRY(TCGLabelQemuLdst) next;
> > } TCGLabelQemuLdst;
> > diff --git a/tcg/tcg-pool.c.inc b/tcg/tcg-pool.c.inc
> > index 82cbcc89bd..97bb90b7cc 100644
> > --- a/tcg/tcg-pool.c.inc
> > +++ b/tcg/tcg-pool.c.inc
> > @@ -119,7 +119,7 @@ static inline void new_pool_l8(TCGContext *s, int
> > rtype, tcg_insn_unit *label,
> > }
> >
> > /* To be provided by cpu/tcg-target.c.inc. */
> > -static void tcg_out_nop_fill(tcg_insn_unit *p, int count);
> > +static void tcg_out_nop_fill(TCGContext *s, tcg_insn_unit *p, int count);
> >
> > static int tcg_out_pool_finalize(TCGContext *s)
> > {
> > @@ -135,7 +135,7 @@ static int tcg_out_pool_finalize(TCGContext *s)
> > again when allocating the next TranslationBlock structure. */
> > a = (void *)ROUND_UP((uintptr_t)s->code_ptr,
> > sizeof(tcg_target_ulong) * p->nlong);
> > - tcg_out_nop_fill(s->code_ptr, (tcg_insn_unit *)a - s->code_ptr);
> > + tcg_out_nop_fill(s, s->code_ptr, (tcg_insn_unit *)a - s->code_ptr);
> > s->data_gen_ptr = a;
> >
> > for (; p != NULL; p = p->next) {
> > @@ -144,11 +144,12 @@ static int tcg_out_pool_finalize(TCGContext *s)
> > if (unlikely(a > s->code_gen_highwater)) {
> > return -1;
> > }
> > - memcpy(a, p->data, size);
> > + memcpy(TCG_CODE_PTR_RW(s, a), p->data, size);
> > a += size;
> > l = p;
> > }
> > - if (!patch_reloc(p->label, p->rtype, (intptr_t)a - size,
> > p->addend)) {
> > + if (!patch_reloc(s, p->label, p->rtype,
> > + (intptr_t)a - size, p->addend)) {
> > return -2;
> > }
> > }
> > diff --git a/tcg/tcg.c b/tcg/tcg.c
> > index a8c28440e2..ef203a34a6 100644
> > --- a/tcg/tcg.c
> > +++ b/tcg/tcg.c
> > @@ -70,7 +70,7 @@
> > static void tcg_target_init(TCGContext *s);
> > static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode);
> > static void tcg_target_qemu_prologue(TCGContext *s);
> > -static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
> > +static bool patch_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type,
> > intptr_t value, intptr_t addend);
> >
> > /* The CIE and FDE header definitions will be common to all hosts. */
> > @@ -148,7 +148,7 @@ static void tcg_out_st(TCGContext *s, TCGType type,
> > TCGReg arg, TCGReg arg1,
> > intptr_t arg2);
> > static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
> > TCGReg base, intptr_t ofs);
> > -static void tcg_out_call(TCGContext *s, tcg_insn_unit *target);
> > +static void tcg_out_call(TCGContext *s, const tcg_insn_unit *target);
> > static int tcg_target_const_match(tcg_target_long val, TCGType type,
> > const TCGArgConstraint *arg_ct);
> > #ifdef TCG_TARGET_NEED_LDST_LABELS
> > @@ -203,13 +203,15 @@ static TCGRegSet tcg_target_call_clobber_regs;
> > #if TCG_TARGET_INSN_UNIT_SIZE == 1
> > static __attribute__((unused)) inline void tcg_out8(TCGContext *s, uint8_t
> > v)
> > {
> > - *s->code_ptr++ = v;
> > + *TCG_CODE_PTR_RW(s, s->code_ptr) = v;
> > + s->code_ptr++;
> > }
> >
> > -static __attribute__((unused)) inline void tcg_patch8(tcg_insn_unit *p,
> > +static __attribute__((unused)) inline void tcg_patch8(TCGContext *s,
> > + tcg_insn_unit *p,
> > uint8_t v)
> > {
> > - *p = v;
> > + *TCG_CODE_PTR_RW(s, p) = v;
> > }
> > #endif
> >
> > @@ -217,21 +219,23 @@ static __attribute__((unused)) inline void
> > tcg_patch8(tcg_insn_unit *p,
> > static __attribute__((unused)) inline void tcg_out16(TCGContext *s,
> > uint16_t v)
> > {
> > if (TCG_TARGET_INSN_UNIT_SIZE == 2) {
> > - *s->code_ptr++ = v;
> > + *TCG_CODE_PTR_RW(s, s->code_ptr) = v;
> > + s->code_ptr++;
> > } else {
> > tcg_insn_unit *p = s->code_ptr;
> > - memcpy(p, &v, sizeof(v));
> > + memcpy(TCG_CODE_PTR_RW(s, p), &v, sizeof(v));
> > s->code_ptr = p + (2 / TCG_TARGET_INSN_UNIT_SIZE);
> > }
> > }
> >
> > -static __attribute__((unused)) inline void tcg_patch16(tcg_insn_unit *p,
> > +static __attribute__((unused)) inline void tcg_patch16(TCGContext *s,
> > + tcg_insn_unit *p,
> > uint16_t v)
> > {
> > if (TCG_TARGET_INSN_UNIT_SIZE == 2) {
> > - *p = v;
> > + *TCG_CODE_PTR_RW(s, p) = v;
> > } else {
> > - memcpy(p, &v, sizeof(v));
> > + memcpy(TCG_CODE_PTR_RW(s, p), &v, sizeof(v));
> > }
> > }
> > #endif
> > @@ -240,21 +244,23 @@ static __attribute__((unused)) inline void
> > tcg_patch16(tcg_insn_unit *p,
> > static __attribute__((unused)) inline void tcg_out32(TCGContext *s,
> > uint32_t v)
> > {
> > if (TCG_TARGET_INSN_UNIT_SIZE == 4) {
> > - *s->code_ptr++ = v;
> > + *TCG_CODE_PTR_RW(s, s->code_ptr) = v;
> > + s->code_ptr++;
> > } else {
> > tcg_insn_unit *p = s->code_ptr;
> > - memcpy(p, &v, sizeof(v));
> > + memcpy(TCG_CODE_PTR_RW(s, p), &v, sizeof(v));
> > s->code_ptr = p + (4 / TCG_TARGET_INSN_UNIT_SIZE);
> > }
> > }
> >
> > -static __attribute__((unused)) inline void tcg_patch32(tcg_insn_unit *p,
> > +static __attribute__((unused)) inline void tcg_patch32(TCGContext *s,
> > + tcg_insn_unit *p,
> > uint32_t v)
> > {
> > if (TCG_TARGET_INSN_UNIT_SIZE == 4) {
> > *p = v;
> > } else {
> > - memcpy(p, &v, sizeof(v));
> > + memcpy(TCG_CODE_PTR_RW(s, p), &v, sizeof(v));
> > }
> > }
> > #endif
> > @@ -263,21 +269,23 @@ static __attribute__((unused)) inline void
> > tcg_patch32(tcg_insn_unit *p,
> > static __attribute__((unused)) inline void tcg_out64(TCGContext *s,
> > uint64_t v)
> > {
> > if (TCG_TARGET_INSN_UNIT_SIZE == 8) {
> > - *s->code_ptr++ = v;
> > + *TCG_CODE_PTR_RW(s, s->code_ptr) = v;
> > + s->code_ptr++;
> > } else {
> > tcg_insn_unit *p = s->code_ptr;
> > - memcpy(p, &v, sizeof(v));
> > + memcpy(TCG_CODE_PTR_RW(s, p), &v, sizeof(v));
> > s->code_ptr = p + (8 / TCG_TARGET_INSN_UNIT_SIZE);
> > }
> > }
> >
> > -static __attribute__((unused)) inline void tcg_patch64(tcg_insn_unit *p,
> > +static __attribute__((unused)) inline void tcg_patch64(TCGContext *s,
> > + tcg_insn_unit *p,
> > uint64_t v)
> > {
> > if (TCG_TARGET_INSN_UNIT_SIZE == 8) {
> > *p = v;
> > } else {
> > - memcpy(p, &v, sizeof(v));
> > + memcpy(TCG_CODE_PTR_RW(s, p), &v, sizeof(v));
> > }
> > }
> > #endif
> > @@ -295,7 +303,7 @@ static void tcg_out_reloc(TCGContext *s, tcg_insn_unit
> > *code_ptr, int type,
> > QSIMPLEQ_INSERT_TAIL(&l->relocs, r, next);
> > }
> >
> > -static void tcg_out_label(TCGContext *s, TCGLabel *l, tcg_insn_unit *ptr)
> > +static void tcg_out_label(TCGContext *s, TCGLabel *l, const tcg_insn_unit
> > *ptr)
> > {
> > tcg_debug_assert(!l->has_value);
> > l->has_value = 1;
> > @@ -325,7 +333,7 @@ static bool tcg_resolve_relocs(TCGContext *s)
> > uintptr_t value = l->u.value;
> >
> > QSIMPLEQ_FOREACH(r, &l->relocs, next) {
> > - if (!patch_reloc(r->ptr, r->type, value, r->addend)) {
> > + if (!patch_reloc(s, r->ptr, r->type, value, r->addend)) {
> > return false;
> > }
> > }
> > @@ -1039,7 +1047,7 @@ TranslationBlock *tcg_tb_alloc(TCGContext *s)
> > }
> > qatomic_set(&s->code_gen_ptr, next);
> > s->data_gen_ptr = NULL;
> > - return tb;
> > + return (TranslationBlock *)TCG_CODE_PTR_RW(s, tb);
> > }
> >
> > void tcg_prologue_init(TCGContext *s)
> > @@ -1076,6 +1084,10 @@ void tcg_prologue_init(TCGContext *s)
> > #endif
> >
> > buf1 = s->code_ptr;
> > +#if defined(CONFIG_IOS_JIT)
> > + flush_dcache_range((uintptr_t)TCG_CODE_PTR_RW(s, buf0),
> > + (uintptr_t)TCG_CODE_PTR_RW(s, buf1));
> > +#endif
> > flush_icache_range((uintptr_t)buf0, (uintptr_t)buf1);
> >
> > /* Deduct the prologue from the buffer. */
> > @@ -4267,6 +4279,12 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
> > return -2;
> > }
> >
> > +#if defined(CONFIG_IOS_JIT)
> > + /* flush data cache on mirror */
> > + flush_dcache_range((uintptr_t)TCG_CODE_PTR_RW(s, s->code_buf),
> > + (uintptr_t)TCG_CODE_PTR_RW(s, s->code_ptr));
> > +#endif
> > +
> > /* flush instruction cache */
> > flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr);
> >
> > diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
> > index 231b9b1775..133213be3a 100644
> > --- a/tcg/tci/tcg-target.c.inc
> > +++ b/tcg/tci/tcg-target.c.inc
> > @@ -369,7 +369,7 @@ static const char *const
> > tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
> > };
> > #endif
> >
> > -static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
> > +static bool patch_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type,
> > intptr_t value, intptr_t addend)
> > {
> > /* tcg_out_reloc always uses the same type, addend. */
> > @@ -377,9 +377,9 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int
> > type,
> > tcg_debug_assert(addend == 0);
> > tcg_debug_assert(value != 0);
> > if (TCG_TARGET_REG_BITS == 32) {
> > - tcg_patch32(code_ptr, value);
> > + tcg_patch32(s, code_ptr, value);
> > } else {
> > - tcg_patch64(code_ptr, value);
> > + tcg_patch64(s, code_ptr, value);
> > }
> > return true;
> > }
> > @@ -545,7 +545,7 @@ static void tcg_out_movi(TCGContext *s, TCGType type,
> > old_code_ptr[1] = s->code_ptr - old_code_ptr;
> > }
> >
> > -static inline void tcg_out_call(TCGContext *s, tcg_insn_unit *arg)
> > +static inline void tcg_out_call(TCGContext *s, const tcg_insn_unit *arg)
> > {
> > uint8_t *old_code_ptr = s->code_ptr;
> > tcg_out_op_t(s, INDEX_op_call);
> > diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
> > index 8c1c1d265d..2a258ea350 100644
> > --- a/tcg/tci/tcg-target.h
> > +++ b/tcg/tci/tcg-target.h
> > @@ -195,6 +195,12 @@ static inline void flush_icache_range(uintptr_t start,
> > uintptr_t stop)
> > {
> > }
> >
> > +#if defined(CONFIG_IOS_JIT)
> > +static inline void flush_dcache_range(uintptr_t start, uintptr_t stop)
> > +{
> > +}
> > +#endif
> > +
> > /* We could notice __i386__ or __s390x__ and reduce the barriers depending
> > on the host. But if you want performance, you use the normal backend.
> > We prefer consistency across hosts on this. */
> > @@ -203,7 +209,8 @@ static inline void flush_icache_range(uintptr_t start,
> > uintptr_t stop)
> > #define TCG_TARGET_HAS_MEMORY_BSWAP 1
> >
> > static inline void tb_target_set_jmp_target(uintptr_t tc_ptr,
> > - uintptr_t jmp_addr, uintptr_t
> > addr)
> > + uintptr_t jmp_addr, uintptr_t
> > addr,
> > + uintptr_t wr_addr)
> > {
> > /* patch the branch destination */
> > qatomic_set((int32_t *)jmp_addr, addr - (jmp_addr + 4));
> >
>
- Re: [PATCH 06/10] coroutine: add libucontext as external library, (continued)
[PATCH 07/10] tcg: implement bulletproof JIT, Joelle van Dyne, 2020/10/12
- Re: [PATCH 07/10] tcg: implement bulletproof JIT, Philippe Mathieu-Daudé, 2020/10/13
- Re: [PATCH 07/10] tcg: implement bulletproof JIT, BALATON Zoltan, 2020/10/13
- Re: [PATCH 07/10] tcg: implement bulletproof JIT, Joelle van Dyne, 2020/10/14
- Re: [PATCH 07/10] tcg: implement bulletproof JIT, BALATON Zoltan, 2020/10/14
- Re: [PATCH 07/10] tcg: implement bulletproof JIT, Richard Henderson, 2020/10/14
- Re: [PATCH 07/10] tcg: implement bulletproof JIT, Joelle van Dyne, 2020/10/14
[PATCH 01/10] configure: option to disable host block devices, Joelle van Dyne, 2020/10/12
[PATCH 04/10] meson: option to build as shared library, Joelle van Dyne, 2020/10/12