VOID EFIAPI RemoveBreakPoint ( IN EFI_SYSTEM_CONTEXT SystemContext, IN CHAR8 *PacketData ) { UINTN Type; UINTN Address; UINTN Length; UINTN ErrorCode; //Parse breakpoint packet data ErrorCode = ParseBreakpointPacket (PacketData, &Type, &Address, &Length); if (ErrorCode > 0) { SendError ((UINT8)ErrorCode); return; } switch (Type) { case 0: //Software breakpoint break; default: SendError (GDB_EINVALIDBRKPOINTTYPE); return; } ClearBreakpoint (Address); SendSuccess (); }
DWORD TraceBpHandler( PPROCESS_INFO ThisProcess, PTHREAD_INFO ThisThread, PEXCEPTION_RECORD ExceptionRecord, PBREAKPOINT_INFO BreakpointInfo ) { CONTEXT Context; #ifdef _M_IX86 if (BreakpointInfo->Flags & BPF_TRACE) { CurrContext.EFlags &= ~0x100; SetRegContext( ThisThread->hThread, &CurrContext ); } #endif if (BreakpointInfo->LastBp) { WriteMemory( ThisProcess->hProcess, (PVOID) BreakpointInfo->LastBp->Address, &BpInstr, BpSize ); BreakpointInfo->LastBp = NULL; } // // clear the trace breakpoint // ClearBreakpoint( ThisProcess, BreakpointInfo ); // // print the registers // if (PrintRegistersFlag) { PrintRegisters(); } // // print the code // PrintOneInstruction( ThisProcess->hProcess, (ULONG)ExceptionRecord->ExceptionAddress ); // // enter the debugger // ULONG ContinueStatus = ConsoleDebugger( ThisThread->hProcess, ThisThread->hThread, ExceptionRecord, FALSE, BreakpointInfo->Command ); // // continue the debuggee // return ContinueStatus; }
BOOL CmdBreakPoint( LPSTR CmdBuf, HANDLE hProcess, HANDLE hThread, PEXCEPTION_RECORD ExceptionRecord ) { CHAR BpCmd = tolower(CmdBuf[1]); ULONG Address = 0; PBREAKPOINT_INFO bp; PPROCESS_INFO ThisProcess; ULONG Flags; LPSTR p; LPSTR SymName; ULONG i; IMAGEHLP_MODULE mi; ThisProcess = GetProcessInfo( hProcess ); if (!ThisProcess) { printf( "could not get process information\n" ); return FALSE; } PTHREAD_INFO ThisThread = GetThreadInfo( hProcess, hThread ); if (!ThisThread) { printf( "could not get thread information\n" ); return FALSE; } SKIP_NONWHITE( CmdBuf ); SKIP_WHITE( CmdBuf ); p = CmdBuf; switch ( BpCmd ) { case 'p': Flags = 0; CmdBuf = GetAddress( CmdBuf, &Address ); SymName = (LPSTR) MemAlloc( CmdBuf - p + 16 ); if (!SymName) { printf( "could not allocate memory for bp command\n" ); break; } strncpy( SymName, p, CmdBuf - p ); if (!Address) { Flags = BPF_UNINSTANCIATED; printf( "breakpoint not instanciated\n" ); } bp = SetBreakpoint( ThisProcess, Address, Flags, SymName, UserBpHandler ); MemFree( SymName ); if (!bp) { printf( "could not set breakpoint\n" ); } ThisProcess->UserBpCount += 1; bp->Number = ThisProcess->UserBpCount; SKIP_WHITE( CmdBuf ); if (CmdBuf[0]) { if (CmdBuf[0] == '/') { switch (tolower(CmdBuf[1])) { case 'c': CmdBuf += 3; if (CmdBuf[0] != '\"') { printf( "invalid syntax\n" ); return FALSE; } CmdBuf += 1; p = strchr( CmdBuf, '\"' ); if (!p) { printf( "invalid syntax\n" ); return FALSE; } p[0] = 0; bp->Command = _strdup( CmdBuf ); break; default: break; } } } break; case 'l': for (i=0; i<MAX_BREAKPOINTS; i++) { if (ThisProcess->Breakpoints[i].Number) { ULONG disp = 0; if (ThisProcess->Breakpoints[i].Flags & BPF_WATCH) { printf( "#%d %c%c\t \tWatch\n", ThisProcess->Breakpoints[i].Number, ThisProcess->Breakpoints[i].Flags & BPF_UNINSTANCIATED ? 'U' : 'I', ThisProcess->Breakpoints[i].Flags & BPF_DISABLED ? 'D' : 'E' ); } else if ((ThisProcess->Breakpoints[i].Address != 0) && (ThisProcess->Breakpoints[i].Address != 0xffffffff)) { SymGetModuleInfo( ThisProcess->hProcess, ThisProcess->Breakpoints[i].Address, &mi ); if (SymGetSymFromAddr( ThisProcess->hProcess, ThisProcess->Breakpoints[i].Address, &disp, sym )) { printf( "#%d %c%c\t0x%08x\t%s!%s\n", ThisProcess->Breakpoints[i].Number, ThisProcess->Breakpoints[i].Flags & BPF_UNINSTANCIATED ? 'U' : 'I', ThisProcess->Breakpoints[i].Flags & BPF_DISABLED ? 'D' : 'E', ThisProcess->Breakpoints[i].Address, mi.ModuleName, sym ? sym->Name : "" ); } } else { printf( "#%d %c%c\t \t%s\n", ThisProcess->Breakpoints[i].Number, ThisProcess->Breakpoints[i].Flags & BPF_UNINSTANCIATED ? 'U' : 'I', ThisProcess->Breakpoints[i].Flags & BPF_DISABLED ? 'D' : 'E', ThisProcess->Breakpoints[i].SymName ); } } } break; case 'c': if (!CmdBuf[0]) { printf( "missing breakpoint number\n" ); return FALSE; } if (CmdBuf[0] == '*') { for (i=0; i<MAX_BREAKPOINTS; i++) { if (ThisProcess->Breakpoints[i].Number) { ClearBreakpoint( ThisProcess, &ThisProcess->Breakpoints[i] ); } } return TRUE; } if (isdigit(CmdBuf[0])) { ULONG BpNum = atoi( CmdBuf ); for (i=0; i<MAX_BREAKPOINTS; i++) { if (ThisProcess->Breakpoints[i].Number == BpNum) { ClearBreakpoint( ThisProcess, &ThisProcess->Breakpoints[i] ); return TRUE; } } } printf( "invalid breakpoint number\n" ); return FALSE; case 'd': break; case 'e': break; case 'a': #if defined(_M_IX86) CmdBuf = GetAddress( CmdBuf, &Address ); bp = GetAvailBreakpoint( ThisProcess ); if (!bp) { printf( "could not set breakpoint\n" ); return FALSE; } bp->Address = Address; bp->Handler = UserBpHandler; bp->Flags = BPF_WATCH; ThisProcess->UserBpCount += 1; bp->Number = ThisProcess->UserBpCount; CurrContext.Dr0 = Address; CurrContext.Dr6 = 0x000d0002; SetRegContext( ThisThread->hThread, &CurrContext ); #else printf( "only available on x86\n" ); #endif break; default: break; } return TRUE; }