xref: /freebsd/lib/libefivar/uefi-dplib.h (revision ce1342883e03e6a021f03a49d13539a145d320e2)
1 /*-
2  * Copyright (c) 2017 Netflix, Inc.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  */
25 
26 /*
27  * Taken from MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.h
28  */
29 
30 /** @file
31   Definition for Device Path library.
32 
33 Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
34 SPDX-License-Identifier: BSD-2-Clause-Patent
35 
36 **/
37 
38 #ifndef _UEFI_DEVICE_PATH_LIB_H_
39 #define _UEFI_DEVICE_PATH_LIB_H_
40 
41 #include <Uefi.h>
42 #include <Protocol/DevicePathUtilities.h>
43 #include <Protocol/DebugPort.h>
44 #include <Protocol/DevicePathToText.h>
45 #include <Protocol/DevicePathFromText.h>
46 #include <Guid/PcAnsi.h>
47 #include <Library/DebugLib.h>
48 #include <Library/PrintLib.h>
49 #include <Library/BaseLib.h>
50 #include <Library/BaseMemoryLib.h>
51 #include <Library/MemoryAllocationLib.h>
52 #include <Library/UefiBootServicesTableLib.h>
53 #include <Library/DevicePathLib.h>
54 #include <Library/PcdLib.h>
55 #include <IndustryStandard/Bluetooth.h>
56 
57 #define IS_COMMA(a)          ((a) == ',')
58 #define IS_HYPHEN(a)         ((a) == '-')
59 #define IS_DOT(a)            ((a) == '.')
60 #define IS_LEFT_PARENTH(a)   ((a) == '(')
61 #define IS_RIGHT_PARENTH(a)  ((a) == ')')
62 #define IS_SLASH(a)          ((a) == '/')
63 #define IS_NULL(a)           ((a) == '\0')
64 
65 //
66 // Private Data structure
67 //
68 typedef struct {
69   char      *Str;
70   UINTN     Count;
71   UINTN     Capacity;
72 } POOL_PRINT;
73 
74 typedef
75 EFI_DEVICE_PATH_PROTOCOL  *
76 (*DEVICE_PATH_FROM_TEXT) (
77   IN  char    *Str
78   );
79 
80 typedef
81 VOID
82 (*DEVICE_PATH_TO_TEXT) (
83   IN OUT POOL_PRINT  *Str,
84   IN VOID            *DevicePath,
85   IN BOOLEAN         DisplayOnly,
86   IN BOOLEAN         AllowShortcuts
87   );
88 
89 typedef struct {
90   UINT8                  Type;
91   UINT8                  SubType;
92   DEVICE_PATH_TO_TEXT    Function;
93 } DEVICE_PATH_TO_TEXT_TABLE;
94 
95 typedef struct {
96   UINT8     Type;
97   const char    *Text;
98 } DEVICE_PATH_TO_TEXT_GENERIC_TABLE;
99 
100 typedef struct {
101   const char               *DevicePathNodeText;
102   DEVICE_PATH_FROM_TEXT    Function;
103 } DEVICE_PATH_FROM_TEXT_TABLE;
104 
105 typedef struct {
106   BOOLEAN    ClassExist;
107   UINT8      Class;
108   BOOLEAN    SubClassExist;
109   UINT8      SubClass;
110 } USB_CLASS_TEXT;
111 
112 #define USB_CLASS_AUDIO         1
113 #define USB_CLASS_CDCCONTROL    2
114 #define USB_CLASS_HID           3
115 #define USB_CLASS_IMAGE         6
116 #define USB_CLASS_PRINTER       7
117 #define USB_CLASS_MASS_STORAGE  8
118 #define USB_CLASS_HUB           9
119 #define USB_CLASS_CDCDATA       10
120 #define USB_CLASS_SMART_CARD    11
121 #define USB_CLASS_VIDEO         14
122 #define USB_CLASS_DIAGNOSTIC    220
123 #define USB_CLASS_WIRELESS      224
124 
125 #define USB_CLASS_RESERVE         254
126 #define USB_SUBCLASS_FW_UPDATE    1
127 #define USB_SUBCLASS_IRDA_BRIDGE  2
128 #define USB_SUBCLASS_TEST         3
129 
130 #define RFC_1700_UDP_PROTOCOL  17
131 #define RFC_1700_TCP_PROTOCOL  6
132 
133 #pragma pack(1)
134 
135 typedef struct {
136   EFI_DEVICE_PATH_PROTOCOL    Header;
137   EFI_GUID                    Guid;
138   UINT8                       VendorDefinedData[1];
139 } VENDOR_DEFINED_HARDWARE_DEVICE_PATH;
140 
141 typedef struct {
142   EFI_DEVICE_PATH_PROTOCOL    Header;
143   EFI_GUID                    Guid;
144   UINT8                       VendorDefinedData[1];
145 } VENDOR_DEFINED_MESSAGING_DEVICE_PATH;
146 
147 typedef struct {
148   EFI_DEVICE_PATH_PROTOCOL    Header;
149   EFI_GUID                    Guid;
150   UINT8                       VendorDefinedData[1];
151 } VENDOR_DEFINED_MEDIA_DEVICE_PATH;
152 
153 typedef struct {
154   EFI_DEVICE_PATH_PROTOCOL    Header;
155   UINT32                      Hid;
156   UINT32                      Uid;
157   UINT32                      Cid;
158   CHAR8                       HidUidCidStr[3];
159 } ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR;
160 
161 typedef struct {
162   EFI_DEVICE_PATH_PROTOCOL    Header;
163   UINT16                      NetworkProtocol;
164   UINT16                      LoginOption;
165   UINT64                      Lun;
166   UINT16                      TargetPortalGroupTag;
167   CHAR8                       TargetName[1];
168 } ISCSI_DEVICE_PATH_WITH_NAME;
169 
170 typedef struct {
171   EFI_DEVICE_PATH_PROTOCOL    Header;
172   EFI_GUID                    Guid;
173   UINT8                       VendorDefinedData[1];
174 } VENDOR_DEVICE_PATH_WITH_DATA;
175 
176 #pragma pack()
177 
178 #ifdef FreeBSD		/* Remove these on FreeBSD */
179 
180 /**
181   Returns the size of a device path in bytes.
182 
183   This function returns the size, in bytes, of the device path data structure
184   specified by DevicePath including the end of device path node.
185   If DevicePath is NULL or invalid, then 0 is returned.
186 
187   @param  DevicePath  A pointer to a device path data structure.
188 
189   @retval 0           If DevicePath is NULL or invalid.
190   @retval Others      The size of a device path in bytes.
191 
192 **/
193 UINTN
194 EFIAPI
195 UefiDevicePathLibGetDevicePathSize (
196   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
197   );
198 
199 /**
200   Creates a new copy of an existing device path.
201 
202   This function allocates space for a new copy of the device path specified by DevicePath.
203   If DevicePath is NULL, then NULL is returned.  If the memory is successfully
204   allocated, then the contents of DevicePath are copied to the newly allocated
205   buffer, and a pointer to that buffer is returned.  Otherwise, NULL is returned.
206   The memory for the new device path is allocated from EFI boot services memory.
207   It is the responsibility of the caller to free the memory allocated.
208 
209   @param  DevicePath    A pointer to a device path data structure.
210 
211   @retval NULL          DevicePath is NULL or invalid.
212   @retval Others        A pointer to the duplicated device path.
213 
214 **/
215 EFI_DEVICE_PATH_PROTOCOL *
216 EFIAPI
217 UefiDevicePathLibDuplicateDevicePath (
218   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
219   );
220 
221 /**
222   Creates a new device path by appending a second device path to a first device path.
223 
224   This function creates a new device path by appending a copy of SecondDevicePath
225   to a copy of FirstDevicePath in a newly allocated buffer.  Only the end-of-device-path
226   device node from SecondDevicePath is retained. The newly created device path is
227   returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of
228   SecondDevicePath is returned.  If SecondDevicePath is NULL, then it is ignored,
229   and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and
230   SecondDevicePath are NULL, then a copy of an end-of-device-path is returned.
231 
232   If there is not enough memory for the newly allocated buffer, then NULL is returned.
233   The memory for the new device path is allocated from EFI boot services memory.
234   It is the responsibility of the caller to free the memory allocated.
235 
236   @param  FirstDevicePath            A pointer to a device path data structure.
237   @param  SecondDevicePath           A pointer to a device path data structure.
238 
239   @retval NULL      If there is not enough memory for the newly allocated buffer.
240   @retval NULL      If FirstDevicePath or SecondDevicePath is invalid.
241   @retval Others    A pointer to the new device path if success.
242                     Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL.
243 
244 **/
245 EFI_DEVICE_PATH_PROTOCOL *
246 EFIAPI
247 UefiDevicePathLibAppendDevicePath (
248   IN CONST EFI_DEVICE_PATH_PROTOCOL  *FirstDevicePath   OPTIONAL,
249   IN CONST EFI_DEVICE_PATH_PROTOCOL  *SecondDevicePath  OPTIONAL
250   );
251 
252 /**
253   Creates a new path by appending the device node to the device path.
254 
255   This function creates a new device path by appending a copy of the device node
256   specified by DevicePathNode to a copy of the device path specified by DevicePath
257   in an allocated buffer. The end-of-device-path device node is moved after the
258   end of the appended device node.
259   If DevicePathNode is NULL then a copy of DevicePath is returned.
260   If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device
261   path device node is returned.
262   If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path
263   device node is returned.
264   If there is not enough memory to allocate space for the new device path, then
265   NULL is returned.
266   The memory is allocated from EFI boot services memory. It is the responsibility
267   of the caller to free the memory allocated.
268 
269   @param  DevicePath                 A pointer to a device path data structure.
270   @param  DevicePathNode             A pointer to a single device path node.
271 
272   @retval NULL      If there is not enough memory for the new device path.
273   @retval Others    A pointer to the new device path if success.
274                     A copy of DevicePathNode followed by an end-of-device-path node
275                     if both FirstDevicePath and SecondDevicePath are NULL.
276                     A copy of an end-of-device-path node if both FirstDevicePath
277                     and SecondDevicePath are NULL.
278 
279 **/
280 EFI_DEVICE_PATH_PROTOCOL *
281 EFIAPI
282 UefiDevicePathLibAppendDevicePathNode (
283   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath      OPTIONAL,
284   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode  OPTIONAL
285   );
286 
287 /**
288   Creates a new device path by appending the specified device path instance to the specified device
289   path.
290 
291   This function creates a new device path by appending a copy of the device path
292   instance specified by DevicePathInstance to a copy of the device path specified
293   by DevicePath in a allocated buffer.
294   The end-of-device-path device node is moved after the end of the appended device
295   path instance and a new end-of-device-path-instance node is inserted between.
296   If DevicePath is NULL, then a copy if DevicePathInstance is returned.
297   If DevicePathInstance is NULL, then NULL is returned.
298   If DevicePath or DevicePathInstance is invalid, then NULL is returned.
299   If there is not enough memory to allocate space for the new device path, then
300   NULL is returned.
301   The memory is allocated from EFI boot services memory. It is the responsibility
302   of the caller to free the memory allocated.
303 
304   @param  DevicePath                 A pointer to a device path data structure.
305   @param  DevicePathInstance         A pointer to a device path instance.
306 
307   @return A pointer to the new device path.
308 
309 **/
310 EFI_DEVICE_PATH_PROTOCOL *
311 EFIAPI
312 UefiDevicePathLibAppendDevicePathInstance (
313   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath         OPTIONAL,
314   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathInstance OPTIONAL
315   );
316 
317 /**
318   Creates a copy of the current device path instance and returns a pointer to the next device path
319   instance.
320 
321   This function creates a copy of the current device path instance. It also updates
322   DevicePath to point to the next device path instance in the device path (or NULL
323   if no more) and updates Size to hold the size of the device path instance copy.
324   If DevicePath is NULL, then NULL is returned.
325   If DevicePath points to a invalid device path, then NULL is returned.
326   If there is not enough memory to allocate space for the new device path, then
327   NULL is returned.
328   The memory is allocated from EFI boot services memory. It is the responsibility
329   of the caller to free the memory allocated.
330   If Size is NULL, then ASSERT().
331 
332   @param  DevicePath                 On input, this holds the pointer to the current
333                                      device path instance. On output, this holds
334                                      the pointer to the next device path instance
335                                      or NULL if there are no more device path
336                                      instances in the device path pointer to a
337                                      device path data structure.
338   @param  Size                       On output, this holds the size of the device
339                                      path instance, in bytes or zero, if DevicePath
340                                      is NULL.
341 
342   @return A pointer to the current device path instance.
343 
344 **/
345 EFI_DEVICE_PATH_PROTOCOL *
346 EFIAPI
347 UefiDevicePathLibGetNextDevicePathInstance (
348   IN OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePath,
349   OUT UINTN                        *Size
350   );
351 
352 /**
353   Creates a device node.
354 
355   This function creates a new device node in a newly allocated buffer of size
356   NodeLength and initializes the device path node header with NodeType and NodeSubType.
357   The new device path node is returned.
358   If NodeLength is smaller than a device path header, then NULL is returned.
359   If there is not enough memory to allocate space for the new device path, then
360   NULL is returned.
361   The memory is allocated from EFI boot services memory. It is the responsibility
362   of the caller to free the memory allocated.
363 
364   @param  NodeType                   The device node type for the new device node.
365   @param  NodeSubType                The device node sub-type for the new device node.
366   @param  NodeLength                 The length of the new device node.
367 
368   @return The new device path.
369 
370 **/
371 EFI_DEVICE_PATH_PROTOCOL *
372 EFIAPI
373 UefiDevicePathLibCreateDeviceNode (
374   IN UINT8   NodeType,
375   IN UINT8   NodeSubType,
376   IN UINT16  NodeLength
377   );
378 
379 /**
380   Determines if a device path is single or multi-instance.
381 
382   This function returns TRUE if the device path specified by DevicePath is
383   multi-instance.
384   Otherwise, FALSE is returned.
385   If DevicePath is NULL or invalid, then FALSE is returned.
386 
387   @param  DevicePath                 A pointer to a device path data structure.
388 
389   @retval  TRUE                      DevicePath is multi-instance.
390   @retval  FALSE                     DevicePath is not multi-instance, or DevicePath
391                                      is NULL or invalid.
392 
393 **/
394 BOOLEAN
395 EFIAPI
396 UefiDevicePathLibIsDevicePathMultiInstance (
397   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
398   );
399 
400 /**
401   Converts a device path to its text representation.
402 
403   @param DevicePath      A Pointer to the device to be converted.
404   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
405                          of the display node is used, where applicable. If DisplayOnly
406                          is FALSE, then the longer text representation of the display node
407                          is used.
408   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
409                          representation for a device node can be used, where applicable.
410 
411   @return A pointer to the allocated text representation of the device path or
412           NULL if DeviceNode is NULL or there was insufficient memory.
413 
414 **/
415 CHAR16 *
416 EFIAPI
417 UefiDevicePathLibConvertDevicePathToText (
418   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
419   IN BOOLEAN                         DisplayOnly,
420   IN BOOLEAN                         AllowShortcuts
421   );
422 
423 /**
424   Converts a device node to its string representation.
425 
426   @param DeviceNode        A Pointer to the device node to be converted.
427   @param DisplayOnly       If DisplayOnly is TRUE, then the shorter text representation
428                            of the display node is used, where applicable. If DisplayOnly
429                            is FALSE, then the longer text representation of the display node
430                            is used.
431   @param AllowShortcuts    If AllowShortcuts is TRUE, then the shortcut forms of text
432                            representation for a device node can be used, where applicable.
433 
434   @return A pointer to the allocated text representation of the device node or NULL if DeviceNode
435           is NULL or there was insufficient memory.
436 
437 **/
438 CHAR16 *
439 EFIAPI
440 UefiDevicePathLibConvertDeviceNodeToText (
441   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DeviceNode,
442   IN BOOLEAN                         DisplayOnly,
443   IN BOOLEAN                         AllowShortcuts
444   );
445 
446 /**
447   Convert text to the binary representation of a device node.
448 
449   @param TextDeviceNode  TextDeviceNode points to the text representation of a device
450                          node. Conversion starts with the first character and continues
451                          until the first non-device node character.
452 
453   @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
454           insufficient memory or text unsupported.
455 
456 **/
457 EFI_DEVICE_PATH_PROTOCOL *
458 EFIAPI
459 UefiDevicePathLibConvertTextToDeviceNode (
460   IN CONST CHAR16  *TextDeviceNode
461   );
462 
463 /**
464   Convert text to the binary representation of a device path.
465 
466 
467   @param TextDevicePath  TextDevicePath points to the text representation of a device
468                          path. Conversion starts with the first character and continues
469                          until the first non-device node character.
470 
471   @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
472           there was insufficient memory.
473 
474 **/
475 EFI_DEVICE_PATH_PROTOCOL *
476 EFIAPI
477 UefiDevicePathLibConvertTextToDevicePath (
478   IN CONST CHAR16  *TextDevicePath
479   );
480 #else
481 
482 /*
483  * Small FreeBSD shim layer. Fast and lose hacks to make this code work with FreeBSD.
484  */
485 
486 #include <ctype.h>
487 
488 #define _PCD_GET_MODE_32_PcdMaximumDevicePathNodeCount 1000
489 #define MAX_UINTN UINTPTR_MAX
490 
491 #define AllocatePool(x) malloc(x)
492 #define AllocateZeroPool(x) calloc(1,x)
493 #define AsciiStrLen(s) strlen(s)
494 #define CopyGuid(dst, src) memcpy(dst, src, sizeof(uuid_t))
495 #define CopyMem(d, s, l) memcpy(d, s, l)
496 #define FreePool(x) free(x)
497 #define LShiftU64(x, s) ((x) << s)
498 #define ReadUnaligned64(x)    le64dec(x)
499 #define ReallocatePool(old, new, ptr) realloc(ptr, new)
500 /*
501  * Quirky StrCmp returns 0 if equal, 1 if not. This is what the code
502  * expects, though that expectation is likely a bug (it casts the
503  * return value. EDK2's StrCmp returns values just like C's strcmp,
504  * but the parse code casts this to an UINTN, which is bogus. This
505  * definition papers over that bogusness to do the right thing.  If
506  * iSCSI protocol string processing is ever fixed, we can remove this
507  * bletcherous kludge.
508  */
509 #define StrCmp(a, b) (strcmp(a, b) != 0)
510 #define StrCpyS(d, l, s) strcpy(d, s)
511 #define StrHexToUint64(x) strtoll(x, NULL, 16)
512 #define StrHexToUintn(x) strtoll(x, NULL, 16)
513 #define StrLen(x) strlen(x)
514 #define StrSize(x) (strlen(x) + 1)
515 #define StrnCatS(d, l, s, len) strncat(d, s, len)
516 #define StrnCmp(a, b, n) strncmp(a, b, n)
517 #define StrnLenS(str, max) strlen(str)
518 #define Strtoi(x) strtol(x, NULL, 0)
519 #define Strtoi64(x, y) *(long long *)y = strtoll(x, NULL, 0)
520 #define SwapBytes64(u64) bswap64(u64)
521 #define UnicodeStrToAsciiStrS(src, dest, len) strlcpy(dest, src, len)
522 #define ZeroMem(p,l) memset(p, 0, l)
523 
524 #undef ASSERT
525 #define ASSERT(x)
526 
527 /*
528  * Define AllocateCopyPool and others so that we "forget" about the
529  * previous non-static deifnition since we want these to be static
530  * inlines.
531  */
532 #define AllocateCopyPool AllocateCopyPoolFreeBSD
533 #define CompareGuid CompareGuidFreeBSD
534 #define StrHexToBytes StrHexToBytesFreeBSD
535 #define StrToGuid StrToGuidFreeBSD
536 #define WriteUnaligned64 WriteUnaligned64FreeBSD
537 
538 static inline void *
AllocateCopyPool(size_t l,const void * p)539 AllocateCopyPool(size_t l, const void *p)
540 {
541 	void *rv;
542 
543 	rv = malloc(l);
544 	if (rv == NULL)
545 		return NULL;
546 	memcpy(rv, p, l);
547 	return (rv);
548 }
549 
550 static inline BOOLEAN
CompareGuid(const EFI_GUID * g1,const EFI_GUID * g2)551 CompareGuid (const EFI_GUID *g1, const EFI_GUID *g2)
552 {
553 	uint32_t ignored_status;
554 
555 	return (uuid_compare((const uuid_t *)g1, (const uuid_t *)g2,
556 	    &ignored_status) == 0);
557 }
558 
559 static inline int
StrHexToBytes(const char * str,size_t len,uint8_t * buf,size_t buflen)560 StrHexToBytes(const char *str, size_t len, uint8_t *buf, size_t buflen)
561 {
562 	size_t i;
563 	char hex[3];
564 
565 	/*
566 	 * Sanity check preconditions.
567 	 */
568 	if (buflen != len / 2 || (len % 2) == 1)
569 		return 1;
570 	for (i = 0; i < len; i += 2) {
571 		if (!isxdigit(str[i]) || !isxdigit(str[i + 1]))
572 			return 1;
573 		hex[0] = str[i];
574 		hex[1] = str[i + 1];
575 		hex[2] = '\0';
576 		buf[i / 2] = strtol(hex, NULL, 16);
577 	}
578 	return 0;
579 }
580 
581 static inline void
StrToGuid(const char * str,EFI_GUID * guid)582 StrToGuid(const char *str, EFI_GUID *guid)
583 {
584 	uint32_t status;
585 
586 	uuid_from_string(str, (uuid_t *)guid, &status);
587 }
588 
589 static inline void
WriteUnaligned64(void * ptr,uint64_t val)590 WriteUnaligned64(void *ptr, uint64_t val)
591 {
592 	memcpy(ptr, &val, sizeof(val));
593 }
594 
595 /*
596  * Hack to allow converting %g to %s in printfs. Hack because
597  * it's single entry, uses a static buffer, etc. Sufficient for
598  * the day for this file though. IF you ever have to convert
599  * two %g's in one format, punt. Did I mention this was super lame.
600  * Not to mention it's name.... Also, the error GUID is horrific.
601  */
602 static inline const char *
guid_str(const EFI_GUID * g)603 guid_str(const EFI_GUID *g)
604 {
605 	static char buf[36 + 1];
606 	char *str = NULL;
607 	int32_t ignored_status;
608 
609 	uuid_to_string((const uuid_t *)g, &str, &ignored_status);
610 	if (str != NULL)
611 		strlcpy(buf, str, sizeof(buf));
612 	else
613 		strlcpy(buf, "groot-cannot-decode-guid-groot-smash",
614 		    sizeof(buf)); /* ^^^^^^^ 36 characters ^^^^^^^ */
615 	free(str);
616 	return buf;
617 }
618 #define G(x) guid_str((const EFI_GUID *)(const void *)x)
619 #endif
620 
621 #undef GLOBAL_REMOVE_IF_UNREFERENCED
622 #define GLOBAL_REMOVE_IF_UNREFERENCED static
623 
624 #endif
625