Add more error checking for CLI version arguments
authorHugo Villeneuve <hugo@hugovil.com>
Mon, 10 Feb 2014 04:26:33 +0000 (23:26 -0500)
committerHugo Villeneuve <hugo@hugovil.com>
Thu, 13 Feb 2014 05:25:18 +0000 (00:25 -0500)
src/cli/parser.y
src/common/cpu8051.c
src/common/cpu8051.h
src/common/memory.c
src/common/memory.h

index 7d22681..82b632e 100644 (file)
@@ -9,6 +9,7 @@
 #include "menu.h"
 #include "memory.h"
 #include "timers.h"
+#include "memory.h"
 #include "cpu8051.h"
 
 /* int yydebug = 1; */
@@ -112,7 +113,7 @@ breakpoint_set:
        {
           log_debug("  Set breakpoint at $%04X", $2);
           SetBreakpoint($2);
-       }
+        }
        ;
 
 breakpoint_display:
index fb93126..b420f78 100644 (file)
@@ -46,11 +46,11 @@ IsBreakpoint(unsigned int address)
 
        for (k = 0; k < cpu8051.bp_count; k++) {
                if (cpu8051.bp[k] == address)
-                       return 1;
+                       return true;
        }
 
        /* The address was not found in the list of breakpoints */
-       return 0;
+       return false;
 }
 
 /* Check if the address is a stop point */
@@ -58,9 +58,9 @@ int
 IsStoppoint(unsigned int address)
 {
        if ((options.stop_address != 0) && (options.stop_address == address))
-               return 1;
+               return true;
        else
-               return 0;
+               return false;
 }
 
 /* Show Breakpoints list */
@@ -69,18 +69,27 @@ ShowBreakpoints(void)
 {
        int k;
 
-       for (k = 0; k < cpu8051.bp_count; k++)
-               printf("Breakpoint at address = %.4X\n", cpu8051.bp[k]);
+       if (cpu8051.bp_count) {
+               printf("Breakpoints:\n");
+               for (k = 0; k < cpu8051.bp_count; k++)
+                       printf("  $%.4X\n", cpu8051.bp[k]);
+       } else
+               printf("No breakpoints defined\n");
 }
 
 /* Set Breakpoint at address at the end of the breakpoint list */
 void
 SetBreakpoint(unsigned int address)
 {
-       if (IsBreakpoint(address))
-               return; /* Already a breakpoint */
+       int rc;
+
+       rc = memory_check_address(PGM_MEM_ID, address, DISPLAY_ERROR_YES);
+       if (rc == false)
+               return; /* Error */
 
-       if (cpu8051.bp_count < MAXBP)
+       /* Check if breakpoint is already defined. */
+       if ((IsBreakpoint(address) == false) &&
+           (cpu8051.bp_count < MAXBP))
                cpu8051.bp[cpu8051.bp_count++] = address;
 }
 
@@ -89,6 +98,17 @@ void
 ClearBreakpoint(unsigned int address)
 {
        int k;
+       int rc;
+
+       rc = memory_check_address(PGM_MEM_ID, address, DISPLAY_ERROR_YES);
+       if (rc == false)
+               return; /* Error */
+
+       /* Check if breakpoint is defined. */
+       if (IsBreakpoint(address) == false) {
+               log_err("No breakpoint defined at address $%X", address);
+               return;
+       }
 
        for (k = 0; k < cpu8051.bp_count; k++) {
                if (cpu8051.bp[k] == address) {
@@ -306,13 +326,21 @@ cpu8051_CheckInterrupts(void)
 }
 
 /* Execute at address cpu8051.pc from PGMMem */
-void
+int
 cpu8051_Exec(void)
 {
        int i;
+       int rc;
        unsigned char opcode;
        int insttiming;
 
+       /* Basic address check (may fail later if opcode has operands). */
+       rc = memory_check_address(PGM_MEM_ID, cpu8051.pc, DISPLAY_ERROR_NO);
+       if (rc == false) {
+               log_err("Trying to run past program memory limit");
+               return false; /* Error */
+       }
+
        opcode = memory_read8(PGM_MEM_ID, cpu8051.pc);
        cpu8051.pc++;
        insttiming = (*opcode_table[opcode])(); /* Function callback. */
@@ -330,6 +358,8 @@ cpu8051_Exec(void)
                timers_check();
                cpu8051.clock++;
        }
+
+       return true;
 }
 
 /*
@@ -343,35 +373,39 @@ cpu8051_Exec(void)
 int
 cpu8051_run(int instr_count, int (*interface_stop)(void))
 {
+       int rc;
        int stop = false;
        int breakpoint_hit = false;
 
        while (stop == false) {
-               cpu8051_Exec();
-
-               if (instr_count > 0)
-                       instr_count--;
-
-               if (instr_count == 0) {
+               rc = cpu8051_Exec();
+               if (rc == false)
                        stop = true;
-                       log_info("Number of instructions reached! Stopping!");
-               }
+               else {
+                       if (instr_count > 0)
+                               instr_count--;
 
-               if (IsBreakpoint(cpu8051.pc)) {
-                       stop = true;
-                       breakpoint_hit = true;
-                       log_info("Breakpoint hit at %.4X! Stopping!", cpu8051.pc);
-               }
+                       if (instr_count == 0) {
+                               stop = true;
+                               log_info("Number of instructions reached");
+                       }
 
-               if (IsStoppoint(cpu8051.pc)) {
-                       stop = true;
-                       log_info("Stoppoint hit at %.4X! Stopping!", cpu8051.pc);
-               }
+                       if (IsBreakpoint(cpu8051.pc)) {
+                               stop = true;
+                               breakpoint_hit = true;
+                               log_info("Breakpoint hit at %.4X", cpu8051.pc);
+                       }
 
-               if (interface_stop != NULL) {
-                       if (interface_stop()) {
+                       if (IsStoppoint(cpu8051.pc)) {
                                stop = true;
-                               log_info("Caught break signal!");
+                               log_info("Stoppoint hit at %.4X", cpu8051.pc);
+                       }
+
+                       if (interface_stop != NULL) {
+                               if (interface_stop()) {
+                                       stop = true;
+                                       log_info("Caught break signal");
+                               }
                        }
                }
        }
index 430e00e..25aad11 100644 (file)
@@ -80,7 +80,7 @@ ToggleBreakpoint(unsigned int Address);
 void
 cpu8051_init(void);
 
-void
+int
 cpu8051_Exec(void);
 
 int
index d01153a..4b17ffa 100644 (file)
@@ -19,6 +19,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
+#include <stdbool.h>
 #include <stdio.h>
 #include <string.h>
 
@@ -75,6 +76,20 @@ memory_init(void)
        }
 }
 
+/* Return true if address is valid, false otherwise. */
+int
+memory_check_address(enum mem_id_t id, unsigned long address, int display_error)
+{
+       if (address >= (unsigned long) mem_infos[id].max_size) {
+               if (display_error == DISPLAY_ERROR_YES)
+                       log_err("Address out of range ($%X >= $%X", address,
+                               mem_infos[id].max_size - 1);
+               return false;
+       }
+       else
+               return true;
+}
+
 u_int8_t *
 memory_getbuf(enum mem_id_t id, unsigned long address)
 {
@@ -207,8 +222,27 @@ pgm_read_addr16(uint16_t base)
 void
 DumpMem(unsigned int address, int size, int memory_id)
 {
+       int rc;
        int Offset, Column;
 
+       if (size == 0) {
+               log_err("invalid size: 0");
+               return;
+       }
+
+       /* Validate start address. */
+       rc = memory_check_address(memory_id, address, DISPLAY_ERROR_YES);
+       if (rc != false) {
+               /* Validate end address. */
+               rc = memory_check_address(memory_id, address + (size - 1),
+                                         DISPLAY_ERROR_NO);
+               if (rc == false)
+                       log_err("Trying to read beyond memory limit");
+       }
+
+       if (rc == false)
+               return;
+
        for (Offset = 0; Offset < size; Offset += 16) {
                unsigned char data[16];
 
index cbb9eb8..9b3bae1 100644 (file)
@@ -43,9 +43,15 @@ enum mem_id_t {
        MEM_ID_COUNT
 };
 
+#define DISPLAY_ERROR_NO  0
+#define DISPLAY_ERROR_YES 1
+
 void
 memory_init(void);
 
+int
+memory_check_address(enum mem_id_t id, unsigned long address, int display_error);
+
 u_int8_t *
 memory_getbuf(enum mem_id_t id, unsigned long address);