This patch makes booting Mac OS 9.2 possible. It replaces all occurrences of
r and r> with sub_>r and sub_r>. This allows for the return stack to be left
alone. This patch also makes it so that the boot script is executed one line at a time.
Signed-off-by: John Arbuckle programmingkidx@gmail.com
Note: this patch depends on the strstr() and return stack substitution patches.
Index: libopenbios/bootinfo_load.c =================================================================== --- libopenbios/bootinfo_load.c (revision 1395) +++ libopenbios/bootinfo_load.c (working copy) @@ -19,6 +19,7 @@ #include "libopenbios/bootinfo_load.h" #include "libopenbios/ofmem.h" #include "libc/vsprintf.h" +#include "libc/string.h"
//#define DEBUG_BOOTINFO
@@ -116,6 +117,75 @@ return LOADER_NOT_SUPPORT; }
+// Replace all occurrences of orig_str in buffer with replace_str +static void replace_string(char *buffer, const char *orig_str, const char *replace_str) +{ + char *ptr; + int index, new_buf_index = 0; + const int max_size = 5000; + char *new_buffer = malloc(max_size * sizeof(char)); + + for (index = 0; index < strlen(buffer); index++) { + if (buffer[index] == orig_str[0]) { + ptr = strstr(buffer + index, orig_str); + + // if we encountered an orig_str in the buffer + if (index == (ptr - buffer)) { + sprintf(new_buffer + new_buf_index, "%s ", replace_str); + new_buf_index += strlen(replace_str) + 1; + index += strlen(orig_str); + continue; + } + } + new_buffer[new_buf_index++] = buffer[index]; + } + + // copy new_buffer into buffer + for (index = 0; index < strlen(new_buffer); index++) { + buffer[index] = new_buffer[index]; + } + buffer[index+1] = '\0'; +} + +/* Replace >r and r> with sub_>r and sub_r> */ +static void replace_return_stack_words(char *bootscript) +{ + const char *find_str1 = ">r"; + const char *replace_str1 = "sub_>r"; + const char *find_str2 = "r>"; + const char *replace_str2 = "sub_r>"; + + replace_string(bootscript, find_str1, replace_str1); + replace_string(bootscript, find_str2, replace_str2); +} + +/* Runs the bootscript one line at a time */ +void run_script(char *bootscript) +{ + int index = 0, buf_index = 0; + char c; + char *buffer = malloc(1000 * sizeof(char)); + + while (1) { + c = bootscript[index]; + + // fill up buffer + while (c != '\n' && c != '\r' && c != '\0') { + buffer[buf_index++] = c; + c = bootscript[++index]; + } + buffer[buf_index] = '\0'; + buf_index = 0; + index++; + DPRINTF("%s\n", buffer); + feval(buffer); + if (c == '\0') { + break; + } + } + free(buffer); +} + /* Parse SGML structure like: <chrp-boot> @@ -209,9 +279,6 @@ script = 0; bootscript[scriptlen] = '\0';
- DPRINTF("got bootscript %s\n", - bootscript); - scriptvalid = -1;
break; @@ -261,8 +328,8 @@
/* If the payload is bootinfo then we execute it immediately */ if (scriptvalid) { - DPRINTF("bootscript: %s\n", bootscript); - feval(bootscript); + replace_return_stack_words(bootscript); + run_script(bootscript); } else DPRINTF("Unable to parse bootinfo bootscript\n");