xref: /netbsd-src/sys/external/bsd/gnu-efi/dist/apps/debughook.c (revision 3f351f34c6d827cf017cdcff3543f6ec0c88b420)
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