util/cbfstool/flashmap/fmap.c: fix fmaptool endianness bugs on BE
This patch makes all accesses to the FMAP fields explicitly little endian. It fixes issue where build on BE host produced different binary image than on LE. Signed-off-by: Marek Kasiewicz <marek.kasiewicz@3mdeb.com> Signed-off-by: Krystian Hebel <krystian.hebel@3mdeb.com> Change-Id: Ia88c0625cefa1e594ac1849271a71c3aacc8ce78 Reviewed-on: https://review.coreboot.org/c/coreboot/+/55039 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Julius Werner <jwerner@chromium.org>
This commit is contained in:
parent
a5cbe27148
commit
f1e401c6cb
|
@ -15,6 +15,7 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <commonlib/bsd/sysincludes.h>
|
||||||
|
|
||||||
#include "fmap.h"
|
#include "fmap.h"
|
||||||
#include "kv_pair.h"
|
#include "kv_pair.h"
|
||||||
|
@ -35,7 +36,7 @@ int fmap_size(const struct fmap *fmap)
|
||||||
if (!fmap)
|
if (!fmap)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return sizeof(*fmap) + (fmap->nareas * sizeof(struct fmap_area));
|
return sizeof(*fmap) + (le16toh(fmap->nareas) * sizeof(struct fmap_area));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make a best-effort assessment if the given fmap is real */
|
/* Make a best-effort assessment if the given fmap is real */
|
||||||
|
@ -47,8 +48,8 @@ static int is_valid_fmap(const struct fmap *fmap)
|
||||||
if (fmap->ver_major != FMAP_VER_MAJOR)
|
if (fmap->ver_major != FMAP_VER_MAJOR)
|
||||||
return 0;
|
return 0;
|
||||||
/* a basic consistency check: flash should be larger than fmap */
|
/* a basic consistency check: flash should be larger than fmap */
|
||||||
if (fmap->size <
|
if (le32toh(fmap->size) <
|
||||||
sizeof(*fmap) + fmap->nareas * sizeof(struct fmap_area))
|
sizeof(*fmap) + le16toh(fmap->nareas) * sizeof(struct fmap_area))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* fmap-alikes along binary data tend to fail on having a valid,
|
/* fmap-alikes along binary data tend to fail on having a valid,
|
||||||
|
@ -177,14 +178,14 @@ int fmap_print(const struct fmap *fmap)
|
||||||
kv_pair_fmt(kv, "fmap_ver_major", "%d", fmap->ver_major);
|
kv_pair_fmt(kv, "fmap_ver_major", "%d", fmap->ver_major);
|
||||||
kv_pair_fmt(kv, "fmap_ver_minor","%d", fmap->ver_minor);
|
kv_pair_fmt(kv, "fmap_ver_minor","%d", fmap->ver_minor);
|
||||||
kv_pair_fmt(kv, "fmap_base", "0x%016llx",
|
kv_pair_fmt(kv, "fmap_base", "0x%016llx",
|
||||||
(unsigned long long)fmap->base);
|
(unsigned long long)le64toh(fmap->base));
|
||||||
kv_pair_fmt(kv, "fmap_size", "0x%04x", fmap->size);
|
kv_pair_fmt(kv, "fmap_size", "0x%04x", le32toh(fmap->size));
|
||||||
kv_pair_fmt(kv, "fmap_name", "%s", fmap->name);
|
kv_pair_fmt(kv, "fmap_name", "%s", fmap->name);
|
||||||
kv_pair_fmt(kv, "fmap_nareas", "%d", fmap->nareas);
|
kv_pair_fmt(kv, "fmap_nareas", "%d", le16toh(fmap->nareas));
|
||||||
kv_pair_print(kv);
|
kv_pair_print(kv);
|
||||||
kv_pair_free(kv);
|
kv_pair_free(kv);
|
||||||
|
|
||||||
for (i = 0; i < fmap->nareas; i++) {
|
for (i = 0; i < le16toh(fmap->nareas); i++) {
|
||||||
struct kv_pair *pair;
|
struct kv_pair *pair;
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
char *str;
|
char *str;
|
||||||
|
@ -194,16 +195,16 @@ int fmap_print(const struct fmap *fmap)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
kv_pair_fmt(pair, "area_offset", "0x%08x",
|
kv_pair_fmt(pair, "area_offset", "0x%08x",
|
||||||
fmap->areas[i].offset);
|
le32toh(fmap->areas[i].offset));
|
||||||
kv_pair_fmt(pair, "area_size", "0x%08x",
|
kv_pair_fmt(pair, "area_size", "0x%08x",
|
||||||
fmap->areas[i].size);
|
le32toh(fmap->areas[i].size));
|
||||||
kv_pair_fmt(pair, "area_name", "%s",
|
kv_pair_fmt(pair, "area_name", "%s",
|
||||||
fmap->areas[i].name);
|
fmap->areas[i].name);
|
||||||
kv_pair_fmt(pair, "area_flags_raw", "0x%02x",
|
kv_pair_fmt(pair, "area_flags_raw", "0x%02x",
|
||||||
fmap->areas[i].flags);
|
le16toh(fmap->areas[i].flags));
|
||||||
|
|
||||||
/* Print descriptive strings for flags rather than the field */
|
/* Print descriptive strings for flags rather than the field */
|
||||||
flags = fmap->areas[i].flags;
|
flags = le16toh(fmap->areas[i].flags);
|
||||||
str = fmap_flags_to_string(flags);
|
str = fmap_flags_to_string(flags);
|
||||||
if (str == NULL) {
|
if (str == NULL) {
|
||||||
kv_pair_free(pair);
|
kv_pair_free(pair);
|
||||||
|
@ -265,8 +266,8 @@ struct fmap *fmap_create(uint64_t base, uint32_t size, uint8_t *name)
|
||||||
memcpy(&fmap->signature, FMAP_SIGNATURE, strlen(FMAP_SIGNATURE));
|
memcpy(&fmap->signature, FMAP_SIGNATURE, strlen(FMAP_SIGNATURE));
|
||||||
fmap->ver_major = FMAP_VER_MAJOR;
|
fmap->ver_major = FMAP_VER_MAJOR;
|
||||||
fmap->ver_minor = FMAP_VER_MINOR;
|
fmap->ver_minor = FMAP_VER_MINOR;
|
||||||
fmap->base = base;
|
fmap->base = htole64(base);
|
||||||
fmap->size = size;
|
fmap->size = htole32(size);
|
||||||
memccpy(&fmap->name, name, '\0', FMAP_STRLEN);
|
memccpy(&fmap->name, name, '\0', FMAP_STRLEN);
|
||||||
|
|
||||||
return fmap;
|
return fmap;
|
||||||
|
@ -289,7 +290,7 @@ int fmap_append_area(struct fmap **fmap,
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* too many areas */
|
/* too many areas */
|
||||||
if ((*fmap)->nareas >= 0xffff)
|
if (le16toh((*fmap)->nareas) >= 0xffff)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
orig_size = fmap_size(*fmap);
|
orig_size = fmap_size(*fmap);
|
||||||
|
@ -301,12 +302,12 @@ int fmap_append_area(struct fmap **fmap,
|
||||||
|
|
||||||
area = (struct fmap_area *)((uint8_t *)*fmap + orig_size);
|
area = (struct fmap_area *)((uint8_t *)*fmap + orig_size);
|
||||||
memset(area, 0, sizeof(*area));
|
memset(area, 0, sizeof(*area));
|
||||||
memcpy(&area->offset, &offset, sizeof(area->offset));
|
|
||||||
memcpy(&area->size, &size, sizeof(area->size));
|
|
||||||
memccpy(&area->name, name, '\0', FMAP_STRLEN);
|
memccpy(&area->name, name, '\0', FMAP_STRLEN);
|
||||||
memcpy(&area->flags, &flags, sizeof(area->flags));
|
area->offset = htole32(offset);
|
||||||
|
area->size = htole32(size);
|
||||||
|
area->flags = htole16(flags);
|
||||||
|
|
||||||
(*fmap)->nareas++;
|
(*fmap)->nareas = htole16(le16toh((*fmap)->nareas) + 1);
|
||||||
return new_size;
|
return new_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,7 +320,7 @@ const struct fmap_area *fmap_find_area(const struct fmap *fmap,
|
||||||
if (!fmap || !name)
|
if (!fmap || !name)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (i = 0; i < fmap->nareas; i++) {
|
for (i = 0; i < le16toh(fmap->nareas); i++) {
|
||||||
if (!strcmp((const char *)fmap->areas[i].name, name)) {
|
if (!strcmp((const char *)fmap->areas[i].name, name)) {
|
||||||
area = &fmap->areas[i];
|
area = &fmap->areas[i];
|
||||||
break;
|
break;
|
||||||
|
@ -358,12 +359,12 @@ static struct fmap *fmap_create_test(void)
|
||||||
goto fmap_create_test_exit;
|
goto fmap_create_test_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fmap->base != base) {
|
if (le64toh(fmap->base) != base) {
|
||||||
printf("FAILURE: base is incorrect\n");
|
printf("FAILURE: base is incorrect\n");
|
||||||
goto fmap_create_test_exit;
|
goto fmap_create_test_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fmap->size != 0x100000) {
|
if (le32toh(fmap->size) != 0x100000) {
|
||||||
printf("FAILURE: size is incorrect\n");
|
printf("FAILURE: size is incorrect\n");
|
||||||
goto fmap_create_test_exit;
|
goto fmap_create_test_exit;
|
||||||
}
|
}
|
||||||
|
@ -373,7 +374,7 @@ static struct fmap *fmap_create_test(void)
|
||||||
goto fmap_create_test_exit;
|
goto fmap_create_test_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fmap->nareas != 0) {
|
if (le16toh(fmap->nareas) != 0) {
|
||||||
printf("FAILURE: number of areas is incorrect\n");
|
printf("FAILURE: number of areas is incorrect\n");
|
||||||
goto fmap_create_test_exit;
|
goto fmap_create_test_exit;
|
||||||
}
|
}
|
||||||
|
@ -414,10 +415,10 @@ static int fmap_append_area_test(struct fmap **fmap)
|
||||||
uint16_t nareas_orig;
|
uint16_t nareas_orig;
|
||||||
/* test_area will be used by fmap_csum_test and find_area_test */
|
/* test_area will be used by fmap_csum_test and find_area_test */
|
||||||
struct fmap_area test_area = {
|
struct fmap_area test_area = {
|
||||||
.offset = 0x400,
|
.offset = htole32(0x400),
|
||||||
.size = 0x10000,
|
.size = htole32(0x10000),
|
||||||
.name = "test_area_1",
|
.name = "test_area_1",
|
||||||
.flags = FMAP_AREA_STATIC,
|
.flags = htole16(FMAP_AREA_STATIC),
|
||||||
};
|
};
|
||||||
|
|
||||||
status = fail;
|
status = fail;
|
||||||
|
@ -428,26 +429,26 @@ static int fmap_append_area_test(struct fmap **fmap)
|
||||||
goto fmap_append_area_test_exit;
|
goto fmap_append_area_test_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
nareas_orig = (*fmap)->nareas;
|
nareas_orig = le16toh((*fmap)->nareas);
|
||||||
(*fmap)->nareas = ~(0);
|
(*fmap)->nareas = htole16(~(0));
|
||||||
if (fmap_append_area(fmap, 0, 0, (const uint8_t *)"foo", 0) >= 0) {
|
if (fmap_append_area(fmap, 0, 0, (const uint8_t *)"foo", 0) >= 0) {
|
||||||
printf("FAILURE: failed to abort with too many areas\n");
|
printf("FAILURE: failed to abort with too many areas\n");
|
||||||
goto fmap_append_area_test_exit;
|
goto fmap_append_area_test_exit;
|
||||||
}
|
}
|
||||||
(*fmap)->nareas = nareas_orig;
|
(*fmap)->nareas = htole16(nareas_orig);
|
||||||
|
|
||||||
total_size = sizeof(**fmap) + sizeof(test_area);
|
total_size = sizeof(**fmap) + sizeof(test_area);
|
||||||
if (fmap_append_area(fmap,
|
if (fmap_append_area(fmap,
|
||||||
test_area.offset,
|
le32toh(test_area.offset),
|
||||||
test_area.size,
|
le32toh(test_area.size),
|
||||||
test_area.name,
|
test_area.name,
|
||||||
test_area.flags
|
le16toh(test_area.flags)
|
||||||
) != total_size) {
|
) != total_size) {
|
||||||
printf("failed to append area\n");
|
printf("failed to append area\n");
|
||||||
goto fmap_append_area_test_exit;
|
goto fmap_append_area_test_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*fmap)->nareas != 1) {
|
if (le16toh((*fmap)->nareas) != 1) {
|
||||||
printf("FAILURE: failed to increment number of areas\n");
|
printf("FAILURE: failed to increment number of areas\n");
|
||||||
goto fmap_append_area_test_exit;
|
goto fmap_append_area_test_exit;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ IFDTOOLCFLAGS = -O2 -g -Wall -Wextra -Wmissing-prototypes -Werror
|
||||||
IFDTOOLCFLAGS += -I$(top)/src/commonlib/include -I$(top)/src/commonlib/bsd/include
|
IFDTOOLCFLAGS += -I$(top)/src/commonlib/include -I$(top)/src/commonlib/bsd/include
|
||||||
IFDTOOLCFLAGS += -I$(top)/util/cbfstool/flashmap
|
IFDTOOLCFLAGS += -I$(top)/util/cbfstool/flashmap
|
||||||
IFDTOOLCFLAGS += -include $(top)/src/commonlib/bsd/include/commonlib/bsd/compiler.h
|
IFDTOOLCFLAGS += -include $(top)/src/commonlib/bsd/include/commonlib/bsd/compiler.h
|
||||||
|
IFDTOOLCFLAGS += -D_DEFAULT_SOURCE # for endianness converting functions
|
||||||
|
|
||||||
$(objutil)/ifdtool/%.o: $(top)/util/ifdtool/%.c
|
$(objutil)/ifdtool/%.o: $(top)/util/ifdtool/%.c
|
||||||
$(HOSTCC) $(IFDTOOLCFLAGS) $(HOSTCFLAGS) -c -o $@ $<
|
$(HOSTCC) $(IFDTOOLCFLAGS) $(HOSTCFLAGS) -c -o $@ $<
|
||||||
|
|
Loading…
Reference in New Issue