:: commit c0417a875df8a73c690dbb1f5135570726de2b59

mintsuki <mintsuki@protonmail.com> — 2020-11-27 18:33

parents: 81b9911613

config: Dynamically allocate buffer for config values when requested

diff --git a/limine-pxe.bin b/limine-pxe.bin
index 30c86eab..cfd63bc5 100644
Binary files a/limine-pxe.bin and b/limine-pxe.bin differ
diff --git a/limine.bin b/limine.bin
index 7c19f54e..f2e53300 100644
Binary files a/limine.bin and b/limine.bin differ
diff --git a/stage2.map b/stage2.map
index 266ffc58..fcd22902 100644
Binary files a/stage2.map and b/stage2.map differ
diff --git a/stage2/drivers/vbe.c b/stage2/drivers/vbe.c
index 602ae5c5..24514caf 100644
--- a/stage2/drivers/vbe.c
+++ b/stage2/drivers/vbe.c
@@ -351,12 +351,11 @@ void vbe_putchar(char c) {
 }
 
 bool vbe_tty_init(int *_rows, int *_cols, uint32_t *_colours, int _margin, int _margin_gradient, struct image *_background) {
-    char buf[32];
-
     int req_width = 0, req_height = 0, req_bpp = 0;
 
-    if (config_get_value(NULL, buf, 0, 32, "MENU_RESOLUTION"))
-        parse_resolution(&req_width, &req_height, &req_bpp, buf);
+    char *menu_resolution = config_get_value(NULL, 0, "MENU_RESOLUTION");
+    if (menu_resolution == NULL)
+        parse_resolution(&req_width, &req_height, &req_bpp, menu_resolution);
 
     // We force bpp to 32
     req_bpp = 32;
diff --git a/stage2/lib/config.c b/stage2/lib/config.c
index 4fc70c92..6f35fa31 100644
--- a/stage2/lib/config.c
+++ b/stage2/lib/config.c
@@ -200,9 +200,8 @@ cont:
     return ret;
 }
 
-char *config_get_value(const char *config,
-                       char *buf, size_t index, size_t limit, const char *key) {
-    if (!limit || !buf || !key)
+char *config_get_value(const char *config, size_t index, const char *key) {
+    if (!key)
         return NULL;
 
     if (config == NULL)
@@ -217,13 +216,12 @@ char *config_get_value(const char *config,
             if (index--)
                 continue;
             i += key_len + 1;
-            size_t j;
-            for (j = 0; config[i + j] != SEPARATOR && config[i + j]; j++) {
-                if (j == limit - 1)
-                    break;
-                buf[j] = config[i + j];
-            }
-            buf[j] = 0;
+            size_t value_len;
+            for (value_len = 0;
+                 config[i + value_len] != SEPARATOR && config[i + value_len];
+                 value_len++);
+            char *buf = ext_mem_alloc(value_len + 1);
+            memcpy(buf, config + i, value_len);
             return buf;
         }
     }
diff --git a/stage2/lib/config.h b/stage2/lib/config.h
index 49eb2036..005ed91c 100644
--- a/stage2/lib/config.h
+++ b/stage2/lib/config.h
@@ -23,7 +23,6 @@ int init_config_pxe(void);
 int init_config(size_t config_size);
 bool config_get_entry_name(char *ret, size_t index, size_t limit);
 char *config_get_entry(size_t *size, size_t index);
-char *config_get_value(const char *config,
-                       char *buf, size_t index, size_t limit, const char *key);
+char *config_get_value(const char *config, size_t index, const char *key);
 
 #endif
diff --git a/stage2/lib/print.c b/stage2/lib/print.c
index 0c4bf844..57b70699 100644
--- a/stage2/lib/print.c
+++ b/stage2/lib/print.c
@@ -119,8 +119,9 @@ static char print_buf[PRINT_BUF_MAX];
 
 void vprint(const char *fmt, va_list args) {
     if (config_ready && e9_output == -1) {
-        e9_output = config_get_value(NULL, print_buf, 0, PRINT_BUF_MAX, "E9_OUTPUT") &&
-                    !strcmp(print_buf, "yes");
+        char *e9_output_config = config_get_value(NULL, 0, "E9_OUTPUT");
+        e9_output = e9_output_config != NULL &&
+                    !strcmp(e9_output_config, "yes");
     }
 
     size_t print_buf_i = 0;
diff --git a/stage2/lib/trace.c b/stage2/lib/trace.c
index 5bd88a15..362379ed 100644
--- a/stage2/lib/trace.c
+++ b/stage2/lib/trace.c
@@ -11,8 +11,8 @@
 static char *stage2_map = NULL;
 
 void trace_init(void) {
-    char map_filename[80];
-    if (!config_get_value(NULL, map_filename, 0, 80, "STAGE2_MAP"))
+    char *map_filename = config_get_value(NULL, 0, "STAGE2_MAP");
+    if (map_filename == NULL)
         return;
 
     struct file_handle stage2_map_file;
diff --git a/stage2/main.c b/stage2/main.c
index c2757af2..25d0ebe1 100644
--- a/stage2/main.c
+++ b/stage2/main.c
@@ -73,8 +73,8 @@ void entry(uint8_t _boot_drive, int pxe_boot) {
     char *cmdline;
     char *config = menu(&cmdline);
 
-    char proto[32];
-    if (!config_get_value(config, proto, 0, 32, "PROTOCOL")) {
+    char *proto = config_get_value(config, 0, "PROTOCOL");
+    if (proto == NULL) {
         panic("PROTOCOL not specified");
     }
 
diff --git a/stage2/menu.c b/stage2/menu.c
index b88d028d..586936b8 100644
--- a/stage2/menu.c
+++ b/stage2/menu.c
@@ -244,25 +244,26 @@ static int print_tree(int level, int base_index, int selected_entry,
 char *menu(char **cmdline_ret) {
     cmdline = conv_mem_alloc(CMDLINE_MAX);
 
-    char *buf = conv_mem_alloc(256);
-
     struct menu_entry *selected_menu_entry;
 
     int selected_entry = 0;
-    if (config_get_value(NULL, buf, 0, 16, "DEFAULT_ENTRY")) {
-        selected_entry = (int)strtoui(buf, NULL, 10);
+    char *default_entry = config_get_value(NULL, 0, "DEFAULT_ENTRY");
+    if (default_entry != NULL) {
+        selected_entry = strtoui(default_entry, NULL, 10);
     }
 
     int timeout = 5;
-    if (config_get_value(NULL, buf, 0, 16, "TIMEOUT")) {
-        timeout = (int)strtoui(buf, NULL, 10);
+    char *timeout_config = config_get_value(NULL, 0, "TIMEOUT");
+    if (timeout_config != NULL) {
+        timeout = strtoui(timeout_config, NULL, 10);
     }
 
     if (!timeout)
         goto autoboot;
 
     // If there is GRAPHICS config key and the value is "yes", enable graphics
-    if (config_get_value(NULL, buf, 0, 16, "GRAPHICS") && !strcmp(buf, "yes")) {
+    char *graphics = config_get_value(NULL, 0, "GRAPHICS");
+    if (graphics != NULL && !strcmp(graphics, "yes")) {
         // default scheme
         int margin = 64;
         int margin_gradient = 20;
@@ -277,9 +278,11 @@ char *menu(char **cmdline_ret) {
             0x00aaaaaa  // grey
         };
 
-        if (config_get_value(NULL, buf, 0, 256, "THEME_COLOURS")
-         || config_get_value(NULL, buf, 0, 256, "THEME_COLORS")) {
-            const char *first = buf;
+        char *colours = config_get_value(NULL, 0, "THEME_COLOURS");
+        if (colours == NULL)
+            colours = config_get_value(NULL, 0, "THEME_COLORS");
+        if (colours != NULL) {
+            const char *first = colours;
             for (int i = 0; i < 8; i++) {
                 const char *last;
                 uint32_t col = strtoui(first, &last, 16);
@@ -292,32 +295,32 @@ char *menu(char **cmdline_ret) {
             }
         }
 
-        if (config_get_value(NULL, buf, 0, 16, "THEME_MARGIN")) {
-            margin = (int)strtoui(buf, NULL, 10);
+        char *theme_margin = config_get_value(NULL, 0, "THEME_MARGIN");
+        if (theme_margin != NULL) {
+            margin = strtoui(theme_margin, NULL, 10);
         }
 
-        if (config_get_value(NULL, buf, 0, 16, "THEME_MARGIN_GRADIENT")) {
-            margin_gradient = (int)strtoui(buf, NULL, 10);
+        char *theme_margin_gradient = config_get_value(NULL, 0, "THEME_MARGIN_GRADIENT");
+        if (theme_margin_gradient != NULL) {
+            margin_gradient = strtoui(theme_margin_gradient, NULL, 10);
         }
 
-        if (!config_get_value(NULL, cmdline, 0, CMDLINE_MAX, "BACKGROUND_PATH"))
-            goto nobg;
+        struct image *bg = NULL;
 
-        struct file_handle *bg_file = conv_mem_alloc(sizeof(struct file_handle));
-        if (!uri_open(bg_file, cmdline))
+        char *background_path = config_get_value(NULL, 0, "BACKGROUND_PATH");
+        if (background_path == NULL)
             goto nobg;
 
-        struct image *bg = conv_mem_alloc(sizeof(struct image));
-        if (open_image(bg, bg_file))
+        struct file_handle *bg_file = ext_mem_alloc(sizeof(struct file_handle));
+        if (!uri_open(bg_file, background_path))
             goto nobg;
 
-        term_vbe(colourscheme, margin, margin_gradient, bg);
-        goto yesbg;
+        bg = ext_mem_alloc(sizeof(struct image));
+        if (open_image(bg, bg_file))
+            bg = NULL;
 
     nobg:
-        term_vbe(colourscheme, margin, margin_gradient, NULL);
-
-    yesbg:;
+        term_vbe(colourscheme, margin, margin_gradient, bg);
     }
 
     disable_cursor();
@@ -377,10 +380,12 @@ timeout_aborted:
                     goto refresh;
                 }
                 enable_cursor();
-                if (!config_get_value(selected_menu_entry->body, cmdline, 0, CMDLINE_MAX, "KERNEL_CMDLINE")) {
-                    if (!config_get_value(selected_menu_entry->body, cmdline, 0, CMDLINE_MAX, "CMDLINE")) {
-                        cmdline[0] = '\0';
-                    }
+                cmdline = config_get_value(selected_menu_entry->body, 0, "KERNEL_CMDLINE");
+                if (!cmdline) {
+                    cmdline = config_get_value(selected_menu_entry->body, 0, "CMDLINE");
+                }
+                if (!cmdline) {
+                    cmdline[0] = '\0';
                 }
                 clear(true);
                 *cmdline_ret = cmdline;
diff --git a/stage2/protos/chainload.c b/stage2/protos/chainload.c
index a97a0580..8048e100 100644
--- a/stage2/protos/chainload.c
+++ b/stage2/protos/chainload.c
@@ -50,11 +50,11 @@ void chainload(char *config) {
     uint64_t val;
 
     int part; {
-        char buf[32];
-        if (!config_get_value(config, buf, 0, 32, "PARTITION")) {
+        char *part_config = config_get_value(config, 0, "PARTITION");
+        if (part_config == NULL) {
             part = -1;
         } else {
-            val = strtoui(buf, NULL, 10);
+            val = strtoui(part_config, NULL, 10);
             if (val < 1 || val > 256) {
                 panic("BIOS partition number outside range 1-256");
             }
@@ -62,11 +62,11 @@ void chainload(char *config) {
         }
     }
     int drive; {
-        char buf[32];
-        if (!config_get_value(config, buf, 0, 32, "DRIVE")) {
+        char *drive_config = config_get_value(config, 0, "DRIVE");
+        if (drive_config == NULL) {
             panic("DRIVE not specified");
         }
-        val = strtoui(buf, NULL, 10);
+        val = strtoui(drive_config, NULL, 10);
         if (val < 1 || val > 16) {
             panic("BIOS drive number outside range 1-16");
         }
diff --git a/stage2/protos/linux.c b/stage2/protos/linux.c
index c3386277..5e1c420e 100644
--- a/stage2/protos/linux.c
+++ b/stage2/protos/linux.c
@@ -53,13 +53,13 @@ static void spinup(uint16_t real_mode_code_seg, uint16_t kernel_entry_seg) {
 }
 
 void linux_load(char *config, char *cmdline) {
-    char buf[128];
     struct file_handle *kernel = conv_mem_alloc(sizeof(struct file_handle));
 
-    if (!config_get_value(config, buf, 0, 128, "KERNEL_PATH"))
+    char *kernel_path = config_get_value(config, 0, "KERNEL_PATH");
+    if (kernel_path == NULL)
         panic("KERNEL_PATH not specified");
 
-    if (!uri_open(kernel, buf))
+    if (!uri_open(kernel, kernel_path))
         panic("Could not open kernel resource");
 
     uint32_t signature;
@@ -129,14 +129,15 @@ void linux_load(char *config, char *cmdline) {
 
     size_t modules_mem_base = INITRD_LOAD_ADDR;
     for (size_t i = 0; ; i++) {
-        if (!config_get_value(config, buf, i, 128, "MODULE_PATH"))
+        char *module_path = config_get_value(config, i, "MODULE_PATH");
+        if (module_path == NULL)
             break;
 
         struct file_handle module;
-        if (!uri_open(&module, buf))
-            panic("Could not open `%s`", buf);
+        if (!uri_open(&module, module_path))
+            panic("Could not open `%s`", module_path);
 
-        print("Loading module `%s`...\n", buf);
+        print("Loading module `%s`...\n", module_path);
 
         memmap_alloc_range(modules_mem_base, module.size, 0);
         fread(&module, (void *)modules_mem_base, 0, module.size);
diff --git a/stage2/protos/stivale.c b/stage2/protos/stivale.c
index 8dabb812..146264d4 100644
--- a/stage2/protos/stivale.c
+++ b/stage2/protos/stivale.c
@@ -2,6 +2,7 @@
 #include <stddef.h>
 #include <stdbool.h>
 #include <protos/stivale.h>
+#include <lib/libc.h>
 #include <lib/elf.h>
 #include <lib/blib.h>
 #include <lib/acpi.h>
@@ -26,16 +27,15 @@
 struct stivale_struct stivale_struct = {0};
 
 void stivale_load(char *config, char *cmdline) {
-    char buf[128];
-
     stivale_struct.flags |= (1 << 0);  // set bit 0 since we are BIOS and not UEFI
 
     struct file_handle *kernel = conv_mem_alloc(sizeof(struct file_handle));
 
-    if (!config_get_value(config, buf, 0, 128, "KERNEL_PATH"))
+    char *kernel_path = config_get_value(config, 0, "KERNEL_PATH");
+    if (kernel_path == NULL)
         panic("KERNEL_PATH not specified");
 
-    if (!uri_open(kernel, buf))
+    if (!uri_open(kernel, kernel_path))
         panic("Could not open kernel resource");
 
     struct stivale_header stivale_hdr;
@@ -116,26 +116,34 @@ void stivale_load(char *config, char *cmdline) {
     stivale_struct.module_count = 0;
     uint64_t *prev_mod_ptr = &stivale_struct.modules;
     for (int i = 0; ; i++) {
-        if (!config_get_value(config, buf, i, 128, "MODULE_PATH"))
+        char *module_path = config_get_value(config, i, "MODULE_PATH");
+        if (module_path == NULL)
             break;
 
         stivale_struct.module_count++;
 
         struct stivale_module *m = conv_mem_alloc(sizeof(struct stivale_module));
 
-        if (!config_get_value(config, m->string, i, 128, "MODULE_STRING")) {
+        char *module_string = config_get_value(config, i, "MODULE_STRING");
+        if (module_string == NULL) {
             m->string[0] = '\0';
+        } else {
+            // TODO perhaps change this to be a pointer
+            size_t str_len = strlen(module_string);
+            if (str_len > 127)
+                str_len = 127;
+            memcpy(m->string, module_string, str_len);
         }
 
         struct file_handle f;
-        if (!uri_open(&f, buf))
-            panic("Requested module with path \"%s\" not found!", buf);
+        if (!uri_open(&f, module_path))
+            panic("Requested module with path \"%s\" not found!", module_path);
 
         void *module_addr = (void *)(((uint32_t)top_used_addr & 0xfff) ?
             ((uint32_t)top_used_addr & ~((uint32_t)0xfff)) + 0x1000 :
             (uint32_t)top_used_addr);
 
-        print("stivale: Loading module `%s`...\n", buf);
+        print("stivale: Loading module `%s`...\n", module_path);
 
         memmap_alloc_range((size_t)module_addr, f.size, 10);
         fread(&f, module_addr, 0, f.size);
@@ -150,7 +158,7 @@ void stivale_load(char *config, char *cmdline) {
         prev_mod_ptr  = &m->next;
 
         print("stivale: Requested module %u:\n", i);
-        print("         Path:   %s\n", buf);
+        print("         Path:   %s\n", module_path);
         print("         String: %s\n", m->string);
         print("         Begin:  %X\n", m->begin);
         print("         End:    %X\n", m->end);
@@ -170,8 +178,9 @@ void stivale_load(char *config, char *cmdline) {
         int req_height = stivale_hdr.framebuffer_height;
         int req_bpp    = stivale_hdr.framebuffer_bpp;
 
-        if (config_get_value(config, buf, 0, 128, "RESOLUTION"))
-            parse_resolution(&req_width, &req_height, &req_bpp, buf);
+        char *resolution = config_get_value(config, 0, "RESOLUTION");
+        if (resolution != NULL)
+            parse_resolution(&req_width, &req_height, &req_bpp, resolution);
 
         struct vbe_framebuffer_info fbinfo;
         init_vbe(&fbinfo, req_width, req_height, req_bpp);
diff --git a/stage2/protos/stivale2.c b/stage2/protos/stivale2.c
index 81917230..e1580486 100644
--- a/stage2/protos/stivale2.c
+++ b/stage2/protos/stivale2.c
@@ -51,14 +51,13 @@ static void append_tag(struct stivale2_struct *s, struct stivale2_tag *tag) {
 }
 
 void stivale2_load(char *config, char *cmdline) {
-    char buf[128];
-
     struct file_handle *kernel = conv_mem_alloc(sizeof(struct file_handle));
 
-    if (!config_get_value(config, buf, 0, 128, "KERNEL_PATH"))
+    char *kernel_path = config_get_value(config, 0, "KERNEL_PATH");
+    if (kernel_path == NULL)
         panic("KERNEL_PATH not specified");
 
-    if (!uri_open(kernel, buf))
+    if (!uri_open(kernel, kernel_path))
         panic("Could not open kernel resource");
 
     struct stivale2_header stivale2_hdr;
@@ -157,8 +156,8 @@ void stivale2_load(char *config, char *cmdline) {
     {
     size_t module_count;
     for (module_count = 0; ; module_count++) {
-        char module_file[64];
-        if (!config_get_value(config, module_file, module_count, 64, "MODULE_PATH"))
+        char *module_file = config_get_value(config, module_count, "MODULE_PATH");
+        if (module_file == NULL)
             break;
     }
 
@@ -169,25 +168,31 @@ void stivale2_load(char *config, char *cmdline) {
     tag->tag.identifier = STIVALE2_STRUCT_TAG_MODULES_ID;
     tag->module_count   = module_count;
 
-    for (int i = 0; ; i++) {
-        if (!config_get_value(config, buf, i, 128, "MODULE_PATH"))
-            break;
+    for (size_t i = 0; i < module_count; i++) {
+        char *module_path = config_get_value(config, i, "MODULE_PATH");
 
         struct stivale2_module *m = &tag->modules[i];
 
-        if (!config_get_value(config, m->string, i, 128, "MODULE_STRING")) {
+        char *module_string = config_get_value(config, i, "MODULE_STRING");
+        if (module_string == NULL) {
             m->string[0] = '\0';
+        } else {
+            // TODO perhaps change this to be a pointer
+            size_t str_len = strlen(module_string);
+            if (str_len > 127)
+                str_len = 127;
+            memcpy(m->string, module_string, str_len);
         }
 
         struct file_handle f;
-        if (!uri_open(&f, buf))
-            panic("Requested module with path \"%s\" not found!", buf);
+        if (!uri_open(&f, module_path))
+            panic("Requested module with path \"%s\" not found!", module_path);
 
         void *module_addr = (void *)(((uint32_t)top_used_addr & 0xfff) ?
             ((uint32_t)top_used_addr & ~((uint32_t)0xfff)) + 0x1000 :
             (uint32_t)top_used_addr);
 
-        print("stivale2: Loading module `%s`...\n", buf);
+        print("stivale2: Loading module `%s`...\n", module_path);
 
         memmap_alloc_range((size_t)module_addr, f.size, 0x1001);
         fread(&f, module_addr, 0, f.size);
@@ -198,7 +203,7 @@ void stivale2_load(char *config, char *cmdline) {
         top_used_addr = (uint64_t)(size_t)m->end;
 
         print("stivale2: Requested module %u:\n", i);
-        print("          Path:   %s\n", buf);
+        print("          Path:   %s\n", module_path);
         print("          String: %s\n", m->string);
         print("          Begin:  %X\n", m->begin);
         print("          End:    %X\n", m->end);
@@ -257,8 +262,9 @@ void stivale2_load(char *config, char *cmdline) {
         int req_height = hdrtag->framebuffer_height;
         int req_bpp    = hdrtag->framebuffer_bpp;
 
-        if (config_get_value(config, buf, 0, 128, "RESOLUTION"))
-            parse_resolution(&req_width, &req_height, &req_bpp, buf);
+        char *resolution = config_get_value(config, 0, "RESOLUTION");
+        if (resolution != NULL)
+            parse_resolution(&req_width, &req_height, &req_bpp, resolution);
 
         struct vbe_framebuffer_info fbinfo;
         if (init_vbe(&fbinfo, req_width, req_height, req_bpp)) {
tab: 248 wrap: offon