selfpatch-slr/selfpatch/src/targets.c

133 lines
2.3 KiB
C

#include "targets.h"
#include <stdlib.h>
struct Field {
uint32_t initial_offset;
uint32_t initial_idx;
uint32_t offset;
uint32_t size;
uint32_t flags;
};
struct FinalField {
uint32_t initial_offset;
uint32_t offset;
};
struct Target {
uint32_t uid;
uint32_t size;
uint32_t field_count;
uint32_t present_field_count;
struct Field* fields;
struct FinalField* final_fields; // After rand (indexable by initial layout)
struct Target* next;
};
static struct Target* targets = NULL;
static struct Target* find_target(uint32_t uid) {
struct Target* cur = targets;
while (cur) {
if (cur->uid == uid)
return cur;
cur = cur->next;
}
return NULL;
}
static int add_target(uint32_t uid, uint32_t size, uint32_t fieldcnt) {
if (find_target(uid))
return -1;
struct Target* new_target = (struct Target*)malloc(sizeof(struct Target));
if (!new_target)
return -1;
new_target->uid = uid;
new_target->size = size;
new_target->field_count = fieldcnt;
new_target->present_field_count = 0;
new_target->final_fields = NULL;
new_target->fields = (struct Field*)malloc(sizeof(struct Field) * fieldcnt);
if (!new_target->fields) {
free(new_target);
return -1;
}
new_target->next = targets;
targets = new_target;
return 0;
}
static void clear_targets() {
struct Target* cur = targets;
while (cur) {
if (cur->fields)
free(cur->fields);
if (cur->final_fields)
free(cur->final_fields);
struct Target* tmp = cur;
cur = cur->next;
free(tmp);
}
targets = NULL;
}
int spslr_target(uint32_t uid, uint32_t size, uint32_t fieldcnt) {
if (find_target(uid))
return -1;
return add_target(uid, size, fieldcnt);
}
int spslr_field(uint32_t target, uint32_t offset, uint32_t size, uint32_t flags) {
struct Target* t = find_target(target);
if (!t)
return -1;
if (offset + size > t->size)
return -1;
if (t->present_field_count >= t->field_count)
return -1;
if (t->present_field_count) {
struct Field* pred = &t->fields[t->present_field_count - 1];
if (offset < pred->offset + pred->size)
return -1;
}
uint32_t idx = t->present_field_count++;
struct Field* f = &t->fields[idx];
f->initial_offset = offset;
f->initial_idx = idx;
f->offset = offset;
f->size = size;
f->flags = flags;
return 0;
}
int spslr_randomize(uint32_t target) {
// TODO
return 0;
}
void spslr_targets_clear() {
clear_targets();
}