📄 monitor.c
字号:
//==========================================================================//// monitor.c//// Monitor shell and main routines for CygMON the Wonder Monitor////==========================================================================//####COPYRIGHTBEGIN####// // ------------------------------------------- // The contents of this file are subject to the Red Hat eCos Public License // Version 1.1 (the "License"); you may not use this file except in // compliance with the License. You may obtain a copy of the License at // http://www.redhat.com/ // // Software distributed under the License is distributed on an "AS IS" // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the // License for the specific language governing rights and limitations under // the License. // // The Original Code is eCos - Embedded Configurable Operating System, // released September 30, 1998. // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are // Copyright (C) 1998, 1999, 2000 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- // //####COPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s): // Contributors: gthomas// Date: 1999-10-20// Purpose: Monitor shell and main routines for CygMON the Wonder Monitor// Description: // ////####DESCRIPTIONEND####////=========================================================================/* Platform-independent code for cygmon */#include <stdlib.h>#include <unistd.h>#ifdef HAVE_BSP#include <bsp/bsp.h>#include <bsp/cpu.h>#include <bsp/hex-utils.h>#endif#include <monitor.h>#ifdef HAVE_BSP#include "cpu_info.h"#endif#include <ledit.h>#include <signal.h>#include <string.h>#include <ctype.h>#if USE_CYGMON_PROTOTYPES/* Use common prototypes *//* Some of the composed board.h files compose these prototypes redundently, but if they dont, these are the common definitions */#include "fmt_util.h" /* Interface to string formatting utilities */#include "tservice.h" /* Interface to target specific services */#include "generic-stub.h" /* from libstub */#endif /* USE_CYGMON_PROTOTYPES */static int cygmon_handle_exception (int sigval);static void monitor_take_control (void);#if CYGMON_SYSTEM_SERVICESextern int process_syscall (int syscall_num);#endifint stub_is_active = 0;mem_addr_t last_pc;#ifdef HAVE_BSPstatic int mon_dbg_handler(int exc_nr, void *regs);static int mon_kill_handler(int exc_nr, void *regs);#define __is_breakpoint_function() (get_pc() == (target_register_t)bsp_breakinsn)/* Global pointer to current set of saved registers. */void *mon_saved_regs;/* Original BSP debug vector replaced by monitor. */static bsp_handler_t old_dbg_vec;#elsestatic int handle_signal (int signal_val);__PFI user_signal_handler = NULL;#endif#ifdef __ECOS__extern (*__process_exception_vec)(int);#endif#ifdef MONITOR_CONTROL_INTERRUPTS/* This is set if the user wants interrupts enabled in the monitor. */static int monitor_interrupts_enabled;#endif#if NOMAINint monitor_main (int argc, char **argv) /* Suppress default main() junk */#elseint main (int argc, char **argv) #endif{#ifdef HAVE_BSP int cur_port; struct bsp_comm_info comm_info;#else /* Set up exception handling traps */ initialize_stub ();#endif initialize_mon ();#ifdef HAVE_BSP /* get info on debug channel */ cur_port = bsp_set_debug_comm(-1); bsp_sysinfo(BSP_INFO_COMM, cur_port, &comm_info); /* * If we're using a network interface, don't install * the cygmon vectors. Currently, we only support stub * mode over a network connection. */ if (comm_info.kind != BSP_COMM_ENET) { xprintf("\n"); version (); /* replace original BSP debug and kill handler with ours */ old_dbg_vec = bsp_install_dbg_handler(mon_dbg_handler); (void)bsp_install_kill_handler(mon_kill_handler); } else { /* This forces the console to use the gdb channel. */ bsp_set_console_comm(cur_port); }#else xprintf("\n"); version (); __process_exception_vec = cygmon_handle_exception; __process_exit_vec = monitor_take_control;#if CYGMON_SYSTEM_SERVICES __process_syscall_vec = process_syscall;#endif __process_signal_vec = handle_signal; __init_vec = install_breakpoints; __cleanup_vec = clear_breakpoints;#endif#if 0#ifdef __ECOS__ __process_exception_vec = cygmon_handle_exception;#endif#endif while (1) { breakpoint (); if (switch_to_stub_flag) { xprintf("Switching to stub\n"); switch_to_stub_flag = 0; } } /* never reached */ exit (0);}/* Transfer control to gdb stub */ int transfer_to_stub (){ /* Return back to the exception handler, but the exception handler should invoke the stub's exception handler instead of ours. */#ifdef HAVE_BSP (void)bsp_install_dbg_handler(old_dbg_vec);#else __switch_to_stub ();#endif /* The stub is now active. */ stub_is_active = 1; return -1;}voidclear_user_state (void){#ifdef HAS_TIMER if (__timer_enabled ()) __settimer (0, 0);#endif clear_breakpoints ();#ifdef HAVE_BSP bsp_singlestep_cleanup(mon_saved_regs);#else user_signal_handler = NULL; __clear_single_step ();#endif}static voidmonitor_take_control (void){ stub_is_active = 0;#ifdef HAVE_BSP /* replace original BSP debug trap handler with ours */ (void)bsp_install_dbg_handler(mon_dbg_handler);#else clear_user_state (); __process_exception_vec = cygmon_handle_exception;#endif}#ifdef MONITOR_CONTROL_INTERRUPTSvoidmonitor_enable_interrupts (void){ monitor_interrupts_enabled = 1; enable_interrupts ();}voidmonitor_disable_interrupts (void){ monitor_interrupts_enabled = 0; disable_interrupts ();}intmonitor_interrupt_state (void){ return monitor_interrupts_enabled;}#endifstatic intcygmon_handle_exception (int sigval){ target_register_t pc;#ifdef MONITOR_CONTROL_INTERRUPTS if (monitor_interrupts_enabled) { if (! __in_interrupt) enable_interrupts (); }#endif#ifdef TARGET_EXCEPTION_CODE TARGET_EXCEPTION_CODE#endif#ifndef HAVE_BSP if (sigval != SIGKILL) if (handle_signal (sigval) == 0) return 0;#endif clear_user_state (); /* We may want to tweak the PC to point at the faulting instruction, for example. (breakpoints on x86). */#ifdef TARGET_ADJUST_PC TARGET_ADJUST_PC#endif pc = get_pc(); MAKE_STD_ADDR (pc, &last_pc); if ((sigval == SIGTRAP) && __is_breakpoint_function()) { /* * This is the initial breakpoint inserted by the BSP * Don't print anything for this as it is confusing */ } else { if (sigval == SIGTRAP) xprintf ("Hit breakpoint"); else xprintf ("Got signal %d", sigval); xprintf (" at 0x%s\n", int2str (pc, 16, sizeof (target_register_t) * 2));#ifdef DISASSEMBLER if (!__is_breakpoint_function ()) { do_dis (&last_pc); flush_dis (); }#endif } monitor_take_control (); return monitor_loop ();}#ifndef HAVE_BSP/* Returns 0 if the program should restart at the point at which the signal was received, -1 otherwise. */static inthandle_signal (int signal){ if (signal == SIGKILL) return -1; if (user_signal_handler != NULL) { int result = user_signal_handler (signal); switch (result) { /* Don't ignore potential hardware signals. */ case 3: if (signal == SIGSEGV || signal == SIGBUS || signal == SIGFPE || signal == SIGTRAP || signal == SIGILL) return -1; case 0: return 0; default: case 1: case 2: return -1; } } return -1;}#endifvoidversion (void){#ifdef HAVE_BSP struct bsp_platform_info platform; struct bsp_mem_info mem; int i; unsigned long u, totmem, topmem;#endif extern char *build_date; xprintf ("Cygmon, the Cygnus ROM monitor.\n"); xprintf ("Copyright(c) 1997, 1998, 1999, 2000 Red Hat\n\n"); xprintf ("Version: %s\nThis image was built on %s\n\n", VERSION, build_date);#ifdef HAVE_BSP bsp_sysinfo(BSP_INFO_PLATFORM, &platform); totmem = topmem = 0; i = 0; while (bsp_sysinfo(BSP_INFO_MEMORY, i++, &mem) == 0) { if (mem.kind == BSP_MEM_RAM) { totmem += mem.nbytes; u = (unsigned long)mem.virt_start + mem.nbytes; if (u > topmem) topmem = u; } } xprintf("CPU: %s\n", platform.cpu); xprintf("Board: %s\n", platform.board); if (*(platform.extra)) xprintf("%s\n", platform.extra); xprintf("Total RAM: %d bytes\n", totmem); xprintf("Top of RAM: 0x%x\n", topmem);#endif}#ifdef HAVE_BSPstatic intmon_kill_handler(int exc_nr, void *regs){ monitor_take_control(); return 1;}static intmon_dbg_handler(int exc_nr, void *regs){ int sig; unsigned long cur_pc; mon_saved_regs = regs; sig = bsp_get_signal(exc_nr, regs); cygmon_handle_exception(sig); cur_pc = bsp_get_pc(regs); if (cur_pc == (unsigned long)bsp_breakinsn) bsp_skip_instruction(regs); if (!stub_is_active) install_breakpoints(); return 1;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -