Fixed selfpatch randomizer
This commit is contained in:
parent
b5cc83537d
commit
1b184f5740
@ -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) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user