Implenent --fromfile to read variable values when printing variables

So

./efivar --fromfile Boot0001.bin --print --load-option

will take the value from Boot0001.bin file and then decode it as if it
were a load-option. This is useful for debugging handling of such
variables that may be hanging the boot for some people.

Sponsored by: Netflix, Inc
This commit is contained in:
Warner Losh 2018-10-26 22:13:40 +00:00
parent 9a815e0a58
commit e08bb1091c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=339797
2 changed files with 42 additions and 9 deletions

View File

@ -86,8 +86,17 @@ This flag implies
.Fl -write
unless the
.Fl -append
flag is given.
This behavior is not well understood and is currently unimplemented.
or
.Fl -print
flags are given.
This behavior is not well understood and is currently unimplemented
for writes.
When
.Fl -print
is specified, the contents of the file are used as the value to
print using any other specified flags.
This is used primarily for testing purposes for more complicated
variable decoding.
.It Fl a Fl -append
Append the specified value to the UEFI variable rather than replacing
it.

View File

@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
#include <efivar-dp.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <stddef.h>
#include <stdio.h>
@ -70,6 +71,7 @@ static struct option longopts[] = {
static int aflag, Aflag, bflag, dflag, Dflag, gflag, Hflag, Nflag,
lflag, Lflag, Rflag, wflag, pflag, uflag, load_opt_flag;
static char *varname;
static char *fromfile;
static u_long attrib = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
static void
@ -183,15 +185,31 @@ print_var(efi_guid_t *guid, char *name)
uint32_t att;
uint8_t *data;
size_t datalen;
char *gname;
char *gname = NULL;
int rv;
pretty_guid(guid, &gname);
if (pflag) {
rv = efi_get_variable(*guid, name, &data, &datalen, &att);
if (guid)
pretty_guid(guid, &gname);
if (pflag || fromfile) {
if (fromfile) {
int fd;
fd = open(fromfile, O_RDONLY);
if (fd < 0)
err(1, "open %s", fromfile);
data = malloc(64 * 1024);
if (data == NULL)
err(1, "malloc");
datalen = read(fd, data, 64 * 1024);
if (datalen <= 0)
err(1, "read");
close(fd);
} else {
rv = efi_get_variable(*guid, name, &data, &datalen, &att);
if (rv < 0)
err(1, "fetching %s-%s", gname, name);
}
if (rv < 0)
err(1, "%s-%s", gname, name);
if (!Nflag)
printf("%s-%s\n", gname, name);
@ -310,6 +328,9 @@ parse_args(int argc, char **argv)
wflag++;
break;
case 'f':
free(fromfile);
fromfile = strdup(optarg);
break;
case 0:
errx(1, "unknown or unimplemented option\n");
break;
@ -343,7 +364,10 @@ parse_args(int argc, char **argv)
write_variable(varname, NULL);
else if (Lflag)
print_known_guid();
else if (varname) {
else if (fromfile) {
Nflag = 1;
print_var(NULL, NULL);
} else if (varname) {
pflag++;
print_variable(varname);
} else if (argc > 0) {