debughook.c revision 1.1 1 /* $NetBSD: debughook.c,v 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