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

Aaron Durbin (adurbin@chromium.org) gerrit at coreboot.org
Mon Sep 14 02:28:17 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 662fa13f8f8b48bfb3c6d038692dd0d646be4f6a
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. 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 | 93 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/lib/cbfs.c           | 51 +++++++++++++++++---------
 2 files changed, 127 insertions(+), 17 deletions(-)

diff --git a/src/include/bytestream.h b/src/include/bytestream.h
new file mode 100644
index 0000000..badc5a5
--- /dev/null
+++ b/src/include/bytestream.h
@@ -0,0 +1,93 @@
+/*
+ * 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>
+
+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;
+	val = read_be8(src, offset);
+	val <<= 8;
+	val |= read_be8(src, offset + sizeof(uint8_t));
+	return val;
+}
+
+static inline uint32_t read_be32(const void *src, size_t offset)
+{
+	uint32_t val;
+	val = read_be16(src, offset);
+	val <<= 16;
+	val |= read_be16(src, offset + sizeof(uint16_t));
+	return val;
+}
+
+static inline uint64_t read_be64(const void *src, size_t offset)
+{
+	uint64_t val;
+	val = read_be32(src, offset);
+	val <<= 32;
+	val |= read_be32(src, offset + sizeof(uint32_t));
+	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;
+	val = read_le8(src, offset + sizeof(uint8_t));
+	val <<= 8;
+	val |= read_le8(src, offset);
+	return val;
+}
+
+static inline uint32_t read_le32(const void *src, size_t offset)
+{
+	uint32_t val;
+	val = read_le16(src, offset + sizeof(uint16_t));
+	val <<= 16;
+	val = read_le16(src, offset);
+	return val;
+}
+
+static inline uint64_t read_le64(const void *src, size_t offset)
+{
+	uint64_t val;
+	val = read_le32(src, offset + sizeof(uint32_t));
+	val <<= 32;
+	val |= read_le32(src, offset);
+	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