2 * libefivar - library for the manipulation of EFI variables
3 * Copyright 2012-2015 Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public License as
7 * published by the Free Software Foundation; either version 2.1 of the
8 * License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, see
17 * <http://www.gnu.org/licenses/>.
20 #ifndef _EFIVAR_INTERNAL_DP_H
21 #define _EFIVAR_INTERNAL_DP_H
30 #define format(buf, size, off, dp_type, fmt, args...) ({ \
31 ssize_t _insize = 0; \
32 void *_inbuf = NULL; \
33 if ((buf) != NULL && (size) > 0) { \
34 _inbuf = (buf) + (off); \
35 _insize = (size) - (off); \
38 ((buf == NULL && _insize == 0) || \
39 (buf != NULL && _insize >= 0))) { \
41 _x = snprintf(_inbuf, _insize, fmt, ## args); \
44 "could not build %s DP string", \
53 #define format_helper(fn, buf, size, off, dp_type, args...) ({ \
55 _x = (fn)(((buf)+(off)), \
56 ((size)?((size)-(off)):0), dp_type, ## args); \
58 efi_error("could not build %s DP string", \
63 #define onstack(buf, len) ({ \
64 char *__newbuf = alloca(len); \
65 memcpy(__newbuf, buf, len); \
70 #define format_guid(buf, size, off, dp_type, guid) ({ \
72 char *_guidstr = NULL; \
74 _rc = efi_guid_to_str(guid, &_guidstr); \
76 efi_error("could not build %s GUID DP string", \
79 _guidstr = onstack(_guidstr, \
80 strlen(_guidstr)+1); \
81 _rc = format(buf, size, off, dp_type, "%s", \
88 __attribute__((__unused__))
89 format_hex_helper(char *buf, size_t size, const char *dp_type, char *separator,
90 int stride, const void * const addr, const size_t len)
93 for (size_t i = 0; i < len; i++) {
94 if (i && separator && stride > 0 && i % stride == 0)
95 format(buf, size, off, dp_type, "%s", separator);
96 format(buf, size, off, dp_type, "%02x",
97 *((const unsigned char * const )addr+i));
102 #define format_hex(buf, size, off, dp_type, addr, len) \
103 format_helper(format_hex_helper, buf, size, off, dp_type, "", 0, \
106 #define format_hex_separated(buf, size, off, dp_type, sep, stride, addr, len) \
107 format_helper(format_hex_helper, buf, size, off, dp_type, sep, stride, \
110 static inline ssize_t
111 __attribute__((__unused__))
112 format_vendor_helper(char *buf, size_t size, char *label, const_efidp dp)
115 ssize_t bytes = efidp_node_size(dp)
116 - sizeof (efidp_header)
117 - sizeof (efi_guid_t);
119 format(buf, size, off, label, "%s(", label);
120 format_guid(buf, size, off, label, &dp->hw_vendor.vendor_guid);
122 format(buf, size, off, label, ",");
123 format_hex(buf, size, off, label, dp->hw_vendor.vendor_data,
126 format(buf, size, off, label, ")");
130 #define format_vendor(buf, size, off, label, dp) \
131 format_helper(format_vendor_helper, buf, size, off, label, dp)
133 #define format_ucs2(buf, size, off, dp_type, str, len) ({ \
134 uint16_t *_ucs2buf; \
135 uint32_t _ucs2size = sizeof(uint16_t) * len; \
136 _ucs2buf = alloca(_ucs2size); \
137 if (_ucs2buf == NULL) \
139 memset(_ucs2buf, '\0', _ucs2size); \
140 memcpy(_ucs2buf, str, _ucs2size - sizeof(uint16_t)); \
141 unsigned char *_asciibuf; \
142 _asciibuf = ucs2_to_utf8(_ucs2buf, (len) - 1); \
143 if (_asciibuf == NULL) \
145 _asciibuf = onstack(_asciibuf, (len)); \
146 format(buf, size, off, dp_type, "%s", _asciibuf); \
149 #define format_array(buf, size, off, dp_type, fmt, type, addr, len) ({ \
150 for (size_t _i = 0; _i < len; _i++) { \
152 format(buf, size, off, dp_type, ","); \
153 format(buf, size, off, dp_type, fmt, \
154 ((type *)addr)[_i]); \
159 extern ssize_t _format_hw_dn(char *buf, size_t size, const_efidp dp);
160 extern ssize_t _format_acpi_dn(char *buf, size_t size, const_efidp dp);
161 extern ssize_t _format_message_dn(char *buf, size_t size, const_efidp dp);
162 extern ssize_t _format_media_dn(char *buf, size_t size, const_efidp dp);
163 extern ssize_t _format_bios_boot_dn(char *buf, size_t size, const_efidp dp);
165 #define format_helper_2(name, buf, size, off, dp) ({ \
167 _sz = name(((buf)+(off)), \
168 ((size)?((size)-(off)):0), \
171 efi_error("%s failed", #name); \
177 #define format_hw_dn(buf, size, off, dp) \
178 format_helper_2(_format_hw_dn, buf, size, off, dp)
179 #define format_acpi_dn(buf, size, off, dp) \
180 format_helper_2(_format_acpi_dn, buf, size, off, dp)
181 #define format_message_dn(buf, size, off, dp) \
182 format_helper_2(_format_message_dn, buf, size, off, dp)
183 #define format_media_dn(buf, size, off, dp) \
184 format_helper_2(_format_media_dn, buf, size, off, dp)
185 #define format_bios_boot_dn(buf, size, off, dp) \
186 format_helper_2(_format_bios_boot_dn, buf, size, off, dp)
188 #endif /* _EFIVAR_INTERNAL_DP_H */