• 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 __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