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