From: chaoskagami Date: Mon, 25 Jul 2016 00:39:58 +0000 (-0400) Subject: Started to rewrite all of the awful static allocations out X-Git-Tag: v0.3.0~77 X-Git-Url: https://chaos.moe/g/?a=commitdiff_plain;h=031b9726e8612623c968d72abd558c0dd4070b00;p=corbenik%2Fcorbenik.git Started to rewrite all of the awful static allocations out --- diff --git a/include/firm/fcram.h b/include/firm/fcram.h index 81da640..f743a51 100644 --- a/include/firm/fcram.h +++ b/include/firm/fcram.h @@ -20,28 +20,19 @@ extern void *fcram_temp; #define FCRAM_TWL_FIRM_LOC (FCRAM_FIRM_LOC + FCRAM_SPACING) // Double size #define FCRAM_AGB_FIRM_LOC (FCRAM_TWL_FIRM_LOC + FCRAM_SPACING * 2) -// Location patches get loaded to. -#define FCRAM_PATCH_LOC (FCRAM_AGB_FIRM_LOC + FCRAM_SPACING * 2) - // Throwaway temporary space. Don't expect it to stay sane. -#define FCRAM_JUNK_LOC (FCRAM_PATCH_LOC + FCRAM_SPACING) - -// Path that the patch menu is created at. -#define FCRAM_MENU_LOC (FCRAM_JUNK_LOC + FCRAM_SPACING) - -// Path that the patch enable list is located at. -#define FCRAM_PATCHLIST_LOC (FCRAM_MENU_LOC + (FCRAM_SPACING / 2)) +#define FCRAM_JUNK_LOC FCRAM_START -// Path that the font will be loaded at. -#define FCRAM_FONT_LOC (FCRAM_PATCHLIST_LOC + (FCRAM_SPACING / 2)) +// Location to perform static allocations at. +#define FCRAM_STATIC_ALLOC_LOC (FCRAM_START + FCRAM_SPACING) -// Path that the menu for chains will be at -#define FCRAM_CHAIN_LOC (FCRAM_FONT_LOC + FCRAM_SPACING) +// Grow memory segment. +void *fake_sbrk(size_t bytes); -// Location to perform static allocations at. -#define FCRAM_STATIC_ALLOC_LOC (0x25000000) +// Allocate memory for use. +void *malloc (size_t size); -// Allocate static memory. -void *static_allocate(size_t bytes); +// Free in-use memory. +void free (void* ptr); #endif diff --git a/source/chain.c b/source/chain.c index e007919..7a102c4 100644 --- a/source/chain.c +++ b/source/chain.c @@ -8,7 +8,7 @@ uint32_t current_chain_index = 0; -struct options_s *chains = (struct options_s*)FCRAM_CHAIN_LOC; +struct options_s *chains = NULL; int show_menu(struct options_s *options, uint8_t *toggles); @@ -153,7 +153,10 @@ list_chain_build(char *name) } void chainload_menu() { - list_chain_build(PATH_CHAINS); + if (chains == NULL) { + chains = malloc(sizeof(struct options_s) * 100); + list_chain_build(PATH_CHAINS); + } show_menu(chains, NULL); } diff --git a/source/firm/fcram.c b/source/firm/fcram.c index 8b5d428..3b1b263 100644 --- a/source/firm/fcram.c +++ b/source/firm/fcram.c @@ -1,11 +1,59 @@ #include +// 16 <- AES block size. +#define SALLOC_ALIGN 16 + void *fcram_temp = (void *)0x23000000; void *fcram_static_mem = (void*)FCRAM_STATIC_ALLOC_LOC; -void *static_allocate(size_t bytes) { - size_t aligned_bytes = bytes + (4 - (bytes % 4)); // Align to integer size (for ARM processor) + +struct alloc_info* first_mem = NULL; + +// Low level static allocator / sbrk-like function. +void *fake_sbrk(size_t bytes) { void *ret = fcram_static_mem; - fcram_static_mem = (uint8_t*)fcram_static_mem + aligned_bytes; + + fcram_static_mem = (uint8_t*)fcram_static_mem + bytes; + return ret; } + +// This is an incredibly crappy and inefficient implementation of malloc/free nicked from stackoverflow. + +typedef struct free_block { + size_t size; + struct free_block* next; +} free_block; + +static free_block free_block_list_head = { 0, 0 }; + +// static const size_t overhead = sizeof(size_t); + +static const size_t align_to = 16; + +void* malloc(size_t size) { + size = (size + sizeof(free_block) + (align_to - 1)) & ~ (align_to - 1); + free_block* block = free_block_list_head.next; + free_block** head = &(free_block_list_head.next); + while (block != 0) { + if (block->size >= size) { + *head = block->next; + return ((char*)block) + sizeof(free_block); + } + head = &(block->next); + block = block->next; + } + + block = (free_block*)fake_sbrk(size); + block->size = size; + + return ((char*)block) + sizeof(free_block); +} + +void free(void* ptr) { + if (ptr == NULL) return; + + free_block* block = (free_block*)(((char*)ptr) - sizeof(free_block )); + block->next = free_block_list_head.next; + free_block_list_head.next = block; +} diff --git a/source/firm/firm.c b/source/firm/firm.c index 0a54d64..dadcf7d 100644 --- a/source/firm/firm.c +++ b/source/firm/firm.c @@ -6,17 +6,17 @@ #include #include -firm_h *firm_loc = (firm_h *)FCRAM_FIRM_LOC; +firm_h *firm_loc = NULL; uint32_t firm_size = FCRAM_SPACING; firm_section_h firm_proc9; exefs_h *firm_p9_exefs; -firm_h *twl_firm_loc = (firm_h *)FCRAM_TWL_FIRM_LOC; +firm_h *twl_firm_loc = NULL; uint32_t twl_firm_size = FCRAM_SPACING * 2; firm_section_h twl_firm_proc9; exefs_h *twl_firm_p9_exefs; -firm_h *agb_firm_loc = (firm_h *)FCRAM_AGB_FIRM_LOC; +firm_h *agb_firm_loc = NULL; uint32_t agb_firm_size = FCRAM_SPACING * 2; firm_section_h agb_firm_proc9; exefs_h *agb_firm_p9_exefs; @@ -40,7 +40,7 @@ void dump_firm(firm_h** buffer, uint8_t index) { uint32_t firm_offset = 0x0B130000 + (index % 2) * 0x400000, firm_size = 0x00100000; // 1MB, because - buffer[0] = static_allocate(firm_size); + buffer[0] = malloc(firm_size); uint8_t ctr[0x10], cid[0x10], @@ -514,6 +514,8 @@ load_firms() fprintf(stderr, "FIRM load triggered.\n"); + firm_loc = malloc(firm_size); + fprintf(stderr, "Loading NATIVE_FIRM\n"); if (load_firm(firm_loc, PATH_NATIVE_F, PATH_NATIVE_FIRMKEY, PATH_NATIVE_CETK, &firm_size, NATIVE_FIRM_TITLEID) != 0) { abort("\n Failed to load NATIVE_FIRM.\n"); @@ -521,6 +523,8 @@ load_firms() find_proc9(firm_loc, &firm_proc9, &firm_p9_exefs); fprintf(stderr, " Ver: %x, %u\n", get_firm_info(firm_loc)->version, get_firm_info(firm_loc)->console ); + twl_firm_loc = malloc(twl_firm_size); + fprintf(stderr, "TWL_FIRM\n"); if (load_firm(twl_firm_loc, PATH_TWL_F, PATH_TWL_FIRMKEY, PATH_TWL_CETK, &twl_firm_size, TWL_FIRM_TITLEID) != 0) { fprintf(stderr, "\n TWL_FIRM failed to load.\n"); @@ -530,6 +534,8 @@ load_firms() fprintf(stderr, " Ver: %x, %u\n", get_firm_info(twl_firm_loc)->version, get_firm_info(twl_firm_loc)->console ); } + agb_firm_loc = malloc(agb_firm_size); + fprintf(stderr, "AGB_FIRM\n"); if (load_firm(agb_firm_loc, PATH_AGB_F, PATH_AGB_FIRMKEY, PATH_AGB_CETK, &agb_firm_size, AGB_FIRM_TITLEID) != 0) { fprintf(stderr, "\n AGB_FIRM failed to load.\n"); diff --git a/source/interp.c b/source/interp.c index dbcfdba..eed4b45 100644 --- a/source/interp.c +++ b/source/interp.c @@ -647,12 +647,16 @@ execb(char *filename, int build_cache) // File wasn't found. The user didn't enable anything. return 0; } + uint32_t len = fsize(f); - fread((uint8_t *)FCRAM_PATCH_LOC, 1, len, f); + + uint8_t* patch_loc = malloc(len); + + fread(patch_loc, 1, len, f); fclose(f); if (build_cache == 1) { - patch = (struct system_patch *)FCRAM_PATCH_LOC; + patch = (struct system_patch*)patch_loc; // Make sure various bits are correct. if (memcmp(patch->magic, "AIDA", 4)) { @@ -711,7 +715,7 @@ execb(char *filename, int build_cache) return 0; } else { - patch_mem = (uint8_t *)FCRAM_PATCH_LOC; + patch_mem = patch_loc; patch_len = len; } #endif @@ -723,7 +727,7 @@ execb(char *filename, int build_cache) #ifndef LOADER if (stack_glob == NULL) { - stack_glob = static_allocate(STACK_SIZE); + stack_glob = malloc(STACK_SIZE); } #endif diff --git a/source/menu.c b/source/menu.c index d06b09c..3743a87 100644 --- a/source/menu.c +++ b/source/menu.c @@ -1,9 +1,10 @@ #include #include -#define MAX_PATCHES ((FCRAM_SPACING / 2) / sizeof(struct options_s)) -struct options_s *patches = (struct options_s *)FCRAM_MENU_LOC; -uint8_t *enable_list = (uint8_t *)FCRAM_PATCHLIST_LOC; +// FIXME - Remove limit +#define MAX_PATCHES 256 +struct options_s *patches = NULL; +uint8_t *enable_list = NULL; static struct options_s options[] = { // Patches. @@ -138,6 +139,12 @@ list_patches_build(char *name, int desc_is_fname) { current_menu_index_patches = 0; + if (!enable_list) + enable_list = malloc(FCRAM_SPACING / 2); // FIXME - the PATCHENABLE file has to go. Badly. + + if (!patches) + patches = malloc(sizeof(struct options_s) * 258); // FIXME - hard limit. Implement realloc. + memset(enable_list, 0, FCRAM_SPACING / 2); if (!desc_is_fname) { diff --git a/source/patcher.c b/source/patcher.c index 2d6f9c5..dc919af 100644 --- a/source/patcher.c +++ b/source/patcher.c @@ -13,6 +13,8 @@ extern int doing_autoboot; extern uint8_t *enable_list; +extern struct options_s* patches; + void wait() { @@ -34,8 +36,6 @@ generate_patch_cache() list_patches_build(PATH_PATCHES, 1); - struct options_s *patches = (struct options_s *)FCRAM_MENU_LOC; - for (int i = 0; patches[i].index != -1; i++) { if (enable_list[patches[i].index]) { // Patch is enabled. Cache it. diff --git a/source/std/draw.c b/source/std/draw.c index 8b60297..ff21b79 100644 --- a/source/std/draw.c +++ b/source/std/draw.c @@ -29,6 +29,8 @@ unsigned char color_top = 0xf0; unsigned char color_bottom = 0xf0; int kill_output = 0; +uint8_t* font_data = NULL; + #define TRANSP_THRESH 178 static uint8_t alphamap[256] = {0}; @@ -40,9 +42,9 @@ void std_init() { alphamap[i] = i - 0x7F; } - top_bg = static_allocate(TOP_SIZE); - bottom_bg = static_allocate(BOTTOM_SIZE); - log_buffer = static_allocate(LOG_BUFFER_SIZE); + top_bg = malloc(TOP_SIZE); + bottom_bg = malloc(BOTTOM_SIZE); + log_buffer = malloc(LOG_BUFFER_SIZE); } static uint32_t colors[16] = { @@ -190,7 +192,9 @@ void set_font(const char* filename) { unsigned int c_font_w = (new_w / 8) + (new_w % 8 ? 1 : 0); - fread((void*)FCRAM_FONT_LOC, 1, c_font_w * new_h * (256 - ' '), f); // Skip non-printing chars. + font_data = malloc(c_font_w * new_h * (256 - ' ')); + + fread(font_data, 1, c_font_w * new_h * (256 - ' '), f); // Skip non-printing chars. fclose(f); @@ -314,7 +318,7 @@ draw_character(uint8_t *screen, const uint32_t character, int ch_x, int ch_y, co int yDisplacementBg = ((height - (y + yy) - 1) * 3); unsigned int pos_b = xDisplacementBg + yDisplacementBg; - unsigned char char_dat = ((char*)FCRAM_FONT_LOC)[(character - ' ') * (c_font_w * font_h) + yy]; + unsigned char char_dat = font_data[(character - ' ') * (c_font_w * font_h) + yy]; for(unsigned int i=0; i < font_w + font_kern; i++) { screen[pos] = 0xFF;