|  | /* err.c --- handle errors for RX simulator. | 
|  |  | 
|  | Copyright (C) 2008-2023 Free Software Foundation, Inc. | 
|  | Contributed by Red Hat, Inc. | 
|  |  | 
|  | This file is part of the GNU simulators. | 
|  |  | 
|  | This program is free software; you can redistribute it and/or modify | 
|  | it under the terms of the GNU General Public License as published by | 
|  | the Free Software Foundation; either version 3 of the License, or | 
|  | (at your option) any later version. | 
|  |  | 
|  | This program is distributed in the hope that it will be useful, | 
|  | but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | GNU General Public License for more details. | 
|  |  | 
|  | You should have received a copy of the GNU General Public License | 
|  | along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ | 
|  |  | 
|  | /* This must come before any other includes.  */ | 
|  | #include "defs.h" | 
|  |  | 
|  | #include <stdio.h> | 
|  | #include <stdlib.h> | 
|  |  | 
|  | #include "err.h" | 
|  |  | 
|  | static unsigned char ee_actions[SIM_ERR_NUM_ERRORS]; | 
|  |  | 
|  | static enum execution_error last_error; | 
|  |  | 
|  | static void | 
|  | ee_overrides (void) | 
|  | { | 
|  | /* GCC may initialize a bitfield by reading the uninitialized byte, | 
|  | masking in the bitfield, and writing the byte back out.  */ | 
|  | ee_actions[SIM_ERR_READ_UNWRITTEN_BYTES] = SIM_ERRACTION_IGNORE; | 
|  | /* This breaks stack unwinding for exceptions because it leaves | 
|  | MC_PUSHED_PC tags in the unwound stack frames.  */ | 
|  | ee_actions[SIM_ERR_CORRUPT_STACK] = SIM_ERRACTION_IGNORE; | 
|  | } | 
|  |  | 
|  | void | 
|  | execution_error_init_standalone (void) | 
|  | { | 
|  | int i; | 
|  |  | 
|  | for (i = 0; i < SIM_ERR_NUM_ERRORS; i++) | 
|  | ee_actions[i] = SIM_ERRACTION_EXIT; | 
|  |  | 
|  | ee_overrides (); | 
|  | } | 
|  |  | 
|  | void | 
|  | execution_error_init_debugger (void) | 
|  | { | 
|  | int i; | 
|  |  | 
|  | for (i = 0; i < SIM_ERR_NUM_ERRORS; i++) | 
|  | ee_actions[i] = SIM_ERRACTION_DEBUG; | 
|  |  | 
|  | ee_overrides (); | 
|  | } | 
|  |  | 
|  | void | 
|  | execution_error_warn_all (void) | 
|  | { | 
|  | int i; | 
|  |  | 
|  | for (i = 0; i < SIM_ERR_NUM_ERRORS; i++) | 
|  | ee_actions[i] = SIM_ERRACTION_WARN; | 
|  | } | 
|  |  | 
|  | void | 
|  | execution_error_ignore_all (void) | 
|  | { | 
|  | int i; | 
|  |  | 
|  | for (i = 0; i < SIM_ERR_NUM_ERRORS; i++) | 
|  | ee_actions[i] = SIM_ERRACTION_IGNORE; | 
|  | } | 
|  |  | 
|  | void | 
|  | execution_error (enum execution_error num, unsigned long address) | 
|  | { | 
|  | if (ee_actions[num] != SIM_ERRACTION_IGNORE) | 
|  | last_error = num; | 
|  |  | 
|  | if (ee_actions[num] == SIM_ERRACTION_EXIT | 
|  | || ee_actions[num] == SIM_ERRACTION_WARN) | 
|  | { | 
|  | switch (num) | 
|  | { | 
|  | case SIM_ERR_READ_UNWRITTEN_PAGES: | 
|  | case SIM_ERR_READ_UNWRITTEN_BYTES: | 
|  | printf("Read from unwritten memory at 0x%lx\n", address); | 
|  | break; | 
|  |  | 
|  | case SIM_ERR_NULL_POINTER_DEREFERENCE: | 
|  | printf ("NULL pointer dereference\n"); | 
|  | break; | 
|  |  | 
|  | case SIM_ERR_CORRUPT_STACK: | 
|  | printf ("Stack corruption detected at 0x%lx\n", address); | 
|  | break; | 
|  |  | 
|  | default: | 
|  | printf ("Unknown execution error %d\n", num); | 
|  | exit (1); | 
|  | } | 
|  | } | 
|  |  | 
|  | if (ee_actions[num] == SIM_ERRACTION_EXIT) | 
|  | exit (1); | 
|  | } | 
|  |  | 
|  | enum execution_error | 
|  | execution_error_get_last_error (void) | 
|  | { | 
|  | return last_error; | 
|  | } | 
|  |  | 
|  | void | 
|  | execution_error_clear_last_error (void) | 
|  | { | 
|  | last_error = SIM_ERR_NONE; | 
|  | } | 
|  |  | 
|  | void | 
|  | execution_error_set_action (enum execution_error num, enum execution_error_action act) | 
|  | { | 
|  | ee_actions[num] = act; | 
|  | } |