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

Implements the FFI logic for the System V AMD64 ABI. More...

#include "common/infix_internals.h"
#include "common/utility.h"
#include <abi_x64_common.h>
#include <abi_x64_emitters.h>
#include <stdbool.h>
#include <stdlib.h>
Include dependency graph for abi_sysv_x64.c:

Macros

#define NUM_GPR_ARGS   6
 
#define NUM_XMM_ARGS   8
 
#define MAX_CLASSIFY_DEPTH   32
 
#define MAX_AGGREGATE_FIELDS_TO_CLASSIFY   32
 

Enumerations

enum  arg_class_t { NO_CLASS , INTEGER , SSE , MEMORY }
 

Functions

static infix_status prepare_forward_call_frame_sysv_x64 (infix_arena_t *arena, infix_call_frame_layout **out_layout, infix_type *ret_type, infix_type **arg_types, size_t num_args, size_t num_fixed_args, void *target_fn)
 
static infix_status generate_forward_prologue_sysv_x64 (code_buffer *buf, infix_call_frame_layout *layout)
 
static infix_status generate_forward_argument_moves_sysv_x64 (code_buffer *buf, infix_call_frame_layout *layout, infix_type **arg_types, size_t num_args, size_t num_fixed_args)
 
static infix_status generate_forward_call_instruction_sysv_x64 (code_buffer *, infix_call_frame_layout *)
 
static infix_status generate_forward_epilogue_sysv_x64 (code_buffer *buf, infix_call_frame_layout *layout, infix_type *ret_type)
 
static infix_status prepare_reverse_call_frame_sysv_x64 (infix_arena_t *arena, infix_reverse_call_frame_layout **out_layout, infix_reverse_t *context)
 
static infix_status generate_reverse_prologue_sysv_x64 (code_buffer *buf, infix_reverse_call_frame_layout *layout)
 
static infix_status generate_reverse_argument_marshalling_sysv_x64 (code_buffer *buf, infix_reverse_call_frame_layout *layout, infix_reverse_t *context)
 
static infix_status generate_reverse_dispatcher_call_sysv_x64 (code_buffer *buf, infix_reverse_call_frame_layout *layout, infix_reverse_t *context)
 
static infix_status generate_reverse_epilogue_sysv_x64 (code_buffer *buf, infix_reverse_call_frame_layout *layout, infix_reverse_t *context)
 
static bool classify_recursive (infix_type *type, size_t offset, arg_class_t classes[2], int depth, size_t *field_count)
 
static void classify_aggregate_sysv (infix_type *type, arg_class_t classes[2], size_t *num_classes)
 
static infix_status generate_forward_argument_moves_sysv_x64 (code_buffer *buf, infix_call_frame_layout *layout, infix_type **arg_types, size_t num_args, c23_maybe_unused size_t num_fixed_args)
 
static infix_status generate_forward_call_instruction_sysv_x64 (code_buffer *buf, c23_maybe_unused infix_call_frame_layout *layout)
 

Variables

static const x64_gpr GPR_ARGS [] = {RDI_REG, RSI_REG, RDX_REG, RCX_REG, R8_REG, R9_REG}
 
static const x64_xmm XMM_ARGS [] = {XMM0_REG, XMM1_REG, XMM2_REG, XMM3_REG, XMM4_REG, XMM5_REG, XMM6_REG, XMM7_REG}
 
const infix_forward_abi_spec g_sysv_x64_forward_spec
 
const infix_reverse_abi_spec g_sysv_x64_reverse_spec
 

Detailed Description

Implements the FFI logic for the System V AMD64 ABI.

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

Macro Definition Documentation

◆ MAX_AGGREGATE_FIELDS_TO_CLASSIFY

#define MAX_AGGREGATE_FIELDS_TO_CLASSIFY   32

A safe limit on the number of fields to classify to prevent DoS from exponential complexity.

◆ MAX_CLASSIFY_DEPTH

#define MAX_CLASSIFY_DEPTH   32

A safe recursion limit for the aggregate classification algorithm to prevent stack overflow.

◆ NUM_GPR_ARGS

#define NUM_GPR_ARGS   6

The number of GPRs available for argument passing.

◆ NUM_XMM_ARGS

#define NUM_XMM_ARGS   8

The number of XMM registers available for argument passing.

Enumeration Type Documentation

◆ arg_class_t

Enumerator
NO_CLASS 

This eightbyte has not been classified yet. It's the initial state.

INTEGER 

This eightbyte should be passed in a general-purpose register (GPR).

SSE 

This eightbyte should be passed in an SSE register (XMM).

MEMORY 

The argument is too complex or large and must be passed on the stack.

Function Documentation

◆ classify_aggregate_sysv()

static void classify_aggregate_sysv ( infix_type type,
arg_class_t  classes[2],
size_t *  num_classes 
)
static

◆ classify_recursive()

static bool classify_recursive ( infix_type type,
size_t  offset,
arg_class_t  classes[2],
int  depth,
size_t *  field_count 
)
static

◆ generate_forward_argument_moves_sysv_x64() [1/2]

static infix_status generate_forward_argument_moves_sysv_x64 ( code_buffer buf,
infix_call_frame_layout layout,
infix_type **  arg_types,
size_t  num_args,
c23_maybe_unused size_t  num_fixed_args 
)
static

◆ generate_forward_argument_moves_sysv_x64() [2/2]

static infix_status generate_forward_argument_moves_sysv_x64 ( code_buffer buf,
infix_call_frame_layout layout,
infix_type **  arg_types,
size_t  num_args,
size_t  num_fixed_args 
)
static

◆ generate_forward_call_instruction_sysv_x64() [1/2]

static infix_status generate_forward_call_instruction_sysv_x64 ( code_buffer ,
infix_call_frame_layout  
)
static

◆ generate_forward_call_instruction_sysv_x64() [2/2]

static infix_status generate_forward_call_instruction_sysv_x64 ( code_buffer buf,
c23_maybe_unused infix_call_frame_layout layout 
)
static

◆ generate_forward_epilogue_sysv_x64()

static infix_status generate_forward_epilogue_sysv_x64 ( code_buffer buf,
infix_call_frame_layout layout,
infix_type ret_type 
)
static

◆ generate_forward_prologue_sysv_x64()

static infix_status generate_forward_prologue_sysv_x64 ( code_buffer buf,
infix_call_frame_layout layout 
)
static

◆ generate_reverse_argument_marshalling_sysv_x64()

static infix_status generate_reverse_argument_marshalling_sysv_x64 ( code_buffer buf,
infix_reverse_call_frame_layout layout,
infix_reverse_t context 
)
static

◆ generate_reverse_dispatcher_call_sysv_x64()

static infix_status generate_reverse_dispatcher_call_sysv_x64 ( code_buffer buf,
infix_reverse_call_frame_layout layout,
infix_reverse_t context 
)
static

◆ generate_reverse_epilogue_sysv_x64()

static infix_status generate_reverse_epilogue_sysv_x64 ( code_buffer buf,
infix_reverse_call_frame_layout layout,
infix_reverse_t context 
)
static

◆ generate_reverse_prologue_sysv_x64()

static infix_status generate_reverse_prologue_sysv_x64 ( code_buffer buf,
infix_reverse_call_frame_layout layout 
)
static

◆ prepare_forward_call_frame_sysv_x64()

static infix_status prepare_forward_call_frame_sysv_x64 ( infix_arena_t arena,
infix_call_frame_layout **  out_layout,
infix_type ret_type,
infix_type **  arg_types,
size_t  num_args,
size_t  num_fixed_args,
void *  target_fn 
)
static

◆ prepare_reverse_call_frame_sysv_x64()

static infix_status prepare_reverse_call_frame_sysv_x64 ( infix_arena_t arena,
infix_reverse_call_frame_layout **  out_layout,
infix_reverse_t context 
)
static

Variable Documentation

◆ g_sysv_x64_forward_spec

const infix_forward_abi_spec g_sysv_x64_forward_spec
Initial value:
= {
.prepare_forward_call_frame = prepare_forward_call_frame_sysv_x64,
.generate_forward_prologue = generate_forward_prologue_sysv_x64,
.generate_forward_argument_moves = generate_forward_argument_moves_sysv_x64,
.generate_forward_call_instruction = generate_forward_call_instruction_sysv_x64,
.generate_forward_epilogue = generate_forward_epilogue_sysv_x64}
static infix_status generate_forward_epilogue_sysv_x64(code_buffer *buf, infix_call_frame_layout *layout, infix_type *ret_type)
Definition abi_sysv_x64.c:718
static infix_status prepare_forward_call_frame_sysv_x64(infix_arena_t *arena, infix_call_frame_layout **out_layout, infix_type *ret_type, infix_type **arg_types, size_t num_args, size_t num_fixed_args, void *target_fn)
Definition abi_sysv_x64.c:335
static infix_status generate_forward_argument_moves_sysv_x64(code_buffer *buf, infix_call_frame_layout *layout, infix_type **arg_types, size_t num_args, size_t num_fixed_args)
static infix_status generate_forward_call_instruction_sysv_x64(code_buffer *, infix_call_frame_layout *)
static infix_status generate_forward_prologue_sysv_x64(code_buffer *buf, infix_call_frame_layout *layout)
Definition abi_sysv_x64.c:539

The v-table of System V x64 functions for generating forward trampolines.

◆ g_sysv_x64_reverse_spec

const infix_reverse_abi_spec g_sysv_x64_reverse_spec
Initial value:
= {
.prepare_reverse_call_frame = prepare_reverse_call_frame_sysv_x64,
.generate_reverse_prologue = generate_reverse_prologue_sysv_x64,
.generate_reverse_argument_marshalling = generate_reverse_argument_marshalling_sysv_x64,
.generate_reverse_dispatcher_call = generate_reverse_dispatcher_call_sysv_x64,
.generate_reverse_epilogue = generate_reverse_epilogue_sysv_x64}
static infix_status prepare_reverse_call_frame_sysv_x64(infix_arena_t *arena, infix_reverse_call_frame_layout **out_layout, infix_reverse_t *context)
Definition abi_sysv_x64.c:833
static infix_status generate_reverse_epilogue_sysv_x64(code_buffer *buf, infix_reverse_call_frame_layout *layout, infix_reverse_t *context)
Definition abi_sysv_x64.c:1060
static infix_status generate_reverse_prologue_sysv_x64(code_buffer *buf, infix_reverse_call_frame_layout *layout)
Definition abi_sysv_x64.c:886
static infix_status generate_reverse_dispatcher_call_sysv_x64(code_buffer *buf, infix_reverse_call_frame_layout *layout, infix_reverse_t *context)
Definition abi_sysv_x64.c:1010
static infix_status generate_reverse_argument_marshalling_sysv_x64(code_buffer *buf, infix_reverse_call_frame_layout *layout, infix_reverse_t *context)
Definition abi_sysv_x64.c:898

The v-table of System V x64 functions for generating reverse trampolines.

◆ GPR_ARGS

const x64_gpr GPR_ARGS[] = {RDI_REG, RSI_REG, RDX_REG, RCX_REG, R8_REG, R9_REG}
static

An array of GPRs used for passing the first 6 integer/pointer arguments, in order.

◆ XMM_ARGS

An array of XMM registers used for passing the first 8 floating-point arguments, in order.