infix
A JIT-Powered FFI Library for C
Loading...
Searching...
No Matches
executor.c File Reference

Implements platform-specific memory management for JIT code and execution. More...

#include "common/infix_internals.h"
#include "common/utility.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdint.h>
Include dependency graph for executor.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

static int shm_open_anonymous ()
 
c23_nodiscard infix_executable_t infix_executable_alloc (size_t size)
 Allocates a block of executable memory using the platform's W^X strategy.
 
void infix_executable_free (infix_executable_t exec)
 Frees a block of executable memory and applies guard pages to prevent use-after-free.
 
c23_nodiscard bool infix_executable_make_executable (infix_executable_t exec)
 Makes a block of JIT memory executable, completing the W^X process.
 
c23_nodiscard infix_protected_t infix_protected_alloc (size_t size)
 Allocates a block of standard memory for later protection.
 
void infix_protected_free (infix_protected_t prot)
 Frees a block of protected memory.
 
c23_nodiscard bool infix_protected_make_readonly (infix_protected_t prot)
 Makes a block of memory read-only for security hardening.
 
void infix_internal_dispatch_callback_fn_impl (infix_reverse_t *context, void *return_value_ptr, void **args_array)
 The universal C entry point for all reverse call trampolines.
 

Detailed Description

Implements platform-specific memory management for JIT code and execution.

Copyright (c) 2025 Sanko Robinson

This source code is dual-licensed under the Artistic License 2.0 or the MIT License. You may choose to use this code under the terms of either license.

SPDX-License-Identifier: (Artistic-2.0 OR MIT)

The documentation blocks within this file are licensed under the Creative Commons Attribution 4.0 International License (CC BY 4.0).

SPDX-License-Identifier: CC-BY-4.0

This module serves as the critical OS abstraction layer for the JIT engine. Its primary responsibilities are:

  1. Executable Memory Management: It allocates, protects, and frees executable memory in a way that is secure and compliant with modern OS security features like W^X (Write XOR Execute). It implements different strategies (single- vs. dual-mapping) depending on the platform's capabilities and security model.
  2. Security Hardening: It provides mechanisms to make memory regions read-only, which is used to protect the infix_reverse_t context from runtime memory corruption. It also implements "guard pages" on freed memory to immediately catch use-after-free bugs.
  3. Universal Dispatch: It contains the infix_internal_dispatch_callback_fn_impl, the universal C entry point that is the final target of all reverse trampoline stubs. This function is the bridge between the low-level JIT code and the high-level user-provided C handlers.

Function Documentation

◆ infix_executable_alloc()

c23_nodiscard infix_executable_t infix_executable_alloc ( size_t  size)

Allocates a block of executable memory using the platform's W^X strategy.

Located in src/jit/executor.c. This is a platform-specific function that abstracts VirtualAlloc, mmap with MAP_JIT, or shm_open with dual-mapping.

Parameters
sizeThe number of bytes to allocate.
Returns
An infix_executable_t handle containing pointers to the allocated memory.

◆ infix_executable_free()

void infix_executable_free ( infix_executable_t  exec)

Frees a block of executable memory and applies guard pages to prevent use-after-free.

Located in src/jit/executor.c. Before freeing, it attempts to change the memory's protection to be inaccessible, causing an immediate crash on a UAF.

Parameters
execThe handle to the memory block to free.

◆ infix_executable_make_executable()

c23_nodiscard bool infix_executable_make_executable ( infix_executable_t  exec)

Makes a block of JIT memory executable, completing the W^X process.

Located in src/jit/executor.c. For single-map platforms, this calls VirtualProtect or mprotect. For dual-map platforms, this is a no-op. It also handles instruction cache flushing on relevant architectures like AArch64.

Parameters
execThe handle to the memory block to make executable.
Returns
true on success, false on failure.

◆ infix_internal_dispatch_callback_fn_impl()

void infix_internal_dispatch_callback_fn_impl ( infix_reverse_t context,
void *  return_value_ptr,
void **  args_array 
)

The universal C entry point for all reverse call trampolines.

Located in src/jit/executor.c, this function is called by the JIT-compiled stub. It receives the marshalled arguments and dispatches the call to either the type-safe callback (via a cached forward trampoline) or the generic closure handler.

Parameters
[in]contextThe infix_reverse_t context for this call.
[out]return_value_ptrA pointer to the stack buffer for the return value.
[in]args_arrayA pointer to the void** array of argument pointers.

◆ infix_protected_alloc()

c23_nodiscard infix_protected_t infix_protected_alloc ( size_t  size)

Allocates a block of standard memory for later protection.

Located in src/jit/executor.c. This is used to allocate the memory for an infix_reverse_t context before it is made read-only.

Parameters
sizeThe number of bytes to allocate.
Returns
An infix_protected_t handle.

◆ infix_protected_free()

void infix_protected_free ( infix_protected_t  prot)

Frees a block of protected memory.

Located in src/jit/executor.c.

Parameters
protThe memory block to free.

◆ infix_protected_make_readonly()

c23_nodiscard bool infix_protected_make_readonly ( infix_protected_t  prot)

Makes a block of memory read-only for security hardening.

Located in src/jit/executor.c. This is called on the infix_reverse_t context after it has been fully initialized.

Parameters
protThe memory block to make read-only.
Returns
true on success, false on failure.

◆ shm_open_anonymous()

static int shm_open_anonymous ( )
static