Updated interpreters
[projects/chimara/chimara.git] / interpreters / glulxe / vm.c
index 4a113f50a019be9a606c37b6f7f4a633ea54e41b..72fd868a2a9b748cede5efb2c6ed495fec96e7f2 100644 (file)
@@ -287,7 +287,7 @@ glui32 *pop_arguments(glui32 count, glui32 addr)
 
 /* verify_address():
    Make sure that count bytes beginning with addr all fall within the
-   current memory map. This is called at every memory access if
+   current memory map. This is called at every memory (read) access if
    VERIFY_MEMORY_ACCESS is defined in the header file.
 */
 void verify_address(glui32 addr, glui32 count)
@@ -301,3 +301,50 @@ void verify_address(glui32 addr, glui32 count)
   }
 }
 
+/* verify_address_write():
+   Make sure that count bytes beginning with addr all fall within RAM.
+   This is called at every memory write if VERIFY_MEMORY_ACCESS is 
+   defined in the header file.
+*/
+void verify_address_write(glui32 addr, glui32 count)
+{
+  if (addr < ramstart)
+    fatal_error_i("Memory write to read-only address", addr);
+  if (addr >= endmem)
+    fatal_error_i("Memory access out of range", addr);
+  if (count > 1) {
+    addr += (count-1);
+    if (addr >= endmem)
+      fatal_error_i("Memory access out of range", addr);
+  }
+}
+
+/* verify_array_addresses():
+   Make sure that an array of count elements (size bytes each),
+   starting at addr, does not fall outside the memory map. This goes
+   to some trouble that verify_address() does not, because we need
+   to be wary of lengths near -- or beyond -- 0x7FFFFFFF.
+*/
+void verify_array_addresses(glui32 addr, glui32 count, glui32 size)
+{
+  glui32 bytecount;
+  if (addr >= endmem)
+    fatal_error_i("Memory access out of range", addr);
+
+  if (count == 0)
+    return;
+  bytecount = count*size;
+
+  /* If just multiplying by the element size overflows, we have trouble. */
+  if (bytecount < count)
+    fatal_error_i("Memory access way too long", addr);
+
+  /* If the byte length by itself is too long, or if its end overflows,
+     we have trouble. */
+  if (bytecount > endmem || addr+bytecount < addr)
+    fatal_error_i("Memory access much too long", addr);
+  /* The simple length test. */
+  if (addr+bytecount > endmem)
+    fatal_error_i("Memory access too long", addr);
+}
+