Author: mcayland Date: Tue Dec 10 22:01:42 2013 New Revision: 1237 URL: http://tracker.coreboot.org/trac/openbios/changeset/1237
Log: load.c: fix Forth stack underflow
The load() API was incorrect in that it did not push the resulting loaded file size onto the Forth stack. This caused a stack underflow in the Forth $load word, except for devices which were interposed (such as those with partition arguments).
Fix the load() function so that the resulting size is pushed onto the Forth stack as per the load package method description in IEEE1275. Since the loaders access load-base directly then currently the address argument is dropped.
This exposed another bug whereby disk-label would explicitly drop the address parameter from the stack for non-interposed packages. Remove this as it is now consistently handled in load() for all cases.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk
Modified: trunk/openbios-devel/libopenbios/load.c trunk/openbios-devel/packages/disk-label.c
Modified: trunk/openbios-devel/libopenbios/load.c ============================================================================== --- trunk/openbios-devel/libopenbios/load.c Sun Dec 8 13:48:24 2013 (r1236) +++ trunk/openbios-devel/libopenbios/load.c Tue Dec 10 22:01:42 2013 (r1237) @@ -44,11 +44,17 @@ struct sys_info sys_info; void *elf_boot_notes = NULL;
+/* ( addr -- size ) */ + void load(ihandle_t dev) { /* Invoke the loaders on the specified device */ char *param; - ucell valid; + ucell valid; + + /* TODO: Currently the internal loader APIs use load-base directly, so + drop the address */ + POP();
#ifdef CONFIG_LOADER_ELF
@@ -65,6 +71,7 @@ feval("state-valid @"); valid = POP(); if (valid) { + feval("saved-program-state >sps.file-size @"); return; } #endif @@ -74,6 +81,7 @@ feval("state-valid @"); valid = POP(); if (valid) { + feval("saved-program-state >sps.file-size @"); return; } #endif @@ -83,6 +91,7 @@ feval("state-valid @"); valid = POP(); if (valid) { + feval("saved-program-state >sps.file-size @"); return; } #endif @@ -92,6 +101,7 @@ feval("state-valid @"); valid = POP(); if (valid) { + feval("saved-program-state >sps.file-size @"); return; } #endif @@ -105,4 +115,6 @@ } #endif
+ /* Didn't load anything, so return zero size */ + PUSH(0); }
Modified: trunk/openbios-devel/packages/disk-label.c ============================================================================== --- trunk/openbios-devel/packages/disk-label.c Sun Dec 8 13:48:24 2013 (r1236) +++ trunk/openbios-devel/packages/disk-label.c Tue Dec 10 22:01:42 2013 (r1237) @@ -187,19 +187,8 @@ dlabel_load( __attribute__((unused)) dlabel_info_t *di ) { /* Try the load method of the part package */ -#ifdef DEBUG_DISK_LABEL - char *buf; -#endif xt_t xt;
-#ifdef DEBUG_DISK_LABEL - buf = (char *)POP(); -#else - POP(); -#endif - - DPRINTF("load invoked with address %p\n", buf); - /* If we have a partition handle, invoke the load word on it */ if (di->part_ih) { xt = find_ih_method("load", di->part_ih);