Home | History | Annotate | Line # | Download | only in apps
      1 /*	$NetBSD: debughook.c,v 1.1.1.1 2018/08/16 18:17:47 jmcneill Exp $	*/
      2 
      3 #include <efi.h>
      4 #include <efilib.h>
      5 
      6 EFI_STATUS
      7 GetVariableAttr(CHAR16 *var, UINT8 **data, UINTN *len, EFI_GUID owner,
      8 		  UINT32 *attributes)
      9 {
     10 	EFI_STATUS efi_status;
     11 
     12 	*len = 0;
     13 
     14 	efi_status = uefi_call_wrapper(RT->GetVariable, 5, var, &owner,
     15 				       NULL, len, NULL);
     16 	if (efi_status != EFI_BUFFER_TOO_SMALL)
     17 		return efi_status;
     18 
     19 	*data = AllocateZeroPool(*len);
     20 	if (!*data)
     21 		return EFI_OUT_OF_RESOURCES;
     22 
     23 	efi_status = uefi_call_wrapper(RT->GetVariable, 5, var, &owner,
     24 				       attributes, len, *data);
     25 
     26 	if (efi_status != EFI_SUCCESS) {
     27 		FreePool(*data);
     28 		*data = NULL;
     29 	}
     30 	return efi_status;
     31 }
     32 
     33 EFI_STATUS
     34 GetVariable(CHAR16 *var, UINT8 **data, UINTN *len, EFI_GUID owner)
     35 {
     36 	return GetVariableAttr(var, data, len, owner, NULL);
     37 }
     38 
     39 EFI_GUID DUMMY_GUID =
     40 {0x55aad538, 0x8f82, 0x4e2a, {0xa4,0xf0,0xbe, 0x59, 0x13, 0xb6, 0x5f, 0x1e}};
     41 
     42 #if defined(__clang__)
     43 # define _OPTNONE __attribute__((optnone))
     44 #else
     45 # define _OPTNONE __attribute__((__optimize__("0")))
     46 #endif
     47 
     48 static _OPTNONE void
     49 DebugHook(void)
     50 {
     51 	EFI_GUID guid = DUMMY_GUID;
     52 	UINT8 *data = NULL;
     53 	UINTN dataSize = 0;
     54 	EFI_STATUS efi_status;
     55 	register volatile unsigned long long x = 0;
     56 	extern char _text, _data;
     57 
     58 	if (x)
     59 		return;
     60 
     61 	efi_status = GetVariable(L"DUMMY_DEBUG", &data, &dataSize, guid);
     62 	if (EFI_ERROR(efi_status)) {
     63 		return;
     64 	}
     65 
     66 	Print(L"add-symbol-file /usr/lib/debug/boot/efi/debughook.debug "
     67 	      L"0x%08x -s .data 0x%08x\n", &_text, &_data);
     68 
     69 	Print(L"Pausing for debugger attachment.\n");
     70 	Print(L"To disable this, remove the EFI variable DUMMY_DEBUG-%g .\n",
     71 	      &guid);
     72 	x = 1;
     73 	while (x++) {
     74 		/* Make this so it can't /totally/ DoS us. */
     75 #if defined(__x86_64__) || defined(__i386__) || defined(__i686__)
     76 		if (x > 4294967294ULL)
     77 			break;
     78 		__asm__ __volatile__("pause");
     79 #elif defined(__aarch64__)
     80 		if (x > 1000)
     81 			break;
     82 		__asm__ __volatile__("wfi");
     83 #else
     84 		if (x > 12000)
     85 			break;
     86 		uefi_call_wrapper(BS->Stall, 1, 5000);
     87 #endif
     88 	}
     89 	x = 1;
     90 }
     91 
     92 
     93 EFI_STATUS
     94 efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
     95 {
     96 	InitializeLib(image, systab);
     97 	DebugHook();
     98 	return EFI_SUCCESS;
     99 }
    100