1 /** @file 2 3 Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR> 4 This program and the accompanying materials 5 are licensed and made available under the terms and conditions of the BSD License 6 which accompanies this distribution. The full text of the license may be found at 7 http://opensource.org/licenses/bsd-license.php 8 9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 12 13 **/ 14 15 #include "Edb.h" 16 17 /** 18 19 Check whether current IP is EBC BREAK3 instruction. 20 21 @param Address EBC IP address. 22 23 @retval TRUE Current IP is EBC BREAK3 instruction 24 @retval FALSE Current IP is not EBC BREAK3 instruction 25 26 **/ 27 BOOLEAN 28 IsEBCBREAK3 ( 29 IN UINTN Address 30 ) 31 { 32 if (GET_OPCODE(Address) != OPCODE_BREAK) { 33 return FALSE; 34 } 35 36 if (GET_OPERANDS (Address) != 3) { 37 return FALSE; 38 } else { 39 return TRUE; 40 } 41 } 42 43 /** 44 45 Check whether the Address is already set in breakpoint. 46 47 @param DebuggerPrivate EBC Debugger private data structure 48 @param Address Breakpoint Address 49 50 @retval TRUE breakpoint is found 51 @retval FALSE breakpoint is not found 52 53 **/ 54 BOOLEAN 55 DebuggerBreakpointIsDuplicated ( 56 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, 57 IN UINTN Address 58 ) 59 { 60 UINTN Index; 61 62 // 63 // Go through each breakpoint context 64 // 65 for (Index = 0; Index < DebuggerPrivate->DebuggerBreakpointCount; Index++) { 66 if (DebuggerPrivate->DebuggerBreakpointContext[Index].BreakpointAddress == Address) { 67 // 68 // Found it 69 // 70 return TRUE; 71 } 72 } 73 74 // 75 // Not found 76 // 77 return FALSE; 78 } 79 80 /** 81 82 Add this breakpoint. 83 84 @param DebuggerPrivate EBC Debugger private data structure 85 @param Address Breakpoint Address 86 87 @retval EFI_SUCCESS breakpoint added successfully 88 @retval EFI_ALREADY_STARTED breakpoint is already added 89 @retval EFI_OUT_OF_RESOURCES all the breakpoint entries are used 90 91 **/ 92 EFI_STATUS 93 DebuggerBreakpointAdd ( 94 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, 95 IN UINTN Address 96 ) 97 { 98 // 99 // Check duplicated breakpoint 100 // 101 if (DebuggerBreakpointIsDuplicated (DebuggerPrivate, Address)) { 102 EDBPrint (L"Breakpoint duplicated!\n"); 103 return EFI_ALREADY_STARTED; 104 } 105 106 // 107 // Check whether the address is a breakpoint 3 instruction 108 // 109 if (IsEBCBREAK3 (Address)) { 110 EDBPrint (L"Breakpoint can not be set on BREAK 3 instruction!\n"); 111 return EFI_ALREADY_STARTED; 112 } 113 114 if (DebuggerPrivate->DebuggerBreakpointCount >= EFI_DEBUGGER_BREAKPOINT_MAX) { 115 EDBPrint (L"Breakpoint out of resource!\n"); 116 return EFI_OUT_OF_RESOURCES; 117 } 118 119 // 120 // Set the breakpoint 121 // 122 DebuggerPrivate->DebuggerBreakpointContext[DebuggerPrivate->DebuggerBreakpointCount].BreakpointAddress = Address; 123 DebuggerPrivate->DebuggerBreakpointContext[DebuggerPrivate->DebuggerBreakpointCount].State = TRUE; 124 DebuggerPrivate->DebuggerBreakpointContext[DebuggerPrivate->DebuggerBreakpointCount].OldInstruction = 0; 125 CopyMem ( 126 &DebuggerPrivate->DebuggerBreakpointContext[DebuggerPrivate->DebuggerBreakpointCount].OldInstruction, 127 (VOID *)Address, 128 sizeof(UINT16) 129 ); 130 131 DebuggerPrivate->DebuggerBreakpointCount ++; 132 133 // 134 // Done 135 // 136 return EFI_SUCCESS; 137 } 138 139 /** 140 141 Delete this breakpoint. 142 143 @param DebuggerPrivate EBC Debugger private data structure 144 @param Index Breakpoint Index 145 146 @retval EFI_SUCCESS breakpoint deleted successfully 147 @retval EFI_NOT_FOUND breakpoint not found 148 149 **/ 150 EFI_STATUS 151 DebuggerBreakpointDel ( 152 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, 153 IN UINTN Index 154 ) 155 { 156 UINTN BpIndex; 157 158 if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) || 159 (Index >= DebuggerPrivate->DebuggerBreakpointCount)) { 160 return EFI_NOT_FOUND; 161 } 162 163 // 164 // Delete this breakpoint 165 // 166 for (BpIndex = Index; BpIndex < DebuggerPrivate->DebuggerBreakpointCount - 1; BpIndex++) { 167 DebuggerPrivate->DebuggerBreakpointContext[BpIndex] = DebuggerPrivate->DebuggerBreakpointContext[BpIndex + 1]; 168 } 169 ZeroMem ( 170 &DebuggerPrivate->DebuggerBreakpointContext[BpIndex], 171 sizeof(DebuggerPrivate->DebuggerBreakpointContext[BpIndex]) 172 ); 173 174 DebuggerPrivate->DebuggerBreakpointCount --; 175 176 // 177 // Done 178 // 179 return EFI_SUCCESS; 180 } 181 182 /** 183 184 Disable this breakpoint. 185 186 @param DebuggerPrivate EBC Debugger private data structure 187 @param Index Breakpoint Index 188 189 @retval EFI_SUCCESS breakpoint disabled successfully 190 @retval EFI_NOT_FOUND breakpoint not found 191 192 **/ 193 EFI_STATUS 194 DebuggerBreakpointDis ( 195 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, 196 IN UINTN Index 197 ) 198 { 199 if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) || 200 (Index >= DebuggerPrivate->DebuggerBreakpointCount)) { 201 return EFI_NOT_FOUND; 202 } 203 204 // 205 // Disable this breakpoint 206 // 207 DebuggerPrivate->DebuggerBreakpointContext[Index].State = FALSE; 208 209 return EFI_SUCCESS; 210 } 211 212 /** 213 214 Enable this breakpoint. 215 216 @param DebuggerPrivate - EBC Debugger private data structure 217 @param Index - Breakpoint Index 218 219 @retval EFI_SUCCESS - breakpoint enabled successfully 220 @retval EFI_NOT_FOUND - breakpoint not found 221 222 **/ 223 EFI_STATUS 224 DebuggerBreakpointEn ( 225 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, 226 IN UINTN Index 227 ) 228 { 229 if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) || 230 (Index >= DebuggerPrivate->DebuggerBreakpointCount)) { 231 return EFI_NOT_FOUND; 232 } 233 234 // 235 // Enable this breakpoint 236 // 237 DebuggerPrivate->DebuggerBreakpointContext[Index].State = TRUE; 238 239 return EFI_SUCCESS; 240 } 241 242 /** 243 244 DebuggerCommand - BreakpointList. 245 246 @param CommandArg - The argument for this command 247 @param DebuggerPrivate - EBC Debugger private data structure 248 @param ExceptionType - Exception type. 249 @param SystemContext - EBC system context. 250 251 @retval EFI_DEBUG_CONTINUE - formal return value 252 253 **/ 254 EFI_DEBUG_STATUS 255 DebuggerBreakpointList ( 256 IN CHAR16 *CommandArg, 257 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, 258 IN EFI_EXCEPTION_TYPE ExceptionType, 259 IN OUT EFI_SYSTEM_CONTEXT SystemContext 260 ) 261 { 262 UINTN Index; 263 264 // 265 // Check breakpoint cound 266 // 267 if (DebuggerPrivate->DebuggerBreakpointCount == 0) { 268 EDBPrint (L"No Breakpoint\n"); 269 return EFI_DEBUG_CONTINUE; 270 } else if (DebuggerPrivate->DebuggerBreakpointCount > EFI_DEBUGGER_BREAKPOINT_MAX) { 271 EDBPrint (L"Breakpoint too many!\n"); 272 DebuggerPrivate->DebuggerBreakpointCount = 0; 273 return EFI_DEBUG_CONTINUE; 274 } 275 276 // 277 // Go through each breakpoint 278 // 279 EDBPrint (L"Breakpoint :\n"); 280 EDBPrint (L" Index Address Status\n"); 281 EDBPrint (L"======= ================== ========\n"); 282 //EDBPrint (L" 1 0xFFFFFFFF00000000 *\n"); 283 //EDBPrint (L" 12 0x00000000FFFFFFFF\n"); 284 for (Index = 0; Index < DebuggerPrivate->DebuggerBreakpointCount; Index++) { 285 // 286 // Print the breakpoint 287 // 288 EDBPrint (L" %2d 0x%016lx", Index, DebuggerPrivate->DebuggerBreakpointContext[Index].BreakpointAddress); 289 if (DebuggerPrivate->DebuggerBreakpointContext[Index].State) { 290 EDBPrint (L" *\n"); 291 } else { 292 EDBPrint (L"\n"); 293 } 294 } 295 296 // 297 // Done 298 // 299 return EFI_DEBUG_CONTINUE; 300 } 301 302 /** 303 304 DebuggerCommand - BreakpointSet. 305 306 @param CommandArg The argument for this command 307 @param DebuggerPrivate EBC Debugger private data structure 308 @param ExceptionType Exception type. 309 @param SystemContext EBC system context. 310 311 @retval EFI_DEBUG_CONTINUE - formal return value 312 313 **/ 314 EFI_DEBUG_STATUS 315 DebuggerBreakpointSet ( 316 IN CHAR16 *CommandArg, 317 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, 318 IN EFI_EXCEPTION_TYPE ExceptionType, 319 IN OUT EFI_SYSTEM_CONTEXT SystemContext 320 ) 321 { 322 UINTN Address; 323 EFI_STATUS Status; 324 325 if (CommandArg == NULL) { 326 EDBPrint (L"BreakpointSet Argument error!\n"); 327 return EFI_DEBUG_CONTINUE; 328 } 329 330 // 331 // Get breakpoint address 332 // 333 Status = Symboltoi (CommandArg, &Address); 334 if (EFI_ERROR (Status)) { 335 if (Status == EFI_NOT_FOUND) { 336 Address = Xtoi(CommandArg); 337 } else { 338 // 339 // Something wrong, let Symboltoi print error info. 340 // 341 EDBPrint (L"Command Argument error!\n"); 342 return EFI_DEBUG_CONTINUE; 343 } 344 } 345 346 // 347 // Add breakpoint 348 // 349 Status = DebuggerBreakpointAdd (DebuggerPrivate, Address); 350 if (EFI_ERROR(Status)) { 351 EDBPrint (L"BreakpointSet error!\n"); 352 } 353 354 // 355 // Done 356 // 357 return EFI_DEBUG_CONTINUE; 358 } 359 360 /** 361 362 DebuggerCommand - BreakpointClear 363 364 @param CommandArg The argument for this command 365 @param DebuggerPrivate EBC Debugger private data structure 366 @param ExceptionType Exception type. 367 @param SystemContext EBC system context. 368 369 @retval EFI_DEBUG_CONTINUE formal return value 370 371 **/ 372 EFI_DEBUG_STATUS 373 DebuggerBreakpointClear ( 374 IN CHAR16 *CommandArg, 375 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, 376 IN EFI_EXCEPTION_TYPE ExceptionType, 377 IN OUT EFI_SYSTEM_CONTEXT SystemContext 378 ) 379 { 380 UINTN Index; 381 EFI_STATUS Status; 382 383 if (CommandArg == NULL) { 384 EDBPrint (L"BreakpointClear Argument error!\n"); 385 return EFI_DEBUG_CONTINUE; 386 } 387 388 if (StriCmp (CommandArg, L"*") == 0) { 389 // 390 // delete all breakpoint 391 // 392 DebuggerPrivate->DebuggerBreakpointCount = 0; 393 ZeroMem (DebuggerPrivate->DebuggerBreakpointContext, sizeof(DebuggerPrivate->DebuggerBreakpointContext)); 394 EDBPrint (L"All the Breakpoint is cleared\n"); 395 return EFI_DEBUG_CONTINUE; 396 } 397 398 // 399 // Get breakpoint index 400 // 401 Index = Atoi(CommandArg); 402 if (Index == (UINTN) -1) { 403 EDBPrint (L"BreakpointClear Argument error!\n"); 404 return EFI_DEBUG_CONTINUE; 405 } 406 407 if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) || 408 (Index >= DebuggerPrivate->DebuggerBreakpointCount)) { 409 EDBPrint (L"BreakpointClear error!\n"); 410 return EFI_DEBUG_CONTINUE; 411 } 412 413 // 414 // Delete breakpoint 415 // 416 Status = DebuggerBreakpointDel (DebuggerPrivate, Index); 417 if (EFI_ERROR(Status)) { 418 EDBPrint (L"BreakpointClear error!\n"); 419 } 420 421 // 422 // Done 423 // 424 return EFI_DEBUG_CONTINUE; 425 } 426 427 /** 428 429 DebuggerCommand - BreakpointDisable 430 431 @param CommandArg The argument for this command 432 @param DebuggerPrivate EBC Debugger private data structure 433 @param ExceptionType Exception type. 434 @param SystemContext EBC system context. 435 436 @retval EFI_DEBUG_CONTINUE formal return value 437 438 **/ 439 EFI_DEBUG_STATUS 440 DebuggerBreakpointDisable ( 441 IN CHAR16 *CommandArg, 442 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, 443 IN EFI_EXCEPTION_TYPE ExceptionType, 444 IN OUT EFI_SYSTEM_CONTEXT SystemContext 445 ) 446 { 447 UINTN Index; 448 EFI_STATUS Status; 449 450 if (CommandArg == NULL) { 451 EDBPrint (L"BreakpointDisable Argument error!\n"); 452 return EFI_DEBUG_CONTINUE; 453 } 454 455 if (StriCmp (CommandArg, L"*") == 0) { 456 // 457 // disable all breakpoint 458 // 459 for (Index = 0; Index < DebuggerPrivate->DebuggerBreakpointCount; Index++) { 460 Status = DebuggerBreakpointDis (DebuggerPrivate, Index); 461 } 462 EDBPrint (L"All the Breakpoint is disabled\n"); 463 return EFI_DEBUG_CONTINUE; 464 } 465 466 // 467 // Get breakpoint index 468 // 469 Index = Atoi(CommandArg); 470 if (Index == (UINTN) -1) { 471 EDBPrint (L"BreakpointDisable Argument error!\n"); 472 return EFI_DEBUG_CONTINUE; 473 } 474 475 // 476 // Disable breakpoint 477 // 478 Status = DebuggerBreakpointDis (DebuggerPrivate, Index); 479 if (EFI_ERROR(Status)) { 480 EDBPrint (L"BreakpointDisable error!\n"); 481 } 482 483 // 484 // Done 485 // 486 return EFI_DEBUG_CONTINUE; 487 } 488 489 /** 490 DebuggerCommand - BreakpointEnable. 491 492 @param CommandArg The argument for this command 493 @param DebuggerPrivate EBC Debugger private data structure 494 @param ExceptionType Exception type. 495 @param SystemContext EBC system context. 496 497 @retval EFI_DEBUG_CONTINUE formal return value 498 499 **/ 500 EFI_DEBUG_STATUS 501 DebuggerBreakpointEnable ( 502 IN CHAR16 *CommandArg, 503 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, 504 IN EFI_EXCEPTION_TYPE ExceptionType, 505 IN OUT EFI_SYSTEM_CONTEXT SystemContext 506 ) 507 { 508 UINTN Index; 509 EFI_STATUS Status; 510 511 if (CommandArg == NULL) { 512 EDBPrint (L"BreakpointEnable Argument error!\n"); 513 return EFI_DEBUG_CONTINUE; 514 } 515 516 if (StriCmp (CommandArg, L"*") == 0) { 517 // 518 // enable all breakpoint 519 // 520 for (Index = 0; Index < DebuggerPrivate->DebuggerBreakpointCount; Index++) { 521 Status = DebuggerBreakpointEn (DebuggerPrivate, Index); 522 } 523 EDBPrint (L"All the Breakpoint is enabled\n"); 524 return EFI_DEBUG_CONTINUE; 525 } 526 527 // 528 // Get breakpoint index 529 // 530 Index = Atoi(CommandArg); 531 if (Index == (UINTN) -1) { 532 EDBPrint (L"BreakpointEnable Argument error!\n"); 533 return EFI_DEBUG_CONTINUE; 534 } 535 536 // 537 // Enable breakpoint 538 // 539 Status = DebuggerBreakpointEn (DebuggerPrivate, Index); 540 if (EFI_ERROR(Status)) { 541 EDBPrint (L"BreakpointEnable error!\n"); 542 } 543 544 // 545 // Done 546 // 547 return EFI_DEBUG_CONTINUE; 548 } 549