1/** @file
2  UEFI driver that implements a GDB stub
3
4  Note: Any code in the path of the Serial IO output can not call DEBUG as will
5  will blow out the stack. Serial IO calls DEBUG, debug calls Serail IO, ...
6
7
8  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
9
10  This program and the accompanying materials
11  are licensed and made available under the terms and conditions of the BSD License
12  which accompanies this distribution.  The full text of the license may be found at
13  http://opensource.org/licenses/bsd-license.php
14
15  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
16  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17
18**/
19
20#include <GdbStubInternal.h>
21#include <Protocol/DebugPort.h>
22
23
24UINTN     gMaxProcessorIndex = 0;
25
26//
27// Buffers for basic gdb communication
28//
29CHAR8 gInBuffer[MAX_BUF_SIZE];
30CHAR8 gOutBuffer[MAX_BUF_SIZE];
31
32// Assume gdb does a "qXfer:libraries:read::offset,length" when it connects so we can default
33// this value to FALSE. Since gdb can reconnect its self a global default is not good enough
34BOOLEAN   gSymbolTableUpdate = FALSE;
35EFI_EVENT gEvent;
36VOID      *gGdbSymbolEventHandlerRegistration = NULL;
37
38//
39// Globals for returning XML from qXfer:libraries:read packet
40//
41UINTN                             gPacketqXferLibraryOffset = 0;
42UINTN                             gEfiDebugImageTableEntry = 0;
43EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *gDebugImageTableHeader = NULL;
44EFI_DEBUG_IMAGE_INFO              *gDebugTable = NULL;
45CHAR8                             gXferLibraryBuffer[2000];
46
47GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mHexToStr[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
48
49
50VOID
51EFIAPI
52GdbSymbolEventHandler (
53  IN  EFI_EVENT       Event,
54  IN  VOID            *Context
55  )
56{
57}
58
59
60/**
61  The user Entry Point for Application. The user code starts with this function
62  as the real entry point for the image goes into a library that calls this
63  function.
64
65  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
66  @param[in] SystemTable    A pointer to the EFI System Table.
67
68  @retval EFI_SUCCESS       The entry point is executed successfully.
69  @retval other             Some error occurs when executing this entry point.
70
71**/
72EFI_STATUS
73EFIAPI
74GdbStubEntry (
75  IN EFI_HANDLE        ImageHandle,
76  IN EFI_SYSTEM_TABLE  *SystemTable
77  )
78{
79  EFI_STATUS                  Status;
80  EFI_DEBUG_SUPPORT_PROTOCOL  *DebugSupport;
81  UINTN                       HandleCount;
82  EFI_HANDLE                  *Handles;
83  UINTN                       Index;
84  UINTN                       Processor;
85  BOOLEAN                     IsaSupported;
86
87  Status = EfiGetSystemConfigurationTable (&gEfiDebugImageInfoTableGuid, (VOID **)&gDebugImageTableHeader);
88  if (EFI_ERROR (Status)) {
89    gDebugImageTableHeader = NULL;
90  }
91
92  Status = gBS->LocateHandleBuffer (
93                  ByProtocol,
94                  &gEfiDebugSupportProtocolGuid,
95                  NULL,
96                  &HandleCount,
97                  &Handles
98                  );
99  if (EFI_ERROR (Status)) {
100    DEBUG ((EFI_D_ERROR, "Debug Support Protocol not found\n"));
101
102    return Status;
103  }
104
105  DebugSupport = NULL;
106  IsaSupported = FALSE;
107  do {
108    HandleCount--;
109    Status = gBS->HandleProtocol (
110                    Handles[HandleCount],
111                    &gEfiDebugSupportProtocolGuid,
112                    (VOID **) &DebugSupport
113                    );
114    if (!EFI_ERROR (Status)) {
115      if (CheckIsa (DebugSupport->Isa)) {
116        // We found what we are looking for so break out of the loop
117        IsaSupported = TRUE;
118        break;
119      }
120    }
121  } while (HandleCount > 0);
122  FreePool (Handles);
123
124  if (!IsaSupported) {
125    DEBUG ((EFI_D_ERROR, "Debug Support Protocol does not support our ISA\n"));
126
127    return EFI_NOT_FOUND;
128  }
129
130  Status = DebugSupport->GetMaximumProcessorIndex (DebugSupport, &gMaxProcessorIndex);
131  ASSERT_EFI_ERROR (Status);
132
133  DEBUG ((EFI_D_INFO, "Debug Support Protocol ISA %x\n", DebugSupport->Isa));
134  DEBUG ((EFI_D_INFO, "Debug Support Protocol Processor Index %d\n", gMaxProcessorIndex));
135
136  // Call processor-specific init routine
137  InitializeProcessor ();
138
139  for (Processor = 0; Processor <= gMaxProcessorIndex; Processor++) {
140    for (Index = 0; Index < MaxEfiException (); Index++) {
141      Status = DebugSupport->RegisterExceptionCallback (DebugSupport, Processor,  GdbExceptionHandler, gExceptionType[Index].Exception);
142      ASSERT_EFI_ERROR (Status);
143    }
144    //
145    // Current edk2 DebugPort is not interrupt context safe so we can not use it
146    //
147    Status = DebugSupport->RegisterPeriodicCallback (DebugSupport, Processor, GdbPeriodicCallBack);
148    ASSERT_EFI_ERROR (Status);
149  }
150
151  //
152  // This even fires every time an image is added. This allows the stub to know when gdb needs
153  // to update the symbol table.
154  //
155  Status = gBS->CreateEvent (
156                  EVT_NOTIFY_SIGNAL,
157                  TPL_CALLBACK,
158                  GdbSymbolEventHandler,
159                  NULL,
160                  &gEvent
161                  );
162  ASSERT_EFI_ERROR (Status);
163
164  //
165  // Register for protocol notifications on this event
166  //
167  Status = gBS->RegisterProtocolNotify (
168                  &gEfiLoadedImageProtocolGuid,
169                  gEvent,
170                  &gGdbSymbolEventHandlerRegistration
171                  );
172  ASSERT_EFI_ERROR (Status);
173
174
175 if (PcdGetBool (PcdGdbSerial)) {
176   GdbInitializeSerialConsole ();
177 }
178
179  return EFI_SUCCESS;
180}
181
182/**
183 Transfer length bytes of input buffer, starting at Address, to memory.
184
185 @param     length                  the number of the bytes to be transferred/written
186 @param     *address                the start address of the transferring/writing the memory
187 @param     *new_data               the new data to be written to memory
188 **/
189
190VOID
191TransferFromInBufToMem (
192  IN    UINTN                       Length,
193  IN    unsigned char               *Address,
194  IN    CHAR8                       *NewData
195  )
196{
197  CHAR8 c1;
198  CHAR8 c2;
199
200  while (Length-- > 0) {
201    c1 = (CHAR8)HexCharToInt (*NewData++);
202    c2 = (CHAR8)HexCharToInt (*NewData++);
203
204    if ((c1 < 0) || (c2 < 0)) {
205      Print ((CHAR16 *)L"Bad message from write to memory..\n");
206      SendError (GDB_EBADMEMDATA);
207      return;
208    }
209    *Address++ = (UINT8)((c1 << 4) + c2);
210  }
211
212  SendSuccess();
213}
214
215
216/**
217 Transfer Length bytes of memory starting at Address to an output buffer, OutBuffer. This function will finally send the buffer
218 as a packet.
219
220 @param     Length                  the number of the bytes to be transferred/read
221 @param     *address                pointer to the start address of the transferring/reading the memory
222 **/
223
224VOID
225TransferFromMemToOutBufAndSend (
226  IN    UINTN                       Length,
227  IN    unsigned char               *Address
228  )
229{
230  // there are Length bytes and every byte is represented as 2 hex chars
231  CHAR8   OutBuffer[MAX_BUF_SIZE];
232  CHAR8   *OutBufPtr;             // pointer to the output buffer
233  CHAR8   Char;
234
235  if (ValidateAddress(Address) == FALSE) {
236    SendError(14);
237    return;
238  }
239
240  OutBufPtr = OutBuffer;
241  while (Length > 0) {
242
243    Char = mHexToStr[*Address >> 4];
244    if ((Char >= 'A') && (Char <= 'F')) {
245      Char = Char - 'A' + 'a';
246    }
247    *OutBufPtr++ = Char;
248
249    Char = mHexToStr[*Address & 0x0f];
250    if ((Char >= 'A') && (Char <= 'F')) {
251      Char = Char - 'A' + 'a';
252    }
253    *OutBufPtr++ = Char;
254
255    Address++;
256    Length--;
257  }
258
259  *OutBufPtr = '\0' ;  // the end of the buffer
260  SendPacket (OutBuffer);
261}
262
263
264
265/**
266  Send a GDB Remote Serial Protocol Packet
267
268  $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',
269  the packet teminating character '#' and the two digit checksum.
270
271  If an ack '+' is not sent resend the packet, but timeout eventually so we don't end up
272  in an infinit loop. This is so if you unplug the debugger code just keeps running
273
274  @param PacketData   Payload data for the packet
275
276
277  @retval             Number of bytes of packet data sent.
278
279**/
280UINTN
281SendPacket (
282  IN  CHAR8 *PacketData
283  )
284{
285  UINT8 CheckSum;
286  UINTN Timeout;
287  CHAR8 *Ptr;
288  CHAR8 TestChar;
289  UINTN Count;
290
291  Timeout = PcdGet32 (PcdGdbMaxPacketRetryCount);
292
293  Count = 0;
294  do {
295
296    Ptr = PacketData;
297
298    if (Timeout-- == 0) {
299      // Only try a finite number of times so we don't get stuck in the loop
300      return Count;
301    }
302
303    // Packet prefix
304    GdbPutChar ('$');
305
306    for (CheckSum = 0, Count =0 ; *Ptr != '\0'; Ptr++, Count++) {
307      GdbPutChar (*Ptr);
308      CheckSum = CheckSum + *Ptr;
309    }
310
311    // Packet terminating character and checksum
312    GdbPutChar ('#');
313    GdbPutChar (mHexToStr[CheckSum >> 4]);
314    GdbPutChar (mHexToStr[CheckSum & 0x0F]);
315
316    TestChar =  GdbGetChar ();
317  } while (TestChar != '+');
318
319  return Count;
320}
321
322/**
323  Receive a GDB Remote Serial Protocol Packet
324
325  $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',
326  the packet teminating character '#' and the two digit checksum.
327
328  If host re-starts sending a packet without ending the previous packet, only the last valid packet is proccessed.
329  (In other words, if received packet is '$12345$12345$123456#checksum', only '$123456#checksum' will be processed.)
330
331  If an ack '+' is not sent resend the packet
332
333  @param PacketData   Payload data for the packet
334
335  @retval             Number of bytes of packet data received.
336
337**/
338UINTN
339ReceivePacket (
340  OUT  CHAR8 *PacketData,
341  IN   UINTN PacketDataSize
342 )
343{
344  UINT8 CheckSum;
345  UINTN Index;
346  CHAR8 Char;
347  CHAR8 SumString[3];
348  CHAR8 TestChar;
349
350  ZeroMem (PacketData, PacketDataSize);
351
352  for (;;) {
353      // wait for the start of a packet
354    TestChar = GdbGetChar ();
355    while (TestChar != '$') {
356      TestChar = GdbGetChar ();
357    };
358
359  retry:
360    for (Index = 0, CheckSum = 0; Index < (PacketDataSize - 1); Index++) {
361      Char = GdbGetChar ();
362      if (Char == '$') {
363        goto retry;
364      }
365      if (Char == '#') {
366        break;
367      }
368
369      PacketData[Index] = Char;
370      CheckSum = CheckSum + Char;
371    }
372    PacketData[Index] = '\0';
373
374    if (Index == PacketDataSize) {
375      continue;
376    }
377
378    SumString[0] = GdbGetChar ();
379    SumString[1] = GdbGetChar ();
380    SumString[2] = '\0';
381
382    if (AsciiStrHexToUintn (SumString) == CheckSum) {
383      // Ack: Success
384      GdbPutChar ('+');
385
386      // Null terminate the callers string
387      PacketData[Index] = '\0';
388      return Index;
389    } else {
390      // Ack: Failure
391      GdbPutChar ('-');
392    }
393  }
394
395  //return 0;
396}
397
398
399/**
400 Empties the given buffer
401 @param   Buf          pointer to the first element in buffer to be emptied
402 **/
403VOID
404EmptyBuffer (
405  IN  CHAR8           *Buf
406  )
407{
408  *Buf = '\0';
409}
410
411
412/**
413 Converts an 8-bit Hex Char into a INTN.
414
415 @param   Char the hex character to be converted into UINTN
416 @retval  a INTN, from 0 to 15, that corressponds to Char
417 -1 if Char is not a hex character
418 **/
419INTN
420HexCharToInt (
421  IN  CHAR8           Char
422  )
423{
424  if ((Char >= 'A') && (Char <= 'F')) {
425    return Char - 'A' + 10;
426  } else if ((Char >= 'a') && (Char <= 'f')) {
427    return Char - 'a' + 10;
428  } else if ((Char >= '0') && (Char <= '9')) {
429    return Char - '0';
430  } else { // if not a hex value, return a negative value
431    return -1;
432  }
433}
434
435  // 'E' + the biggest error number is 255, so its 2 hex digits + buffer end
436CHAR8 *gError = "E__";
437
438/** 'E NN'
439 Send an error with the given error number after converting to hex.
440 The error number is put into the buffer in hex. '255' is the biggest errno we can send.
441 ex: 162 will be sent as A2.
442
443 @param   errno           the error number that will be sent
444 **/
445VOID
446EFIAPI
447SendError (
448  IN  UINT8              ErrorNum
449  )
450{
451  //
452  // Replace _, or old data, with current errno
453  //
454  gError[1] = mHexToStr [ErrorNum >> 4];
455  gError[2] = mHexToStr [ErrorNum & 0x0f];
456
457  SendPacket (gError); // send buffer
458}
459
460
461
462/**
463 Send 'OK' when the function is done executing successfully.
464 **/
465VOID
466EFIAPI
467SendSuccess (
468  VOID
469  )
470{
471  SendPacket ("OK"); // send buffer
472}
473
474
475/**
476 Send empty packet to specify that particular command/functionality is not supported.
477 **/
478VOID
479EFIAPI
480SendNotSupported (
481  VOID
482  )
483{
484  SendPacket ("");
485}
486
487
488/**
489 Send the T signal with the given exception type (in gdb order) and possibly with n:r pairs related to the watchpoints
490
491 @param  SystemContext        Register content at time of the exception
492 @param  GdbExceptionType     GDB exception type
493 **/
494VOID
495GdbSendTSignal (
496  IN  EFI_SYSTEM_CONTEXT  SystemContext,
497  IN  UINT8               GdbExceptionType
498  )
499{
500  CHAR8 TSignalBuffer[128];
501  CHAR8 *TSignalPtr;
502  UINTN BreakpointDetected;
503  BREAK_TYPE BreakType;
504  UINTN DataAddress;
505  CHAR8 *WatchStrPtr = NULL;
506  UINTN RegSize;
507
508  TSignalPtr = &TSignalBuffer[0];
509
510  //Construct TSignal packet
511  *TSignalPtr++ = 'T';
512
513  //
514  // replace _, or previous value, with Exception type
515  //
516  *TSignalPtr++ = mHexToStr [GdbExceptionType >> 4];
517  *TSignalPtr++ = mHexToStr [GdbExceptionType & 0x0f];
518
519  if (GdbExceptionType == GDB_SIGTRAP) {
520    if (gSymbolTableUpdate) {
521      //
522      // We can only send back on reason code. So if the flag is set it means the breakpoint is from our event handler
523      //
524      WatchStrPtr = "library:;";
525      while (*WatchStrPtr != '\0') {
526        *TSignalPtr++ = *WatchStrPtr++;
527      }
528      gSymbolTableUpdate = FALSE;
529    } else {
530
531
532      //
533      // possible n:r pairs
534      //
535
536      //Retrieve the breakpoint number
537      BreakpointDetected = GetBreakpointDetected (SystemContext);
538
539      //Figure out if the exception is happend due to watch, rwatch or awatch.
540      BreakType = GetBreakpointType (SystemContext, BreakpointDetected);
541
542      //INFO: rwatch is not supported due to the way IA32 debug registers work
543      if ((BreakType == DataWrite) || (BreakType == DataRead) || (BreakType == DataReadWrite)) {
544
545        //Construct n:r pair
546        DataAddress = GetBreakpointDataAddress (SystemContext, BreakpointDetected);
547
548        //Assign appropriate buffer to print particular watchpoint type
549        if (BreakType == DataWrite) {
550          WatchStrPtr = "watch";
551        } else if (BreakType == DataRead) {
552          WatchStrPtr = "rwatch";
553        } else if (BreakType == DataReadWrite) {
554          WatchStrPtr = "awatch";
555        }
556
557        while (*WatchStrPtr != '\0') {
558          *TSignalPtr++ = *WatchStrPtr++;
559        }
560
561        *TSignalPtr++ = ':';
562
563        //Set up series of bytes in big-endian byte order. "awatch" won't work with little-endian byte order.
564        RegSize = REG_SIZE;
565        while (RegSize > 0) {
566          RegSize = RegSize-4;
567          *TSignalPtr++ = mHexToStr[(UINT8)(DataAddress >> RegSize) & 0xf];
568        }
569
570        //Always end n:r pair with ';'
571        *TSignalPtr++ = ';';
572      }
573    }
574  }
575
576  *TSignalPtr = '\0';
577
578  SendPacket (TSignalBuffer);
579}
580
581
582/**
583 Translates the EFI mapping to GDB mapping
584
585 @param   EFIExceptionType    EFI Exception that is being processed
586 @retval  UINTN that corresponds to EFIExceptionType's GDB exception type number
587 **/
588UINT8
589ConvertEFItoGDBtype (
590  IN  EFI_EXCEPTION_TYPE      EFIExceptionType
591  )
592{
593  UINTN Index;
594
595  for (Index = 0; Index < MaxEfiException () ; Index++) {
596    if (gExceptionType[Index].Exception == EFIExceptionType) {
597      return gExceptionType[Index].SignalNo;
598    }
599  }
600  return GDB_SIGTRAP; // this is a GDB trap
601}
602
603
604/** "m addr,length"
605 Find the Length of the area to read and the start addres. Finally, pass them to
606 another function, TransferFromMemToOutBufAndSend, that will read from that memory space and
607 send it as a packet.
608 **/
609
610VOID
611EFIAPI
612ReadFromMemory (
613  CHAR8 *PacketData
614  )
615{
616  UINTN Address;
617  UINTN Length;
618  CHAR8 AddressBuffer[MAX_ADDR_SIZE]; // the buffer that will hold the address in hex chars
619  CHAR8 *AddrBufPtr; // pointer to the address buffer
620  CHAR8 *InBufPtr; /// pointer to the input buffer
621
622  AddrBufPtr = AddressBuffer;
623  InBufPtr = &PacketData[1];
624  while (*InBufPtr != ',') {
625    *AddrBufPtr++ = *InBufPtr++;
626  }
627  *AddrBufPtr = '\0';
628
629  InBufPtr++; // this skips ',' in the buffer
630
631  /* Error checking */
632  if (AsciiStrLen (AddressBuffer) >= MAX_ADDR_SIZE) {
633    Print((CHAR16 *)L"Address is too long\n");
634    SendError (GDB_EBADMEMADDRBUFSIZE);
635    return;
636  }
637
638  // 2 = 'm' + ','
639  if (AsciiStrLen (PacketData) - AsciiStrLen (AddressBuffer) - 2 >= MAX_LENGTH_SIZE) {
640    Print((CHAR16 *)L"Length is too long\n");
641    SendError (GDB_EBADMEMLENGTH);
642    return;
643  }
644
645  Address = AsciiStrHexToUintn (AddressBuffer);
646  Length = AsciiStrHexToUintn (InBufPtr);
647
648  TransferFromMemToOutBufAndSend (Length, (unsigned char *)Address);
649}
650
651
652/** "M addr,length :XX..."
653 Find the Length of the area in bytes to write and the start addres. Finally, pass them to
654 another function, TransferFromInBufToMem, that will write to that memory space the info in
655 the input buffer.
656 **/
657VOID
658EFIAPI
659WriteToMemory (
660  IN CHAR8 *PacketData
661  )
662{
663  UINTN Address;
664  UINTN Length;
665  UINTN MessageLength;
666  CHAR8 AddressBuffer[MAX_ADDR_SIZE]; // the buffer that will hold the Address in hex chars
667  CHAR8 LengthBuffer[MAX_LENGTH_SIZE]; // the buffer that will hold the Length in hex chars
668  CHAR8 *AddrBufPtr; // pointer to the Address buffer
669  CHAR8 *LengthBufPtr; // pointer to the Length buffer
670  CHAR8 *InBufPtr; /// pointer to the input buffer
671
672  AddrBufPtr = AddressBuffer;
673  LengthBufPtr = LengthBuffer;
674  InBufPtr = &PacketData[1];
675
676  while (*InBufPtr != ',') {
677    *AddrBufPtr++ = *InBufPtr++;
678  }
679  *AddrBufPtr = '\0';
680
681  InBufPtr++; // this skips ',' in the buffer
682
683  while (*InBufPtr != ':') {
684    *LengthBufPtr++ = *InBufPtr++;
685  }
686  *LengthBufPtr = '\0';
687
688  InBufPtr++; // this skips ':' in the buffer
689
690  Address = AsciiStrHexToUintn (AddressBuffer);
691  Length = AsciiStrHexToUintn (LengthBuffer);
692
693  /* Error checking */
694
695  //Check if Address is not too long.
696  if (AsciiStrLen (AddressBuffer) >= MAX_ADDR_SIZE) {
697    Print ((CHAR16 *)L"Address too long..\n");
698    SendError (GDB_EBADMEMADDRBUFSIZE);
699    return;
700  }
701
702  //Check if message length is not too long
703  if (AsciiStrLen (LengthBuffer) >= MAX_LENGTH_SIZE) {
704    Print ((CHAR16 *)L"Length too long..\n");
705    SendError (GDB_EBADMEMLENGBUFSIZE);
706    return;
707  }
708
709  // Check if Message is not too long/short.
710  // 3 = 'M' + ',' + ':'
711  MessageLength = (AsciiStrLen (PacketData) - AsciiStrLen (AddressBuffer) - AsciiStrLen (LengthBuffer) - 3);
712  if (MessageLength != (2*Length)) {
713    //Message too long/short. New data is not the right size.
714    SendError (GDB_EBADMEMDATASIZE);
715    return;
716  }
717  TransferFromInBufToMem (Length, (unsigned char *)Address, InBufPtr);
718}
719
720/**
721  Parses breakpoint packet data and captures Breakpoint type, Address and length.
722  In case of an error, function returns particular error code. Returning 0 meaning
723  no error.
724
725  @param  PacketData  Pointer to the payload data for the packet.
726  @param  Type        Breakpoint type
727  @param  Address     Breakpoint address
728  @param  Length      Breakpoint length in Bytes (1 byte, 2 byte, 4 byte)
729
730  @retval 1           Success
731  @retval {other}     Particular error code
732
733**/
734UINTN
735ParseBreakpointPacket (
736  IN  CHAR8 *PacketData,
737  OUT UINTN *Type,
738  OUT UINTN *Address,
739  OUT UINTN *Length
740  )
741{
742  CHAR8 AddressBuffer[MAX_ADDR_SIZE];
743  CHAR8 *AddressBufferPtr;
744  CHAR8 *PacketDataPtr;
745
746  PacketDataPtr = &PacketData[1];
747  AddressBufferPtr = AddressBuffer;
748
749  *Type = AsciiStrHexToUintn (PacketDataPtr);
750
751  //Breakpoint/watchpoint type should be between 0 to 4
752  if (*Type > 4) {
753    Print ((CHAR16 *)L"Type is invalid\n");
754    return 22; //EINVAL: Invalid argument.
755  }
756
757  //Skip ',' in the buffer.
758  while (*PacketDataPtr++ != ',');
759
760  //Parse Address information
761  while (*PacketDataPtr != ',') {
762    *AddressBufferPtr++ = *PacketDataPtr++;
763  }
764  *AddressBufferPtr = '\0';
765
766  //Check if Address is not too long.
767  if (AsciiStrLen (AddressBuffer) >= MAX_ADDR_SIZE) {
768    Print ((CHAR16 *)L"Address too long..\n");
769    return 40; //EMSGSIZE: Message size too long.
770  }
771
772  *Address = AsciiStrHexToUintn (AddressBuffer);
773
774  PacketDataPtr++; //This skips , in the buffer
775
776  //Parse Length information
777  *Length = AsciiStrHexToUintn (PacketDataPtr);
778
779  //Length should be 1, 2 or 4 bytes
780  if (*Length > 4) {
781    Print ((CHAR16 *)L"Length is invalid\n");
782    return 22; //EINVAL: Invalid argument
783  }
784
785  return 0; //0 = No error
786}
787
788UINTN
789gXferObjectReadResponse (
790  IN  CHAR8         Type,
791  IN  CHAR8         *Str
792  )
793{
794  CHAR8   *OutBufPtr;             // pointer to the output buffer
795  CHAR8   Char;
796  UINTN   Count;
797
798  // Response starts with 'm' or 'l' if it is the end
799  OutBufPtr = gOutBuffer;
800  *OutBufPtr++ = Type;
801  Count = 1;
802
803  // Binary data encoding
804  OutBufPtr = gOutBuffer;
805  while (*Str != '\0') {
806    Char = *Str++;
807    if ((Char == 0x7d) || (Char == 0x23) || (Char == 0x24) || (Char == 0x2a)) {
808      // escape character
809      *OutBufPtr++ = 0x7d;
810
811      Char ^= 0x20;
812    }
813    *OutBufPtr++ = Char;
814    Count++;
815  }
816
817  *OutBufPtr = '\0' ;  // the end of the buffer
818  SendPacket (gOutBuffer);
819
820  return Count;
821}
822
823
824/**
825  Note: This should be a library function.  In the Apple case you have to add
826  the size of the PE/COFF header into the starting address to make things work
827  right as there is no way to pad the Mach-O for the size of the PE/COFF header.
828
829
830  Returns a pointer to the PDB file name for a PE/COFF image that has been
831  loaded into system memory with the PE/COFF Loader Library functions.
832
833  Returns the PDB file name for the PE/COFF image specified by Pe32Data.  If
834  the PE/COFF image specified by Pe32Data is not a valid, then NULL is
835  returned.  If the PE/COFF image specified by Pe32Data does not contain a
836  debug directory entry, then NULL is returned.  If the debug directory entry
837  in the PE/COFF image specified by Pe32Data does not contain a PDB file name,
838  then NULL is returned.
839  If Pe32Data is NULL, then ASSERT().
840
841  @param  Pe32Data   Pointer to the PE/COFF image that is loaded in system
842                     memory.
843  @param  DebugBase  Address that the debugger would use as the base of the image
844
845  @return The PDB file name for the PE/COFF image specified by Pe32Data or NULL
846          if it cannot be retrieved. DebugBase is only valid if PDB file name is
847          valid.
848
849**/
850VOID *
851EFIAPI
852PeCoffLoaderGetDebuggerInfo (
853  IN VOID     *Pe32Data,
854  OUT VOID    **DebugBase
855  )
856{
857  EFI_IMAGE_DOS_HEADER                  *DosHdr;
858  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;
859  EFI_IMAGE_DATA_DIRECTORY              *DirectoryEntry;
860  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY       *DebugEntry;
861  UINTN                                 DirCount;
862  VOID                                  *CodeViewEntryPointer;
863  INTN                                  TEImageAdjust;
864  UINT32                                NumberOfRvaAndSizes;
865  UINT16                                Magic;
866  UINTN                                 SizeOfHeaders;
867
868  ASSERT (Pe32Data   != NULL);
869
870  TEImageAdjust       = 0;
871  DirectoryEntry      = NULL;
872  DebugEntry          = NULL;
873  NumberOfRvaAndSizes = 0;
874  SizeOfHeaders       = 0;
875
876  DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;
877  if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
878    //
879    // DOS image header is present, so read the PE header after the DOS image header.
880    //
881    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));
882  } else {
883    //
884    // DOS image header is not present, so PE header is at the image base.
885    //
886    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;
887  }
888
889  if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
890    if (Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) {
891      DirectoryEntry  = &Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG];
892      TEImageAdjust   = sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize;
893      DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) Hdr.Te +
894                    Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress +
895                    TEImageAdjust);
896    }
897    SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN)Hdr.Te->BaseOfCode - (UINTN)Hdr.Te->StrippedSize;
898
899    // __APPLE__ check this math...
900    *DebugBase = ((CHAR8 *)Pe32Data) -  TEImageAdjust;
901  } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {
902
903    *DebugBase = Pe32Data;
904
905
906    //
907    // NOTE: We use Machine field to identify PE32/PE32+, instead of Magic.
908    //       It is due to backward-compatibility, for some system might
909    //       generate PE32+ image with PE32 Magic.
910    //
911    switch (Hdr.Pe32->FileHeader.Machine) {
912    case EFI_IMAGE_MACHINE_IA32:
913      //
914      // Assume PE32 image with IA32 Machine field.
915      //
916      Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
917      break;
918    case EFI_IMAGE_MACHINE_X64:
919    case EFI_IMAGE_MACHINE_IA64:
920      //
921      // Assume PE32+ image with X64 or IPF Machine field
922      //
923      Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
924      break;
925    default:
926      //
927      // For unknow Machine field, use Magic in optional Header
928      //
929      Magic = Hdr.Pe32->OptionalHeader.Magic;
930    }
931
932    if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
933      //
934      // Use PE32 offset get Debug Directory Entry
935      //
936      SizeOfHeaders = Hdr.Pe32->OptionalHeader.SizeOfHeaders;
937      NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;
938      DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
939      DebugEntry     = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);
940    } else if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
941      //
942      // Use PE32+ offset get Debug Directory Entry
943      //
944      SizeOfHeaders = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders;
945      NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;
946      DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
947      DebugEntry     = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);
948    }
949
950    if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
951      DirectoryEntry = NULL;
952      DebugEntry = NULL;
953    }
954  } else {
955    return NULL;
956  }
957
958  if (DebugEntry == NULL || DirectoryEntry == NULL) {
959    return NULL;
960  }
961
962  for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), DebugEntry++) {
963    if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
964      if (DebugEntry->SizeOfData > 0) {
965        CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + ((UINTN)Pe32Data) + (UINTN)TEImageAdjust);
966        switch (* (UINT32 *) CodeViewEntryPointer) {
967        case CODEVIEW_SIGNATURE_NB10:
968          return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY));
969        case CODEVIEW_SIGNATURE_RSDS:
970          return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY));
971        case CODEVIEW_SIGNATURE_MTOC:
972          *DebugBase = (VOID *)(UINTN)((UINTN)DebugBase - SizeOfHeaders);
973          return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY));
974        default:
975          break;
976        }
977      }
978    }
979  }
980
981  (void)SizeOfHeaders;
982  return NULL;
983}
984
985
986/**
987  Process "qXfer:object:read:annex:offset,length" request.
988
989  Returns an XML document that contains loaded libraries. In our case it is
990  information in the EFI Debug Image Table converted into an XML document.
991
992  GDB will call with an arbitrary length (it can't know the real length and
993  will reply with chunks of XML that are easy for us to deal with. Gdb will
994  keep calling until we say we are done. XML doc looks like:
995
996  <library-list>
997    <library name="/a/a/c/d.dSYM"><segment address="0x10000000"/></library>
998    <library name="/a/m/e/e.pdb"><segment address="0x20000000"/></library>
999    <library name="/a/l/f/f.dll"><segment address="0x30000000"/></library>
1000  </library-list>
1001
1002  Since we can not allocate memory in interrupt context this module has
1003  assumptions about how it will get called:
1004  1) Length will generally be max remote packet size (big enough)
1005  2) First Offset of an XML document read needs to be 0
1006  3) This code will return back small chunks of the XML document on every read.
1007     Each subsequent call will ask for the next available part of the document.
1008
1009  Note: The only variable size element in the XML is:
1010  "  <library name=\"%s\"><segment address=\"%p\"/></library>\n" and it is
1011  based on the file path and name of the symbol file. If the symbol file name
1012  is bigger than the max gdb remote packet size we could update this code
1013  to respond back in chunks.
1014
1015 @param Offset  offset into special data area
1016 @param Length  number of bytes to read starting at Offset
1017
1018 **/
1019VOID
1020QxferLibrary (
1021  IN  UINTN   Offset,
1022  IN  UINTN   Length
1023  )
1024{
1025  VOID                              *LoadAddress;
1026  CHAR8                             *Pdb;
1027  UINTN                             Size;
1028
1029  if (Offset != gPacketqXferLibraryOffset) {
1030    SendError (GDB_EINVALIDARG);
1031    Print (L"\nqXferLibrary (%d, %d) != %d\n", Offset, Length, gPacketqXferLibraryOffset);
1032
1033    // Force a retry from the beginning
1034    gPacketqXferLibraryOffset = 0;
1035
1036    return;
1037  }
1038
1039  if (Offset == 0) {
1040    gPacketqXferLibraryOffset += gXferObjectReadResponse ('m', "<library-list>\n");
1041
1042    // The owner of the table may have had to ralloc it so grab a fresh copy every time
1043    // we assume qXferLibrary will get called over and over again until the entire XML table is
1044    // returned in a tight loop. Since we are in the debugger the table should not get updated
1045    gDebugTable = gDebugImageTableHeader->EfiDebugImageInfoTable;
1046    gEfiDebugImageTableEntry = 0;
1047    return;
1048  }
1049
1050  if (gDebugTable != NULL) {
1051    for (; gEfiDebugImageTableEntry < gDebugImageTableHeader->TableSize; gEfiDebugImageTableEntry++, gDebugTable++) {
1052      if (gDebugTable->NormalImage != NULL) {
1053        if ((gDebugTable->NormalImage->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) &&
1054            (gDebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) {
1055          Pdb = PeCoffLoaderGetDebuggerInfo (
1056                 gDebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase,
1057                 &LoadAddress
1058                 );
1059          if (Pdb != NULL) {
1060            Size = AsciiSPrint (
1061                    gXferLibraryBuffer,
1062                    sizeof (gXferLibraryBuffer),
1063                    "  <library name=\"%a\"><segment address=\"0x%p\"/></library>\n",
1064                    Pdb,
1065                    LoadAddress
1066                    );
1067            if ((Size != 0) && (Size != (sizeof (gXferLibraryBuffer) - 1))) {
1068              gPacketqXferLibraryOffset += gXferObjectReadResponse ('m', gXferLibraryBuffer);
1069
1070              // Update loop variables so we are in the right place when we get back
1071              gEfiDebugImageTableEntry++;
1072              gDebugTable++;
1073              return;
1074            } else {
1075              // We could handle <library> entires larger than sizeof (gXferLibraryBuffer) here if
1076              // needed by breaking up into N packets
1077              // "<library name=\"%s
1078              // the rest of the string (as many packets as required
1079              // \"><segment address=\"%d\"/></library> (fixed size)
1080              //
1081              // But right now we just skip any entry that is too big
1082            }
1083          }
1084        }
1085      }
1086    }
1087  }
1088
1089
1090  gXferObjectReadResponse ('l', "</library-list>\n");
1091  gPacketqXferLibraryOffset = 0;
1092  return;
1093}
1094
1095
1096/**
1097 Exception Hanldler for GDB. It will be called for all exceptions
1098 registered via the gExceptionType[] array.
1099
1100 @param ExceptionType     Exception that is being processed
1101 @param SystemContext     Register content at time of the exception
1102 **/
1103VOID
1104EFIAPI
1105GdbExceptionHandler (
1106  IN  EFI_EXCEPTION_TYPE        ExceptionType,
1107  IN OUT EFI_SYSTEM_CONTEXT     SystemContext
1108  )
1109{
1110  UINT8   GdbExceptionType;
1111  CHAR8   *Ptr;
1112
1113
1114  if (ValidateException (ExceptionType, SystemContext) == FALSE) {
1115    return;
1116  }
1117
1118  RemoveSingleStep (SystemContext);
1119
1120  GdbExceptionType = ConvertEFItoGDBtype (ExceptionType);
1121  GdbSendTSignal (SystemContext, GdbExceptionType);
1122
1123  for( ; ; ) {
1124    ReceivePacket (gInBuffer, MAX_BUF_SIZE);
1125
1126    switch (gInBuffer[0]) {
1127      case '?':
1128        GdbSendTSignal (SystemContext, GdbExceptionType);
1129        break;
1130
1131      case 'c':
1132        ContinueAtAddress (SystemContext, gInBuffer);
1133        return;
1134
1135      case 'g':
1136        ReadGeneralRegisters (SystemContext);
1137        break;
1138
1139      case 'G':
1140        WriteGeneralRegisters (SystemContext, gInBuffer);
1141        break;
1142
1143      case 'H':
1144        //Return "OK" packet since we don't have more than one thread.
1145        SendSuccess ();
1146        break;
1147
1148      case 'm':
1149        ReadFromMemory (gInBuffer);
1150        break;
1151
1152      case 'M':
1153        WriteToMemory (gInBuffer);
1154        break;
1155
1156      case 'P':
1157        WriteNthRegister (SystemContext, gInBuffer);
1158        break;
1159
1160      //
1161      // Still debugging this code. Not used in Darwin
1162      //
1163      case 'q':
1164        // General Query Packets
1165        if (AsciiStrnCmp (gInBuffer, "qSupported", 10) == 0) {
1166          // return what we currently support, we don't parse what gdb suports
1167          AsciiSPrint (gOutBuffer, MAX_BUF_SIZE, "qXfer:libraries:read+;PacketSize=%d", MAX_BUF_SIZE);
1168          SendPacket (gOutBuffer);
1169        } else if (AsciiStrnCmp (gInBuffer, "qXfer:libraries:read::", 22) == 0) {
1170          // ‘qXfer:libraries:read::offset,length
1171          // gInBuffer[22] is offset string, ++Ptr is length string’
1172          for (Ptr = &gInBuffer[22]; *Ptr != ','; Ptr++);
1173
1174          // Not sure if multi-radix support is required. Currently only support decimal
1175          QxferLibrary (AsciiStrHexToUintn (&gInBuffer[22]), AsciiStrHexToUintn (++Ptr));
1176        } if (AsciiStrnCmp (gInBuffer, "qOffsets", 10) == 0) {
1177          AsciiSPrint (gOutBuffer, MAX_BUF_SIZE, "Text=1000;Data=f000;Bss=f000");
1178          SendPacket (gOutBuffer);
1179        } else {
1180          //Send empty packet
1181          SendNotSupported ();
1182        }
1183        break;
1184
1185      case 's':
1186        SingleStep (SystemContext, gInBuffer);
1187        return;
1188
1189      case 'z':
1190        RemoveBreakPoint (SystemContext, gInBuffer);
1191        break;
1192
1193      case 'Z':
1194        InsertBreakPoint (SystemContext, gInBuffer);
1195        break;
1196
1197      default:
1198        //Send empty packet
1199        SendNotSupported ();
1200        break;
1201    }
1202  }
1203}
1204
1205
1206/**
1207 Periodic callback for GDB. This function is used to catch a ctrl-c or other
1208 break in type command from GDB.
1209
1210 @param SystemContext     Register content at time of the call
1211 **/
1212VOID
1213EFIAPI
1214GdbPeriodicCallBack (
1215  IN OUT EFI_SYSTEM_CONTEXT     SystemContext
1216  )
1217{
1218  //
1219  // gCtrlCBreakFlag may have been set from a previous F response package
1220  // and we set the global as we need to process it at a point where we
1221  // can update the system context. If we are in the middle of processing
1222  // a F Packet it is not safe to read the GDB serial stream so we need
1223  // to skip it on this check
1224  //
1225  if (!gCtrlCBreakFlag && !gProcessingFPacket) {
1226    //
1227    // Ctrl-C was not pending so grab any pending characters and see if they
1228    // are a Ctrl-c (0x03). If so set the Ctrl-C global.
1229    //
1230    while (TRUE) {
1231      if (!GdbIsCharAvailable ()) {
1232        //
1233        // No characters are pending so exit the loop
1234        //
1235        break;
1236      }
1237
1238      if (GdbGetChar () == 0x03) {
1239        gCtrlCBreakFlag = TRUE;
1240        //
1241        // We have a ctrl-c so exit the loop
1242        //
1243        break;
1244      }
1245    }
1246  }
1247
1248  if (gCtrlCBreakFlag) {
1249    //
1250    // Update the context to force a single step trap when we exit the GDB
1251    // stub. This will transfer control to GdbExceptionHandler () and let
1252    // us break into the program. We don't want to break into the GDB stub.
1253    //
1254    AddSingleStep (SystemContext);
1255    gCtrlCBreakFlag = FALSE;
1256  }
1257}
1258