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