public abstract bool setBreakpoint(UInt32 addr, EBreakpointType type = EBreakpointType.BREAKPOINT_AUTO);
// Set a hardware or software breakpoint at a specific location in memory. // // @retval True Breakpoint was set. // @retval False Breakpoint could not be set. public override bool setBreakpoint(UInt32 addr, EBreakpointType type = EBreakpointType.BREAKPOINT_AUTO) { return(this.bp_manager.set_breakpoint(addr, type)); }
// Set a hardware or software breakpoint at a specific location in memory. // // @retval True Breakpoint was set. // @retval False Breakpoint could not be set. public virtual bool set_breakpoint(UInt32 addr, EBreakpointType type = EBreakpointType.BREAKPOINT_AUTO) { Trace.TraceInformation("set bkpt type {0} at 0x{1:x}", type, addr); // Clear Thumb bit in case it is set. addr = (UInt32)(addr & ~1); var in_hw_bkpt_range = addr < 0x20000000; var fbp_available = this._fpb != null && this._fpb.available_breakpoints() > 0; var fbp_below_min = this._fpb == null || this._fpb.available_breakpoints() <= MIN_HW_BREAKPOINTS; // Check for an existing breakpoint at this address. Provider.Breakpoint bp = this.find_breakpoint(addr); if (bp != null) { return(true); } bool is_flash; bool is_ram; if (this._core.memory_map == null) { // No memory map - fallback to hardware breakpoints. type = EBreakpointType.BREAKPOINT_HW; is_flash = false; is_ram = false; } else { // Look up the memory type for the requested address. Core.Memory.MemoryRegion region = this._core.memory_map.getRegionForAddress(addr); if (region != null) { is_flash = region.isFlash; is_ram = region.isRam; } else { // No memory region - fallback to hardware breakpoints. type = EBreakpointType.BREAKPOINT_HW; is_flash = false; is_ram = false; } } // Determine best type to use if auto. if (type == EBreakpointType.BREAKPOINT_AUTO) { // Use sw breaks for: // 1. Addresses outside the supported FPBv1 range of 0-0x1fffffff // 2. RAM regions by default. // 3. Number of remaining hw breaks are at or less than the minimum we want to keep. // // Otherwise use hw. if ((!in_hw_bkpt_range) || is_ram || fbp_below_min) { type = EBreakpointType.BREAKPOINT_SW; } else { type = EBreakpointType.BREAKPOINT_HW; } Trace.TraceInformation("using type {0} for auto bp", type); } // Revert to sw bp if out of hardware breakpoint range. if (type == EBreakpointType.BREAKPOINT_HW && !in_hw_bkpt_range) { if (is_ram) { Trace.TraceInformation("using sw bp instead because of unsupported addr"); type = EBreakpointType.BREAKPOINT_SW; } else { Trace.TraceInformation("could not fallback to software breakpoint"); return(false); } } // Revert to hw bp if region is flash. if (is_flash) { if (in_hw_bkpt_range && fbp_available) { Trace.TraceInformation("using hw bp instead because addr is flash"); type = EBreakpointType.BREAKPOINT_HW; } else { Trace.TraceInformation("could not fallback to hardware breakpoint"); return(false); } } // Set the bp. try { var provider = this._providers[type]; bp = provider.set_breakpoint(addr); } catch (KeyNotFoundException) { throw new Exception(String.Format("Unknown breakpoint type {0}", type)); } if (bp == null) { return(false); } // Save the bp. this._breakpoints[addr] = bp; return(true); }