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