[coreboot-gerrit] Patch set updated for coreboot: corebot: add bytestream helpfer functions

Aaron Durbin (adurbin@chromium.org) gerrit at coreboot.org
Mon Sep 14 03:31:06 CET 2015


Aaron Durbin (adurbin at chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11625

-gerrit

commit 99aea7f7870728362799e8898cb0597b40b5d525
Author: Aaron Durbin <adurbin at chromium.org>
Date:   Fri Sep 11 11:26:37 2015 -0500

    corebot: add bytestream helpfer functions
    
    Allow one to operate on a buffer to interpret values
    based on an endianness encoding. Endian functions are
    open coded and unrolled. The cbfs walking code was
    update to use the API. It requires one to open code
    the tracking field offset and sizes while also not
    providing any bounds checking.
    
    TEST=Built and booted on glados.
    
    Change-Id: I59a44704e9bff9bf11e779970ad4667e2e6b2bdd
    Signed-off-by: Aaron Durbin <adurbin at chromium.org>
---
 src/include/bytestream.h | 122 +++++++++++++++++++++++++++++++++++++++++++++++
 src/lib/cbfs.c           |  51 +++++++++++++-------
 2 files changed, 156 insertions(+), 17 deletions(-)

diff --git a/src/include/bytestream.h b/src/include/bytestream.h
new file mode 100644
index 0000000..2cbf579
--- /dev/null
+++ b/src/include/bytestream.h
@@ -0,0 +1,122 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.
+ */
+
+#ifndef _BYTESTREAM_H_
+#define _BYTESTREAM_H_
+
+#include <stdint.h>
+#include <stddef.h>
+
+static inline uint8_t read_be8(const void *src, size_t offset)
+{
+	const uint8_t *s = src;
+	s += offset;
+	return *s;
+}
+
+static inline uint16_t read_be16(const void *src, size_t offset)
+{
+	uint16_t val;
+	const uint8_t *s = src;
+	s += offset;
+	val = 0;
+	val |= ((uint16_t)s[0]) << 8;
+	val |= ((uint16_t)s[1]) << 0;
+	return val;
+}
+
+static inline uint32_t read_be32(const void *src, size_t offset)
+{
+	uint32_t val;
+	const uint8_t *s = src;
+	s += offset;
+	val = 0;
+	val |= ((uint32_t)s[0]) << 24;
+	val |= ((uint32_t)s[1]) << 16;
+	val |= ((uint32_t)s[2]) << 8;
+	val |= ((uint32_t)s[3]) << 0;
+	return val;
+}
+
+static inline uint64_t read_be64(const void *src, size_t offset)
+{
+	uint64_t val;
+	const uint8_t *s = src;
+	s += offset;
+	val = 0;
+	val |= ((uint64_t)s[0]) << (24 + 32);
+	val |= ((uint64_t)s[1]) << (16 + 32);
+	val |= ((uint64_t)s[2]) << (8 + 32);
+	val |= ((uint64_t)s[3]) << (0 + 32);
+	val |= ((uint64_t)s[4]) << 24;
+	val |= ((uint64_t)s[5]) << 16;
+	val |= ((uint64_t)s[6]) << 8;
+	val |= ((uint64_t)s[7]) << 0;
+	return val;
+}
+
+static inline uint8_t read_le8(const void *src, size_t offset)
+{
+	const uint8_t *s = src;
+	s += offset;
+	return *s;
+}
+
+static inline uint16_t read_le16(const void *src, size_t offset)
+{
+	uint16_t val;
+	const uint8_t *s = src;
+	s += offset;
+	val = 0;
+	val |= ((uint16_t)s[0]) << 0;
+	val |= ((uint16_t)s[1]) << 8;
+	return val;
+}
+
+static inline uint32_t read_le32(const void *src, size_t offset)
+{
+	uint32_t val;
+	const uint8_t *s = src;
+	s += offset;
+	val = 0;
+	val |= ((uint32_t)s[0]) << 0;
+	val |= ((uint32_t)s[1]) << 8;
+	val |= ((uint32_t)s[2]) << 16;
+	val |= ((uint32_t)s[3]) << 24;
+	return val;
+}
+
+static inline uint64_t read_le64(const void *src, size_t offset)
+{
+	uint64_t val;
+	const uint8_t *s = src;
+	s += offset;
+	val = 0;
+	val |= ((uint64_t)s[0]) << 0;
+	val |= ((uint64_t)s[1]) << 8;
+	val |= ((uint64_t)s[2]) << 16;
+	val |= ((uint64_t)s[3]) << 24;
+	val |= ((uint64_t)s[4]) << (0 + 32);
+	val |= ((uint64_t)s[5]) << (8 + 32);
+	val |= ((uint64_t)s[6]) << (16 + 32);
+	val |= ((uint64_t)s[7]) << (24 + 32);
+	return val;
+}
+
+#endif
diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c
index abc4077..83cd247 100644
--- a/src/lib/cbfs.c
+++ b/src/lib/cbfs.c
@@ -22,6 +22,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <boot_device.h>
+#include <bytestream.h>
 #include <cbfs.h>
 #include <endian.h>
 #include <lib.h>
@@ -90,30 +91,46 @@ int cbfs_locate(struct region_device *fh, const struct cbfsd *cbfs,
 
 	/* Try to scan the entire cbfs region looking for file name. */
 	while (1) {
-		struct cbfs_file file;
-		const size_t fsz = sizeof(file);
+		uint8_t magic[8];
+		uint32_t flen;
+		uint32_t ftype;
+		uint32_t foffset;
+		size_t strmoff;
+		const size_t fsz = sizeof(struct cbfs_file);
+		void *file_mapping;
 		char *fname;
 		int name_match;
 		size_t datasz;
 
 		DEBUG("Checking offset %zx\n", offset);
 
-		/* Can't read file. Nothing else to do but bail out. */
-		if (rdev_readat(rd, &file, offset, fsz) != fsz)
+		file_mapping = rdev_mmap(rd, offset, fsz);
+
+		if (file_mapping == NULL)
 			break;
 
-		if (memcmp(file.magic, CBFS_FILE_MAGIC, sizeof(file.magic))) {
+		/* Magic is a byte string w/ no endian encoding. */
+		memcpy(magic, file_mapping, sizeof(magic));
+		strmoff = sizeof(magic);
+
+		flen = read_be32(file_mapping, strmoff);
+		strmoff += sizeof(flen);
+		ftype = read_be32(file_mapping, strmoff);
+		strmoff += sizeof(ftype);
+		/* Skip the checksum field. */
+		strmoff += sizeof(ftype);
+		foffset = read_be32(file_mapping, strmoff);
+
+		rdev_munmap(rd, file_mapping);
+
+		if (memcmp(magic, CBFS_FILE_MAGIC, sizeof(magic))) {
 			offset++;
 			offset = ALIGN_UP(offset, CBFS_ALIGNMENT);
 			continue;
 		}
 
-		file.len = ntohl(file.len);
-		file.type = ntohl(file.type);
-		file.offset = ntohl(file.offset);
-
 		/* See if names match. */
-		fname = rdev_mmap(rd, offset + fsz, file.offset - fsz);
+		fname = rdev_mmap(rd, offset + fsz, foffset - fsz);
 
 		if (fname == NULL)
 			break;
@@ -123,23 +140,23 @@ int cbfs_locate(struct region_device *fh, const struct cbfsd *cbfs,
 
 		if (!name_match) {
 			DEBUG(" Unmatched '%s' at %zx\n", fname, offset);
-			offset += file.offset + file.len;
+			offset += foffset + flen;
 			offset = ALIGN_UP(offset, CBFS_ALIGNMENT);
 			continue;
 		}
 
-		if (type != NULL && *type != file.type) {
-			DEBUG(" Unmatched type %x at %zx\n", file.type, offset);
-			offset += file.offset + file.len;
+		if (type != NULL && *type != ftype) {
+			DEBUG(" Unmatched type %x at %zx\n", ftype, offset);
+			offset += foffset + flen;
 			offset = ALIGN_UP(offset, CBFS_ALIGNMENT);
 			continue;
 		}
 
-		LOG("Found @ offset %zx size %x\n", offset, file.len);
+		LOG("Found @ offset %zx size %x\n", offset, flen);
 		/* File and type match. Create a chained region_device to
 		 * represent the cbfs file. */
-		offset += file.offset;
-		datasz = file.len;
+		offset += foffset;
+		datasz = flen;
 		if (rdev_chain(fh, rd, offset, datasz))
 			break;
 



More information about the coreboot-gerrit mailing list