Fixed selfpatch randomizer

This commit is contained in:
York Jasper Niebuhr 2025-10-28 00:34:13 +01:00
parent b5cc83537d
commit 1b184f5740

View File

@ -161,13 +161,6 @@ static uint32_t target_get_shuffle_options(const struct Target* target, uint32_t
const struct ShuffleRegion* origin, uint32_t alignment) { const struct ShuffleRegion* origin, uint32_t alignment) {
uint32_t count = 0; uint32_t count = 0;
/*
TODO
Self overlap...
1. Can skip swap check for origin field
2. Origin field can however reduce one side of the origin region if it still overlaps
*/
uint32_t current_field = 0; uint32_t current_field = 0;
for (uint32_t offset = 0; offset < target->size; offset += alignment) { for (uint32_t offset = 0; offset < target->size; offset += alignment) {
// Placing the origin region here or further would exceed struct boundaries // Placing the origin region here or further would exceed struct boundaries
@ -180,10 +173,23 @@ static uint32_t target_get_shuffle_options(const struct Target* target, uint32_t
+ target->fields[current_field].size <= offset) current_field++; + target->fields[current_field].size <= offset) current_field++;
// If origin->fill_begin was placed at offset, could all fields that overlap with range swap with origin? // If origin->fill_begin was placed at offset, could all fields that overlap with range swap with origin?
uint32_t true_origin_region_begin = origin->begin;
uint32_t true_origin_region_end = origin->end;
if (offset <= origin->fill_begin && option_would_end > true_origin_region_begin)
true_origin_region_begin = option_would_end;
if (offset >= origin->fill_begin && offset < true_origin_region_end)
true_origin_region_end = offset;
int conflict = 0; int conflict = 0;
uint32_t origin_region_ptr = origin->begin; uint32_t origin_region_ptr = true_origin_region_begin;
for (uint32_t it = current_field; it < target->field_count; it++) { for (uint32_t it = current_field; it < target->field_count; it++) {
struct Field* f = &target->fields[it]; struct Field* f = &target->fields[it];
if (f->offset == origin->fill_begin)
continue;
if (f->offset >= option_would_end) if (f->offset >= option_would_end)
break; break;
@ -198,7 +204,7 @@ static uint32_t target_get_shuffle_options(const struct Target* target, uint32_t
origin_region_ptr += f->size; origin_region_ptr += f->size;
if (origin_region_ptr > origin->end) { if (origin_region_ptr > true_origin_region_end) {
conflict = 1; conflict = 1;
break; break;
} }
@ -211,21 +217,25 @@ static uint32_t target_get_shuffle_options(const struct Target* target, uint32_t
return count; return count;
} }
static void print_indices(const char* txt, const struct Target* target) {
// TODO
printf("%s\n", txt);
for (uint32_t i = 0; i < target->field_count; i++) {
printf(" %u\n", target->fields[i].initial_idx);
}
}
static void target_swap(struct Target* target, uint32_t origin_idx, const struct ShuffleRegion* origin_region, static void target_swap(struct Target* target, uint32_t origin_idx, const struct ShuffleRegion* origin_region,
uint32_t new_offset) { uint32_t new_offset) {
print_indices("Before swap:", target); int pulled = 0;
int origin_pulled = 0;
uint32_t origin_region_ptr = origin_region->begin;
uint32_t option_fill_end = new_offset + (origin_region->fill_end - origin_region->fill_begin); uint32_t option_fill_end = new_offset + (origin_region->fill_end - origin_region->fill_begin);
// If origin->fill_begin was placed at offset, could all fields that overlap with range swap with origin?
uint32_t true_origin_region_begin = origin_region->begin;
if (new_offset <= origin_region->fill_begin && option_fill_end > true_origin_region_begin)
true_origin_region_begin = option_fill_end;
uint32_t origin_initial_index = target->fields[origin_idx].initial_idx;
uint32_t origin_region_ptr = true_origin_region_begin;
for (uint32_t it = 0; it < target->field_count; it++) { for (uint32_t it = 0; it < target->field_count; it++) {
if (target->fields[it].initial_idx == origin_initial_index)
continue;
// Fields that end before new_offset can stay there // Fields that end before new_offset can stay there
if (target->fields[it].offset + target->fields[it].size <= new_offset) if (target->fields[it].offset + target->fields[it].size <= new_offset)
continue; continue;
@ -239,8 +249,8 @@ static void target_swap(struct Target* target, uint32_t origin_idx, const struct
origin_region_ptr += falign - (origin_region_ptr % falign); origin_region_ptr += falign - (origin_region_ptr % falign);
// First field in swap region is exchanged with origin // First field in swap region is exchanged with origin
if (!origin_pulled) { if (!pulled) {
origin_pulled = 1; pulled = 1;
struct Field tmp = target->fields[it]; struct Field tmp = target->fields[it];
target->fields[it] = target->fields[origin_idx]; target->fields[it] = target->fields[origin_idx];
@ -259,12 +269,28 @@ static void target_swap(struct Target* target, uint32_t origin_idx, const struct
// For all other fields in swap region, pull all until origin_idx one forward and place at origin_idx // For all other fields in swap region, pull all until origin_idx one forward and place at origin_idx
struct Field tmp = target->fields[it]; struct Field tmp = target->fields[it];
if (origin_idx >= it) {
for (uint32_t pull_it = it + 1; pull_it <= origin_idx; pull_it++) for (uint32_t pull_it = it + 1; pull_it <= origin_idx; pull_it++)
target->fields[pull_it - 1] = target->fields[pull_it]; target->fields[pull_it - 1] = target->fields[pull_it];
target->fields[origin_idx] = tmp; target->fields[origin_idx] = tmp;
target->fields[origin_idx].offset = origin_region_ptr;
origin_region_ptr += target->fields[origin_idx].size;
} else {
// O X A B C -> pulled=0
// A X O B C -> pulled=1
// A B X O C -> pulled=2
// A B C X O -> pulled=3
for (uint32_t pull_it = it; pull_it > origin_idx + pulled; pull_it--)
target->fields[pull_it] = target->fields[pull_it - 1];
target->fields[origin_idx + pulled] = tmp;
target->fields[origin_idx + pulled].offset = origin_region_ptr;
origin_region_ptr += target->fields[origin_idx + pulled].size;
}
pulled++;
} }
print_indices("After swap:", target);
} }
static void target_shuffle_one(struct Target* target) { static void target_shuffle_one(struct Target* target) {