summaryrefslogtreecommitdiff
path: root/src/lisp/ao_lisp_save.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2016-11-11 23:34:54 -0800
committerKeith Packard <keithp@keithp.com>2017-02-20 11:16:50 -0800
commit33aeffc123af1f9063969acf585f1caac885ced4 (patch)
treebf4f87c83c46ce815070933b947ba27fa65724c8 /src/lisp/ao_lisp_save.c
parent8f2d60b4c029bffaa559bd1f31f5b15230dfa674 (diff)
altos/lisp: Append a CRC to the saved image to validate on restore
The CRC is actually of the ROM bits, so we can tell if the restored image relates to the currently running code. Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src/lisp/ao_lisp_save.c')
-rw-r--r--src/lisp/ao_lisp_save.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/src/lisp/ao_lisp_save.c b/src/lisp/ao_lisp_save.c
index 2b19fdcb..030846b7 100644
--- a/src/lisp/ao_lisp_save.c
+++ b/src/lisp/ao_lisp_save.c
@@ -17,12 +17,18 @@
ao_poly
ao_lisp_save(struct ao_lisp_cons *cons)
{
+ if (!ao_lisp_check_argc(_ao_lisp_atom_save, cons, 0, 0))
+ return AO_LISP_NIL;
+
#ifdef AO_LISP_SAVE
struct ao_lisp_os_save *os = (struct ao_lisp_os_save *) &ao_lisp_pool[AO_LISP_POOL];
ao_lisp_collect();
- os->ao_lisp_atoms = ao_lisp_atom_poly(ao_lisp_atoms);
- os->ao_lisp_globals = ao_lisp_frame_poly(ao_lisp_frame_global);
+ os->atoms = ao_lisp_atom_poly(ao_lisp_atoms);
+ os->globals = ao_lisp_frame_poly(ao_lisp_frame_global);
+ os->const_checksum = ao_lisp_const_checksum;
+ os->const_checksum_inv = ~ao_lisp_const_checksum;
+
if (ao_lisp_os_save())
return _ao_lisp_atom_t;
#endif
@@ -32,13 +38,26 @@ ao_lisp_save(struct ao_lisp_cons *cons)
ao_poly
ao_lisp_restore(struct ao_lisp_cons *cons)
{
+ if (!ao_lisp_check_argc(_ao_lisp_atom_save, cons, 0, 0))
+ return AO_LISP_NIL;
+
#ifdef AO_LISP_SAVE
+ struct ao_lisp_os_save save;
struct ao_lisp_os_save *os = (struct ao_lisp_os_save *) &ao_lisp_pool[AO_LISP_POOL];
+ if (!ao_lisp_os_restore_save(&save, AO_LISP_POOL))
+ return ao_lisp_error(AO_LISP_INVALID, "header restore failed");
+
+ if (save.const_checksum != ao_lisp_const_checksum ||
+ save.const_checksum_inv != (uint16_t) ~ao_lisp_const_checksum)
+ {
+ return ao_lisp_error(AO_LISP_INVALID, "image is corrupted or stale");
+ }
+
if (ao_lisp_os_restore()) {
- ao_lisp_atoms = ao_lisp_poly_atom(os->ao_lisp_atoms);
- ao_lisp_frame_global = ao_lisp_poly_frame(os->ao_lisp_globals);
+ ao_lisp_atoms = ao_lisp_poly_atom(os->atoms);
+ ao_lisp_frame_global = ao_lisp_poly_frame(os->globals);
/* Clear the eval global variabls */
ao_lisp_eval_clear_globals();