<commit_before>/*
 * Simple UEFI boot loader which executes configured EFI images, where the
 * default entry is selected by a configured pattern (glob) or an on-screen
 * menu.
 *
 * All gummiboot code is LGPL not GPL, to stay out of politics and to give
 * the freedom of copying code from programs to possible future libraries.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * Copyright (C) 2012 <NAME> <<EMAIL>>
 * Copyright (C) 2012 <NAME> <<EMAIL>>
 *
 * "Any intelligent fool can make things bigger, more complex, and more violent."
 *   -- <NAME>
 */

#include "efi.h"
#include "efilib.h"

/*
 * Allocated random UUID, intended to be shared across tools that implement
 * the (ESP)\loader\entries\<vendor>-<revision>.conf convention and the
 * associated EFI variables.
 */
static const EFI_GUID loader_guid = { 0x4a67b082, 0x0a4c, 0x41cf, {0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f} };

enum loader_type {
        LOADER_UNDEFINED,
        LOADER_EFI,
        LOADER_LINUX
};

typedef struct {
        CHAR16 *file;
        CHAR16 *title_show;
        CHAR16 *title;
        CHAR16 *title_version;
        CHAR16 *title_machine;
        EFI_HANDLE *device;
        enum loader_type type;
        CHAR16 *loader;
        CHAR16 *options;
        BOOLEAN no_autoselect;
        BOOLEAN non_unique;
} ConfigEntry;

typedef struct {
        ConfigEntry **entries;
        UINTN entry_count;
        UINTN idx_default;
        INTN idx_default_efivar;
        UINTN timeout_sec;
        UINTN timeout_sec_config;
        INTN timeout_sec_efivar;
        CHAR16 *entry_default_pattern;
        CHAR16 *options_edit;
} Config;

#ifdef __x86_64__
static UINT64 ticks_read() {
        UINT64 a, d;
        __asm__ volatile ("rdtsc" : "=a" (a), "=d" (d));
        return (d << 32) | a;
}
#else
static UINT64 ticks_read() { return 0; }
#endif

static EFI_STATUS efivar_set(CHAR16 *name, CHAR16 *value, BOOLEAN persistent) {
        UINT32 flags;

        flags = EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS;
        if (persistent)
                flags |= EFI_VARIABLE_NON_VOLATILE;

        return uefi_call_wrapper(RT->SetVariable, 5, name, &loader_guid, flags,
                                 value ? (StrLen(value)+1) * sizeof(CHAR16) : 0, value);
}

static EFI_STATUS efivar_get(CHAR16 *name, CHAR16 **value) {
        CHAR16 *val;
        UINTN size;
        EFI_STATUS err;

        size = sizeof(CHAR16 *) * EFI_MAXIMUM_VARIABLE_SIZE;
        val = AllocatePool(size);
        if (!val)
                return EFI_OUT_OF_RESOURCES;

        err = uefi_call_wrapper(RT->GetVariable, 5, name, &loader_guid, NULL, &size, val);
        if (EFI_ERROR(err) == 0)
                *value = val;
        else
                FreePool(val);
        return err;

}

static EFI_STATUS efivar_set_int(CHAR16 *name, INTN i, BOOLEAN persistent) {
        CHAR16 str[32];

        SPrint(str, 32, L"%d", i);
        return efivar_set(name, str, persistent);
}

static EFI_STATUS efivar_get_int(CHAR16 *name, INTN *i) {
        CHAR16 *val;
        EFI_STATUS err;

        err = efivar_get(name, &val);
        if (EFI_ERROR(err) == 0) {
                *i = Atoi(val);
                FreePool(val);
        }
        return err;
}

static VOID efivar_set_ticks(CHAR16 *name, UINT64 ticks) {
        CHAR16 str[32];

        if (ticks == 0)
                ticks = ticks_read();
        if (ticks == 0)
                return;

        SPrint(str, 32, L"%ld", ticks ? ticks : ticks_read());<commit_msg>standardize error checks<commit_after>/*
 * Simple UEFI boot loader which executes configured EFI images, where the
 * default entry is selected by a configured pattern (glob) or an on-screen
 * menu.
 *
 * All gummiboot code is LGPL not GPL, to stay out of politics and to give
 * the freedom of copying code from programs to possible future libraries.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * Copyright (C) 2012 <NAME> <<EMAIL>>
 * Copyright (C) 2012 <NAME> <<EMAIL>>
 *
 * "Any intelligent fool can make things bigger, more complex, and more violent."
 *   -- <NAME>
 */

#include "efi.h"
#include "efilib.h"

/*
 * Allocated random UUID, intended to be shared across tools that implement
 * the (ESP)\loader\entries\<vendor>-<revision>.conf convention and the
 * associated EFI variables.
 */
static const EFI_GUID loader_guid = { 0x4a67b082, 0x0a4c, 0x41cf, {0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f} };

enum loader_type {
        LOADER_UNDEFINED,
        LOADER_EFI,
        LOADER_LINUX
};

typedef struct {
        CHAR16 *file;
        CHAR16 *title_show;
        CHAR16 *title;
        CHAR16 *title_version;
        CHAR16 *title_machine;
        EFI_HANDLE *device;
        enum loader_type type;
        CHAR16 *loader;
        CHAR16 *options;
        BOOLEAN no_autoselect;
        BOOLEAN non_unique;
} ConfigEntry;

typedef struct {
        ConfigEntry **entries;
        UINTN entry_count;
        UINTN idx_default;
        INTN idx_default_efivar;
        UINTN timeout_sec;
        UINTN timeout_sec_config;
        INTN timeout_sec_efivar;
        CHAR16 *entry_default_pattern;
        CHAR16 *options_edit;
} Config;

#ifdef __x86_64__
static UINT64 ticks_read() {
        UINT64 a, d;
        __asm__ volatile ("rdtsc" : "=a" (a), "=d" (d));
        return (d << 32) | a;
}
#else
static UINT64 ticks_read() { return 0; }
#endif

static EFI_STATUS efivar_set(CHAR16 *name, CHAR16 *value, BOOLEAN persistent) {
        UINT32 flags;

        flags = EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS;
        if (persistent)
                flags |= EFI_VARIABLE_NON_VOLATILE;

        return uefi_call_wrapper(RT->SetVariable, 5, name, &loader_guid, flags,
                                 value ? (StrLen(value)+1) * sizeof(CHAR16) : 0, value);
}

static EFI_STATUS efivar_get(CHAR16 *name, CHAR16 **value) {
        CHAR16 *val;
        UINTN size;
        EFI_STATUS err;

        size = sizeof(CHAR16 *) * EFI_MAXIMUM_VARIABLE_SIZE;
        val = AllocatePool(size);
        if (!val)
                return EFI_OUT_OF_RESOURCES;

        err = uefi_call_wrapper(RT->GetVariable, 5, name, &loader_guid, NULL, &size, val);
        if (EFI_ERROR(err) == EFI_SUCCESS)
                *value = val;
        else
                FreePool(val);
        return err;

}

static EFI_STATUS efivar_set_int(CHAR16 *name, INTN i, BOOLEAN persistent) {
        CHAR16 str[32];

        SPrint(str, 32, L"%d", i);
        return efivar_set(name, str, persistent);
}

static EFI_STATUS efivar_get_int(CHAR16 *name, INTN *i) {
        CHAR16 *val;
        EFI_STATUS err;

        err = efivar_get(name, &val);
        if (EFI_ERROR(err) == EFI_SUCCESS) {
                *i = Atoi(val);
                FreePool(val);
        }
        return err;
}

static VOID efivar_set_ticks(CHAR16 *name, UINT64 ticks) {
        CHAR16 str[32];

        if (ticks == 0)
                ticks = ticks_read();
        if (ticks == 0)
                return;

        SPrint(str, 32, L"%ld", ticks ? ticks : ticks_read());
{'fraction_non_alphanumeric': 0.09482220835932627, 'fraction_numerical': 0.02894572676232065, 'mean_word_length': 2.535950595500662, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2424588', 'n_tokens_mistral': 2814, 'n_tokens_neox': 2573, 'n_words': 797}