📄 rdi150-low.c
字号:
output ("\nTarget characteristics:\n"); rdi_proc_vec->info (target_arm_module, RDIInfo_Target, &flags, &dummy); output ("\tHardware?:\t\t"); if (flags & RDITarget_HW) { output ("YES\n"); } else { output ("NO\n"); } output ("\tComms Channel?:\t\t"); if (flags & RDITarget_HasCommsChannel) { output ("YES\n"); } else { output ("NO\n"); } output ("\tEndian-ness:\t\t"); if (target_byte_order ==BIG_ENDIAN) { output ("BIG\n"); } else { output ("LITTLE\n"); } rdi_proc_vec->info (target_arm_module, RDIInfo_Step, &flags, NULL); output ("\tSingle-Step Support:\t"); if (flags & RDIStep_Single) { target_step = 1; output ("YES\n"); } else { target_step = 0; output ("NO\n"); } result = rdi_proc_vec->info (target_arm_module, RDIInfo_GetLoadSize, (ARMword *) &target_load_size, NULL); output ("\tLoad Size:\t\t"); if (result == RDIError_NoError) { output ("%d\n", target_load_size); } else { output ("unknown\n"); target_load_size = -1; } result = rdi_proc_vec->info (target_arm_module, RDIInfo_CustomLoad, (ARMword *) &dummy, NULL); output ("\tCustom Load?:\t\t"); if (result == RDIError_NoError) { output ("YES\n"); } else { output ("NO\n"); } output ("\n"); if (num_procs > 1) { output ("Other modules found on debug target:\n"); for (i = 0; i < num_procs; i++) { if (i == target_arm_core) { output ("\t%d\tCurrent Target\n", i); } else { output ("\t%d\t%s\n", i, proc_desc_array[i].name); } } } else { output ("No other modules found on debug target.\n"); } output ("\n"); if ( !aregisters ) aregisters = malloc( REGISTER_BYTES ); return 1;}/* * low_close_target - Closes all the open modules in the target, and * closes the agent connection. */intlow_close_target(){ unsigned i; int result; ARMword dummy1, dummy2; /* If we haven't allocated the processor description array yet, then we have probably not gotten anywhere yet, so just exit. */ if (proc_desc_array == NULL) return 1; if (currently_running) { result = rdi_proc_vec->info (gdb_agent, RDISignal_Stop, &dummy1, &dummy2); if (result != RDIError_NoError) { output_error ("Could not stop the target.\n"); /* If we could not stop the target, it does not seem safe to shut down (we often crash when we do...) */ return 0; } } for (i = 0; i < num_procs; i++) { rdi_proc_vec->close(proc_desc_array[i].handle); } rdi_proc_vec->closeagent(gdb_agent); free (proc_desc_array); return 1; }/* * None of the Thread code works at present, since the RDI Thread * queries are not supported. This will have to be supplemented * by calls into the OS on the board. *//* low_set_thread_for_resume: This sets the target for step and continue operations. For now, the RDI doesn't support these operations, so this is a no-op. If it did work, THREAD_ID would be the thread to target, and -1 would indicate all threads. Returns 1 for success, 0 for error. */intlow_set_thread_for_resume (long thread_id){ return 1;}/* low_set_thread_for_query: This sets the target for all query operations. Returns 1 for success, 0 for error. */intlow_set_thread_for_query (char *input_buffer){ /* Need to notify target as well */ return low_thread_op(input_buffer, NULL);}/* low_is_thread_alive: Returns 1 if thread THREAD_ID is alive, 0 otherwise. */intlow_is_thread_alive (char *input_buffer){ return low_thread_op(input_buffer, NULL);}/* low_get_current_thread: Sets THREAD_ID to the current thread id. Returns 1 if it can do this, and 0 if for some reason it cannot (like the fact that this is not supported in RDI1.5.0.*/intlow_get_current_thread (long *thread_id){ return 0;}/* low_get_offsets: Fills TEXT, DATA and BSS with the program offsets. Returns 1 for success, and 0 if the packet is not supported. For now, I just return 1 since it is not that important to answer this one.*/intlow_get_offsets (CORE_ADDR *text, CORE_ADDR *data, CORE_ADDR *bss){ /* * The RDI doesn't really know this information, I think, * since it has nothing really to do with loading the executible. * So I just pretend I don't understand the query. */ return 0;}/* low_query_last_signal Fills SIGNAL with the reason for the last stop. Returns 1 on success, and 0 if it cannot return the information.*/enum target_signallow_query_last_signal (){ /* return TARGET_SIGNAL_TRAP; */ return 0;}/* * low_update_registers * * Fetches the register values from the board, and updates the registers * array with the current values for all the registers. * */int low_update_registers(){ int result, rdi_regmask, regno; ARMword rawreg, rawregs[32]; if (registers_up_to_date) { return 1; } result = rdi_proc_vec->CPUread (target_arm_module, RDIMode_Curr, 0x7fff|RDIReg_CPSR, rawregs); if (result) { output_error ("RDI_CPUread: %s\n", rdi_error_message (result)); return 0; } for (regno = 0; regno < 15; regno++) { record_register (regno, rawregs[regno]); }/* Note: this is very strange. It seems that only R15 will return the PS, * but RDIReg_CPSR must be used to set it! Looks like an ARM server bug. */ record_register (PS_REGNUM, rawregs[15]); /* * Now get the PC register... */ rdi_regmask = RDIReg_PC; result = rdi_proc_vec->CPUread (target_arm_module, RDIMode_Curr, rdi_regmask, &rawreg); if (result) { output_error ("RDI_CPUread: %s\n", rdi_error_message (result)); return 0; } record_register (PC_REGNUM, rawreg); registers_up_to_date = 1; registers_are_dirty = 0; return 1;}/* * low_write_registers * * Writes the registers in the register array down to the board */intlow_write_registers (){ ARMword rawregs[32], rawreg; unsigned int write_mask; int regno; if (!registers_are_dirty) { return 1; } write_mask = 0; for (regno = 0; regno < 15; regno++) { rawregs[regno] = restore_register (regno); write_mask |= (1 << regno); } rawregs[15] = restore_register (PS_REGNUM); write_mask |= (1 << 15); rdi_proc_vec->CPUwrite (target_arm_module, RDIMode_Curr, write_mask, rawregs); write_mask = RDIReg_PC; rawreg = restore_register (PC_REGNUM); rdi_proc_vec->CPUwrite (target_arm_module, RDIMode_Curr, write_mask, &rawreg); rawreg = restore_register (PS_REGNUM); write_mask = RDIReg_CPSR; rdi_proc_vec->CPUwrite (target_arm_module, RDIMode_Curr, write_mask, &rawreg); registers_are_dirty = 0; return 1;}intlow_read_memory_raw (CORE_ADDR start, void *buffer, unsigned int *nbytes){ int result; result = rdi_proc_vec->read (target_arm_module, (ARMword) start, buffer, nbytes, RDIAccess_Data); switch (result) { case RDIError_BigEndian: output ("Processor has switched endianness - now BIG ENDIAN\n"); break; case RDIError_LittleEndian: output ("Processor has switched endianness - now LITTLE ENDIAN\n"); break; case RDIError_NoError: break; default: output_error ("RDI_Read error: %s\n", rdi_error_message (result)); return 0; } return 1;}intlow_read_memory (char *buffer, CORE_ADDR start, unsigned int nbytes){#define BUFF_LEN 1024 char rdi_out[BUFF_LEN]; if (nbytes > BUFF_LEN) { output_error ("Requested too much data: %d\n", nbytes); return 0; } if (!low_read_memory_raw (start, rdi_out, &nbytes)) { return 0; } convert_bytes_to_ascii (rdi_out, buffer, nbytes, 0); return nbytes; }intlow_write_memory (char *data, CORE_ADDR start_addr, unsigned int nbytes){ int result, i; char buff[1024]; result = rdi_proc_vec->write (target_arm_module, data, start_addr, &nbytes, RDIAccess_Data); /* This is stupid, but let's see whether we got back what we * put in... */ rdi_proc_vec->read (target_arm_module, start_addr, buff, &nbytes, RDIAccess_Data); for (i = 0; i < nbytes; i++) { if (data[i] != buff[i]) { output_error ("Readback did not match original data\n"); } } switch (result) { case RDIError_BigEndian: output ("Processor has switched endianness - now BIG ENDIAN\n"); break; case RDIError_LittleEndian: output ("Processor has switched endianness - now LITTLE ENDIAN\n"); break; case RDIError_NoError: break; default: output_error ("RDI_Read error: %s\n", rdi_error_message (result)); return 0; } return nbytes; }intlow_set_breakpoint (CORE_ADDR bp_addr, int size){ struct rdi_points *new_point; int result, type; new_point = (struct rdi_points *) malloc (sizeof(struct rdi_points)); new_point->addr = bp_addr; new_point->handle = RDI_NoPointHandle; type = RDIPoint_EQ; if (size == 2) { type |= RDIPoint_16Bit; } if (debug_on) { output ("Adding breakpoint at 0x%x, size: %d\n", bp_addr, size); } result = rdi_proc_vec->setbreak (target_arm_module, bp_addr, type, 0, RDI_NoHandle, &new_point->handle); switch (result) { case RDIError_NoMorePoints: output ("This breakpoint exhausted the available points.\n"); case RDIError_NoError: break; /* Success branches break here */ case RDIError_ConflictingPoint: output_error ("RDI Error: Conflicting breakpoint.\n"); case RDIError_CantSetPoint: output_error ("RDI Error: No more breakpoint resources left.\n"); case RDIError_PointInUse: output_error ("RDI Error: Breakpoint 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 (breakpoint_list == NULL) { breakpoint_list = new_point; new_point->next = NULL; } else { new_point->next = breakpoint_list; breakpoint_list = new_point; } if (debug_on) { ARMword arg1, arg2; int result; struct rdi_points *iter; for (iter = breakpoint_list; iter != NULL; iter = iter->next) { arg1 = (ARMword) iter->handle; result = rdi_proc_vec->info (target_arm_module, RDIPointStatus_Break, &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_breakpoint (CORE_ADDR bp_addr, int size){ 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 breakpoint list:\n", bp_addr); for (iter = breakpoint_list; iter != NULL; iter = iter->next) { arg1 = (ARMword) iter->handle; result = rdi_proc_vec->info (target_arm_module, RDIPointStatus_Break, &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 = breakpoint_list, prev_ptr = NULL; point_ptr != NULL; prev_ptr = point_ptr, point_ptr = point_ptr->next) { if (point_ptr->addr == bp_addr) { break; } } if (point_ptr == NULL) { output_error ("Breakpoint at addr %x not found.\n", bp_addr); return 0; } result = rdi_proc_vec->clearbreak (target_arm_module, point_ptr->handle); if (result != RDIError_NoError) { output_error ("RDI Error deleting breakpoint: %s.\n", rdi_error_message (result)); return 0; } if (prev_ptr == NULL) { breakpoint_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 breakpoint list:\n", bp_addr); for (iter = breakpoint_list; iter != NULL; iter = iter->next) output ("\t-- 0x%x\n", iter->addr); } return 1;}intlow_set_watchpoint (CORE_ADDR watch_addr, int size, enum watch_type mode){ struct rdi_points *new_point; int result, type, watch_mode; new_point = (struct rdi_points *) malloc (sizeof(struct rdi_points)); new_point->addr = watch_addr; new_point->handle = RDI_NoPointHandle; type = RDIPoint_EQ; watch_mode = 0; if ((mode == WATCHPOINT_WRITE) || (mode == WATCHPOINT_ACCESS)) { watch_mode |= size*RDIWatch_ByteWrite; } if ((mode == WATCHPOINT_READ) || (mode == WATCHPOINT_ACCESS)) { watch_mode |= size*RDIWatch_ByteRead; } if (debug_on) { output ("Adding watchpoint at 0x%x, size: %d, mode: %x\n", watch_addr, size, watch_mode); } result = rdi_proc_vec->setwatch (target_arm_module, watch_addr, type, watch_mode, 0, RDI_NoHandle, &new_point->handle);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -