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) {
|
||||
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;
|
||||
for (uint32_t offset = 0; offset < target->size; offset += alignment) {
|
||||
// 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++;
|
||||
|
||||
// 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;
|
||||
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++) {
|
||||
struct Field* f = &target->fields[it];
|
||||
|
||||
if (f->offset == origin->fill_begin)
|
||||
continue;
|
||||
|
||||
if (f->offset >= option_would_end)
|
||||
break;
|
||||
|
||||
@ -198,7 +204,7 @@ static uint32_t target_get_shuffle_options(const struct Target* target, uint32_t
|
||||
|
||||
origin_region_ptr += f->size;
|
||||
|
||||
if (origin_region_ptr > origin->end) {
|
||||
if (origin_region_ptr > true_origin_region_end) {
|
||||
conflict = 1;
|
||||
break;
|
||||
}
|
||||
@ -211,21 +217,25 @@ static uint32_t target_get_shuffle_options(const struct Target* target, uint32_t
|
||||
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,
|
||||
uint32_t new_offset) {
|
||||
print_indices("Before swap:", target);
|
||||
int origin_pulled = 0;
|
||||
uint32_t origin_region_ptr = origin_region->begin;
|
||||
int pulled = 0;
|
||||
|
||||
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++) {
|
||||
if (target->fields[it].initial_idx == origin_initial_index)
|
||||
continue;
|
||||
|
||||
// Fields that end before new_offset can stay there
|
||||
if (target->fields[it].offset + target->fields[it].size <= new_offset)
|
||||
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);
|
||||
|
||||
// First field in swap region is exchanged with origin
|
||||
if (!origin_pulled) {
|
||||
origin_pulled = 1;
|
||||
if (!pulled) {
|
||||
pulled = 1;
|
||||
|
||||
struct Field tmp = target->fields[it];
|
||||
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
|
||||
struct Field tmp = target->fields[it];
|
||||
|
||||
for (uint32_t pull_it = it + 1; pull_it <= origin_idx; pull_it++)
|
||||
target->fields[pull_it - 1] = target->fields[pull_it];
|
||||
if (origin_idx >= 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[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) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user