📄 rdi150-low.c
字号:
switch (result) { case RDIError_NoMorePoints: output ("This watchpoint exhausted the available points.\n"); case RDIError_NoError: break; /* Success branches break here */ case RDIError_ConflictingPoint: output_error ("RDI Error: Conflicting watchpoint.\n"); case RDIError_CantSetPoint: output_error ("RDI Error: No more watchpoint resources left.\n"); case RDIError_PointInUse: output_error ("RDI Error: Watchpoint in use.\n"); default: output_error ("RDI Error: %s.\n", rdi_error_message (result)); free (new_point); return 0; /* All errors fall through to here. */ } if (watchpoint_list == NULL) { watchpoint_list = new_point; new_point->next = NULL; } else { new_point->next = watchpoint_list; watchpoint_list = new_point; } if (debug_on) { ARMword arg1, arg2; int result; struct rdi_points *iter; for (iter = watchpoint_list; iter != NULL; iter = iter->next) { arg1 = (ARMword) iter->handle; result = rdi_proc_vec->info (target_arm_module, RDIPointStatus_Watch, &arg1, &arg2); output ("\t-- addr: 0x%x handle 0x%x hw resource: %d type 0x%x result %d\n", iter->addr, iter->handle, arg1, arg2, result); } } return 1;}intlow_delete_watchpoint (CORE_ADDR watch_addr, int size, enum watch_type type){ struct rdi_points *point_ptr, *prev_ptr; int result; if (debug_on) { ARMword arg1, arg2; int result; struct rdi_points *iter; output ("Before deletion of 0x%x, Current watchpoint list:\n", watch_addr); for (iter = watchpoint_list; iter != NULL; iter = iter->next) { arg1 = (ARMword) iter->handle; result = rdi_proc_vec->info (target_arm_module, RDIPointStatus_Watch, &arg1, &arg2); output ("\t-- addr: 0x%x handle 0x%x hw resource: %d type 0x%x result %d\n", iter->addr, iter->handle, arg1, arg2, result); } } for (point_ptr = watchpoint_list, prev_ptr = NULL; point_ptr != NULL; prev_ptr = point_ptr, point_ptr = point_ptr->next) { if (point_ptr->addr == watch_addr) { break; } } if (point_ptr == NULL) { output_error ("Watchpoint at addr %x not found.\n", watch_addr); return 0; } result = rdi_proc_vec->clearwatch (target_arm_module, point_ptr->handle); if (result != RDIError_NoError) { output_error ("RDI Error deleting watchpoint: %s.\n", rdi_error_message (result)); return 0; } if (prev_ptr == NULL) { watchpoint_list = point_ptr->next; } else { prev_ptr->next = point_ptr->next; } free (point_ptr); if (debug_on) { struct rdi_points *iter; output ("After Deleting 0x%x, Current watchpoint list:\n", watch_addr); for (iter = watchpoint_list; iter != NULL; iter = iter->next) output ("\t-- 0x%x\n", iter->addr); } return 1;}intlow_resume (enum resume_mode mode, int signo){ RDI_PointHandle ret_point; RDI_ModuleHandle target_module = target_arm_module; int result; /* Make sure any changes to the registers are flushed before proceeding */ low_write_registers(); switch (mode) { case RESUME_STEP: if (target_step) { RDI_ModuleHandle mh_ptr; RDI_PointHandle out_handle; mh_ptr = target_arm_module; currently_running = 1; result = rdi_proc_vec->step (gdb_agent, &mh_ptr, 1, 1, &out_handle); currently_running = 0; } else { CORE_ADDR next_pc, current_pc; int dont_delete, type; unsigned short is_thumb; RDI_PointHandle temp_point; /* We just wrote out the registers above, so they should be good. */ current_pc = restore_register(PC_REGNUM); /* Now get the next pc. We need to know whether the next PC is in arm or thumb code, so that we can set the right kind of breakpoint there. */ next_pc = server_arm_get_next_pc (current_pc, &is_thumb); if (debug_on) { output ("Single stepping from 0x%x to 0x%x.\n", current_pc, next_pc); } temp_point = RDI_NoPointHandle; type = RDIPoint_EQ; if (is_thumb) { type |= RDIPoint_16Bit; } result = rdi_proc_vec->setbreak (target_arm_module, next_pc, type, 0, RDI_NoHandle, &temp_point); /* * If there is already a breakpoint here, then don't remove * it. The RDI only allows one Breakpoint at an address. */ dont_delete = 0; if (result == RDIError_PointInUse) { dont_delete = 1; output ("Temp breakpoint fell at used breakpoint at 0x%x.\n", next_pc); } else if (result != RDIError_NoError) { output_error ("BP Error in single stepping: %s.\n", rdi_error_message(result)); break; } /* Always stop the other processors when we are single stepping, since we would rather now hit one of their breakpoints. */ currently_running = 1; result = rdi_proc_vec->execute (gdb_agent, &target_module, 1, &ret_point); currently_running = 0 ; if (!dont_delete) { rdi_proc_vec->clearbreak (target_arm_module, temp_point); } if (debug_on) { if (result == RDIError_BreakpointReached) { if (ret_point != temp_point) { output ("Stopped at a different BP from the temp"); output (" one I set for stepping.\n"); } else { output ("Stopped at the step breakpoint.\n"); } } else { output ("Stopped unexpectedly with return value: %s.\n", rdi_error_message (result)); } } break; } case RESUME_CONTINUE: currently_running = 1; result = rdi_proc_vec->execute (gdb_agent, &target_module, target_stop_others, &ret_point); currently_running = 0; if (debug_on) { if (result == RDIError_BreakpointReached) { struct rdi_points *iter_ptr; for (iter_ptr = breakpoint_list; iter_ptr != NULL; iter_ptr = iter_ptr->next) { if (iter_ptr->handle == ret_point) { output ("Stopped at breakpoint at 0x%x, handle 0x%x.\n", iter_ptr->addr, iter_ptr->handle); break; } } if (iter_ptr == NULL) { output ("Stopped at unknown breakpoint.\n"); } } else { output ("Stopped unexpectedly with return %s: %d.\n", rdi_error_message (result)); } } } /* FIXME - we should probably continue again till WE cause the stop... But I am not sure whether this would steal control from the debug controller watching the other debug target. At least figure out a signal that will keep gdb from getting all confused about this. */ if (target_module != target_arm_module) { output_error ("Oops, somebody else caused the stop while single stepping.\n"); } currently_running = 0; return rdi_to_gdb_signal (result);}/* * rdi_to_gdb_signal * * Translate an rdi ending signal to a signal you can send back to gdb. * Comes from remote-rdi.c. */static intrdi_to_gdb_signal (int rdi_error){ switch (rdi_error) { case RDIError_NoError: case RDIError_TargetStopped: return TARGET_SIGNAL_TERM; case RDIError_Reset: return TARGET_SIGNAL_TERM; /* ??? */ case RDIError_UndefinedInstruction: return TARGET_SIGNAL_ILL; case RDIError_SoftwareInterrupt: case RDIError_PrefetchAbort: case RDIError_DataAbort: return TARGET_SIGNAL_TRAP; case RDIError_AddressException: return TARGET_SIGNAL_SEGV; case RDIError_IRQ: case RDIError_FIQ: return TARGET_SIGNAL_TRAP; case RDIError_Error: return TARGET_SIGNAL_TERM; case RDIError_BranchThrough0: return TARGET_SIGNAL_TRAP; case RDIError_NotInitialised: case RDIError_UnableToInitialise: case RDIError_WrongByteSex: case RDIError_UnableToTerminate: return TARGET_SIGNAL_UNKNOWN; case RDIError_BadInstruction: case RDIError_IllegalInstruction: return TARGET_SIGNAL_ILL; case RDIError_BadCPUStateSetting: case RDIError_UnknownCoPro: case RDIError_UnknownCoProState: case RDIError_BadCoProState: case RDIError_BadPointType: case RDIError_UnimplementedType: case RDIError_BadPointSize: case RDIError_UnimplementedSize: case RDIError_NoMorePoints: return TARGET_SIGNAL_UNKNOWN; case RDIError_BreakpointReached: case RDIError_WatchpointAccessed: return TARGET_SIGNAL_TRAP; case RDIError_NoSuchPoint: case RDIError_ProgramFinishedInStep: return TARGET_SIGNAL_UNKNOWN; case RDIError_UserInterrupt: return TARGET_SIGNAL_INT; case RDIError_IncompatibleRDILevels: case RDIError_LittleEndian: case RDIError_BigEndian: case RDIError_SoftInitialiseError: case RDIError_InsufficientPrivilege: case RDIError_UnimplementedMessage: case RDIError_UndefinedMessage: default: return TARGET_SIGNAL_UNKNOWN; } }/* * This next set of routines are the IO channel for the Target. I haven't * done anything with this yet. Currently they are just stubs. */void my_IO_dbgprint (RDI_Hif_DbgArg *arg, const char *format, va_list ap){ }void my_IO_dbgpause(RDI_Hif_DbgArg *arg) { }void my_IO_writec(RDI_Hif_HostosArg *arg, int c){ }int my_IO_readc(RDI_Hif_HostosArg *arg){ return 0;}int my_IO_write(RDI_Hif_HostosArg *arg, char const *buffer, int len){ return 0;}char *my_IO_gets(RDI_Hif_HostosArg *arg, char *buffer, int len){ return buffer;}/* * rdi_error_message * * Translate an rdi error number into a string, and return it. */char *rdi_error_message (int err){ static char msg[256]; rdi_proc_vec->errmess(gdb_agent, msg, sizeof(msg), err); output("rdi error = %d\n", err); return msg;}/* * record_register * * This copies the data that comes from the RDI CPUread function * over into the registers array. * Make sure that it stays in target byte order. */voidrecord_register (int regno, ARMword val){ unsigned char cookedreg[12]; store_unsigned_integer (cookedreg, REGISTER_RAW_SIZE (regno), val); memcpy (&aregisters[REGISTER_BYTE (regno)], (char *) cookedreg, REGISTER_RAW_SIZE (regno));}ARMwordrestore_register (int regno){ PTR addr; int len; ULONGEST retval; addr = &aregisters[REGISTER_BYTE (regno)]; len = REGISTER_RAW_SIZE (regno); retval = 0; retval = extract_unsigned_integer (addr, len); return retval;}intlow_test (char *buffer){}intlow_stop(void){ need_to_abort++;}#define ICE_THREAD_VECTOR 0x50#define ICE_THREAD_VECTOR_KEY0 0x4D494345 /* 'MICE' */#define ICE_THREAD_VECTOR_KEY1 0x47444220 /* 'GDB ' */#define ICE_THREAD_HANDLER_KEY0 0xDEAD0001#define ICE_THREAD_HANDLER_KEY1 0xDEAD0002struct ice_thread_vector { unsigned long _key0; unsigned long handler; unsigned long eCosRunning; unsigned long _key1;};struct ice_thread_handler { unsigned long _key0; unsigned char *inbuf; long inbuf_size; unsigned char *outbuf; long outbuf_size; unsigned char *stack; long stack_size; unsigned long fun; unsigned long _key1;};/* This routine is the fallback for thread oriented functions when there is * no thread support available at the target. */intno_thread_op(char *input_buffer){ switch (input_buffer[0]) { case 'g': return handle_read_registers(input_buffer+1); default: putpkt("ENN"); return 0; /* Can't handle it! */ }}/* This routine tries to call into the target for thread oriented functions. */static int_low_thread_op(char *input_buffer, char *result, int result_len){ struct ice_thread_handler handler; struct ice_thread_vector vector; int nbytes, res; nbytes = sizeof(vector); if (!low_read_memory_raw(ICE_THREAD_VECTOR, (char *)&vector, &nbytes)) { return 0; } if ((vector._key0 != ICE_THREAD_VECTOR_KEY0) || (vector._key1 != ICE_THREAD_VECTOR_KEY1) || (vector.eCosRunning == 0)) { output("Not a good vector or eCos not running!\n"); return 0; } nbytes = sizeof(handler); if (!low_read_memory_raw(vector.handler, (char *)&handler, &nbytes)) { return no_thread_op(input_buffer); } if ((handler._key0 != ICE_THREAD_HANDLER_KEY0) || (handler._key1 != ICE_THREAD_HANDLER_KEY1)) { output("Not a good handler!\n"); return 0; } /* Copy input buffer so board can see it */ low_write_memory(input_buffer, (int)handler.inbuf, strlen(input_buffer)+1); /* Make sure output buffer is initialized */ result[0] = '\0'; low_write_memory(result, (int)handler.outbuf, 1); /* Save current registers */ low_update_registers(); memcpy(hold_registers, aregisters, sizeof(aregisters)); /* Set up to call the thread support function */ record_register(SP_REGNUM, (int)handler.stack+handler.stack_size); record_register(LR_REGNUM, ICE_THREAD_VECTOR); low_set_breakpoint(ICE_THREAD_VECTOR, 4); record_register(PC_REGNUM, handler.fun); record_register(PS_REGNUM, 0xD3); registers_are_dirty = 1; res = low_resume(RESUME_CONTINUE, 0); /* Go and execute the code */ /* Restore registers to original state */ registers_are_dirty = 1; registers_up_to_date = 1; memcpy(aregisters, hold_registers, sizeof(aregisters)); low_delete_breakpoint(ICE_THREAD_VECTOR, 4); /* Return results */ if (res == TARGET_SIGNAL_TRAP) { nbytes = result_len; if (!low_read_memory_raw((int)handler.outbuf, result, &nbytes)) { output("Error reading result\n"); strcpy(result, "ENN"); } } else { output("Target didn't execute/stop properly\n"); strcpy(result, "ENN"); } return 1;}/* * low_thread_op * * This is the interface function which calls to the board. It is separated * out from the actual worker function to allow some routines to pass the * result on to the GDB client, and others to use the results locally. */intlow_thread_op(char *input_buffer, char **resptr){ int res; static char result[2048]; res = _low_thread_op(input_buffer, result, sizeof(result)); if (res) { if (resptr) { *resptr = result; } else { putpkt(result); } } return res;}#if 0voidlow_reset_thread_op(void){ struct ice_thread_handler handler; struct ice_thread_vector vector; int nbytes, res; nbytes = sizeof(vector); if (!low_read_memory_raw(ICE_THREAD_VECTOR, (char *)&vector, &nbytes)) { return; } if ((vector._key0 != ICE_THREAD_VECTOR_KEY0) || (vector._key1 != ICE_THREAD_VECTOR_KEY1) || (vector.eCosRunning == 0)) { } vector.eCosRunning = 0; nbytes = sizeof(vector); low_write_memory((char *)&vector, ICE_THREAD_VECTOR, nbytes);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -