Made selfpatch easier to port to kernel
This commit is contained in:
parent
32a73df1cd
commit
a032f39cc5
@ -1,12 +1,28 @@
|
||||
add_library(spslr_randomizer STATIC
|
||||
src/randomizer.c
|
||||
src/spslr_randomizer.c
|
||||
)
|
||||
|
||||
target_include_directories(spslr_randomizer PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
|
||||
)
|
||||
|
||||
add_library(spslr_selfpatch STATIC src/selfpatch.c src/randomizer.c src/env.c)
|
||||
target_compile_options(spslr_randomizer PRIVATE
|
||||
-Wall
|
||||
-Wextra
|
||||
-Werror
|
||||
-Wmissing-prototypes
|
||||
-Wstrict-prototypes
|
||||
-Wold-style-definition
|
||||
-Wmissing-declarations
|
||||
)
|
||||
|
||||
set_target_properties(spslr_randomizer PROPERTIES
|
||||
C_STANDARD 11
|
||||
C_STANDARD_REQUIRED YES
|
||||
C_EXTENSIONS YES
|
||||
)
|
||||
|
||||
add_library(spslr_selfpatch STATIC src/spslr.c src/spslr_randomizer.c src/spslr_env.c)
|
||||
|
||||
target_link_libraries(spslr_selfpatch PUBLIC spslr_randomizer)
|
||||
|
||||
@ -15,6 +31,22 @@ target_include_directories(spslr_selfpatch PUBLIC
|
||||
$<INSTALL_INTERFACE:include>
|
||||
)
|
||||
|
||||
target_compile_options(spslr_selfpatch PRIVATE
|
||||
-Wall
|
||||
-Wextra
|
||||
-Werror
|
||||
-Wmissing-prototypes
|
||||
-Wstrict-prototypes
|
||||
-Wold-style-definition
|
||||
-Wmissing-declarations
|
||||
)
|
||||
|
||||
set_target_properties(spslr_selfpatch PROPERTIES
|
||||
C_STANDARD 11
|
||||
C_STANDARD_REQUIRED YES
|
||||
C_EXTENSIONS YES
|
||||
)
|
||||
|
||||
target_include_directories(spslr_patchcompile PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) # For spslr_list.h
|
||||
|
||||
add_subdirectory(test)
|
||||
|
||||
@ -1,18 +0,0 @@
|
||||
#ifndef SPSLR_ENV_H
|
||||
#define SPSLR_ENV_H
|
||||
|
||||
#include "spslr_types.h"
|
||||
|
||||
void spslr_env_panic(const char* reason);
|
||||
void spslr_env_poke_text_8(void* dst, spslr_u8 value);
|
||||
void spslr_env_poke_text_16(void* dst, spslr_u16 value);
|
||||
void spslr_env_poke_text_32(void* dst, spslr_u32 value);
|
||||
void spslr_env_poke_text_64(void* dst, spslr_u64 value);
|
||||
void* spslr_env_malloc(spslr_u32 n); // Either return valid buffer or panic internally
|
||||
void spslr_env_free(void* ptr);
|
||||
void spslr_env_poke_data(void* dst, const void* src, spslr_u32 n);
|
||||
void spslr_env_memset(void* dst, int v, spslr_u32 n);
|
||||
void spslr_env_memcpy(void* dst, const void* src, spslr_u32 n);
|
||||
spslr_u32 spslr_env_random_u32();
|
||||
|
||||
#endif
|
||||
@ -1,7 +1,7 @@
|
||||
#include <spslr.h>
|
||||
|
||||
#include "randomizer.h"
|
||||
#include "env.h"
|
||||
#include "spslr_randomizer.h"
|
||||
#include "spslr_env.h"
|
||||
#include "spslr_list_link.h"
|
||||
|
||||
#define SPSLR_SANITY_CHECK
|
||||
@ -13,18 +13,35 @@ static void spslr_selfpatch_patch_ipins(void);
|
||||
static void reorder_object(void* dst, const void* src, spslr_u32 target);
|
||||
static spslr_s64 spslr_calculate_ipin_value(spslr_u32 start);
|
||||
|
||||
static void* reorder_buffer = SPSLR_NULL;
|
||||
static void* reorder_buffer = NULL;
|
||||
|
||||
static void allocate_reorder_buffer();
|
||||
static void release_reorder_buffer();
|
||||
static void allocate_reorder_buffer(void);
|
||||
static void release_reorder_buffer(void);
|
||||
|
||||
void spslr_selfpatch(void) {
|
||||
void __init spslr_selfpatch(void) {
|
||||
if (spslr_randomizer_init() < 0)
|
||||
spslr_env_panic("failed to initialize randomizer");
|
||||
|
||||
#ifdef SPSLR_SANITY_CHECK
|
||||
for (spslr_u32 tidx = 0; tidx < spslr_target_cnt; tidx++) {
|
||||
if (spslr_randomizer_validate_target(tidx) < 0)
|
||||
spslr_env_panic("original layout of target %u is invalid", tidx);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (spslr_randomize() < 0)
|
||||
spslr_env_panic("failed to randomize targets");
|
||||
|
||||
#ifdef SPSLR_SANITY_CHECK
|
||||
for (spslr_u32 tidx = 0; tidx < spslr_target_cnt; tidx++) {
|
||||
if (spslr_randomizer_debug_target(tidx) < 0)
|
||||
spslr_env_panic("failed to debug print final layout of target %u", tidx);
|
||||
|
||||
if (spslr_randomizer_validate_target(tidx) < 0)
|
||||
spslr_env_panic("final layout of target %u is invalid", tidx);
|
||||
}
|
||||
#endif
|
||||
|
||||
allocate_reorder_buffer();
|
||||
spslr_selfpatch_patch_dpins();
|
||||
release_reorder_buffer();
|
||||
@ -34,7 +51,7 @@ void spslr_selfpatch(void) {
|
||||
spslr_randomizer_clear();
|
||||
}
|
||||
|
||||
static void allocate_reorder_buffer() {
|
||||
static void __init allocate_reorder_buffer(void) {
|
||||
if (reorder_buffer)
|
||||
return;
|
||||
|
||||
@ -46,28 +63,28 @@ static void allocate_reorder_buffer() {
|
||||
|
||||
reorder_buffer = spslr_env_malloc(max_target_size);
|
||||
if (!reorder_buffer)
|
||||
spslr_env_panic("failed to allocate reorder buffer");
|
||||
spslr_env_panic("failed to allocate reorder buffer of size %u", max_target_size);
|
||||
}
|
||||
|
||||
static void release_reorder_buffer() {
|
||||
static void __init release_reorder_buffer(void) {
|
||||
if (!reorder_buffer)
|
||||
return;
|
||||
|
||||
spslr_env_free(reorder_buffer);
|
||||
reorder_buffer = SPSLR_NULL;
|
||||
reorder_buffer = NULL;
|
||||
}
|
||||
|
||||
static void spslr_selfpatch_patch_dpins(void) {
|
||||
static void __init spslr_selfpatch_patch_dpins(void) {
|
||||
for (spslr_u32 dpidx = 0; dpidx < spslr_dpin_cnt; dpidx++) {
|
||||
const struct spslr_dpin* dp = &spslr_dpins[dpidx];
|
||||
spslr_selfpatch_patch_dpin((void*)dp->addr, dp->target);
|
||||
}
|
||||
}
|
||||
|
||||
static void reorder_object(void* dst, const void* src, spslr_u32 target) {
|
||||
static void __init reorder_object(void* dst, const void* src, spslr_u32 target) {
|
||||
spslr_u32 field_count;
|
||||
if (spslr_randomizer_get_target(target, SPSLR_NULL, &field_count))
|
||||
spslr_env_panic("failed to get target field count");
|
||||
if (spslr_randomizer_get_target(target, NULL, &field_count))
|
||||
spslr_env_panic("failed to get field count of target %u", target);
|
||||
|
||||
const spslr_u8* src_countable = (const spslr_u8*)src;
|
||||
spslr_u8* dst_countable = (spslr_u8*)dst;
|
||||
@ -75,16 +92,16 @@ static void reorder_object(void* dst, const void* src, spslr_u32 target) {
|
||||
for (spslr_u32 i = 0; i < field_count; i++) {
|
||||
struct spslr_randomizer_field_info finfo;
|
||||
if (spslr_randomizer_get_field(target, i, SPSLR_RANDOMIZER_FIELD_IDX_MODE_FINAL, &finfo))
|
||||
spslr_env_panic("failed to get ordered field descriptor");
|
||||
spslr_env_panic("failed to get descriptor of final field %u of target %u", i, target);
|
||||
|
||||
spslr_env_memcpy(dst_countable + finfo.offset, src_countable + finfo.initial_offset, finfo.size);
|
||||
}
|
||||
}
|
||||
|
||||
static void spslr_selfpatch_patch_dpin(void* addr, spslr_u32 target) {
|
||||
static void __init spslr_selfpatch_patch_dpin(void* addr, spslr_u32 target) {
|
||||
#ifdef SPSLR_SANITY_CHECK
|
||||
if (target >= spslr_target_cnt)
|
||||
spslr_env_panic("dpin refers to invalid target");
|
||||
spslr_env_panic("dpin refers to invalid target %u", target);
|
||||
#endif
|
||||
|
||||
const struct spslr_target* t = &spslr_targets[target];
|
||||
@ -94,7 +111,7 @@ static void spslr_selfpatch_patch_dpin(void* addr, spslr_u32 target) {
|
||||
spslr_env_poke_data(addr, reorder_buffer, t->size);
|
||||
}
|
||||
|
||||
static void spslr_selfpatch_patch_ipins(void) {
|
||||
static void __init spslr_selfpatch_patch_ipins(void) {
|
||||
for (spslr_u32 ipidx = 0; ipidx < spslr_ipin_cnt; ipidx++) {
|
||||
const struct spslr_ipin* ip = &spslr_ipins[ipidx];
|
||||
|
||||
@ -115,20 +132,20 @@ static void spslr_selfpatch_patch_ipins(void) {
|
||||
break;
|
||||
#ifdef SPSLR_SANITY_CHECK
|
||||
default:
|
||||
spslr_env_panic("invalid ipin size");
|
||||
spslr_env_panic("invalid ipin size of %u bytes", ip->size);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static spslr_s64 spslr_calculate_ipin_value(spslr_u32 start) {
|
||||
static spslr_s64 __init spslr_calculate_ipin_value(spslr_u32 start) {
|
||||
spslr_s64 res = 0;
|
||||
|
||||
spslr_u32 pc = start;
|
||||
while (true) {
|
||||
while (1) {
|
||||
#ifdef SPSLR_SANITY_CHECK
|
||||
if (pc >= spslr_ipin_op_cnt)
|
||||
spslr_env_panic("ipin op out of bounds");
|
||||
spslr_env_panic("ipin op %u out of bounds", pc);
|
||||
#endif
|
||||
|
||||
int end_flag = 0;
|
||||
@ -143,7 +160,8 @@ static spslr_s64 spslr_calculate_ipin_value(spslr_u32 start) {
|
||||
struct spslr_randomizer_field_info finfo;
|
||||
if (spslr_randomizer_get_field(op->op0.add_initial_offset_target,
|
||||
op->op1.add_initial_offset_field, SPSLR_RANDOMIZER_FIELD_IDX_MODE_ORIGINAL, &finfo))
|
||||
spslr_env_panic("failed to get initial field offset");
|
||||
spslr_env_panic("failed to get info of initial field %u of target %u",
|
||||
op->op1.add_initial_offset_field, op->op0.add_initial_offset_target);
|
||||
|
||||
res += finfo.initial_offset;
|
||||
}
|
||||
@ -151,9 +169,10 @@ static spslr_s64 spslr_calculate_ipin_value(spslr_u32 start) {
|
||||
case SPSLR_IPIN_OP_ADD_OFFSET:
|
||||
{
|
||||
struct spslr_randomizer_field_info finfo;
|
||||
if (spslr_randomizer_get_field(op->op0.add_initial_offset_target,
|
||||
if (spslr_randomizer_get_field(op->op0.add_offset_target,
|
||||
op->op1.add_offset_field, SPSLR_RANDOMIZER_FIELD_IDX_MODE_ORIGINAL, &finfo))
|
||||
spslr_env_panic("failed to get initial field offset");
|
||||
spslr_env_panic("failed to get info of initial field %u of target %u",
|
||||
op->op1.add_offset_field, op->op0.add_offset_target);
|
||||
|
||||
res += finfo.offset;
|
||||
}
|
||||
@ -161,9 +180,10 @@ static spslr_s64 spslr_calculate_ipin_value(spslr_u32 start) {
|
||||
case SPSLR_IPIN_OP_SUB_INITIAL_OFFSET:
|
||||
{
|
||||
struct spslr_randomizer_field_info finfo;
|
||||
if (spslr_randomizer_get_field(op->op0.add_initial_offset_target,
|
||||
if (spslr_randomizer_get_field(op->op0.sub_initial_offset_target,
|
||||
op->op1.sub_initial_offset_field, SPSLR_RANDOMIZER_FIELD_IDX_MODE_ORIGINAL, &finfo))
|
||||
spslr_env_panic("failed to get initial field offset");
|
||||
spslr_env_panic("failed to get info of initial field %u of target %u",
|
||||
op->op1.sub_initial_offset_field, op->op0.sub_initial_offset_target);
|
||||
|
||||
res -= finfo.initial_offset;
|
||||
}
|
||||
@ -171,9 +191,10 @@ static spslr_s64 spslr_calculate_ipin_value(spslr_u32 start) {
|
||||
case SPSLR_IPIN_OP_SUB_OFFSET:
|
||||
{
|
||||
struct spslr_randomizer_field_info finfo;
|
||||
if (spslr_randomizer_get_field(op->op0.add_initial_offset_target,
|
||||
if (spslr_randomizer_get_field(op->op0.sub_offset_target,
|
||||
op->op1.sub_offset_field, SPSLR_RANDOMIZER_FIELD_IDX_MODE_ORIGINAL, &finfo))
|
||||
spslr_env_panic("failed to get initial field offset");
|
||||
spslr_env_panic("failed to get info of initial field %u of target %u",
|
||||
op->op1.sub_offset_field, op->op0.sub_offset_target);
|
||||
|
||||
res -= finfo.offset;
|
||||
}
|
||||
@ -1,14 +1,15 @@
|
||||
#include "env.h"
|
||||
#include "spslr_env.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define PAGE_MASK ~(0x1000ull - 1)
|
||||
|
||||
static int spslr_env_get_prot(void* addr, int* prot) {
|
||||
static int __init spslr_env_get_prot(void* addr, int* prot) {
|
||||
FILE* f = fopen("/proc/self/maps", "r");
|
||||
if (!f)
|
||||
return -1;
|
||||
@ -43,10 +44,10 @@ static int spslr_env_get_prot(void* addr, int* prot) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void spslr_env_poke_safe(void* dst, const void* src, spslr_u32 n) {
|
||||
static void __init spslr_env_poke_safe(void* dst, const void* src, spslr_u32 n) {
|
||||
int original_prot;
|
||||
if (spslr_env_get_prot(dst, &original_prot))
|
||||
spslr_env_panic("failed to get prot of text poke destination");
|
||||
spslr_env_panic("failed to get prot of text poke destination %p", dst);
|
||||
|
||||
spslr_u64 ptr_uint = (spslr_u64)dst;
|
||||
spslr_u64 ptr_page = ptr_uint & PAGE_MASK;
|
||||
@ -63,56 +64,75 @@ static void spslr_env_poke_safe(void* dst, const void* src, spslr_u32 n) {
|
||||
mprotect((void*)ptr_page, prot_size, original_prot);
|
||||
}
|
||||
|
||||
void spslr_env_panic(const char* reason) {
|
||||
fprintf(stderr, "[spslr_panic] %s\n", reason);
|
||||
void __init spslr_env_panic(const char* fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
fprintf(stderr, "[spslr_panic] ");
|
||||
vfprintf(stderr, fmt, args);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
va_end(args);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void spslr_env_poke_text_8(void* dst, spslr_u8 value) {
|
||||
void __init spslr_env_debug(const char* fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
fprintf(stdout, "[spslr_debug] ");
|
||||
vfprintf(stdout, fmt, args);
|
||||
fprintf(stdout, "\n");
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void __init spslr_env_poke_text_8(void* dst, spslr_u8 value) {
|
||||
spslr_env_poke_safe(dst, &value, sizeof(value));
|
||||
}
|
||||
|
||||
void spslr_env_poke_text_16(void* dst, spslr_u16 value) {
|
||||
void __init spslr_env_poke_text_16(void* dst, spslr_u16 value) {
|
||||
spslr_env_poke_safe(dst, &value, sizeof(value));
|
||||
}
|
||||
|
||||
void spslr_env_poke_text_32(void* dst, spslr_u32 value) {
|
||||
void __init spslr_env_poke_text_32(void* dst, spslr_u32 value) {
|
||||
spslr_env_poke_safe(dst, &value, sizeof(value));
|
||||
}
|
||||
|
||||
void spslr_env_poke_text_64(void* dst, spslr_u64 value) {
|
||||
void __init spslr_env_poke_text_64(void* dst, spslr_u64 value) {
|
||||
spslr_env_poke_safe(dst, &value, sizeof(value));
|
||||
}
|
||||
|
||||
void* spslr_env_malloc(spslr_u32 n) {
|
||||
void* __init spslr_env_malloc(spslr_u32 n) {
|
||||
void* res = malloc(n);
|
||||
if (!res)
|
||||
spslr_env_panic("malloc failed");
|
||||
spslr_env_panic("malloc of size %u failed", n);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void spslr_env_free(void* ptr) {
|
||||
void __init spslr_env_free(void* ptr) {
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void spslr_env_poke_data(void* dst, const void* src, spslr_u32 n) {
|
||||
void __init spslr_env_poke_data(void* dst, const void* src, spslr_u32 n) {
|
||||
spslr_env_poke_safe(dst, src, n);
|
||||
}
|
||||
|
||||
void spslr_env_memset(void* dst, int v, spslr_u32 n) {
|
||||
void __init spslr_env_memset(void* dst, int v, spslr_u32 n) {
|
||||
memset(dst, v, n);
|
||||
}
|
||||
|
||||
void spslr_env_memcpy(void* dst, const void* src, spslr_u32 n) {
|
||||
void __init spslr_env_memcpy(void* dst, const void* src, spslr_u32 n) {
|
||||
memcpy(dst, src, n);
|
||||
}
|
||||
|
||||
static int rand_initialized = 0;
|
||||
|
||||
spslr_u32 spslr_env_random_u32() {
|
||||
spslr_u32 __init spslr_env_random_u32(void) {
|
||||
if (!rand_initialized) {
|
||||
srand(time(SPSLR_NULL));
|
||||
srand(time(NULL));
|
||||
rand_initialized = 1;
|
||||
}
|
||||
|
||||
49
selfpatch/src/spslr_env.h
Normal file
49
selfpatch/src/spslr_env.h
Normal file
@ -0,0 +1,49 @@
|
||||
#ifndef SPSLR_ENV_H
|
||||
#define SPSLR_ENV_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef __packed
|
||||
#define __packed __attribute__((packed))
|
||||
#endif
|
||||
|
||||
#ifndef __init
|
||||
#define __init /* only required in kernel */
|
||||
#endif
|
||||
|
||||
#ifndef __noreturn
|
||||
#define __noreturn __attribute__((noreturn))
|
||||
#endif
|
||||
|
||||
#ifndef __printf
|
||||
#define __printf(fmt_pos, arg_pos) __attribute__((format(printf, fmt_pos, arg_pos)))
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void*)0)
|
||||
#endif
|
||||
|
||||
typedef uint8_t spslr_u8;
|
||||
typedef uint16_t spslr_u16;
|
||||
typedef uint32_t spslr_u32;
|
||||
typedef uint64_t spslr_u64;
|
||||
typedef int32_t spslr_s32;
|
||||
typedef int64_t spslr_s64;
|
||||
typedef uintptr_t spslr_uintptr;
|
||||
|
||||
void __noreturn spslr_env_panic(const char* fmt, ...) __printf(1, 2);
|
||||
void spslr_env_debug(const char* fmt, ...) __printf(1, 2);
|
||||
|
||||
void spslr_env_poke_text_8(void* dst, spslr_u8 value);
|
||||
void spslr_env_poke_text_16(void* dst, spslr_u16 value);
|
||||
void spslr_env_poke_text_32(void* dst, spslr_u32 value);
|
||||
void spslr_env_poke_text_64(void* dst, spslr_u64 value);
|
||||
void* spslr_env_malloc(spslr_u32 n); // Either return valid buffer or panic internally
|
||||
void spslr_env_free(void* ptr);
|
||||
void spslr_env_poke_data(void* dst, const void* src, spslr_u32 n);
|
||||
void spslr_env_memset(void* dst, int v, spslr_u32 n);
|
||||
void spslr_env_memcpy(void* dst, const void* src, spslr_u32 n);
|
||||
spslr_u32 spslr_env_random_u32(void);
|
||||
|
||||
#endif
|
||||
@ -1,9 +1,7 @@
|
||||
#ifndef SPSLR_LIST_H
|
||||
#define SPSLR_LIST_H
|
||||
|
||||
#include "spslr_types.h"
|
||||
|
||||
#define __packed __attribute__((packed))
|
||||
#include "spslr_env.h"
|
||||
|
||||
#define SPSLR_IPIN_OP_PATCH 1
|
||||
#define SPSLR_IPIN_OP_ADD_INITIAL_OFFSET 2
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#include "randomizer.h"
|
||||
#include "spslr_randomizer.h"
|
||||
|
||||
#include "spslr_list_link.h"
|
||||
#include "env.h"
|
||||
#include "spslr_env.h"
|
||||
|
||||
struct Field {
|
||||
spslr_u32 offset; /* Final field offset -> fields[i].offset = offset of field i in final layout */
|
||||
@ -11,7 +11,7 @@ struct Field {
|
||||
|
||||
static struct Field* fields;
|
||||
|
||||
int spslr_randomizer_init() {
|
||||
int __init spslr_randomizer_init(void) {
|
||||
fields = (struct Field*)spslr_env_malloc(sizeof(struct Field) * spslr_target_field_cnt);
|
||||
if (!fields)
|
||||
return -1;
|
||||
@ -34,15 +34,15 @@ int spslr_randomizer_init() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spslr_randomizer_clear() {
|
||||
void __init spslr_randomizer_clear(void) {
|
||||
if (!fields)
|
||||
return;
|
||||
|
||||
spslr_env_free(fields);
|
||||
fields = SPSLR_NULL;
|
||||
fields = NULL;
|
||||
}
|
||||
|
||||
int spslr_randomizer_get_target(spslr_u32 target, spslr_u32* size, spslr_u32* fieldcnt) {
|
||||
int __init spslr_randomizer_get_target(spslr_u32 target, spslr_u32* size, spslr_u32* fieldcnt) {
|
||||
if (target >= spslr_target_cnt)
|
||||
return -1;
|
||||
|
||||
@ -57,7 +57,7 @@ int spslr_randomizer_get_target(spslr_u32 target, spslr_u32* size, spslr_u32* fi
|
||||
return 0;
|
||||
}
|
||||
|
||||
int spslr_randomizer_get_field(spslr_u32 target, spslr_u32 field, int field_idx_mode,
|
||||
int __init spslr_randomizer_get_field(spslr_u32 target, spslr_u32 field, int field_idx_mode,
|
||||
struct spslr_randomizer_field_info* info) {
|
||||
if (target >= spslr_target_cnt)
|
||||
return -1;
|
||||
@ -70,8 +70,8 @@ int spslr_randomizer_get_field(spslr_u32 target, spslr_u32 field, int field_idx_
|
||||
if (field >= t->fieldcnt)
|
||||
return -1;
|
||||
|
||||
const struct spslr_target_field* of = SPSLR_NULL;
|
||||
const struct Field* rf = SPSLR_NULL;
|
||||
const struct spslr_target_field* of = NULL;
|
||||
const struct Field* rf = NULL;
|
||||
|
||||
switch (field_idx_mode) {
|
||||
case SPSLR_RANDOMIZER_FIELD_IDX_MODE_ORIGINAL:
|
||||
@ -95,6 +95,57 @@ int spslr_randomizer_get_field(spslr_u32 target, spslr_u32 field, int field_idx_
|
||||
return 0;
|
||||
}
|
||||
|
||||
int spslr_randomizer_debug_target(spslr_u32 target) {
|
||||
spslr_u32 size, fieldcnt;
|
||||
|
||||
if (spslr_randomizer_get_target(target, &size, &fieldcnt) < 0)
|
||||
return -1;
|
||||
|
||||
spslr_env_debug("Target %u (%u fields, %u bytes):", target, fieldcnt, size);
|
||||
|
||||
for (spslr_u32 i = 0; i < fieldcnt; i++) {
|
||||
struct spslr_randomizer_field_info finfo;
|
||||
if (spslr_randomizer_get_field(target, i, SPSLR_RANDOMIZER_FIELD_IDX_MODE_ORIGINAL, &finfo) < 0)
|
||||
return -1;
|
||||
|
||||
spslr_env_debug(" Field %u (%u bytes) moved from offset %u to %u", i,
|
||||
finfo.size, finfo.initial_offset, finfo.offset);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int spslr_randomizer_validate_target(spslr_u32 target) {
|
||||
spslr_u32 tsize, fieldcnt;
|
||||
|
||||
if (spslr_randomizer_get_target(target, &tsize, &fieldcnt) < 0)
|
||||
return -1;
|
||||
|
||||
spslr_u32 cur_end = 0;
|
||||
|
||||
for (spslr_u32 i = 0; i < fieldcnt; i++) {
|
||||
struct spslr_randomizer_field_info finfo;
|
||||
if (spslr_randomizer_get_field(target, i, SPSLR_RANDOMIZER_FIELD_IDX_MODE_FINAL, &finfo) < 0)
|
||||
return -1;
|
||||
|
||||
if (finfo.offset < cur_end)
|
||||
return -1;
|
||||
|
||||
if (finfo.offset % finfo.alignment != 0)
|
||||
return -1;
|
||||
|
||||
if ((finfo.flags & SPSLR_FLAG_FIELD_FIXED) && finfo.offset != finfo.initial_offset)
|
||||
return -1;
|
||||
|
||||
if (finfo.offset + finfo.size > tsize)
|
||||
return -1;
|
||||
|
||||
cur_end = finfo.offset + finfo.size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// RANDOMIZATION CODE
|
||||
|
||||
struct ShuffleRegion {
|
||||
@ -119,23 +170,23 @@ static spslr_u32 rand_u32(void) {
|
||||
return spslr_env_random_u32();
|
||||
}
|
||||
|
||||
static struct Field* get_rfield(spslr_u32 target, spslr_u32 final_idx) {
|
||||
static struct Field* __init get_rfield(spslr_u32 target, spslr_u32 final_idx) {
|
||||
const struct spslr_target* t = &spslr_targets[target];
|
||||
return &fields[t->fieldoff + final_idx];
|
||||
}
|
||||
|
||||
static const struct spslr_target_field* get_ofield(spslr_u32 target, spslr_u32 orig_idx) {
|
||||
static const struct spslr_target_field* __init get_ofield(spslr_u32 target, spslr_u32 orig_idx) {
|
||||
const struct spslr_target* t = &spslr_targets[target];
|
||||
return &spslr_target_fields[t->fieldoff + orig_idx];
|
||||
}
|
||||
|
||||
static void get_origin_region(spslr_u32 target, spslr_u32 final_idx, struct ShuffleRegion* region) {
|
||||
static void __init get_origin_region(spslr_u32 target, spslr_u32 final_idx, struct ShuffleRegion* region) {
|
||||
const struct spslr_target* t = &spslr_targets[target];
|
||||
const struct Field* rf = get_rfield(target, final_idx);
|
||||
const struct spslr_target_field* of = get_ofield(target, rf->oidx);
|
||||
|
||||
region->fill_begin = rf->offset;
|
||||
region->fill_end = rf->offset + of->size;
|
||||
region->fill_end = region->fill_begin + of->size;
|
||||
|
||||
if (final_idx == 0) {
|
||||
region->begin = 0;
|
||||
@ -153,7 +204,7 @@ static void get_origin_region(spslr_u32 target, spslr_u32 final_idx, struct Shuf
|
||||
}
|
||||
}
|
||||
|
||||
static int option_is_valid(spslr_u32 target, spslr_u32 origin_final_idx, const struct ShuffleRegion* origin, spslr_u32 offset) {
|
||||
static int __init option_is_valid(spslr_u32 target, spslr_u32 origin_final_idx, const struct ShuffleRegion* origin, spslr_u32 offset) {
|
||||
const struct spslr_target* t = &spslr_targets[target];
|
||||
const struct spslr_target_field* origin_of =
|
||||
get_ofield(target, get_rfield(target, origin_final_idx)->oidx);
|
||||
@ -210,7 +261,7 @@ static int option_is_valid(spslr_u32 target, spslr_u32 origin_final_idx, const s
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pick_shuffle_option(spslr_u32 target, spslr_u32 origin_final_idx, const struct ShuffleRegion* origin,
|
||||
static int __init pick_shuffle_option(spslr_u32 target, spslr_u32 origin_final_idx, const struct ShuffleRegion* origin,
|
||||
spslr_u32 alignment, spslr_u32* selected) {
|
||||
const struct spslr_target* t = &spslr_targets[target];
|
||||
spslr_u32 seen = 0;
|
||||
@ -228,7 +279,7 @@ static int pick_shuffle_option(spslr_u32 target, spslr_u32 origin_final_idx, con
|
||||
return seen ? 0 : -1;
|
||||
}
|
||||
|
||||
static void do_swap(spslr_u32 target, spslr_u32 origin_idx,
|
||||
static void __init do_swap(spslr_u32 target, spslr_u32 origin_idx,
|
||||
const struct ShuffleRegion* origin_region, spslr_u32 new_offset) {
|
||||
const struct spslr_target* t = &spslr_targets[target];
|
||||
int pulled = 0;
|
||||
@ -306,7 +357,7 @@ static void do_swap(spslr_u32 target, spslr_u32 origin_idx,
|
||||
}
|
||||
}
|
||||
|
||||
static void shuffle_one_target(spslr_u32 target) {
|
||||
static void __init shuffle_one_target(spslr_u32 target) {
|
||||
const struct spslr_target* t = &spslr_targets[target];
|
||||
if (t->fieldcnt == 0)
|
||||
return;
|
||||
@ -330,7 +381,7 @@ static void shuffle_one_target(spslr_u32 target) {
|
||||
do_swap(target, origin_final_idx, &origin_region, selected_option);
|
||||
}
|
||||
|
||||
static void shuffle_target(spslr_u32 target) {
|
||||
static void __init shuffle_target(spslr_u32 target) {
|
||||
const struct spslr_target* t = &spslr_targets[target];
|
||||
spslr_u32 shuffle_count = t->fieldcnt * 2;
|
||||
|
||||
@ -338,7 +389,7 @@ static void shuffle_target(spslr_u32 target) {
|
||||
shuffle_one_target(target);
|
||||
}
|
||||
|
||||
int spslr_randomize() {
|
||||
int __init spslr_randomize(void) {
|
||||
if (!fields)
|
||||
return -1;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#ifndef SPSLR_RANDOMIZER_H
|
||||
#define SPSLR_RANDOMIZER_H
|
||||
|
||||
#include "spslr_types.h"
|
||||
#include "spslr_env.h"
|
||||
|
||||
#define SPSLR_RANDOMIZER_FIELD_IDX_MODE_ORIGINAL 1
|
||||
#define SPSLR_RANDOMIZER_FIELD_IDX_MODE_FINAL 2
|
||||
@ -14,12 +14,15 @@ struct spslr_randomizer_field_info {
|
||||
spslr_u32 flags;
|
||||
};
|
||||
|
||||
int spslr_randomizer_init();
|
||||
int spslr_randomize();
|
||||
void spslr_randomizer_clear();
|
||||
int spslr_randomizer_init(void);
|
||||
int spslr_randomize(void);
|
||||
void spslr_randomizer_clear(void);
|
||||
|
||||
int spslr_randomizer_get_target(spslr_u32 target, spslr_u32* size, spslr_u32* fieldcnt);
|
||||
int spslr_randomizer_get_field(spslr_u32 target, spslr_u32 field, int field_idx_mode,
|
||||
struct spslr_randomizer_field_info* info);
|
||||
|
||||
int spslr_randomizer_debug_target(spslr_u32 target);
|
||||
int spslr_randomizer_validate_target(spslr_u32 target);
|
||||
|
||||
#endif
|
||||
@ -1,17 +0,0 @@
|
||||
#ifndef SPSLR_TYPES_H
|
||||
#define SPSLR_TYPES_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
typedef uint8_t spslr_u8;
|
||||
typedef uint16_t spslr_u16;
|
||||
typedef uint32_t spslr_u32;
|
||||
typedef uint64_t spslr_u64;
|
||||
typedef int32_t spslr_s32;
|
||||
typedef int64_t spslr_s64;
|
||||
typedef uintptr_t spslr_uintptr;
|
||||
|
||||
#define SPSLR_NULL NULL
|
||||
|
||||
#endif
|
||||
@ -2,11 +2,12 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <spslr_list_link.h>
|
||||
#include <randomizer.h>
|
||||
#include <spslr_randomizer.h>
|
||||
|
||||
void *spslr_env_malloc(size_t size) {
|
||||
void *spslr_env_malloc(spslr_u32 size) {
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
@ -14,12 +15,23 @@ void spslr_env_free(void *ptr) {
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
uint32_t spslr_env_random_u32(void) {
|
||||
return ((uint32_t)rand() << 16) ^ (uint32_t)rand();
|
||||
spslr_u32 spslr_env_random_u32(void) {
|
||||
return ((spslr_u32)rand() << 16) ^ (spslr_u32)rand();
|
||||
}
|
||||
|
||||
const uint32_t spslr_target_cnt = 1;
|
||||
const uint32_t spslr_target_field_cnt = 196;
|
||||
void __init spslr_env_debug(const char* fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
fprintf(stdout, "[spslr_debug] ");
|
||||
vfprintf(stdout, fmt, args);
|
||||
fprintf(stdout, "\n");
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
const spslr_u32 spslr_target_cnt = 1;
|
||||
const spslr_u32 spslr_target_field_cnt = 196;
|
||||
|
||||
const struct spslr_target spslr_targets[] = {
|
||||
{
|
||||
@ -228,15 +240,15 @@ const struct spslr_target_field spslr_target_fields[] = {
|
||||
{ .offset = 2816, .size = 16, .alignment = 8, .flags = 0 }
|
||||
};
|
||||
|
||||
static int check_target(uint32_t tidx) {
|
||||
uint32_t tsize, fieldcnt;
|
||||
static int check_target(spslr_u32 tidx) {
|
||||
spslr_u32 tsize, fieldcnt;
|
||||
|
||||
if (spslr_randomizer_get_target(tidx, &tsize, &fieldcnt) < 0)
|
||||
return -1;
|
||||
|
||||
uint32_t cur_end = 0;
|
||||
spslr_u32 cur_end = 0;
|
||||
|
||||
for (uint32_t i = 0; i < fieldcnt; i++) {
|
||||
for (spslr_u32 i = 0; i < fieldcnt; i++) {
|
||||
struct spslr_randomizer_field_info finfo;
|
||||
if (spslr_randomizer_get_field(tidx, i, SPSLR_RANDOMIZER_FIELD_IDX_MODE_FINAL, &finfo) < 0) {
|
||||
fprintf(stderr, "failed to get field from randomizer\n");
|
||||
@ -272,9 +284,9 @@ static int check_target(uint32_t tidx) {
|
||||
int main(void) {
|
||||
srand((unsigned)time(NULL));
|
||||
|
||||
uint32_t rounds = 1000;
|
||||
spslr_u32 rounds = 1000;
|
||||
|
||||
for (uint32_t iter = 0; iter < rounds; iter++) {
|
||||
for (spslr_u32 iter = 0; iter < rounds; iter++) {
|
||||
if (spslr_randomizer_init() < 0) {
|
||||
fprintf(stderr, "init failed\n");
|
||||
return 1;
|
||||
@ -285,7 +297,7 @@ int main(void) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (uint32_t tidx = 0; tidx < spslr_target_cnt; tidx++) {
|
||||
for (spslr_u32 tidx = 0; tidx < spslr_target_cnt; tidx++) {
|
||||
if (check_target(tidx) < 0) {
|
||||
fprintf(stderr, "check failed at iter %u target %u\n", iter, tidx);
|
||||
return 1;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user