kernel .crt0 in .rodata reacts only (support for 17.0.0 pk21)

This commit is contained in:
Michael Scire 2023-10-10 18:46:30 -07:00
parent 8017a7a6b6
commit 1d64a83450
2 changed files with 54 additions and 7 deletions

View file

@ -307,7 +307,22 @@ void pk11_save(pk11_ctx_t *ctx) {
} }
} }
static bool pk21_is_valid_kernel_map(const kernel_map_t *map, uint32_t max_size) { static bool pk21_is_valid_kernel_map(const kernel_map_t *raw_map, uint32_t max_size, uint32_t adj) {
kernel_map_t adjusted_map = *raw_map;
adjusted_map.text_start_offset += adj;
adjusted_map.text_end_offset += adj;
adjusted_map.rodata_start_offset += adj;
adjusted_map.rodata_end_offset += adj;
adjusted_map.data_start_offset += adj;
adjusted_map.data_end_offset += adj;
adjusted_map.bss_start_offset += adj;
adjusted_map.bss_end_offset += adj;
adjusted_map.ini1_start_offset += adj;
adjusted_map.dynamic_offset += adj;
adjusted_map.init_array_start_offset += adj;
adjusted_map.init_array_end_offset += adj;
const kernel_map_t *map = &adjusted_map;
if (map->text_start_offset != 0) return false; if (map->text_start_offset != 0) return false;
if (map->text_start_offset >= map->text_end_offset) return false; if (map->text_start_offset >= map->text_end_offset) return false;
if (map->text_end_offset & 0xFFF) return false; if (map->text_end_offset & 0xFFF) return false;
@ -424,15 +439,46 @@ void pk21_process(pk21_ctx_t *ctx) {
ctx->ini1_ctx.header = (ini1_header_t *)(ctx->sections + ctx->header.section_sizes[0]); ctx->ini1_ctx.header = (ini1_header_t *)(ctx->sections + ctx->header.section_sizes[0]);
} else { } else {
ctx->ini1_ctx.header = calloc(1, sizeof(ini1_header_t)); ctx->ini1_ctx.header = calloc(1, sizeof(ini1_header_t));
/* 17.0.0+ branch-to-rodata */
if (((*(const uint64_t *)ctx->sections) & UINT64_C(0xFFFFFFFFFF000000)) == UINT64_C(0x0000000014000000)) {
uint32_t branch_target = ((*(const uint32_t *)ctx->sections) & 0x00FFFFFF) << 2;
for (offset = branch_target; offset < branch_target + 0x1000; offset += 4) {
kernel_map_t *kernel_map = (kernel_map_t *)(ctx->sections + offset);
if (pk21_is_valid_kernel_map(kernel_map, ctx->header.section_sizes[0], offset) && *(const uint32_t *)(ctx->sections + offset + kernel_map->ini1_start_offset) == MAGIC_INI1) {
ctx->kernel_map = calloc(1, sizeof(kernel_map_t));
*(ctx->kernel_map) = *kernel_map;
ctx->kernel_map->text_start_offset += offset;
ctx->kernel_map->text_end_offset += offset;
ctx->kernel_map->rodata_start_offset += offset;
ctx->kernel_map->rodata_end_offset += offset;
ctx->kernel_map->data_start_offset += offset;
ctx->kernel_map->data_end_offset += offset;
ctx->kernel_map->bss_start_offset += offset;
ctx->kernel_map->bss_end_offset += offset;
ctx->kernel_map->ini1_start_offset += offset;
ctx->kernel_map->dynamic_offset += offset;
ctx->kernel_map->init_array_start_offset += offset;
ctx->kernel_map->init_array_end_offset += offset;
ctx->kernel_map->system_registers_offset += offset;
ctx->ini1_ctx.header = (ini1_header_t *)(ctx->sections + ctx->kernel_map->ini1_start_offset);
break;
}
}
} else {
for (offset = 0; offset < 0x1000; offset += 4) { for (offset = 0; offset < 0x1000; offset += 4) {
kernel_map_t *kernel_map = (kernel_map_t *)(ctx->sections + offset); kernel_map_t *kernel_map = (kernel_map_t *)(ctx->sections + offset);
if (pk21_is_valid_kernel_map(kernel_map, ctx->header.section_sizes[0]) && *(const uint32_t *)(ctx->sections + kernel_map->ini1_start_offset) == MAGIC_INI1) { if (pk21_is_valid_kernel_map(kernel_map, ctx->header.section_sizes[0], 0) && *(const uint32_t *)(ctx->sections + kernel_map->ini1_start_offset) == MAGIC_INI1) {
ctx->kernel_map = kernel_map; ctx->kernel_map = kernel_map;
ctx->ini1_ctx.header = (ini1_header_t *)(ctx->sections + ctx->kernel_map->ini1_start_offset); ctx->ini1_ctx.header = (ini1_header_t *)(ctx->sections + ctx->kernel_map->ini1_start_offset);
break; break;
} }
} }
} }
}
if (ctx->ini1_ctx.header->magic == MAGIC_INI1 && ctx->ini1_ctx.header->num_processes <= INI1_MAX_KIPS) { if (ctx->ini1_ctx.header->magic == MAGIC_INI1 && ctx->ini1_ctx.header->num_processes <= INI1_MAX_KIPS) {
offset = 0; offset = 0;
for (unsigned int i = 0; i < ctx->ini1_ctx.header->num_processes; i++) { for (unsigned int i = 0; i < ctx->ini1_ctx.header->num_processes; i++) {

View file

@ -209,6 +209,7 @@ typedef struct {
uint32_t dynamic_offset; uint32_t dynamic_offset;
uint32_t init_array_start_offset; uint32_t init_array_start_offset;
uint32_t init_array_end_offset; uint32_t init_array_end_offset;
uint32_t system_registers_offset; /* 17.0.0+ */
} kernel_map_t; } kernel_map_t;
typedef struct { typedef struct {