1 /** @file 2 Private include file for GDB stub 3 4 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> 5 6 This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 **/ 15 16 #ifndef __GCC_DEBUG_AGENT_INTERNAL__ 17 #define __GCC_DEBUG_AGENT_INTERNAL__ 18 19 #include <Uefi.h> 20 #include <Library/BaseLib.h> 21 #include <Library/BaseMemoryLib.h> 22 #include <Library/MemoryAllocationLib.h> 23 #include <Library/DebugLib.h> 24 #include <Library/PcdLib.h> 25 #include <Library/GdbSerialLib.h> 26 #include <Library/PrintLib.h> 27 #include <Library/CacheMaintenanceLib.h> 28 #include <Library/DebugAgentTimerLib.h> 29 #include <Library/DebugAgentLib.h> 30 31 #include <IndustryStandard/PeImage.h> 32 #include <Protocol/DebugSupport.h> 33 34 extern CONST CHAR8 mHexToStr[]; 35 36 // maximum size of input and output buffers 37 // This value came from the show remote command of the gdb we tested against 38 #define MAX_BUF_SIZE 2000 39 40 // maximum size of address buffer 41 #define MAX_ADDR_SIZE 32 42 43 // maximum size of register number buffer 44 #define MAX_REG_NUM_BUF_SIZE 32 45 46 // maximum size of length buffer 47 #define MAX_LENGTH_SIZE 32 48 49 // maximum size of T signal members 50 #define MAX_T_SIGNAL_SIZE 64 51 52 // the mask used to clear all the cache 53 #define TF_BIT 0x00000100 54 55 56 // 57 // GDB Signal definitions - generic names for interrupts 58 // 59 #define GDB_SIGINT 2 // Interrupt process via ctrl-c 60 #define GDB_SIGILL 4 // Illegal instruction 61 #define GDB_SIGTRAP 5 // Trace Trap (Breakpoint and SingleStep) 62 #define GDB_SIGEMT 7 // Emulator Trap 63 #define GDB_SIGFPE 8 // Floating point exception 64 #define GDB_SIGSEGV 11 // Setgment violation, page fault 65 66 67 // 68 // GDB File I/O Error values, zero means no error 69 // Includes all general GDB Unix like error values 70 // 71 #define GDB_EBADMEMADDRBUFSIZE 11 // the buffer that stores memory Address to be read from/written to is not the right size 72 #define GDB_EBADMEMLENGBUFSIZE 12 // the buffer that stores Length is not the right size 73 #define GDB_EBADMEMLENGTH 13 // Length, the given number of bytes to read or write, is not the right size 74 #define GDB_EBADMEMDATA 14 // one of the bytes or nibbles of the memory is leess than 0 75 #define GDB_EBADMEMDATASIZE 15 // the memory data, 'XX..', is too short or too long 76 #define GDB_EBADBUFSIZE 21 // the buffer created is not the correct size 77 #define GDB_EINVALIDARG 31 // argument is invalid 78 #define GDB_ENOSPACE 41 // 79 #define GDB_EINVALIDBRKPOINTTYPE 51 // the breakpoint type is not recognized 80 #define GDB_EINVALIDREGNUM 61 // given register number is not valid: either <0 or >=Number of Registers 81 #define GDB_EUNKNOWN 255 // unknown 82 83 84 // 85 // These devices are open by GDB so we can just read and write to them 86 // 87 #define GDB_STDIN 0x00 88 #define GDB_STDOUT 0x01 89 #define GDB_STDERR 0x02 90 91 // 92 //Define Register size for different architectures 93 // 94 #if defined (MDE_CPU_IA32) 95 #define REG_SIZE 32 96 #elif defined (MDE_CPU_X64) 97 #define REG_SIZE 64 98 #elif defined (MDE_CPU_ARM) 99 #define REG_SIZE 32 100 #endif 101 102 103 typedef struct { 104 EFI_EXCEPTION_TYPE Exception; 105 UINT8 SignalNo; 106 } EFI_EXCEPTION_TYPE_ENTRY; 107 108 109 #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) 110 111 // 112 // Byte packed structure for DR6 113 // 32-bits on IA-32 114 // 64-bits on X64. The upper 32-bits on X64 are reserved 115 // 116 typedef union { 117 struct { 118 UINT32 B0:1; // Breakpoint condition detected 119 UINT32 B1:1; // Breakpoint condition detected 120 UINT32 B2:1; // Breakpoint condition detected 121 UINT32 B3:1; // Breakpoint condition detected 122 UINT32 Reserved_1:9; // Reserved 123 UINT32 BD:1; // Debug register access detected 124 UINT32 BS:1; // Single step 125 UINT32 BT:1; // Task switch 126 UINT32 Reserved_2:16; // Reserved 127 } Bits; 128 UINTN UintN; 129 } IA32_DR6; 130 131 // 132 // Byte packed structure for DR7 133 // 32-bits on IA-32 134 // 64-bits on X64. The upper 32-bits on X64 are reserved 135 // 136 typedef union { 137 struct { 138 UINT32 L0:1; // Local breakpoint enable 139 UINT32 G0:1; // Global breakpoint enable 140 UINT32 L1:1; // Local breakpoint enable 141 UINT32 G1:1; // Global breakpoint enable 142 UINT32 L2:1; // Local breakpoint enable 143 UINT32 G2:1; // Global breakpoint enable 144 UINT32 L3:1; // Local breakpoint enable 145 UINT32 G3:1; // Global breakpoint enable 146 UINT32 LE:1; // Local exact breakpoint enable 147 UINT32 GE:1; // Global exact breakpoint enable 148 UINT32 Reserved_1:3; // Reserved 149 UINT32 GD:1; // Global detect enable 150 UINT32 Reserved_2:2; // Reserved 151 UINT32 RW0:2; // Read/Write field 152 UINT32 LEN0:2; // Length field 153 UINT32 RW1:2; // Read/Write field 154 UINT32 LEN1:2; // Length field 155 UINT32 RW2:2; // Read/Write field 156 UINT32 LEN2:2; // Length field 157 UINT32 RW3:2; // Read/Write field 158 UINT32 LEN3:2; // Length field 159 } Bits; 160 UINTN UintN; 161 } IA32_DR7; 162 163 #endif /* if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) */ 164 165 typedef enum { 166 InstructionExecution, //Hardware breakpoint 167 DataWrite, //watch 168 DataRead, //rwatch 169 DataReadWrite, //awatch 170 SoftwareBreakpoint, //Software breakpoint 171 NotSupported 172 } BREAK_TYPE; 173 174 // 175 // Array of exception types that need to be hooked by the debugger 176 // 177 extern EFI_EXCEPTION_TYPE_ENTRY gExceptionType[]; 178 179 // 180 // If the periodic callback is called while we are processing an F packet we need 181 // to let the callback know to not read from the serail stream as it could steal 182 // characters from the F reponse packet 183 // 184 extern BOOLEAN gProcessingFPacket; 185 186 187 /** 188 Return the number of entries in the gExceptionType[] 189 190 @retval UINTN, the number of entries in the gExceptionType[] array. 191 **/ 192 UINTN 193 MaxEfiException ( 194 VOID 195 ); 196 197 198 /** 199 Check to see if the ISA is supported. 200 ISA = Instruction Set Architecture 201 202 @retval TRUE if Isa is supported, 203 FALSE otherwise. 204 **/ 205 BOOLEAN 206 CheckIsa ( 207 IN EFI_INSTRUCTION_SET_ARCHITECTURE Isa 208 ); 209 210 211 /** 212 Send the T signal with the given exception type (in gdb order) and possibly with n:r pairs related to the watchpoints 213 214 @param SystemContext Register content at time of the exception 215 @param GdbExceptionType GDB exception type 216 **/ 217 218 VOID 219 GdbSendTSignal ( 220 IN EFI_SYSTEM_CONTEXT SystemContext, 221 IN UINT8 GdbExceptionType 222 ); 223 224 225 /** 226 Translates the EFI mapping to GDB mapping 227 228 @param EFIExceptionType EFI Exception that is being processed 229 @retval UINTN that corresponds to EFIExceptionType's GDB exception type number 230 **/ 231 UINT8 232 ConvertEFItoGDBtype ( 233 IN EFI_EXCEPTION_TYPE EFIExceptionType 234 ); 235 236 237 /** 238 Empties the given buffer 239 @param *Buf pointer to the first element in buffer to be emptied 240 **/ 241 VOID 242 EmptyBuffer ( 243 IN CHAR8 *Buf 244 ); 245 246 247 /** 248 Converts an 8-bit Hex Char into a INTN. 249 250 @param Char - the hex character to be converted into UINTN 251 @retval a INTN, from 0 to 15, that corressponds to Char 252 -1 if Char is not a hex character 253 **/ 254 INTN 255 HexCharToInt ( 256 IN CHAR8 Char 257 ); 258 259 260 /** 'E NN' 261 Send an error with the given error number after converting to hex. 262 The error number is put into the buffer in hex. '255' is the biggest errno we can send. 263 ex: 162 will be sent as A2. 264 265 @param errno the error number that will be sent 266 **/ 267 VOID 268 EFIAPI 269 SendError ( 270 IN UINT8 ErrorNum 271 ); 272 273 274 /** 275 Send 'OK' when the function is done executing successfully. 276 **/ 277 VOID 278 SendSuccess ( 279 VOID 280 ); 281 282 283 /** 284 Send empty packet to specify that particular command/functionality is not supported. 285 **/ 286 VOID 287 SendNotSupported ( 288 VOID 289 ); 290 291 /** ‘p n’ 292 Reads the n-th register's value into an output buffer and sends it as a packet 293 @param SystemContext Register content at time of the exception 294 @param InBuffer This is the input buffer received from gdb server 295 **/ 296 VOID 297 ReadNthRegister ( 298 IN EFI_SYSTEM_CONTEXT SystemContext, 299 IN CHAR8 *InBuffer 300 ); 301 302 303 /** ‘g’ 304 Reads the general registers into an output buffer and sends it as a packet 305 @param SystemContext Register content at time of the exception 306 **/ 307 VOID 308 ReadGeneralRegisters ( 309 IN EFI_SYSTEM_CONTEXT SystemContext 310 ); 311 312 313 /** ‘P n...=r...’ 314 Writes the new value of n-th register received into the input buffer to the n-th register 315 @param SystemContext Register content at time of the exception 316 @param InBuffer This is the input buffer received from gdb server 317 **/ 318 VOID 319 WriteNthRegister ( 320 IN EFI_SYSTEM_CONTEXT SystemContext, 321 IN CHAR8 *InBuffer 322 ); 323 324 325 /** ‘G XX...’ 326 Writes the new values received into the input buffer to the general registers 327 @param SystemContext Register content at time of the exception 328 @param InBuffer Pointer to the input buffer received from gdb server 329 **/ 330 331 VOID 332 WriteGeneralRegisters ( 333 IN EFI_SYSTEM_CONTEXT SystemContext, 334 IN CHAR8 *InBuffer 335 ); 336 337 338 /** ‘m addr,length ’ 339 Find the Length of the area to read and the start addres. Finally, pass them to 340 another function, TransferFromMemToOutBufAndSend, that will read from that memory space and 341 send it as a packet. 342 343 @param *PacketData Pointer to Payload data for the packet 344 **/ 345 VOID 346 ReadFromMemory ( 347 IN CHAR8 *PacketData 348 ); 349 350 351 /** ‘M addr,length :XX...’ 352 Find the Length of the area in bytes to write and the start addres. Finally, pass them to 353 another function, TransferFromInBufToMem, that will write to that memory space the info in 354 the input buffer. 355 356 @param PacketData Pointer to Payload data for the packet 357 **/ 358 VOID 359 WriteToMemory ( 360 IN CHAR8 *PacketData 361 ); 362 363 364 /** ‘c [addr ]’ 365 Continue. addr is Address to resume. If addr is omitted, resume at current 366 Address. 367 368 @param SystemContext Register content at time of the exception 369 @param *PacketData Pointer to PacketData 370 **/ 371 372 VOID 373 ContinueAtAddress ( 374 IN EFI_SYSTEM_CONTEXT SystemContext, 375 IN CHAR8 *PacketData 376 ); 377 378 379 /** ‘s [addr ]’ 380 Single step. addr is the Address at which to resume. If addr is omitted, resume 381 at same Address. 382 383 @param SystemContext Register content at time of the exception 384 @param PacketData Pointer to Payload data for the packet 385 **/ 386 VOID 387 SingleStep ( 388 IN EFI_SYSTEM_CONTEXT SystemContext, 389 IN CHAR8 *PacketData 390 ); 391 392 /** 393 Insert Single Step in the SystemContext 394 395 @param SystemContext Register content at time of the exception 396 **/ 397 VOID 398 AddSingleStep ( 399 IN EFI_SYSTEM_CONTEXT SystemContext 400 ); 401 402 /** 403 Remove Single Step in the SystemContext 404 405 @param SystemContext Register content at time of the exception 406 **/ 407 VOID 408 RemoveSingleStep ( 409 IN EFI_SYSTEM_CONTEXT SystemContext 410 ); 411 412 413 /** 414 ‘Z1, [addr], [length]’ 415 ‘Z2, [addr], [length]’ 416 ‘Z3, [addr], [length]’ 417 ‘Z4, [addr], [length]’ 418 419 Insert hardware breakpoint/watchpoint at address addr of size length 420 421 @param SystemContext Register content at time of the exception 422 @param *PacketData Pointer to the Payload data for the packet 423 424 **/ 425 VOID 426 EFIAPI 427 InsertBreakPoint( 428 IN EFI_SYSTEM_CONTEXT SystemContext, 429 IN CHAR8 *PacketData 430 ); 431 432 433 /** 434 ‘z1, [addr], [length]’ 435 ‘z2, [addr], [length]’ 436 ‘z3, [addr], [length]’ 437 ‘z4, [addr], [length]’ 438 439 Remove hardware breakpoint/watchpoint at address addr of size length 440 441 @param SystemContext Register content at time of the exception 442 @param *PacketData Pointer to the Payload data for the packet 443 444 **/ 445 VOID 446 EFIAPI 447 RemoveBreakPoint( 448 IN EFI_SYSTEM_CONTEXT SystemContext, 449 IN CHAR8 *PacketData 450 ); 451 452 453 /** 454 Exception Hanldler for GDB. It will be called for all exceptions 455 registered via the gExceptionType[] array. 456 457 @param ExceptionType Exception that is being processed 458 @param SystemContext Register content at time of the exception 459 460 **/ 461 VOID 462 EFIAPI 463 GdbExceptionHandler ( 464 IN EFI_EXCEPTION_TYPE ExceptionType, 465 IN OUT EFI_SYSTEM_CONTEXT SystemContext 466 ); 467 468 469 /** 470 Periodic callback for GDB. This function is used to catch a ctrl-c or other 471 break in type command from GDB. 472 473 @param SystemContext Register content at time of the call 474 475 **/ 476 VOID 477 EFIAPI 478 GdbPeriodicCallBack ( 479 IN OUT EFI_SYSTEM_CONTEXT SystemContext 480 ); 481 482 483 /** 484 Make two serail consoles: 1) StdIn and StdOut via GDB. 2) StdErr via GDB. 485 486 These console show up on the remote system running GDB 487 488 **/ 489 490 VOID 491 GdbInitializeSerialConsole ( 492 VOID 493 ); 494 495 496 /** 497 Send a GDB Remote Serial Protocol Packet 498 499 $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$', 500 the packet teminating character '#' and the two digit checksum. 501 502 If an ack '+' is not sent resend the packet, but timeout eventually so we don't end up 503 in an infinit loop. This is so if you unplug the debugger code just keeps running 504 505 @param PacketData Payload data for the packet 506 507 @retval Number of bytes of packet data sent. 508 509 **/ 510 UINTN 511 SendPacket ( 512 IN CHAR8 *PacketData 513 ); 514 515 516 /** 517 Receive a GDB Remote Serial Protocol Packet 518 519 $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$', 520 the packet teminating character '#' and the two digit checksum. 521 522 If host re-starts sending a packet without ending the previous packet, only the last valid packet is processed. 523 (In other words, if received packet is '$12345$12345$123456#checksum', only '$123456#checksum' will be processed.) 524 525 If an ack '+' is not sent resend the packet 526 527 @param PacketData Payload data for the packet 528 529 @retval Number of bytes of packet data received. 530 531 **/ 532 UINTN 533 ReceivePacket ( 534 OUT CHAR8 *PacketData, 535 IN UINTN PacketDataSize 536 ); 537 538 539 /** 540 Read data from a FileDescriptor. On success number of bytes read is returned. Zero indicates 541 the end of a file. On error -1 is returned. If count is zero, GdbRead returns zero. 542 543 @param FileDescriptor Device to talk to. 544 @param Buffer Buffer to hold Count bytes that were read 545 @param Count Number of bytes to transfer. 546 547 @retval -1 Error 548 @retval {other} Number of bytes read. 549 550 **/ 551 INTN 552 GdbRead ( 553 IN INTN FileDescriptor, 554 OUT VOID *Buffer, 555 IN UINTN Count 556 ); 557 558 559 /** 560 Write data to a FileDescriptor. On success number of bytes written is returned. Zero indicates 561 nothing was written. On error -1 is returned. 562 563 @param FileDescriptor Device to talk to. 564 @param Buffer Buffer to hold Count bytes that are to be written 565 @param Count Number of bytes to transfer. 566 567 @retval -1 Error 568 @retval {other} Number of bytes written. 569 570 **/ 571 INTN 572 GdbWrite ( 573 IN INTN FileDescriptor, 574 OUT CONST VOID *Buffer, 575 IN UINTN Count 576 ); 577 578 UINTN * 579 FindPointerToRegister ( 580 IN EFI_SYSTEM_CONTEXT SystemContext, 581 IN UINTN RegNumber 582 ); 583 584 CHAR8 * 585 BasicReadRegister ( 586 IN EFI_SYSTEM_CONTEXT SystemContext, 587 IN UINTN RegNumber, 588 IN CHAR8 *OutBufPtr 589 ); 590 591 VOID 592 TransferFromInBufToMem ( 593 IN UINTN Length, 594 IN UINT8 *Address, 595 IN CHAR8 *NewData 596 ); 597 598 VOID 599 TransferFromMemToOutBufAndSend ( 600 IN UINTN Length, 601 IN UINT8 *Address 602 ); 603 604 CHAR8 * 605 BasicWriteRegister ( 606 IN EFI_SYSTEM_CONTEXT SystemContext, 607 IN UINTN RegNumber, 608 IN CHAR8 *InBufPtr 609 ); 610 611 VOID 612 PrintReg ( 613 EFI_SYSTEM_CONTEXT SystemContext 614 ); 615 616 UINTN 617 ParseBreakpointPacket ( 618 IN CHAR8 *PacketData, 619 OUT UINTN *Type, 620 OUT UINTN *Address, 621 OUT UINTN *Length 622 ); 623 624 UINTN 625 GetBreakpointDataAddress ( 626 IN EFI_SYSTEM_CONTEXT SystemContext, 627 IN UINTN BreakpointNumber 628 ); 629 630 UINTN 631 GetBreakpointDetected ( 632 IN EFI_SYSTEM_CONTEXT SystemContext 633 ); 634 635 BREAK_TYPE 636 GetBreakpointType ( 637 IN EFI_SYSTEM_CONTEXT SystemContext, 638 IN UINTN BreakpointNumber 639 ); 640 641 UINTN 642 ConvertLengthData ( 643 IN UINTN Length 644 ); 645 646 EFI_STATUS 647 FindNextFreeDebugRegister ( 648 IN EFI_SYSTEM_CONTEXT SystemContext, 649 OUT UINTN *Register 650 ); 651 652 EFI_STATUS 653 EnableDebugRegister ( 654 IN EFI_SYSTEM_CONTEXT SystemContext, 655 IN UINTN Register, 656 IN UINTN Address, 657 IN UINTN Length, 658 IN UINTN Type 659 ); 660 661 EFI_STATUS 662 FindMatchingDebugRegister ( 663 IN EFI_SYSTEM_CONTEXT SystemContext, 664 IN UINTN Address, 665 IN UINTN Length, 666 IN UINTN Type, 667 OUT UINTN *Register 668 ); 669 670 EFI_STATUS 671 DisableDebugRegister ( 672 IN EFI_SYSTEM_CONTEXT SystemContext, 673 IN UINTN Register 674 ); 675 676 VOID 677 InitializeProcessor ( 678 VOID 679 ); 680 681 /** 682 Send the T signal with the given exception type (in gdb order) and possibly with n:r pairs related to the watchpoints 683 684 @param SystemContext Register content at time of the exception 685 @param GdbExceptionType GDB exception type 686 **/ 687 VOID 688 ProcessorSendTSignal ( 689 IN EFI_SYSTEM_CONTEXT SystemContext, 690 IN UINT8 GdbExceptionType, 691 IN OUT CHAR8 *TSignalPtr, 692 IN UINTN SizeOfBuffer 693 ); 694 695 /** 696 Check to see if this exception is related to ctrl-c handling. 697 698 @param ExceptionType Exception that is being processed 699 @param SystemContext Register content at time of the exception 700 701 @return TRUE This was a ctrl-c check that did not find a ctrl-c 702 @return FALSE This was not a ctrl-c check or some one hit ctrl-c 703 **/ 704 BOOLEAN 705 ProcessorControlC ( 706 IN EFI_EXCEPTION_TYPE ExceptionType, 707 IN OUT EFI_SYSTEM_CONTEXT SystemContext 708 ); 709 710 711 /** 712 Initialize debug agent. 713 714 This function is used to set up debug enviroment. It may enable interrupts. 715 716 @param[in] InitFlag Init flag is used to decide initialize process. 717 @param[in] Context Context needed according to InitFlag, it was optional. 718 719 **/ 720 VOID 721 EFIAPI 722 DebugAgentHookExceptions ( 723 IN UINT32 InitFlag, 724 IN VOID *Context OPTIONAL 725 ); 726 727 728 #endif 729