Merge pull request #23512 from medhefgo/efi-clang

boot: Add string functions
This commit is contained in:
Yu Watanabe
2022-06-01 06:16:48 +09:00
committed by GitHub
22 changed files with 885 additions and 261 deletions
+4 -8
View File
@@ -7,9 +7,7 @@
# define TEST_STATIC
#else
/* Provide our own "EFI API" if we are running as a unit test. */
# include <stddef.h>
# include <stdint.h>
# include <uchar.h>
# include "efi-string.h"
# include "string-util-fundamental.h"
# define CHAR8 char
@@ -19,8 +17,6 @@
# define UINT32 uint32_t
# define UINT64 uint64_t
# define UINTN size_t
# define strlena(s) strlen(s)
# define strncaseeqa(a, b, n) strncaseeq((a), (b), (n))
# define TEST_STATIC static
#endif
@@ -139,7 +135,7 @@ static const Key *get_subkey(const UINT8 *bcd, UINT32 bcd_len, UINT32 offset, co
return NULL;
for (UINT16 i = 0; i < subkey->n_entries; i++) {
if (!strncaseeqa(name, subkey->entries[i].name_hint, sizeof(subkey->entries[i].name_hint)))
if (!strncaseeq8((char *) name, (char *) subkey->entries[i].name_hint, sizeof(subkey->entries[i].name_hint)))
continue;
const Key *key = get_key(bcd, bcd_len, subkey->entries[i].key_offset, name);
@@ -168,7 +164,7 @@ static const Key *get_key(const UINT8 *bcd, UINT32 bcd_len, UINT32 offset, const
return NULL;
if (*name) {
if (strncaseeqa(name, key->key_name, key->key_name_len) && strlena(name) == key->key_name_len)
if (strncaseeq8((char *) name, (char *) key->key_name, key->key_name_len) && strlen8((const char *) name) == key->key_name_len)
name += key->key_name_len;
else
return NULL;
@@ -213,7 +209,7 @@ static const KeyValue *get_key_value(const UINT8 *bcd, UINT32 bcd_len, const Key
if (BAD_OFFSET(kv->data_offset, kv->data_size, bcd_len))
continue;
if (strncaseeqa(name, kv->name, kv->name_len) && strlena(name) == kv->name_len)
if (strncaseeq8((char *)name, (char *) kv->name, kv->name_len) && strlen8((const char *) name) == kv->name_len)
return kv;
}
+96 -96
View File
@@ -149,11 +149,11 @@ static BOOLEAN line_edit(
assert(line_in);
len = strlen_ptr(*line_in);
len = strlen16(*line_in);
size = len + 1024;
line = xnew(CHAR16, size);
print = xnew(CHAR16, x_max + 1);
StrCpy(line, strempty(*line_in));
strcpy16(line, strempty(*line_in));
for (;;) {
EFI_STATUS err;
@@ -162,7 +162,7 @@ static BOOLEAN line_edit(
UINTN cursor_color = TEXT_ATTR_SWAP(COLOR_EDIT);
j = MIN(len - first, x_max);
CopyMem(print, line + first, j * sizeof(CHAR16));
memcpy(print, line + first, j * sizeof(CHAR16));
while (clear > 0 && j < x_max) {
clear--;
print[j++] = ' ';
@@ -317,7 +317,7 @@ static BOOLEAN line_edit(
case KEYPRESS(0, 0, CHAR_CARRIAGE_RETURN):
case KEYPRESS(0, CHAR_CARRIAGE_RETURN, 0): /* EZpad Mini 4s firmware sends malformed events */
case KEYPRESS(0, CHAR_CARRIAGE_RETURN, CHAR_CARRIAGE_RETURN): /* Teclast X98+ II firmware sends malformed events */
if (!streq(line, *line_in)) {
if (!streq16(line, *line_in)) {
FreePool(*line_in);
*line_in = TAKE_PTR(line);
}
@@ -418,11 +418,11 @@ static CHAR16 *update_timeout_efivar(UINT32 *t, BOOLEAN inc) {
switch (*t) {
case TIMEOUT_UNSET:
return xstrdup(L"Menu timeout defined by configuration file.");
return xstrdup16(u"Menu timeout defined by configuration file.");
case TIMEOUT_MENU_FORCE:
return xstrdup(L"Timeout disabled, menu will always be shown.");
return xstrdup16(u"Timeout disabled, menu will always be shown.");
case TIMEOUT_MENU_HIDDEN:
return xstrdup(L"Menu disabled. Hold down key at bootup to show menu.");
return xstrdup16(u"Menu disabled. Hold down key at bootup to show menu.");
default:
return xpool_print(L"Menu timeout set to %u s.", *t);
}
@@ -554,7 +554,7 @@ static void print_status(Config *config, CHAR16 *loaded_image_path) {
Print(L" config entry: %" PRIuN L"/%" PRIuN L"\n", i + 1, config->entry_count);
ps_string(L" id: %s\n", entry->id);
ps_string(L" title: %s\n", entry->title);
ps_string(L" title show: %s\n", streq_ptr(entry->title, entry->title_show) ? NULL : entry->title_show);
ps_string(L" title show: %s\n", streq16(entry->title, entry->title_show) ? NULL : entry->title_show);
ps_string(L" sort key: %s\n", entry->sort_key);
ps_string(L" version: %s\n", entry->version);
ps_string(L" machine-id: %s\n", entry->machine_id);
@@ -662,7 +662,7 @@ static BOOLEAN menu_run(
/* length of the longest entry */
line_width = 0;
for (UINTN i = 0; i < config->entry_count; i++)
line_width = MAX(line_width, StrLen(config->entries[i]->title_show));
line_width = MAX(line_width, strlen16(config->entries[i]->title_show));
line_width = MIN(line_width + 2 * entry_padding, x_max);
/* offsets to center the entries on the screen */
@@ -686,7 +686,7 @@ static BOOLEAN menu_run(
UINTN j, padding;
lines[i] = xnew(CHAR16, line_width + 1);
padding = (line_width - MIN(StrLen(config->entries[i]->title_show), line_width)) / 2;
padding = (line_width - MIN(strlen16(config->entries[i]->title_show), line_width)) / 2;
for (j = 0; j < padding; j++)
lines[i][j] = ' ';
@@ -750,7 +750,7 @@ static BOOLEAN menu_run(
* input. Therefore, draw one less character then we could for the status message.
* Note that the same does not apply for the separator line as it will never be drawn
* on the last line. */
UINTN len = StrnLen(status, x_max - 1);
UINTN len = strnlen16(status, x_max - 1);
UINTN x = (x_max - len) / 2;
status[len] = '\0';
print_at(0, y_status, COLOR_NORMAL, clearline + x_max - x);
@@ -861,7 +861,7 @@ static BOOLEAN menu_run(
case KEYPRESS(0, 0, 'H'):
case KEYPRESS(0, 0, '?'):
/* This must stay below 80 characters! Q/v/Ctrl+l/f deliberately not advertised. */
status = xstrdup(L"(d)efault (t/T)timeout (e)dit (r/R)resolution (p)rint (h)elp");
status = xstrdup16(u"(d)efault (t/T)timeout (e)dit (r/R)resolution (p)rint (h)elp");
break;
case KEYPRESS(0, 0, 'Q'):
@@ -873,13 +873,13 @@ static BOOLEAN menu_run(
case KEYPRESS(0, 0, 'D'):
if (config->idx_default_efivar != idx_highlight) {
FreePool(config->entry_default_efivar);
config->entry_default_efivar = xstrdup(config->entries[idx_highlight]->id);
config->entry_default_efivar = xstrdup16(config->entries[idx_highlight]->id);
config->idx_default_efivar = idx_highlight;
status = xstrdup(L"Default boot entry selected.");
status = xstrdup16(u"Default boot entry selected.");
} else {
config->entry_default_efivar = mfree(config->entry_default_efivar);
config->idx_default_efivar = IDX_INVALID;
status = xstrdup(L"Default boot entry cleared.");
status = xstrdup16(u"Default boot entry cleared.");
}
config->use_saved_entry_efivar = FALSE;
refresh = TRUE;
@@ -1092,7 +1092,7 @@ static CHAR8 *line_get_key_value(
return NULL;
linelen = 0;
while (line[linelen] && !strchra((CHAR8 *) "\n\r", line[linelen]))
while (line[linelen] && !strchr8("\n\r", line[linelen]))
linelen++;
/* move pos to next line */
@@ -1108,13 +1108,13 @@ static CHAR8 *line_get_key_value(
line[linelen] = '\0';
/* remove leading whitespace */
while (strchra((CHAR8 *) " \t", *line)) {
while (strchr8(" \t", *line)) {
line++;
linelen--;
}
/* remove trailing whitespace */
while (linelen > 0 && strchra((CHAR8 *) " \t", line[linelen - 1]))
while (linelen > 0 && strchr8(" \t", line[linelen - 1]))
linelen--;
line[linelen] = '\0';
@@ -1123,13 +1123,13 @@ static CHAR8 *line_get_key_value(
/* split key/value */
value = line;
while (*value && !strchra(sep, *value))
while (*value && !strchr8((char *) sep, *value))
value++;
if (*value == '\0')
continue;
*value = '\0';
value++;
while (*value && strchra(sep, *value))
while (*value && strchr8((char *) sep, *value))
value++;
/* unquote */
@@ -1154,10 +1154,10 @@ static void config_defaults_load_from_file(Config *config, CHAR8 *content) {
assert(content);
while ((line = line_get_key_value(content, (CHAR8 *)" \t", &pos, &key, &value))) {
if (strcmpa((CHAR8 *)"timeout", key) == 0) {
if (strcmpa((CHAR8*) "menu-force", value) == 0)
if (streq8((char *) key, "timeout")) {
if (streq8((char *) value, "menu-force"))
config->timeout_sec_config = TIMEOUT_MENU_FORCE;
else if (strcmpa((CHAR8*) "menu-hidden", value) == 0)
else if (streq8((char *) value, "menu-hidden"))
config->timeout_sec_config = TIMEOUT_MENU_HIDDEN;
else {
_cleanup_freepool_ CHAR16 *s = NULL;
@@ -1169,8 +1169,8 @@ static void config_defaults_load_from_file(Config *config, CHAR8 *content) {
continue;
}
if (strcmpa((CHAR8 *)"default", key) == 0) {
if (value[0] == '@' && strcmpa((CHAR8 *)"@saved", value) != 0) {
if (streq8((char *) key, "default")) {
if (value[0] == '@' && !streq8((char *) value, "@saved")) {
log_error_stall(L"Unsupported special entry identifier: %a", value);
continue;
}
@@ -1179,47 +1179,47 @@ static void config_defaults_load_from_file(Config *config, CHAR8 *content) {
continue;
}
if (strcmpa((CHAR8 *)"editor", key) == 0) {
if (streq8((char *) key, "editor")) {
err = parse_boolean(value, &config->editor);
if (EFI_ERROR(err))
log_error_stall(L"Error parsing 'editor' config option: %a", value);
continue;
}
if (strcmpa((CHAR8 *)"auto-entries", key) == 0) {
if (streq8((char *) key, "auto-entries")) {
err = parse_boolean(value, &config->auto_entries);
if (EFI_ERROR(err))
log_error_stall(L"Error parsing 'auto-entries' config option: %a", value);
continue;
}
if (strcmpa((CHAR8 *)"auto-firmware", key) == 0) {
if (streq8((char *) key, "auto-firmware")) {
err = parse_boolean(value, &config->auto_firmware);
if (EFI_ERROR(err))
log_error_stall(L"Error parsing 'auto-firmware' config option: %a", value);
continue;
}
if (strcmpa((CHAR8 *)"beep", key) == 0) {
if (streq8((char *) key, "beep")) {
err = parse_boolean(value, &config->beep);
if (EFI_ERROR(err))
log_error_stall(L"Error parsing 'beep' config option: %a", value);
continue;
}
if (strcmpa((CHAR8 *)"reboot-for-bitlocker", key) == 0) {
if (streq8((char *) key, "reboot-for-bitlocker")) {
err = parse_boolean(value, &config->reboot_for_bitlocker);
if (EFI_ERROR(err))
log_error_stall(L"Error parsing 'reboot-for-bitlocker' config option: %a", value);
continue;
}
if (strcmpa((CHAR8 *)"console-mode", key) == 0) {
if (strcmpa((CHAR8 *)"auto", value) == 0)
if (streq8((char *) key, "console-mode")) {
if (streq8((char *) value, "auto"))
config->console_mode = CONSOLE_MODE_AUTO;
else if (strcmpa((CHAR8 *)"max", value) == 0)
else if (streq8((char *) value, "max"))
config->console_mode = CONSOLE_MODE_FIRMWARE_MAX;
else if (strcmpa((CHAR8 *)"keep", value) == 0)
else if (streq8((char *) value, "keep"))
config->console_mode = CONSOLE_MODE_KEEP;
else {
_cleanup_freepool_ CHAR16 *s = NULL;
@@ -1230,12 +1230,12 @@ static void config_defaults_load_from_file(Config *config, CHAR8 *content) {
continue;
}
if (strcmpa((CHAR8*) "random-seed-mode", key) == 0) {
if (strcmpa((CHAR8*) "off", value) == 0)
if (streq8((char *) key, "random-seed-mode")) {
if (streq8((char *) value, "off"))
config->random_seed_mode = RANDOM_SEED_OFF;
else if (strcmpa((CHAR8*) "with-system-token", value) == 0)
else if (streq8((char *) value, "with-system-token"))
config->random_seed_mode = RANDOM_SEED_WITH_SYSTEM_TOKEN;
else if (strcmpa((CHAR8*) "always", value) == 0)
else if (streq8((char *) value, "always"))
config->random_seed_mode = RANDOM_SEED_ALWAYS;
else {
BOOLEAN on;
@@ -1277,13 +1277,13 @@ static void config_entry_parse_tries(
* foobar+4-0.efi → foobar+3-1.efi → foobar+2-2.efi → foobar+1-3.efi → foobar+0-4.efi → STOP!
*/
i = StrLen(file);
i = strlen16(file);
/* Chop off any suffix such as ".conf" or ".efi" */
if (suffix) {
UINTN suffix_length;
suffix_length = StrLen(suffix);
suffix_length = strlen16(suffix);
if (i < suffix_length)
return;
@@ -1360,13 +1360,13 @@ good:
entry->tries_left = left;
entry->tries_done = done;
entry->path = xstrdup(path);
entry->current_name = xstrdup(file);
entry->path = xstrdup16(path);
entry->current_name = xstrdup16(file);
next_left = left <= 0 ? 0 : left - 1;
next_done = done >= (UINTN) -2 ? (UINTN) -2 : done + 1;
prefix = xstrdup(file);
prefix = xstrdup16(file);
prefix[i] = 0;
entry->next_name = xpool_print(L"%s+%" PRIuN L"-%" PRIuN L"%s", prefix, next_left, next_done, strempty(suffix));
@@ -1399,7 +1399,7 @@ static void config_entry_bump_counters(ConfigEntry *entry, EFI_FILE *root_dir) {
return;
/* And rename the file */
StrCpy(file_info->FileName, entry->next_name);
strcpy16(file_info->FileName, entry->next_name);
err = handle->SetInfo(handle, &GenericFileInfo, file_info_size, file_info);
if (EFI_ERROR(err)) {
log_error_stall(L"Failed to rename '%s' to '%s', ignoring: %r", old_path, entry->next_name, err);
@@ -1415,7 +1415,7 @@ static void config_entry_bump_counters(ConfigEntry *entry, EFI_FILE *root_dir) {
efivar_set(LOADER_GUID, L"LoaderBootCountPath", new_path, 0);
/* If the file we just renamed is the loader path, then let's update that. */
if (StrCmp(entry->loader, old_path) == 0) {
if (streq16(entry->loader, old_path)) {
FreePool(entry->loader);
entry->loader = TAKE_PTR(new_path);
}
@@ -1450,31 +1450,31 @@ static void config_entry_add_type1(
};
while ((line = line_get_key_value(content, (CHAR8 *)" \t", &pos, &key, &value))) {
if (strcmpa((CHAR8 *)"title", key) == 0) {
if (streq8((char *) key, "title")) {
FreePool(entry->title);
entry->title = xstra_to_str(value);
continue;
}
if (strcmpa((CHAR8 *)"sort-key", key) == 0) {
if (streq8((char *) key, "sort-key")) {
FreePool(entry->sort_key);
entry->sort_key = xstra_to_str(value);
continue;
}
if (strcmpa((CHAR8 *)"version", key) == 0) {
if (streq8((char *) key, "version")) {
FreePool(entry->version);
entry->version = xstra_to_str(value);
continue;
}
if (strcmpa((CHAR8 *)"machine-id", key) == 0) {
if (streq8((char *) key, "machine-id")) {
FreePool(entry->machine_id);
entry->machine_id = xstra_to_str(value);
continue;
}
if (strcmpa((CHAR8 *)"linux", key) == 0) {
if (streq8((char *) key, "linux")) {
FreePool(entry->loader);
entry->type = LOADER_LINUX;
entry->loader = xstra_to_path(value);
@@ -1482,35 +1482,35 @@ static void config_entry_add_type1(
continue;
}
if (strcmpa((CHAR8 *)"efi", key) == 0) {
if (streq8((char *) key, "efi")) {
entry->type = LOADER_EFI;
FreePool(entry->loader);
entry->loader = xstra_to_path(value);
/* do not add an entry for ourselves */
if (loaded_image_path && StriCmp(entry->loader, loaded_image_path) == 0) {
if (loaded_image_path && strcaseeq16(entry->loader, loaded_image_path)) {
entry->type = LOADER_UNDEFINED;
break;
}
continue;
}
if (strcmpa((CHAR8 *)"architecture", key) == 0) {
if (streq8((char *) key, "architecture")) {
/* do not add an entry for an EFI image of architecture not matching with that of the image */
if (strcmpa((CHAR8 *)EFI_MACHINE_TYPE_NAME, value) != 0) {
if (!streq8((char *) value, EFI_MACHINE_TYPE_NAME)) {
entry->type = LOADER_UNDEFINED;
break;
}
continue;
}
if (strcmpa((CHAR8 *)"devicetree", key) == 0) {
if (streq8((char *) key, "devicetree")) {
FreePool(entry->devicetree);
entry->devicetree = xstra_to_path(value);
continue;
}
if (strcmpa((CHAR8 *)"initrd", key) == 0) {
if (streq8((char *) key, "initrd")) {
entry->initrd = xreallocate_pool(
entry->initrd,
n_initrd == 0 ? 0 : (n_initrd + 1) * sizeof(UINT16 *),
@@ -1520,7 +1520,7 @@ static void config_entry_add_type1(
continue;
}
if (strcmpa((CHAR8 *)"options", key) == 0) {
if (streq8((char *) key, "options")) {
_cleanup_freepool_ CHAR16 *new = NULL;
new = xstra_to_str(value);
@@ -1547,8 +1547,8 @@ static void config_entry_add_type1(
return;
entry->device = device;
entry->id = xstrdup(file);
StrLwr(entry->id);
entry->id = xstrdup16(file);
strtolower16(entry->id);
config_add_entry(config, entry);
@@ -1606,8 +1606,8 @@ static void config_load_defaults(Config *config, EFI_FILE *root_dir) {
(void) efivar_get(LOADER_GUID, L"LoaderEntryDefault", &config->entry_default_efivar);
config->use_saved_entry = streq_ptr(config->entry_default_config, L"@saved");
config->use_saved_entry_efivar = streq_ptr(config->entry_default_efivar, L"@saved");
config->use_saved_entry = streq16(config->entry_default_config, L"@saved");
config->use_saved_entry_efivar = streq16(config->entry_default_efivar, L"@saved");
if (config->use_saved_entry || config->use_saved_entry_efivar)
(void) efivar_get(LOADER_GUID, L"LoaderEntryLastBooted", &config->entry_saved);
}
@@ -1656,8 +1656,8 @@ static void config_load_entries(
}
}
static INTN config_entry_compare(const ConfigEntry *a, const ConfigEntry *b) {
INTN r;
static int config_entry_compare(const ConfigEntry *a, const ConfigEntry *b) {
int r;
assert(a);
assert(b);
@@ -1676,12 +1676,12 @@ static INTN config_entry_compare(const ConfigEntry *a, const ConfigEntry *b) {
return r;
if (a->sort_key && b->sort_key) {
r = strcmp(a->sort_key, b->sort_key);
r = strcmp16(a->sort_key, b->sort_key);
if (r != 0)
return r;
/* If multiple installations of the same OS are around, group by machine ID */
r = strcmp_ptr(a->machine_id, b->machine_id);
r = strcmp16(a->machine_id, b->machine_id);
if (r != 0)
return r;
@@ -1773,7 +1773,7 @@ static BOOLEAN entries_unique(ConfigEntry **entries, BOOLEAN *unique, UINTN entr
for (UINTN i = 0; i < entry_count; i++)
for (UINTN k = i + 1; k < entry_count; k++) {
if (StrCmp(entries[i]->title_show, entries[k]->title_show) != 0)
if (!streq16(entries[i]->title_show, entries[k]->title_show))
continue;
is_unique = unique[i] = unique[k] = FALSE;
@@ -1792,7 +1792,7 @@ static void config_title_generate(Config *config) {
for (UINTN i = 0; i < config->entry_count; i++) {
assert(!config->entries[i]->title_show);
unique[i] = TRUE;
config->entries[i]->title_show = xstrdup(config->entries[i]->title ?: config->entries[i]->id);
config->entries[i]->title_show = xstrdup16(config->entries[i]->title ?: config->entries[i]->id);
}
if (entries_unique(config->entries, unique, config->entry_count))
@@ -1829,7 +1829,7 @@ static void config_title_generate(Config *config) {
config->entries[i]->title_show = xpool_print(
L"%s (%.*s)",
t,
StrnLen(config->entries[i]->machine_id, 8),
strnlen16(config->entries[i]->machine_id, 8),
config->entries[i]->machine_id);
}
@@ -1866,7 +1866,7 @@ static BOOLEAN is_sd_boot(EFI_FILE *root_dir, const CHAR16 *loader_path) {
if (EFI_ERROR(err) || size != read)
return FALSE;
return CompareMem(content, magic, sizeof(magic)) == 0;
return memcmp(content, magic, sizeof(magic)) == 0;
}
static ConfigEntry *config_entry_add_loader_auto(
@@ -1897,7 +1897,7 @@ static ConfigEntry *config_entry_add_loader_auto(
*
* If the default loader is not us, it might be shim. It would
* chainload GRUBX64.EFI in that case, which might be us.*/
if (StriCmp(loader, loaded_image_path) == 0 ||
if (strcaseeq16(loader, loaded_image_path) ||
is_sd_boot(root_dir, loader) ||
is_sd_boot(root_dir, L"\\EFI\\BOOT\\GRUB" EFI_MACHINE_TYPE_NAME L".EFI"))
return NULL;
@@ -1911,11 +1911,11 @@ static ConfigEntry *config_entry_add_loader_auto(
ConfigEntry *entry = xnew(ConfigEntry, 1);
*entry = (ConfigEntry) {
.id = xstrdup(id),
.id = xstrdup16(id),
.type = LOADER_AUTO,
.title = xstrdup(title),
.title = xstrdup16(title),
.device = device,
.loader = xstrdup(loader),
.loader = xstrdup16(loader),
.key = key,
.tries_done = UINTN_MAX,
.tries_left = UINTN_MAX,
@@ -1986,7 +1986,7 @@ static EFI_STATUS boot_windows_bitlocker(void) {
if (EFI_ERROR(err))
continue;
if (CompareMem(buf + 3, "-FVE-FS-", STRLEN("-FVE-FS-")) == 0) {
if (memcmp(buf + 3, "-FVE-FS-", STRLEN("-FVE-FS-")) == 0) {
found = TRUE;
break;
}
@@ -2021,7 +2021,7 @@ static EFI_STATUS boot_windows_bitlocker(void) {
if (buf_size < offset + sizeof(CHAR16))
continue;
if (streq((CHAR16 *) (buf + offset), L"Windows Boot Manager")) {
if (streq16((CHAR16 *) (buf + offset), L"Windows Boot Manager")) {
err = efivar_set_raw(
EFI_GLOBAL_GUID,
L"BootNext",
@@ -2132,49 +2132,49 @@ static void config_entry_add_unified(
/* read properties from the embedded os-release file */
while ((line = line_get_key_value(content, (CHAR8 *)"=", &pos, &key, &value))) {
if (strcmpa((const CHAR8*) "PRETTY_NAME", key) == 0) {
if (streq8((char *) key, "PRETTY_NAME")) {
FreePool(os_pretty_name);
os_pretty_name = xstra_to_str(value);
continue;
}
if (strcmpa((const CHAR8*) "IMAGE_ID", key) == 0) {
if (streq8((char *) key, "IMAGE_ID")) {
FreePool(os_image_id);
os_image_id = xstra_to_str(value);
continue;
}
if (strcmpa((const CHAR8*) "NAME", key) == 0) {
if (streq8((char *) key, "NAME")) {
FreePool(os_name);
os_name = xstra_to_str(value);
continue;
}
if (strcmpa((const CHAR8*) "ID", key) == 0) {
if (streq8((char *) key, "ID")) {
FreePool(os_id);
os_id = xstra_to_str(value);
continue;
}
if (strcmpa((const CHAR8*) "IMAGE_VERSION", key) == 0) {
if (streq8((char *) key, "IMAGE_VERSION")) {
FreePool(os_image_version);
os_image_version = xstra_to_str(value);
continue;
}
if (strcmpa((const CHAR8*) "VERSION", key) == 0) {
if (streq8((char *) key, "VERSION")) {
FreePool(os_version);
os_version = xstra_to_str(value);
continue;
}
if (strcmpa((const CHAR8*) "VERSION_ID", key) == 0) {
if (streq8((char *) key, "VERSION_ID")) {
FreePool(os_version_id);
os_version_id = xstra_to_str(value);
continue;
}
if (strcmpa((const CHAR8*) "BUILD_ID", key) == 0) {
if (streq8((char *) key, "BUILD_ID")) {
FreePool(os_build_id);
os_build_id = xstra_to_str(value);
continue;
@@ -2197,19 +2197,19 @@ static void config_entry_add_unified(
ConfigEntry *entry = xnew(ConfigEntry, 1);
*entry = (ConfigEntry) {
.id = xstrdup(f->FileName),
.id = xstrdup16(f->FileName),
.type = LOADER_UNIFIED_LINUX,
.title = xstrdup(good_name),
.version = good_version ? xstrdup(good_version) : NULL,
.title = xstrdup16(good_name),
.version = xstrdup16(good_version),
.device = device,
.loader = xpool_print(L"\\EFI\\Linux\\%s", f->FileName),
.sort_key = good_sort_key ? xstrdup(good_sort_key) : NULL,
.sort_key = xstrdup16(good_sort_key),
.key = 'l',
.tries_done = UINTN_MAX,
.tries_left = UINTN_MAX,
};
StrLwr(entry->id);
strtolower16(entry->id);
config_add_entry(config, entry);
config_entry_parse_tries(entry, L"\\EFI\\Linux", f->FileName, L".efi");
@@ -2375,7 +2375,7 @@ static EFI_STATUS image_start(
CHAR16 *options = options_initrd ?: entry->options;
if (options) {
loaded_image->LoadOptions = options;
loaded_image->LoadOptionsSize = StrSize(options);
loaded_image->LoadOptionsSize = strsize16(options);
/* Try to log any options to the TPM, especially to catch manually edited options */
(void) tpm_log_load_options(options);
@@ -2426,15 +2426,15 @@ static void config_write_entries_to_variable(Config *config) {
assert(config);
for (UINTN i = 0; i < config->entry_count; i++)
sz += StrSize(config->entries[i]->id);
sz += strsize16(config->entries[i]->id);
p = buffer = xallocate_pool(sz);
for (UINTN i = 0; i < config->entry_count; i++) {
UINTN l;
l = StrSize(config->entries[i]->id);
CopyMem(p, config->entries[i]->id, l);
l = strsize16(config->entries[i]->id);
memcpy(p, config->entries[i]->id, l);
p += l;
}
@@ -2454,12 +2454,12 @@ static void save_selected_entry(const Config *config, const ConfigEntry *entry)
(void) efivar_set(LOADER_GUID, L"LoaderEntrySelected", entry->id, 0);
/* Do not save or delete if this was a oneshot boot. */
if (streq_ptr(config->entry_oneshot, entry->id))
if (streq16(config->entry_oneshot, entry->id))
return;
if (config->use_saved_entry_efivar || (!config->entry_default_efivar && config->use_saved_entry)) {
/* Avoid unnecessary NVRAM writes. */
if (streq_ptr(config->entry_saved, entry->id))
if (streq16(config->entry_saved, entry->id))
return;
(void) efivar_set(LOADER_GUID, L"LoaderEntryLastBooted", entry->id, EFI_VARIABLE_NON_VOLATILE);
@@ -2545,8 +2545,8 @@ static void config_load_all_entries(
if (config->auto_firmware && FLAGS_SET(get_os_indications_supported(), EFI_OS_INDICATIONS_BOOT_TO_FW_UI)) {
ConfigEntry *entry = xnew(ConfigEntry, 1);
*entry = (ConfigEntry) {
.id = xstrdup(L"auto-reboot-to-firmware-setup"),
.title = xstrdup(L"Reboot Into Firmware Interface"),
.id = xstrdup16(u"auto-reboot-to-firmware-setup"),
.title = xstrdup16(u"Reboot Into Firmware Interface"),
.call = reboot_into_firmware,
.tries_done = UINTN_MAX,
.tries_left = UINTN_MAX,
+14 -14
View File
@@ -81,12 +81,12 @@ static EFI_STATUS pack_cpio_one(
l = 6 + 13*8 + 1 + 1; /* Fixed CPIO header size, slash separator, and NUL byte after the file name*/
target_dir_prefix_size = strlena(target_dir_prefix);
target_dir_prefix_size = strlen8((const char *) target_dir_prefix);
if (l > UINTN_MAX - target_dir_prefix_size)
return EFI_OUT_OF_RESOURCES;
l += target_dir_prefix_size;
fname_size = StrLen(fname);
fname_size = strlen16(fname);
if (l > UINTN_MAX - fname_size)
return EFI_OUT_OF_RESOURCES;
l += fname_size; /* append space for file name */
@@ -116,7 +116,7 @@ static EFI_STATUS pack_cpio_one(
*cpio_buffer = a;
a = (CHAR8*) *cpio_buffer + *cpio_buffer_size;
CopyMem(a, "070701", 6); /* magic ID */
memcpy(a, "070701", 6); /* magic ID */
a += 6;
a = write_cpio_word(a, (*inode_counter)++); /* inode */
@@ -139,7 +139,7 @@ static EFI_STATUS pack_cpio_one(
a = write_cpio_word(a, target_dir_prefix_size + fname_size + 2); /* fname size */
a = write_cpio_word(a, 0); /* "crc" */
CopyMem(a, target_dir_prefix, target_dir_prefix_size);
memcpy(a, target_dir_prefix, target_dir_prefix_size);
a += target_dir_prefix_size;
*(a++) = '/';
a = mangle_filename(a, fname);
@@ -147,7 +147,7 @@ static EFI_STATUS pack_cpio_one(
/* Pad to next multiple of 4 */
a = pad4(a, *cpio_buffer);
CopyMem(a, contents, contents_size);
memcpy(a, contents, contents_size);
a += contents_size;
/* Pad to next multiple of 4 */
@@ -182,7 +182,7 @@ static EFI_STATUS pack_cpio_dir(
l = 6 + 13*8 + 1; /* Fixed CPIO header size, and NUL byte after the file name*/
path_size = strlena(path);
path_size = strlen8((const char *) path);
if (l > UINTN_MAX - path_size)
return EFI_OUT_OF_RESOURCES;
l += path_size;
@@ -198,7 +198,7 @@ static EFI_STATUS pack_cpio_dir(
*cpio_buffer = a = xreallocate_pool(*cpio_buffer, *cpio_buffer_size, *cpio_buffer_size + l);
a = (CHAR8*) *cpio_buffer + *cpio_buffer_size;
CopyMem(a, "070701", 6); /* magic ID */
memcpy(a, "070701", 6); /* magic ID */
a += 6;
a = write_cpio_word(a, (*inode_counter)++); /* inode */
@@ -215,7 +215,7 @@ static EFI_STATUS pack_cpio_dir(
a = write_cpio_word(a, path_size + 1); /* fname size */
a = write_cpio_word(a, 0); /* "crc" */
CopyMem(a, path, path_size + 1);
memcpy(a, path, path_size + 1);
a += path_size + 1;
/* Pad to next multiple of 4 */
@@ -248,14 +248,14 @@ static EFI_STATUS pack_cpio_prefix(
for (const CHAR8 *p = path;;) {
const CHAR8 *e;
e = strchra(p, '/');
e = (const CHAR8 *) strchr8((const char *) p, '/');
if (!e)
break;
if (e > p) {
_cleanup_freepool_ CHAR8 *t = NULL;
t = xstrndup8(path, e - path);
t = (CHAR8 *) xstrndup8((const char *) path, e - path);
if (!t)
return EFI_OUT_OF_RESOURCES;
@@ -298,7 +298,7 @@ static EFI_STATUS pack_cpio_trailer(
assert_cc(sizeof(trailer) % 4 == 0);
*cpio_buffer = xreallocate_pool(*cpio_buffer, *cpio_buffer_size, *cpio_buffer_size + sizeof(trailer));
CopyMem((UINT8*) *cpio_buffer + *cpio_buffer_size, trailer, sizeof(trailer));
memcpy((UINT8*) *cpio_buffer + *cpio_buffer_size, trailer, sizeof(trailer));
*cpio_buffer_size += sizeof(trailer);
return EFI_SUCCESS;
@@ -388,10 +388,10 @@ EFI_STATUS pack_cpio(
continue;
if (!is_ascii(dirent->FileName))
continue;
if (StrLen(dirent->FileName) > 255) /* Max filename size on Linux */
if (strlen16(dirent->FileName) > 255) /* Max filename size on Linux */
continue;
d = xstrdup(dirent->FileName);
d = xstrdup16(dirent->FileName);
if (n_items+2 > n_allocated) {
UINTN m;
@@ -418,7 +418,7 @@ EFI_STATUS pack_cpio(
/* Now, sort the files we found, to make this uniform and stable (and to ensure the TPM measurements
* are not dependent on read order) */
sort_pointer_array((void**) items, n_items, (compare_pointer_func_t) StrCmp);
sort_pointer_array((void**) items, n_items, (compare_pointer_func_t) strcmp16);
/* Generate the leading directory inodes right before adding the first files, to the
* archive. Otherwise the cpio archive cannot be unpacked, since the leading dirs won't exist. */
+2 -2
View File
@@ -51,7 +51,7 @@ static EFI_STATUS devicetree_fixup(struct devicetree_state *state, UINTN len) {
if (EFI_ERROR(err))
return err;
CopyMem(PHYSICAL_ADDRESS_TO_POINTER(state->addr), oldptr, len);
memcpy(PHYSICAL_ADDRESS_TO_POINTER(state->addr), oldptr, len);
err = BS->FreePages(oldaddr, oldpages);
if (EFI_ERROR(err))
return err;
@@ -122,7 +122,7 @@ EFI_STATUS devicetree_install_from_memory(struct devicetree_state *state,
if (EFI_ERROR(err))
return err;
CopyMem(PHYSICAL_ADDRESS_TO_POINTER(state->addr), dtb_buffer, dtb_length);
memcpy(PHYSICAL_ADDRESS_TO_POINTER(state->addr), dtb_buffer, dtb_length);
err = devicetree_fixup(state, dtb_length);
if (EFI_ERROR(err))
+233
View File
@@ -0,0 +1,233 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <stdbool.h>
#include <stdint.h>
#include "efi-string.h"
#ifdef SD_BOOT
# include "util.h"
# define xmalloc(n) xallocate_pool(n)
#else
# include <stdlib.h>
# include "macro.h"
# define xmalloc(n) ASSERT_SE_PTR(malloc(n))
#endif
/* String functions for both char and char16_t that should behave the same way as their respective
* counterpart in userspace. Where it makes sense, these accept NULL and do something sensible whereas
* userspace does not allow for this (strlen8(NULL) returns 0 like strlen_ptr(NULL) for example). To make it
* easier to tell in code which kind of string they work on, we use 8/16 suffixes. This also makes is easier
* to unit test them. */
#define DEFINE_STRNLEN(type, name) \
size_t name(const type *s, size_t n) { \
if (!s) \
return 0; \
\
size_t len = 0; \
while (len < n && *s) { \
s++; \
len++; \
} \
\
return len; \
}
DEFINE_STRNLEN(char, strnlen8);
DEFINE_STRNLEN(char16_t, strnlen16);
size_t strlen8(const char *s) {
return strnlen8(s, SIZE_MAX);
}
size_t strlen16(const char16_t *s) {
return strnlen16(s, SIZE_MAX);
}
#define TOLOWER(c) \
({ \
typeof(c) _c = (c); \
(_c >= 'A' && _c <= 'Z') ? _c + ('a' - 'A') : _c; \
})
#define DEFINE_STRTOLOWER(type, name) \
void name(type *s) { \
if (!s) \
return; \
for (; *s; s++) \
*s = TOLOWER(*s); \
}
DEFINE_STRTOLOWER(char, strtolower8);
DEFINE_STRTOLOWER(char16_t, strtolower16);
#define DEFINE_STRNCASECMP(type, name, tolower) \
int name(const type *s1, const type *s2, size_t n) { \
if (!s1 || !s2) \
return CMP(s1, s2); \
\
while (n > 0) { \
int c1 = *s1; \
int c2 = *s2; \
if (tolower) { \
c1 = TOLOWER(c1); \
c2 = TOLOWER(c2); \
} \
if (!c1 || c1 != c2) \
return c1 - c2; \
\
s1++; \
s2++; \
n--; \
} \
\
return 0; \
}
DEFINE_STRNCASECMP(char, strncmp8, false);
DEFINE_STRNCASECMP(char16_t, strncmp16, false);
int strcmp8(const char *s1, const char *s2) {
return strncmp8(s1, s2, SIZE_MAX);
}
int strcmp16(const char16_t *s1, const char16_t *s2) {
return strncmp16(s1, s2, SIZE_MAX);
}
DEFINE_STRNCASECMP(char, strncasecmp8, true);
DEFINE_STRNCASECMP(char16_t, strncasecmp16, true);
int strcasecmp8(const char *s1, const char *s2) {
return strncasecmp8(s1, s2, SIZE_MAX);
}
int strcasecmp16(const char16_t *s1, const char16_t *s2) {
return strncasecmp16(s1, s2, SIZE_MAX);
}
#define DEFINE_STRCPY(type, name) \
type *name(type * restrict dest, const type * restrict src) { \
assert(dest); \
type *ret = dest; \
\
if (!src) { \
*dest = '\0'; \
return ret; \
} \
\
while (*src) { \
*dest = *src; \
dest++; \
src++; \
} \
\
*dest = '\0'; \
return ret; \
}
DEFINE_STRCPY(char, strcpy8);
DEFINE_STRCPY(char16_t, strcpy16);
#define DEFINE_STRCHR(type, name) \
type *name(const type *s, type c) { \
if (!s) \
return NULL; \
\
while (*s) { \
if (*s == c) \
return (type *) s; \
s++; \
} \
\
return NULL; \
}
DEFINE_STRCHR(char, strchr8);
DEFINE_STRCHR(char16_t, strchr16);
#define DEFINE_STRNDUP(type, name, len_func) \
type *name(const type *s, size_t n) { \
if (!s) \
return NULL; \
\
size_t len = len_func(s, n); \
size_t size = len * sizeof(type); \
\
type *dup = xmalloc(size + sizeof(type)); \
efi_memcpy(dup, s, size); \
dup[len] = '\0'; \
\
return dup; \
}
DEFINE_STRNDUP(char, xstrndup8, strnlen8);
DEFINE_STRNDUP(char16_t, xstrndup16, strnlen16);
char *xstrdup8(const char *s) {
return xstrndup8(s, SIZE_MAX);
}
char16_t *xstrdup16(const char16_t *s) {
return xstrndup16(s, SIZE_MAX);
}
int efi_memcmp(const void *p1, const void *p2, size_t n) {
if (!p1 || !p2)
return CMP(p1, p2);
const uint8_t *up1 = p1, *up2 = p2;
while (n > 0) {
if (*up1 != *up2)
return *up1 - *up2;
up1++;
up2++;
n--;
}
return 0;
}
void *efi_memcpy(void * restrict dest, const void * restrict src, size_t n) {
if (!dest || !src || n == 0)
return dest;
uint8_t *d = dest;
const uint8_t *s = src;
while (n > 0) {
*d = *s;
d++;
s++;
n--;
}
return dest;
}
void *efi_memset(void *p, int c, size_t n) {
if (!p || n == 0)
return p;
uint8_t *q = p;
while (n > 0) {
*q = c;
q++;
n--;
}
return p;
}
#ifdef SD_BOOT
# undef memcmp
# undef memcpy
# undef memset
/* Provide the actual implementation for the builtins. To prevent a linker error, we mark memcpy/memset as
* weak, because gnu-efi is currently providing them. */
__attribute__((alias("efi_memcmp"))) int memcmp(const void *p1, const void *p2, size_t n);
__attribute__((weak, alias("efi_memcpy"))) void *memcpy(void * restrict dest, const void * restrict src, size_t n);
__attribute__((weak, alias("efi_memset"))) void *memset(void *p, int c, size_t n);
#endif
+96
View File
@@ -0,0 +1,96 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <uchar.h>
#include "macro-fundamental.h"
size_t strnlen8(const char *s, size_t n);
size_t strnlen16(const char16_t *s, size_t n);
size_t strlen8(const char *s);
size_t strlen16(const char16_t *s);
static inline size_t strsize8(const char *s) {
return s ? (strlen8(s) + 1) * sizeof(*s) : 0;
}
static inline size_t strsize16(const char16_t *s) {
return s ? (strlen16(s) + 1) * sizeof(*s) : 0;
}
void strtolower8(char *s);
void strtolower16(char16_t *s);
int strncmp8(const char *s1, const char *s2, size_t n);
int strncmp16(const char16_t *s1, const char16_t *s2, size_t n);
int strcmp8(const char *s1, const char *s2);
int strcmp16(const char16_t *s1, const char16_t *s2);
int strncasecmp8(const char *s1, const char *s2, size_t n);
int strncasecmp16(const char16_t *s1, const char16_t *s2, size_t n);
int strcasecmp8(const char *s1, const char *s2);
int strcasecmp16(const char16_t *s1, const char16_t *s2);
static inline bool strneq8(const char *s1, const char *s2, size_t n) {
return strncmp8(s1, s2, n) == 0;
}
static inline bool strneq16(const char16_t *s1, const char16_t *s2, size_t n) {
return strncmp16(s1, s2, n) == 0;
}
static inline bool streq8(const char *s1, const char *s2) {
return strcmp8(s1, s2) == 0;
}
static inline bool streq16(const char16_t *s1, const char16_t *s2) {
return strcmp16(s1, s2) == 0;
}
static inline int strncaseeq8(const char *s1, const char *s2, size_t n) {
return strncasecmp8(s1, s2, n) == 0;
}
static inline int strncaseeq16(const char16_t *s1, const char16_t *s2, size_t n) {
return strncasecmp16(s1, s2, n) == 0;
}
static inline bool strcaseeq8(const char *s1, const char *s2) {
return strcasecmp8(s1, s2) == 0;
}
static inline bool strcaseeq16(const char16_t *s1, const char16_t *s2) {
return strcasecmp16(s1, s2) == 0;
}
char *strcpy8(char * restrict dest, const char * restrict src);
char16_t *strcpy16(char16_t * restrict dest, const char16_t * restrict src);
char *strchr8(const char *s, char c);
char16_t *strchr16(const char16_t *s, char16_t c);
char *xstrndup8(const char *s, size_t n);
char16_t *xstrndup16(const char16_t *s, size_t n);
char *xstrdup8(const char *s);
char16_t *xstrdup16(const char16_t *s);
#ifdef SD_BOOT
/* The compiler normaly has knowledge about standard functions such as memcmp, but this is not the case when
* compiling with -ffreestanding. By referring to builtins, the compiler can check arguments and do
* optimizations again. Note that we still need to provide implementations as the compiler is free to not
* inline its own implementation and instead issue a library call. */
# define memcmp __builtin_memcmp
# define memcpy __builtin_memcpy
# define memset __builtin_memset
#endif
/* The actual implementations of builtins with efi_ prefix so we can unit test them. */
int efi_memcmp(const void *p1, const void *p2, size_t n);
void *efi_memcpy(void * restrict dest, const void * restrict src, size_t n);
void *efi_memset(void *p, int c, size_t n);
+1 -1
View File
@@ -61,7 +61,7 @@ EFIAPI EFI_STATUS initrd_load_file(
return EFI_BUFFER_TOO_SMALL;
}
CopyMem(buffer, loader->address, loader->length);
memcpy(buffer, loader->address, loader->length);
*buffer_size = loader->length;
return EFI_SUCCESS;
}
+3 -3
View File
@@ -45,7 +45,7 @@ static EFI_STATUS loaded_image_register(
/* if a cmdline is set convert it to UCS2 */
if (cmdline) {
loaded_image->LoadOptions = xstra_to_str(cmdline);
loaded_image->LoadOptionsSize = StrSize(loaded_image->LoadOptions);
loaded_image->LoadOptionsSize = strsize16(loaded_image->LoadOptions);
}
/* install a new LoadedImage protocol. ret_handle is a new image handle */
@@ -145,9 +145,9 @@ EFI_STATUS linux_exec(
if (EFI_ERROR(err))
return EFI_OUT_OF_RESOURCES;
new_buffer = PHYSICAL_ADDRESS_TO_POINTER(ALIGN_TO(kernel.addr, kernel_alignment));
CopyMem(new_buffer, linux_buffer, linux_length);
memcpy(new_buffer, linux_buffer, linux_length);
/* zero out rest of memory (probably not needed, but BSS section should be 0) */
SetMem((UINT8 *)new_buffer + linux_length, kernel_size_of_image - linux_length, 0);
memset((UINT8 *)new_buffer + linux_length, 0, kernel_size_of_image - linux_length);
/* get the entry point inside the relocated kernel */
kernel_entry = (EFI_IMAGE_ENTRY_POINT) ((const UINT8 *)new_buffer + kernel_entry_address);
+2 -2
View File
@@ -159,7 +159,7 @@ EFI_STATUS linux_exec(
return err;
boot_params = (struct boot_params *) PHYSICAL_ADDRESS_TO_POINTER(addr);
ZeroMem(boot_params, 0x4000);
memset(boot_params, 0, 0x4000);
boot_params->hdr = image_params->hdr;
boot_params->hdr.type_of_loader = 0xff;
setup_sectors = image_params->hdr.setup_sects > 0 ? image_params->hdr.setup_sects : 4;
@@ -176,7 +176,7 @@ EFI_STATUS linux_exec(
if (EFI_ERROR(err))
return err;
CopyMem(PHYSICAL_ADDRESS_TO_POINTER(addr), cmdline, cmdline_len);
memcpy(PHYSICAL_ADDRESS_TO_POINTER(addr), cmdline, cmdline_len);
((CHAR8 *) PHYSICAL_ADDRESS_TO_POINTER(addr))[cmdline_len] = 0;
boot_params->hdr.cmd_line_ptr = (UINT32) addr;
}
+5 -5
View File
@@ -25,14 +25,14 @@ static EFI_STATUS tpm1_measure_to_pcr_and_event_log(
assert(tcg);
assert(description);
desc_len = StrSize(description);
desc_len = strsize16(description);
tcg_event = xallocate_zero_pool(offsetof(TCG_PCR_EVENT, Event) + desc_len);
*tcg_event = (TCG_PCR_EVENT) {
.EventSize = desc_len,
.PCRIndex = pcrindex,
.EventType = EV_IPL,
};
CopyMem(tcg_event->Event, description, desc_len);
memcpy(tcg_event->Event, description, desc_len);
return tcg->HashLogExtendEvent(
(EFI_TCG *) tcg,
@@ -56,7 +56,7 @@ static EFI_STATUS tpm2_measure_to_pcr_and_event_log(
assert(tcg);
assert(description);
desc_len = StrSize(description);
desc_len = strsize16(description);
tcg_event = xallocate_zero_pool(offsetof(EFI_TCG2_EVENT, Event) + desc_len);
*tcg_event = (EFI_TCG2_EVENT) {
.Size = offsetof(EFI_TCG2_EVENT, Event) + desc_len,
@@ -66,7 +66,7 @@ static EFI_STATUS tpm2_measure_to_pcr_and_event_log(
.Header.EventType = EV_IPL,
};
CopyMem(tcg_event->Event, description, desc_len);
memcpy(tcg_event->Event, description, desc_len);
return tcg->HashLogExtendEvent(
tcg,
@@ -171,7 +171,7 @@ EFI_STATUS tpm_log_load_options(const CHAR16 *load_options) {
err = tpm_log_event(pcr,
POINTER_TO_PHYSICAL_ADDRESS(load_options),
StrSize(load_options), load_options);
strsize16(load_options), load_options);
if (EFI_ERROR(err))
return log_error_status_stall(err, L"Unable to add load options (i.e. kernel command) line measurement to PCR %u: %r", pcr, err);
}
+9 -2
View File
@@ -194,6 +194,7 @@ efi_cflags = cc.get_supported_arguments(
'-isystem', efi_incdir,
'-isystem', efi_incdir / efi_arch[1],
'-I', fundamental_path,
'-I', meson.current_source_dir(),
'-DSD_BOOT',
'-DGNU_EFI_USE_MS_ABI',
'-include', efi_config_h,
@@ -331,6 +332,7 @@ efi_headers = files(
'devicetree.h',
'disk.h',
'drivers.h',
'efi-string.h',
'graphics.h',
'initrd.h',
'linux.h',
@@ -350,6 +352,7 @@ common_sources = files(
'assert.c',
'devicetree.c',
'disk.c',
'efi-string.c',
'graphics.c',
'initrd.c',
'measure.c',
@@ -380,18 +383,22 @@ else
stub_sources += files('linux.c')
endif
tests += [
[files('test-efi-string.c', 'efi-string.c')],
]
# BCD parser only makes sense on arches that Windows supports.
if efi_arch[1] in ['ia32', 'x86_64', 'arm', 'aarch64']
systemd_boot_sources += files('bcd.c')
tests += [
[files('test-bcd.c'),
[files('test-bcd.c', 'efi-string.c'),
[],
[libzstd],
[],
'HAVE_ZSTD'],
]
fuzzers += [
[files('fuzz-bcd.c')],
[files('fuzz-bcd.c', 'efi-string.c')],
]
endif
+3 -3
View File
@@ -119,12 +119,12 @@ struct PeSectionHeader {
static inline BOOLEAN verify_dos(const struct DosFileHeader *dos) {
assert(dos);
return CompareMem(dos->Magic, DOS_FILE_MAGIC, STRLEN(DOS_FILE_MAGIC)) == 0;
return memcmp(dos->Magic, DOS_FILE_MAGIC, STRLEN(DOS_FILE_MAGIC)) == 0;
}
static inline BOOLEAN verify_pe(const struct PeFileHeader *pe, BOOLEAN allow_compatibility) {
assert(pe);
return CompareMem(pe->Magic, PE_FILE_MAGIC, STRLEN(PE_FILE_MAGIC)) == 0 &&
return memcmp(pe->Magic, PE_FILE_MAGIC, STRLEN(PE_FILE_MAGIC)) == 0 &&
(pe->FileHeader.Machine == TARGET_MACHINE_TYPE ||
(allow_compatibility && pe->FileHeader.Machine == TARGET_MACHINE_TYPE_COMPATIBILITY)) &&
pe->FileHeader.NumberOfSections > 0 &&
@@ -154,7 +154,7 @@ static void locate_sections(
const struct PeSectionHeader *sect = section_table + i;
for (UINTN j = 0; sections[j]; j++) {
if (CompareMem(sect->Name, sections[j], strlena(sections[j])) != 0)
if (memcmp(sect->Name, sections[j], strlen8((const char *) sections[j])) != 0)
continue;
if (addrs)
+2 -2
View File
@@ -220,10 +220,10 @@ static void validate_sha256(void) {
uint8_t result[HASH_VALUE_SIZE];
sha256_init_ctx(&hash);
sha256_process_bytes(array[i].string, strlena((const CHAR8*) array[i].string), &hash);
sha256_process_bytes(array[i].string, strlen8(array[i].string), &hash);
sha256_finish_ctx(&hash, result);
assert(CompareMem(result, array[i].hash, HASH_VALUE_SIZE) == 0);
assert(memcmp(result, array[i].hash, HASH_VALUE_SIZE) == 0);
}
#endif
+1 -1
View File
@@ -271,7 +271,7 @@ EFI_STATUS graphics_splash(const UINT8 *content, UINTN len, const EFI_GRAPHICS_O
assert(content);
if (!background) {
if (StriCmp(L"Apple", ST->FirmwareVendor) == 0) {
if (strcaseeq16(u"Apple", ST->FirmwareVendor)) {
pixel.Red = 0xc0;
pixel.Green = 0xc0;
pixel.Blue = 0xc0;
+5 -5
View File
@@ -68,28 +68,28 @@ static EFI_STATUS combine_initrd(
/* Order matters, the real initrd must come first, since it might include microcode updates
* which the kernel only looks for in the first cpio archive */
CopyMem(p, PHYSICAL_ADDRESS_TO_POINTER(initrd_base), initrd_size);
memcpy(p, PHYSICAL_ADDRESS_TO_POINTER(initrd_base), initrd_size);
p += initrd_size;
pad = ALIGN_TO(initrd_size, 4) - initrd_size;
if (pad > 0) {
ZeroMem(p, pad);
memset(p, 0, pad);
p += pad;
}
}
if (credential_initrd) {
CopyMem(p, credential_initrd, credential_initrd_size);
memcpy(p, credential_initrd, credential_initrd_size);
p += credential_initrd_size;
}
if (global_credential_initrd) {
CopyMem(p, global_credential_initrd, global_credential_initrd_size);
memcpy(p, global_credential_initrd, global_credential_initrd_size);
p += global_credential_initrd_size;
}
if (sysext_initrd) {
CopyMem(p, sysext_initrd, sysext_initrd_size);
memcpy(p, sysext_initrd, sysext_initrd_size);
p += sysext_initrd_size;
}
+376
View File
@@ -0,0 +1,376 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "efi-string.h"
#include "tests.h"
TEST(strlen8) {
assert_se(strlen8(NULL) == 0);
assert_se(strlen8("") == 0);
assert_se(strlen8("1") == 1);
assert_se(strlen8("11") == 2);
assert_se(strlen8("123456789") == 9);
assert_se(strlen8("12\0004") == 2);
}
TEST(strlen16) {
assert_se(strlen16(NULL) == 0);
assert_se(strlen16(u"") == 0);
assert_se(strlen16(u"1") == 1);
assert_se(strlen16(u"11") == 2);
assert_se(strlen16(u"123456789") == 9);
assert_se(strlen16(u"12\0004") == 2);
}
TEST(strnlen8) {
assert_se(strnlen8(NULL, 0) == 0);
assert_se(strnlen8(NULL, 10) == 0);
assert_se(strnlen8("", 10) == 0);
assert_se(strnlen8("1", 10) == 1);
assert_se(strnlen8("11", 1) == 1);
assert_se(strnlen8("123456789", 7) == 7);
assert_se(strnlen8("12\0004", 5) == 2);
}
TEST(strnlen16) {
assert_se(strnlen16(NULL, 0) == 0);
assert_se(strnlen16(NULL, 10) == 0);
assert_se(strnlen16(u"", 10) == 0);
assert_se(strnlen16(u"1", 10) == 1);
assert_se(strnlen16(u"11", 1) == 1);
assert_se(strnlen16(u"123456789", 7) == 7);
assert_se(strnlen16(u"12\0004", 5) == 2);
}
TEST(strsize8) {
assert_se(strsize8(NULL) == 0);
assert_se(strsize8("") == 1);
assert_se(strsize8("1") == 2);
assert_se(strsize8("11") == 3);
assert_se(strsize8("123456789") == 10);
assert_se(strsize8("12\0004") == 3);
}
TEST(strsize16) {
assert_se(strsize16(NULL) == 0);
assert_se(strsize16(u"") == 2);
assert_se(strsize16(u"1") == 4);
assert_se(strsize16(u"11") == 6);
assert_se(strsize16(u"123456789") == 20);
assert_se(strsize16(u"12\0004") == 6);
}
TEST(strtolower8) {
char s[] = "\0001234abcDEF!\0zZ";
strtolower8(NULL);
strtolower8(s);
assert_se(memcmp(s, "\0001234abcDEF!\0zZ", sizeof(s)) == 0);
s[0] = '#';
strtolower8(s);
assert_se(memcmp(s, "#1234abcdef!\0zZ", sizeof(s)) == 0);
}
TEST(strtolower16) {
char16_t s[] = u"\0001234abcDEF!\0zZ";
strtolower16(NULL);
strtolower16(s);
assert_se(memcmp(s, u"\0001234abcDEF!\0zZ", sizeof(s)) == 0);
s[0] = '#';
strtolower16(s);
assert_se(memcmp(s, u"#1234abcdef!\0zZ", sizeof(s)) == 0);
}
TEST(strncmp8) {
assert_se(strncmp8(NULL, "", 10) < 0);
assert_se(strncmp8("", NULL, 10) > 0);
assert_se(strncmp8(NULL, NULL, 0) == 0);
assert_se(strncmp8(NULL, NULL, 10) == 0);
assert_se(strncmp8("", "", 10) == 0);
assert_se(strncmp8("abc", "abc", 2) == 0);
assert_se(strncmp8("aBc", "aBc", 3) == 0);
assert_se(strncmp8("aBC", "aBC", 4) == 0);
assert_se(strncmp8("", "a", 0) == 0);
assert_se(strncmp8("b", "a", 0) == 0);
assert_se(strncmp8("", "a", 3) < 0);
assert_se(strncmp8("=", "=", 1) == 0);
assert_se(strncmp8("A", "a", 1) < 0);
assert_se(strncmp8("a", "A", 2) > 0);
assert_se(strncmp8("a", "Aa", 2) > 0);
assert_se(strncmp8("12\00034", "12345", 4) < 0);
assert_se(strncmp8("12\00034", "12345", SIZE_MAX) < 0);
assert_se(strncmp8("abc\0def", "abc", SIZE_MAX) == 0);
assert_se(strncmp8("abc\0def", "abcdef", SIZE_MAX) < 0);
assert_se(strncmp8((char[]){ CHAR_MIN }, (char[]){ CHAR_MIN }, 1) == 0);
assert_se(strncmp8((char[]){ CHAR_MAX }, (char[]){ CHAR_MAX }, 1) == 0);
assert_se(strncmp8((char[]){ CHAR_MIN }, (char[]){ CHAR_MAX }, 1) < 0);
assert_se(strncmp8((char[]){ CHAR_MAX }, (char[]){ CHAR_MIN }, 1) > 0);
}
TEST(strncmp16) {
assert_se(strncmp16(NULL, u"", 10) < 0);
assert_se(strncmp16(u"", NULL, 10) > 0);
assert_se(strncmp16(NULL, NULL, 0) == 0);
assert_se(strncmp16(NULL, NULL, 10) == 0);
assert_se(strncmp16(u"", u"", 0) == 0);
assert_se(strncmp16(u"", u"", 10) == 0);
assert_se(strncmp16(u"abc", u"abc", 2) == 0);
assert_se(strncmp16(u"aBc", u"aBc", 3) == 0);
assert_se(strncmp16(u"aBC", u"aBC", 4) == 0);
assert_se(strncmp16(u"", u"a", 0) == 0);
assert_se(strncmp16(u"b", u"a", 0) == 0);
assert_se(strncmp16(u"", u"a", 3) < 0);
assert_se(strncmp16(u"=", u"=", 1) == 0);
assert_se(strncmp16(u"A", u"a", 1) < 0);
assert_se(strncmp16(u"a", u"A", 2) > 0);
assert_se(strncmp16(u"a", u"Aa", 2) > 0);
assert_se(strncmp16(u"12\00034", u"12345", 4) < 0);
assert_se(strncmp16(u"12\00034", u"12345", SIZE_MAX) < 0);
assert_se(strncmp16(u"abc\0def", u"abc", SIZE_MAX) == 0);
assert_se(strncmp16(u"abc\0def", u"abcdef", SIZE_MAX) < 0);
assert_se(strncmp16((char16_t[]){ UINT16_MAX }, (char16_t[]){ UINT16_MAX }, 1) == 0);
assert_se(strncmp16((char16_t[]){ 0 }, (char16_t[]){ UINT16_MAX }, 1) < 0);
assert_se(strncmp16((char16_t[]){ UINT16_MAX }, (char16_t[]){ 0 }, 1) > 0);
}
TEST(strncasecmp8) {
assert_se(strncasecmp8(NULL, "", 10) < 0);
assert_se(strncasecmp8("", NULL, 10) > 0);
assert_se(strncasecmp8(NULL, NULL, 0) == 0);
assert_se(strncasecmp8(NULL, NULL, 10) == 0);
assert_se(strncasecmp8("", "", 10) == 0);
assert_se(strncasecmp8("abc", "abc", 2) == 0);
assert_se(strncasecmp8("aBc", "AbC", 3) == 0);
assert_se(strncasecmp8("aBC", "Abc", 4) == 0);
assert_se(strncasecmp8("", "a", 0) == 0);
assert_se(strncasecmp8("b", "a", 0) == 0);
assert_se(strncasecmp8("", "a", 3) < 0);
assert_se(strncasecmp8("=", "=", 1) == 0);
assert_se(strncasecmp8("A", "a", 1) == 0);
assert_se(strncasecmp8("a", "A", 2) == 0);
assert_se(strncasecmp8("a", "Aa", 2) < 0);
assert_se(strncasecmp8("12\00034", "12345", 4) < 0);
assert_se(strncasecmp8("12\00034", "12345", SIZE_MAX) < 0);
assert_se(strncasecmp8("abc\0def", "ABC", SIZE_MAX) == 0);
assert_se(strncasecmp8("abc\0def", "ABCDEF", SIZE_MAX) < 0);
assert_se(strncasecmp8((char[]){ CHAR_MIN }, (char[]){ CHAR_MIN }, 1) == 0);
assert_se(strncasecmp8((char[]){ CHAR_MAX }, (char[]){ CHAR_MAX }, 1) == 0);
assert_se(strncasecmp8((char[]){ CHAR_MIN }, (char[]){ CHAR_MAX }, 1) < 0);
assert_se(strncasecmp8((char[]){ CHAR_MAX }, (char[]){ CHAR_MIN }, 1) > 0);
}
TEST(strncasecmp16) {
assert_se(strncasecmp16(NULL, u"", 10) < 0);
assert_se(strncasecmp16(u"", NULL, 10) > 0);
assert_se(strncasecmp16(NULL, NULL, 0) == 0);
assert_se(strncasecmp16(NULL, NULL, 10) == 0);
assert_se(strncasecmp16(u"", u"", 10) == 0);
assert_se(strncasecmp16(u"abc", u"abc", 2) == 0);
assert_se(strncasecmp16(u"aBc", u"AbC", 3) == 0);
assert_se(strncasecmp16(u"aBC", u"Abc", 4) == 0);
assert_se(strncasecmp16(u"", u"a", 0) == 0);
assert_se(strncasecmp16(u"b", u"a", 0) == 0);
assert_se(strncasecmp16(u"", u"a", 3) < 0);
assert_se(strncasecmp16(u"=", u"=", 1) == 0);
assert_se(strncasecmp16(u"A", u"a", 1) == 0);
assert_se(strncasecmp16(u"a", u"A", 2) == 0);
assert_se(strncasecmp16(u"a", u"Aa", 2) < 0);
assert_se(strncasecmp16(u"12\00034", u"12345", 4) < 0);
assert_se(strncasecmp16(u"12\00034", u"12345", SIZE_MAX) < 0);
assert_se(strncasecmp16(u"abc\0def", u"ABC", SIZE_MAX) == 0);
assert_se(strncasecmp16(u"abc\0def", u"ABCDEF", SIZE_MAX) < 0);
assert_se(strncasecmp16((char16_t[]){ UINT16_MAX }, (char16_t[]){ UINT16_MAX }, 1) == 0);
assert_se(strncasecmp16((char16_t[]){ 0 }, (char16_t[]){ UINT16_MAX }, 1) < 0);
assert_se(strncasecmp16((char16_t[]){ UINT16_MAX }, (char16_t[]){ 0 }, 1) > 0);
}
TEST(strcpy8) {
char buf[128];
assert_se(strcpy8(buf, "123") == buf);
assert_se(streq8(buf, "123"));
assert_se(strcpy8(buf, "") == buf);
assert_se(streq8(buf, ""));
assert_se(strcpy8(buf, "A") == buf);
assert_se(streq8(buf, "A"));
assert_se(strcpy8(buf, NULL) == buf);
assert_se(streq8(buf, ""));
}
TEST(strcpy16) {
char16_t buf[128];
assert_se(strcpy16(buf, u"123") == buf);
assert_se(streq16(buf, u"123"));
assert_se(strcpy16(buf, u"") == buf);
assert_se(streq16(buf, u""));
assert_se(strcpy16(buf, u"A") == buf);
assert_se(streq16(buf, u"A"));
assert_se(strcpy16(buf, NULL) == buf);
assert_se(streq16(buf, u""));
}
TEST(strchr8) {
assert_se(!strchr8(NULL, 'a'));
assert_se(!strchr8("", 'a'));
assert_se(!strchr8("123", 'a'));
const char str[] = "abcaBc";
assert_se(strchr8(str, 'a') == &str[0]);
assert_se(strchr8(str, 'c') == &str[2]);
assert_se(strchr8(str, 'B') == &str[4]);
}
TEST(strchr16) {
assert_se(!strchr16(NULL, 'a'));
assert_se(!strchr16(u"", 'a'));
assert_se(!strchr16(u"123", 'a'));
const char16_t str[] = u"abcaBc";
assert_se(strchr16(str, 'a') == &str[0]);
assert_se(strchr16(str, 'c') == &str[2]);
assert_se(strchr16(str, 'B') == &str[4]);
}
TEST(xstrndup8) {
char *s = NULL;
assert_se(xstrndup8(NULL, 0) == NULL);
assert_se(xstrndup8(NULL, 10) == NULL);
assert_se(s = xstrndup8("", 10));
assert_se(streq8(s, ""));
free(s);
assert_se(s = xstrndup8("abc", 0));
assert_se(streq8(s, ""));
free(s);
assert_se(s = xstrndup8("ABC", 3));
assert_se(streq8(s, "ABC"));
free(s);
assert_se(s = xstrndup8("123abcDEF", 5));
assert_se(streq8(s, "123ab"));
free(s);
}
TEST(xstrdup8) {
char *s = NULL;
assert_se(xstrdup8(NULL) == NULL);
assert_se(s = xstrdup8(""));
assert_se(streq8(s, ""));
free(s);
assert_se(s = xstrdup8("1"));
assert_se(streq8(s, "1"));
free(s);
assert_se(s = xstrdup8("123abcDEF"));
assert_se(streq8(s, "123abcDEF"));
free(s);
}
TEST(xstrndup16) {
char16_t *s = NULL;
assert_se(xstrndup16(NULL, 0) == NULL);
assert_se(xstrndup16(NULL, 10) == NULL);
assert_se(s = xstrndup16(u"", 10));
assert_se(streq16(s, u""));
free(s);
assert_se(s = xstrndup16(u"abc", 0));
assert_se(streq16(s, u""));
free(s);
assert_se(s = xstrndup16(u"ABC", 3));
assert_se(streq16(s, u"ABC"));
free(s);
assert_se(s = xstrndup16(u"123abcDEF", 5));
assert_se(streq16(s, u"123ab"));
free(s);
}
TEST(xstrdup16) {
char16_t *s = NULL;
assert_se(xstrdup16(NULL) == NULL);
assert_se(s = xstrdup16(u""));
assert_se(streq16(s, u""));
free(s);
assert_se(s = xstrdup16(u"1"));
assert_se(streq16(s, u"1"));
free(s);
assert_se(s = xstrdup16(u"123abcDEF"));
assert_se(streq16(s, u"123abcDEF"));
free(s);
}
TEST(efi_memcmp) {
assert_se(efi_memcmp(NULL, NULL, 0) == 0);
assert_se(efi_memcmp(NULL, NULL, 1) == 0);
assert_se(efi_memcmp(NULL, "", 1) < 0);
assert_se(efi_memcmp("", NULL, 1) > 0);
assert_se(efi_memcmp("", "", 0) == 0);
assert_se(efi_memcmp("", "", 1) == 0);
assert_se(efi_memcmp("1", "1", 1) == 0);
assert_se(efi_memcmp("1", "2", 1) < 0);
assert_se(efi_memcmp("A", "a", 1) < 0);
assert_se(efi_memcmp("a", "A", 1) > 0);
assert_se(efi_memcmp("abc", "ab", 2) == 0);
assert_se(efi_memcmp("ab", "abc", 3) < 0);
assert_se(efi_memcmp("ab\000bd", "ab\000bd", 6) == 0);
assert_se(efi_memcmp("ab\000b\0", "ab\000bd", 6) < 0);
}
TEST(efi_memcpy) {
char buf[10];
assert_se(!efi_memcpy(NULL, NULL, 0));
assert_se(!efi_memcpy(NULL, "", 1));
assert_se(efi_memcpy(buf, NULL, 0) == buf);
assert_se(efi_memcpy(buf, NULL, 1) == buf);
assert_se(efi_memcpy(buf, "a", 0) == buf);
assert_se(efi_memcpy(buf, "", 1) == buf);
assert_se(memcmp(buf, "", 1) == 0);
assert_se(efi_memcpy(buf, "1", 1) == buf);
assert_se(memcmp(buf, "1", 1) == 0);
assert_se(efi_memcpy(buf, "23", 3) == buf);
assert_se(memcmp(buf, "23", 3) == 0);
assert_se(efi_memcpy(buf, "45\0ab\0\0\0c", 9) == buf);
assert_se(memcmp(buf, "45\0ab\0\0\0c", 9) == 0);
}
TEST(efi_memset) {
char buf[10];
assert_se(!efi_memset(NULL, '1', 0));
assert_se(!efi_memset(NULL, '1', 1));
assert_se(efi_memset(buf, '1', 0) == buf);
assert_se(efi_memset(buf, '2', 1) == buf);
assert_se(memcmp(buf, "2", 1) == 0);
assert_se(efi_memset(buf, '4', 4) == buf);
assert_se(memcmp(buf, "4444", 4) == 0);
assert_se(efi_memset(buf, 'a', 10) == buf);
assert_se(memcmp(buf, "aaaaaaaaaa", 10) == 0);
}
DEFINE_TEST_MAIN(LOG_INFO);
+9 -83
View File
@@ -12,22 +12,14 @@ EFI_STATUS parse_boolean(const CHAR8 *v, BOOLEAN *b) {
if (!v)
return EFI_INVALID_PARAMETER;
if (strcmpa(v, (CHAR8 *)"1") == 0 ||
strcmpa(v, (CHAR8 *)"yes") == 0 ||
strcmpa(v, (CHAR8 *)"y") == 0 ||
strcmpa(v, (CHAR8 *)"true") == 0 ||
strcmpa(v, (CHAR8 *)"t") == 0 ||
strcmpa(v, (CHAR8 *)"on") == 0) {
if (streq8((char *) v, "1") || streq8((char *) v, "yes") || streq8((char *) v, "y") ||
streq8((char *) v, "true") || streq8((char *) v, "t") || streq8((char *) v, "on")) {
*b = TRUE;
return EFI_SUCCESS;
}
if (strcmpa(v, (CHAR8 *)"0") == 0 ||
strcmpa(v, (CHAR8 *)"no") == 0 ||
strcmpa(v, (CHAR8 *)"n") == 0 ||
strcmpa(v, (CHAR8 *)"false") == 0 ||
strcmpa(v, (CHAR8 *)"f") == 0 ||
strcmpa(v, (CHAR8 *)"off") == 0) {
if (streq8((char *) v, "0") || streq8((char *) v, "no") || streq8((char *) v, "n") ||
streq8((char *) v, "false") || streq8((char *) v, "f") || streq8((char *) v, "off")) {
*b = FALSE;
return EFI_SUCCESS;
}
@@ -48,7 +40,7 @@ EFI_STATUS efivar_set(const EFI_GUID *vendor, const CHAR16 *name, const CHAR16 *
assert(vendor);
assert(name);
return efivar_set_raw(vendor, name, value, value ? StrSize(value) : 0, flags);
return efivar_set_raw(vendor, name, value, value ? strsize16(value) : 0, flags);
}
EFI_STATUS efivar_set_uint_string(const EFI_GUID *vendor, const CHAR16 *name, UINTN i, UINT32 flags) {
@@ -125,7 +117,7 @@ EFI_STATUS efivar_get(const EFI_GUID *vendor, const CHAR16 *name, CHAR16 **value
/* Make sure a terminating NUL is available at the end */
val = xallocate_pool(size + sizeof(CHAR16));
CopyMem(val, buf, size);
memcpy(val, buf, size);
val[size / sizeof(CHAR16) - 1] = 0; /* NUL terminate */
*value = val;
@@ -306,7 +298,7 @@ CHAR16 *xstra_to_str(const CHAR8 *stra) {
assert(stra);
len = strlena(stra);
len = strlen8((const char *) stra);
str = xnew(CHAR16, len + 1);
strlen = 0;
@@ -336,7 +328,7 @@ CHAR16 *xstra_to_path(const CHAR8 *stra) {
assert(stra);
len = strlena(stra);
len = strlen8((const char *) stra);
str = xnew(CHAR16, len + 2);
str[0] = '\\';
@@ -367,18 +359,6 @@ CHAR16 *xstra_to_path(const CHAR8 *stra) {
return str;
}
CHAR8 *strchra(const CHAR8 *s, CHAR8 c) {
if (!s)
return NULL;
do {
if (*s == c)
return (CHAR8*) s;
} while (*s++);
return NULL;
}
EFI_STATUS file_read(EFI_FILE *dir, const CHAR16 *name, UINTN off, UINTN size, CHAR8 **ret, UINTN *ret_size) {
_cleanup_(file_closep) EFI_FILE *handle = NULL;
_cleanup_freepool_ CHAR8 *buf = NULL;
@@ -417,7 +397,7 @@ EFI_STATUS file_read(EFI_FILE *dir, const CHAR16 *name, UINTN off, UINTN size, C
return err;
/* Note that handle->Read() changes size to reflect the actually bytes read. */
ZeroMem(buf + size, extra);
memset(buf + size, 0, extra);
*ret = TAKE_PTR(buf);
if (ret_size)
@@ -572,60 +552,6 @@ EFI_STATUS readdir_harder(
return EFI_SUCCESS;
}
UINTN strnlena(const CHAR8 *p, UINTN maxlen) {
UINTN c;
if (!p)
return 0;
for (c = 0; c < maxlen; c++)
if (p[c] == 0)
break;
return c;
}
INTN strncasecmpa(const CHAR8 *a, const CHAR8 *b, UINTN maxlen) {
if (!a || !b)
return CMP(a, b);
while (maxlen > 0) {
CHAR8 ca = *a, cb = *b;
if (ca >= 'A' && ca <= 'Z')
ca += 'a' - 'A';
if (cb >= 'A' && cb <= 'Z')
cb += 'a' - 'A';
if (!ca || ca != cb)
return ca - cb;
a++;
b++;
maxlen--;
}
return 0;
}
CHAR8 *xstrndup8(const CHAR8 *p, UINTN sz) {
CHAR8 *n;
/* Following efilib's naming scheme this function would be called strndupa(), but we already have a
* function named like this in userspace, and it does something different there, hence to minimize
* confusion, let's pick a different name here */
assert(p || sz == 0);
sz = strnlena(p, sz);
n = xallocate_pool(sz + 1);
if (sz > 0)
CopyMem(n, p, sz);
n[sz] = 0;
return n;
}
BOOLEAN is_ascii(const CHAR16 *f) {
if (!f)
return FALSE;
+2 -12
View File
@@ -3,11 +3,10 @@
#include <efi.h>
#include <efilib.h>
#include <stddef.h>
#include "string-util-fundamental.h"
#define offsetof(type, member) __builtin_offsetof(type, member)
#define UINTN_MAX (~(UINTN)0)
#define INTN_MAX ((INTN)(UINTN_MAX>>1))
#ifndef UINT32_MAX
@@ -42,7 +41,6 @@ assert_cc(sizeof(int) == sizeof(UINT32));
#define xallocate_zero_pool(size) ASSERT_SE_PTR(AllocateZeroPool(size))
#define xreallocate_pool(p, old_size, new_size) ASSERT_SE_PTR(ReallocatePool((p), (old_size), (new_size)))
#define xpool_print(fmt, ...) ((CHAR16 *) ASSERT_SE_PTR(PoolPrint((fmt), ##__VA_ARGS__)))
#define xstrdup(str) ((CHAR16 *) ASSERT_SE_PTR(StrDuplicate(str)))
#define xnew(type, n) xnew_alloc(type, (n), xallocate_pool)
#define xnew0(type, n) xnew_alloc(type, (n), xallocate_zero_pool)
@@ -62,7 +60,6 @@ EFI_STATUS efivar_get_uint32_le(const EFI_GUID *vendor, const CHAR16 *name, UINT
EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const CHAR16 *name, UINT64 *ret);
EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const CHAR16 *name, BOOLEAN *ret);
CHAR8 *strchra(const CHAR8 *s, CHAR8 c);
CHAR16 *xstra_to_path(const CHAR8 *stra);
CHAR16 *xstra_to_str(const CHAR8 *stra);
@@ -114,20 +111,13 @@ EFI_STATUS log_oom(void);
void print_at(UINTN x, UINTN y, UINTN attr, const CHAR16 *str);
void clear_screen(UINTN attr);
typedef INTN (*compare_pointer_func_t)(const void *a, const void *b);
typedef int (*compare_pointer_func_t)(const void *a, const void *b);
void sort_pointer_array(void **array, UINTN n_members, compare_pointer_func_t compare);
EFI_STATUS get_file_info_harder(EFI_FILE *handle, EFI_FILE_INFO **ret, UINTN *ret_size);
EFI_STATUS readdir_harder(EFI_FILE *handle, EFI_FILE_INFO **buffer, UINTN *buffer_size);
UINTN strnlena(const CHAR8 *p, UINTN maxlen);
CHAR8 *xstrndup8(const CHAR8 *p, UINTN sz);
INTN strncasecmpa(const CHAR8 *a, const CHAR8 *b, UINTN maxlen);
static inline BOOLEAN strncaseeqa(const CHAR8 *a, const CHAR8 *b, UINTN maxlen) {
return strncasecmpa(a, b, maxlen) == 0;
}
BOOLEAN is_ascii(const CHAR16 *f);
CHAR16 **strv_free(CHAR16 **l);
+7 -7
View File
@@ -19,7 +19,7 @@ static EFI_DEVICE_PATH *path_chop(EFI_DEVICE_PATH *path, EFI_DEVICE_PATH *node)
UINTN len = (UINT8 *) node - (UINT8 *) path;
EFI_DEVICE_PATH *chopped = xallocate_pool(len + END_DEVICE_PATH_LENGTH);
CopyMem(chopped, path, len);
memcpy(chopped, path, len);
SetDevicePathEndNode((EFI_DEVICE_PATH *) ((UINT8 *) chopped + len));
return chopped;
@@ -35,7 +35,7 @@ static BOOLEAN verify_gpt(union GptHeaderBuffer *gpt_header_buffer, EFI_LBA lba_
h = &gpt_header_buffer->gpt_header;
/* Some superficial validation of the GPT header */
if (CompareMem(&h->Header.Signature, "EFI PART", sizeof(h->Header.Signature)) != 0)
if (memcmp(&h->Header.Signature, "EFI PART", sizeof(h->Header.Signature)) != 0)
return FALSE;
if (h->Header.HeaderSize < 92 || h->Header.HeaderSize > 512)
@@ -123,12 +123,12 @@ static EFI_STATUS try_gpt(
entry = (EFI_PARTITION_ENTRY*) ((UINT8*) entries + gpt.gpt_header.SizeOfPartitionEntry * i);
if (CompareMem(&entry->PartitionTypeGUID, XBOOTLDR_GUID, sizeof(entry->PartitionTypeGUID)) != 0)
if (memcmp(&entry->PartitionTypeGUID, XBOOTLDR_GUID, sizeof(entry->PartitionTypeGUID)) != 0)
continue;
/* Let's use memcpy(), in case the structs are not aligned (they really should be though) */
CopyMem(&start, &entry->StartingLBA, sizeof(start));
CopyMem(&end, &entry->EndingLBA, sizeof(end));
memcpy(&start, &entry->StartingLBA, sizeof(start));
memcpy(&end, &entry->EndingLBA, sizeof(end));
if (end < start) /* Bogus? */
continue;
@@ -138,7 +138,7 @@ static EFI_STATUS try_gpt(
ret_hd->PartitionSize = end - start + 1;
ret_hd->MBRType = MBR_TYPE_EFI_PARTITION_TABLE_HEADER;
ret_hd->SignatureType = SIGNATURE_TYPE_GUID;
CopyMem(ret_hd->Signature, &entry->UniquePartitionGUID, sizeof(ret_hd->Signature));
memcpy(ret_hd->Signature, &entry->UniquePartitionGUID, sizeof(ret_hd->Signature));
return EFI_SUCCESS;
}
@@ -227,7 +227,7 @@ static EFI_STATUS find_device(EFI_HANDLE *device, EFI_DEVICE_PATH **ret_device_p
/* Patch in the data we found */
EFI_DEVICE_PATH *xboot_path = ASSERT_SE_PTR(DuplicateDevicePath(partition_path));
CopyMem((UINT8 *) xboot_path + ((UINT8 *) part_node - (UINT8 *) partition_path), &hd, sizeof(hd));
memcpy((UINT8 *) xboot_path + ((UINT8 *) part_node - (UINT8 *) partition_path), &hd, sizeof(hd));
*ret_device_path = xboot_path;
return EFI_SUCCESS;
}
-1
View File
@@ -77,7 +77,6 @@
#define static_assert _Static_assert
#define assert_se(expr) ({ _likely_(expr) ? VOID_0 : efi_assert(#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__); })
#define memcpy(a, b, c) CopyMem((a), (b), (c))
#define free(a) FreePool(a)
#endif
+4 -2
View File
@@ -23,8 +23,10 @@
/* Written by Ulrich Drepper <drepper@redhat.com>, 2007. */
#ifndef SD_BOOT
#include <string.h>
#ifdef SD_BOOT
# include "efi-string.h"
#else
# include <string.h>
#endif
#include "macro-fundamental.h"
+11 -12
View File
@@ -2,31 +2,30 @@
#pragma once
#ifdef SD_BOOT
#include <efi.h>
#include <efilib.h>
# include <efi.h>
# include <efilib.h>
# include "efi-string.h"
#else
#include <string.h>
# include <string.h>
#endif
#include "macro-fundamental.h"
#ifdef SD_BOOT
#define strlen(a) StrLen((a))
#define strcmp(a, b) StrCmp((a), (b))
#define strncmp(a, b, n) StrnCmp((a), (b), (n))
#define strcasecmp(a, b) StriCmp((a), (b))
#define STR_C(str) (L ## str)
#define memcmp(a, b, n) CompareMem(a, b, n)
# define strlen strlen16
# define strcmp strcmp16
# define strncmp strncmp16
# define strcasecmp strcasecmp16
# define strncasecmp strncasecmp16
# define STR_C(str) (L ## str)
#else
#define STR_C(str) (str)
# define STR_C(str) (str)
#endif
#define streq(a,b) (strcmp((a),(b)) == 0)
#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
#define strcaseeq(a,b) (strcasecmp((a),(b)) == 0)
#ifndef SD_BOOT
#define strncaseeq(a, b, n) (strncasecmp((a), (b), (n)) == 0)
#endif
static inline sd_int strcmp_ptr(const sd_char *a, const sd_char *b) {
if (a && b)