[coreboot-gerrit] New patch to review for coreboot: 05635ca cbfstool: Add option to ignore section in add-stage

Furquan Shaikh (furquan@google.com) gerrit at coreboot.org
Fri Oct 31 21:38:40 CET 2014


Furquan Shaikh (furquan at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7304

-gerrit

commit 05635ca4b0cc47375a925aec98fe244ef02d7719
Author: Furquan Shaikh <furquan at google.com>
Date:   Thu Oct 30 11:44:20 2014 -0700

    cbfstool: Add option to ignore section in add-stage
    
    Allow add-stage to have an optional parameter for ignoring any section. This is
    required to ensure proper operation of elf_to_stage in case of loadable segments
    with zero filesize.
    
    Change-Id: I49ad62c2a4260ab9cec173c80c0f16923fc66c79
    Signed-off-by: Furquan Shaikh <furquan at google.com>
---
 util/cbfstool/cbfs-mkstage.c | 77 +++++++++++++++++++++++++++++++++++++++++++-
 util/cbfstool/cbfstool.c     | 12 +++++--
 util/cbfstool/common.h       |  3 +-
 3 files changed, 87 insertions(+), 5 deletions(-)

diff --git a/util/cbfstool/cbfs-mkstage.c b/util/cbfstool/cbfs-mkstage.c
index 3da0836..8459334 100644
--- a/util/cbfstool/cbfs-mkstage.c
+++ b/util/cbfstool/cbfs-mkstage.c
@@ -28,16 +28,79 @@
 #include "common.h"
 #include "cbfs.h"
 
+/* Checks if program segment contains the ignored section */
+static int is_phdr_ignored(Elf64_Phdr *phdr, Elf64_Shdr *shdr)
+{
+	/* If no ignored section, return false. */
+	if (shdr == NULL)
+		return 0;
+
+	Elf64_Addr sh_start = shdr->sh_addr;
+	Elf64_Addr sh_end = shdr->sh_addr + shdr->sh_size;
+	Elf64_Addr ph_start = phdr->p_vaddr;
+	Elf64_Addr ph_end = phdr->p_vaddr + phdr->p_memsz;
+
+	/* Return true only if section occupies whole of segment. */
+	if ((sh_start == ph_start) && (sh_end == ph_end)) {
+		DEBUG("Ignoring program segment at %p\n", (void *)ph_start);
+		return 1;
+	}
+
+	/* If shdr intersects phdr at all, its a conflict */
+	if (((sh_start >= ph_start) && (sh_start <= ph_end)) ||
+	    ((sh_end >= ph_start) && (sh_end <= ph_end))) {
+		ERROR("Conflicting sections in segment\n");
+		exit(1);
+	}
+
+	/* Program header doesn't need to be ignored. */
+	return 0;
+}
+
+/* Find section header based on ignored section name */
+static Elf64_Shdr *find_ignored_section_header(struct parsed_elf *pelf,
+					       const char *ignore_section)
+{
+	int i;
+	const char *shstrtab;
+
+	/* No section needs to be ignored */
+	if (ignore_section == NULL)
+		return NULL;
+
+	DEBUG("Section to be ignored: %s\n", ignore_section);
+
+	/* Get pointer to string table */
+	shstrtab = buffer_get(pelf->strtabs[pelf->ehdr.e_shstrndx]);
+
+	for (i = 0; i < pelf->ehdr.e_shnum; i++) {
+		Elf64_Shdr *shdr;
+		const char *section_name;
+
+		shdr = &pelf->shdr[i];
+		section_name = &shstrtab[shdr->sh_name];
+
+		/* If section name matches ignored string, return shdr */
+		if (strcmp(section_name, ignore_section) == 0)
+			return shdr;
+	}
+
+	/* No section matches ignore string */
+	return NULL;
+}
+
 /* returns size of result, or -1 if error.
  * Note that, with the new code, this function
  * works for all elf files, not just the restricted set.
  */
 int parse_elf_to_stage(const struct buffer *input, struct buffer *output,
-		       uint32_t arch, comp_algo algo, uint32_t *location)
+		       uint32_t arch, comp_algo algo, uint32_t *location,
+		       const char *ignore_section)
 {
 	struct parsed_elf pelf;
 	Elf64_Phdr *phdr;
 	Elf64_Ehdr *ehdr;
+	Elf64_Shdr *shdr_ignored;
 	char *buffer;
 	struct buffer outheader;
 	int ret = -1;
@@ -62,8 +125,20 @@ int parse_elf_to_stage(const struct buffer *input, struct buffer *output,
 	ehdr = &pelf.ehdr;
 	phdr = &pelf.phdr[0];
 
+	/* Find the section header corresponding to ignored-section */
+	shdr_ignored = find_ignored_section_header(&pelf, ignore_section);
+
+	if (ignore_section && (shdr_ignored == NULL))
+		WARN("Ignore section not found\n");
+
 	headers = ehdr->e_phnum;
 
+	/* Ignore the program header containing ignored section */
+	for (i = 0; i < headers; i++) {
+		if (is_phdr_ignored(&phdr[i], shdr_ignored))
+			phdr[i].p_type = PT_NULL;
+	}
+
 	data_start = ~0;
 	data_end = 0;
 	mem_end = 0;
diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c
index ca02ca6..66c425b 100644
--- a/util/cbfstool/cbfstool.c
+++ b/util/cbfstool/cbfstool.c
@@ -41,6 +41,7 @@ static struct param {
 	char *name;
 	char *filename;
 	char *bootblock;
+	char *ignore_section;
 	uint64_t u64val;
 	uint32_t type;
 	uint32_t baseaddress;
@@ -184,7 +185,7 @@ static int cbfstool_convert_mkstage(struct buffer *buffer, uint32_t *offset)
 	struct buffer output;
 	int ret;
 	ret = parse_elf_to_stage(buffer, &output, param.arch, param.algo,
-				 offset);
+				 offset, param.ignore_section);
 	if (ret != 0)
 		return -1;
 	buffer_delete(buffer);
@@ -516,7 +517,7 @@ static int cbfs_update_fit(void)
 static const struct command commands[] = {
 	{"add", "f:n:t:b:vh?", cbfs_add},
 	{"add-payload", "f:n:t:c:b:vh?C:I:", cbfs_add_payload},
-	{"add-stage", "f:n:t:c:b:vh?", cbfs_add_stage},
+	{"add-stage", "f:n:t:c:b:S:vh?", cbfs_add_stage},
 	{"add-flat-binary", "f:n:l:e:c:b:vh?", cbfs_add_flat_binary},
 	{"add-int", "i:n:b:vh?", cbfs_add_integer},
 	{"remove", "n:vh?", cbfs_remove},
@@ -546,6 +547,7 @@ static struct option long_options[] = {
 	{"empty-fits",   required_argument, 0, 'x' },
 	{"initrd",       required_argument, 0, 'I' },
 	{"cmdline",      required_argument, 0, 'C' },
+	{"ignore-sec",   required_argument, 0, 'S' },
 	{"verbose",      no_argument,       0, 'v' },
 	{"help",         no_argument,       0, 'h' },
 	{NULL,           0,                 0,  0  }
@@ -566,7 +568,8 @@ static void usage(char *name)
 	     " add-payload -f FILE -n NAME [-c compression] [-b base]      "
 			"Add a payload to the ROM\n"
 	     "        (linux specific: [-C cmdline] [-I initrd])\n"
-	     " add-stage -f FILE -n NAME [-c compression] [-b base]        "
+	     " add-stage -f FILE -n NAME [-c compression] [-b base] \\\n"
+	     "        [-S section-to-ignore]                               "
 			"Add a stage to the ROM\n"
 	     " add-flat-binary -f FILE -n NAME -l load-address \\\n"
 	     "        -e entry-point [-c compression] [-b base]            "
@@ -714,6 +717,9 @@ int main(int argc, char **argv)
 			case 'C':
 				param.cmdline = optarg;
 				break;
+			case 'S':
+				param.ignore_section = optarg;
+				break;
 			case 'h':
 			case '?':
 				usage(argv[0]);
diff --git a/util/cbfstool/common.h b/util/cbfstool/common.h
index 02a088b..41659a2 100644
--- a/util/cbfstool/common.h
+++ b/util/cbfstool/common.h
@@ -139,7 +139,8 @@ int parse_flat_binary_to_payload(const struct buffer *input,
 				 comp_algo algo);
 /* cbfs-mkstage.c */
 int parse_elf_to_stage(const struct buffer *input, struct buffer *output,
-		       uint32_t arch, comp_algo algo, uint32_t *location);
+		       uint32_t arch, comp_algo algo, uint32_t *location,
+		       const char *ignore_section);
 
 void print_supported_filetypes(void);
 



More information about the coreboot-gerrit mailing list