Hello, I'm not an expert in GRUB, but was trying to learn more. I took this chance to learn about this new feature a bit and just had a couple thoughts / questions. Otherwise, thank you!
> +char * > +grub_fdt_prop_to_string (const unsigned char *val, grub_uint32_t len) > +{ > + char *str; > + int pos, slen; > + grub_uint32_t i; > + > + if (prop_isstring (val, len)) > + { > + /* string */ > + return grub_strdup ((const char *)val); > + } > + else if (len & 0x3) > + { > + /* byte string */ > + grub_printf ("["); > + > + slen = (len * 3) + 2; Do you think a bounds check should be placed on 'len' before doing this calculation for 'slen' to ensure we do not exceed the storage capacity of an 'int' for 'slen'. Similar for later uses of 'pos'. Or perhaps, should a uint64_t be used for both 'slen'', 'pos', and 'i'? > + /* cell list */ > + const grub_uint32_t *cell = (const grub_uint32_t *)val; > + > + slen = (len * 11) + 2; Similar question here as above. Thanks, Andrew On Thu, Aug 8, 2024 at 10:39 AM Tobias Heider <tobias.hei...@canonical.com> wrote: > > Device tree properties are not explicitly typed but values can take > multiple forms from strings to arrays and byte-strings. > grub_fdt_prop_to_string() adds a heuristic to determine the type and > convert it to a string for printing. > > Signed-off-by: Tobias Heider <tobias.hei...@canonical.com> > --- > grub-core/lib/fdt.c | 87 ++++++++++++++++++++++++++++++++++++++ > grub-core/loader/efi/fdt.c | 15 +++++-- > include/grub/fdt.h | 3 ++ > 3 files changed, 101 insertions(+), 4 deletions(-) > > diff --git a/grub-core/lib/fdt.c b/grub-core/lib/fdt.c > index 73cfa94a2..5ec32ac56 100644 > --- a/grub-core/lib/fdt.c > +++ b/grub-core/lib/fdt.c > @@ -1,6 +1,7 @@ > /* > * GRUB -- GRand Unified Bootloader > * Copyright (C) 2013 Free Software Foundation, Inc. > + * Copyright (C) 2024 Canonical, Ltd. > * > * GRUB is free software: you can redistribute it and/or modify > * it under the terms of the GNU General Public License as published by > @@ -501,6 +502,92 @@ int grub_fdt_set_prop (void *fdt, unsigned int > nodeoffset, const char *name, > return 0; > } > > +static int > +prop_isstring (const unsigned char *str, grub_uint32_t len) > +{ > + grub_uint32_t i; > + int is_nonzero = 0; > + > + if (!len || str[len - 1]) > + return 0; > + > + for (i = 0; i < len; i++) > + { > + if (!str[i]) > + { > + if (!is_nonzero) > + return 0; > + > + is_nonzero = 0; > + continue; > + } > + if (!grub_isprint (str[i])) > + return 0; > + > + is_nonzero = 1; > + } > + return 1; > +} > + > +char * > +grub_fdt_prop_to_string (const unsigned char *val, grub_uint32_t len) > +{ > + char *str; > + int pos, slen; > + grub_uint32_t i; > + > + if (prop_isstring (val, len)) > + { > + /* string */ > + return grub_strdup ((const char *)val); > + } > + else if (len & 0x3) > + { > + /* byte string */ > + grub_printf ("["); > + > + slen = (len * 3) + 2; > + str = grub_malloc (slen); > + if (str == NULL) > + return NULL; > + > + pos = 0; > + str[pos++] = '['; > + for (i = 0; i < len; i++) > + { > + pos += grub_snprintf (&str[pos], slen - pos, "%02x", val[i]); > + if (i != len - 1) > + str[pos++] = ' '; > + } > + str[pos++] = ']'; > + str[pos] = '\0'; > + } > + else > + { > + /* cell list */ > + const grub_uint32_t *cell = (const grub_uint32_t *)val; > + > + slen = (len * 11) + 2; > + str = grub_malloc (slen); > + if (str == NULL) > + return NULL; > + > + pos = 0; > + str[pos++] = '<'; > + for (i = 0, len /= 4; i < len; i++) > + { > + pos += grub_snprintf (&str[pos], slen - pos, "0x%08x", > + grub_be_to_cpu32 (cell[i])); > + if (i != len - 1) > + str[pos++] = ' '; > + } > + str[pos++] = '>'; > + str[pos] = '\0'; > + } > + > + return str; > +} > + > int > grub_fdt_create_empty_tree (void *fdt, unsigned int size) > { > diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c > index e510b3491..b43ff730d 100644 > --- a/grub-core/loader/efi/fdt.c > +++ b/grub-core/loader/efi/fdt.c > @@ -183,8 +183,10 @@ grub_cmd_fdtdump (grub_extcmd_context_t ctxt, > char **argv __attribute__ ((unused))) > { > struct grub_arg_list *state = ctxt->state; > - const char *value = NULL; > + const unsigned char *value = NULL; > + char *str; > void *fw_fdt; > + grub_uint32_t len; > > fw_fdt = grub_efi_get_firmware_fdt (); > if (fw_fdt == NULL) > @@ -192,17 +194,22 @@ grub_cmd_fdtdump (grub_extcmd_context_t ctxt, > N_("No device tree found")); > > if (state[0].set) > - value = grub_fdt_get_prop (fw_fdt, 0, state[0].arg, NULL); > + value = grub_fdt_get_prop (fw_fdt, 0, state[0].arg, &len); > > if (value == NULL) > return grub_error (GRUB_ERR_OUT_OF_RANGE, > N_("failed to retrieve the prop field")); > > + str = grub_fdt_prop_to_string (value, len); > + if (str == NULL) > + return grub_error (GRUB_ERR_IO, N_("Failed to print string")); > + > if (state[1].set) > - grub_env_set (state[1].arg, value); > + grub_env_set (state[1].arg, str); > else > - grub_printf ("%s\n", value); > + grub_printf ("%s", str); > > + grub_free (str); > return GRUB_ERR_NONE; > } > > diff --git a/include/grub/fdt.h b/include/grub/fdt.h > index e609c7e41..4db644544 100644 > --- a/include/grub/fdt.h > +++ b/include/grub/fdt.h > @@ -118,6 +118,9 @@ EXPORT_FUNC(grub_fdt_get_nodename) (const void *fdt, > unsigned int nodeoffset); > const void *EXPORT_FUNC(grub_fdt_get_prop) (const void *fdt, unsigned int > nodeoffset, const char *name, > grub_uint32_t *len); > > +char *EXPORT_FUNC(grub_fdt_prop_to_string) (const unsigned char *val, > + grub_uint32_t len); > + > int EXPORT_FUNC(grub_fdt_set_prop) (void *fdt, unsigned int nodeoffset, > const char *name, > const void *val, grub_uint32_t len); > #define grub_fdt_set_prop32(fdt, nodeoffset, name, val) \ > -- > 2.43.0 > > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > https://lists.gnu.org/mailman/listinfo/grub-devel _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel