[coreboot-gerrit] Patch set updated for coreboot: cbfstool: merge consecutive elf sections in program segments

Aaron Durbin (adurbin@chromium.org) gerrit at coreboot.org
Wed Oct 28 18:57:56 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/12220

-gerrit

commit cdbbb29071d4aa7a79c2a8d9f676360b67f067b6
Author: Aaron Durbin <adurbin at chromium.org>
Date:   Wed Oct 28 10:09:07 2015 -0500

    cbfstool: merge consecutive elf sections in program segments
    
    Instead of creating a loadable segment for each section with
    SHF_ALLOC flag merge those sections into a single program
    segment. This makes  more tidy readelf, but it also allows
    one to extract an rmodule into an ELF and turn it back into
    an rmodule.
    
    TEST=Extracted both regular stages and rmodule stages. Compared
         against original ELF files prior to cbfs insert.
    
    Change-Id: I0a600d2e9db5ee6c11278d8ad673caab1af6c759
    Signed-off-by: Aaron Durbin <adurbin at chromium.org>
---
 util/cbfstool/elfheaders.c | 95 +++++++++++++++++++++++++++++++++++++---------
 1 file changed, 78 insertions(+), 17 deletions(-)

diff --git a/util/cbfstool/elfheaders.c b/util/cbfstool/elfheaders.c
index da11bfc..262137d 100644
--- a/util/cbfstool/elfheaders.c
+++ b/util/cbfstool/elfheaders.c
@@ -841,6 +841,78 @@ phdr_write(struct elf_writer *ew, struct buffer *m, Elf64_Phdr *phdr)
 
 }
 
+static int section_consecutive(struct elf_writer *ew, Elf64_Half secidx)
+{
+	Elf64_Half i;
+	struct elf_writer_section *prev_alloc = NULL;
+
+	if (secidx == 0)
+		return 0;
+
+	for (i = 0; i < secidx; i++) {
+		if (ew->sections[i].shdr.sh_flags & SHF_ALLOC)
+			prev_alloc = &ew->sections[i];
+	}
+
+	if (prev_alloc == NULL)
+		return 0;
+
+	if (prev_alloc->shdr.sh_addr + prev_alloc->shdr.sh_size ==
+	    ew->sections[secidx].shdr.sh_addr)
+		return 1;
+
+	return 0;
+}
+
+static void write_phdrs(struct elf_writer *ew, struct buffer *phdrs)
+{
+	Elf64_Half i;
+	Elf64_Phdr phdr;
+	size_t num_written = 0;
+
+	for (i = 0; i < ew->num_secs; i++) {
+		struct elf_writer_section *sec = &ew->sections[i];
+
+		if (!(sec->shdr.sh_flags & SHF_ALLOC))
+			continue;
+
+		if (!section_consecutive(ew, i)) {
+			/* Write out previously set phdr. */
+			if (num_written != 0) {
+				phdr_write(ew, phdrs, &phdr);
+				num_written++;
+			}
+			phdr.p_type = PT_LOAD;
+			phdr.p_offset = sec->shdr.sh_offset;
+			phdr.p_vaddr = sec->shdr.sh_addr;
+			phdr.p_paddr = sec->shdr.sh_addr;
+			phdr.p_filesz = buffer_size(&sec->content);
+			phdr.p_memsz = sec->shdr.sh_size;
+			phdr.p_flags = 0;
+			if (sec->shdr.sh_flags & SHF_EXECINSTR)
+				phdr.p_flags |= PF_X | PF_R;
+			if (sec->shdr.sh_flags & SHF_WRITE)
+				phdr.p_flags |= PF_W;
+			phdr.p_align = sec->shdr.sh_addralign;
+		} else {
+			/* Accumulate file size and memsize. The assumption
+			 * is that each section is either NOBITS or full
+			 * (sh_size == file size). This is standard in that
+			 * an ELF section doesn't have a file size component. */
+			if (sec->shdr.sh_flags & SHF_EXECINSTR)
+				phdr.p_flags |= PF_X | PF_R;
+			if (sec->shdr.sh_flags & SHF_WRITE)
+				phdr.p_flags |= PF_W;
+			phdr.p_filesz += buffer_size(&sec->content);
+			phdr.p_memsz += sec->shdr.sh_size;
+		}
+	}
+
+	/* Write out the last phdr. */
+	if (num_written != ew->ehdr.e_phnum)
+		phdr_write(ew, phdrs, &phdr);
+}
+
 /*
  * Serialize the ELF file to the output buffer. Return < 0 on error,
  * 0 on success.
@@ -866,8 +938,10 @@ int elf_writer_serialize(struct elf_writer *ew, struct buffer *out)
 	for (i = 0; i < ew->num_secs; i++) {
 		struct elf_writer_section *sec = &ew->sections[i];
 
-		if (sec->shdr.sh_flags & SHF_ALLOC)
-			ew->ehdr.e_phnum++;
+		if (sec->shdr.sh_flags & SHF_ALLOC) {
+			if (!section_consecutive(ew, i))
+				ew->ehdr.e_phnum++;
+		}
 
 		program_size += buffer_size(&sec->content);
 
@@ -924,7 +998,6 @@ int elf_writer_serialize(struct elf_writer *ew, struct buffer *out)
 	 * program headers. */
 	ew->xdr->put8(strtab, 0);
 	for (i = 0; i < ew->num_secs; i++) {
-		Elf64_Phdr phdr;
 		struct elf_writer_section *sec = &ew->sections[i];
 
 		/* Update section offsets. Be sure to not update SHT_NULL. */
@@ -944,21 +1017,9 @@ int elf_writer_serialize(struct elf_writer *ew, struct buffer *out)
 
 		bputs(&data, buffer_get(&sec->content),
 		      buffer_size(&sec->content));
-
-		phdr.p_type = PT_LOAD;
-		phdr.p_offset = sec->shdr.sh_offset;
-		phdr.p_vaddr = sec->shdr.sh_addr;
-		phdr.p_paddr = sec->shdr.sh_addr;
-		phdr.p_filesz = buffer_size(&sec->content);
-		phdr.p_memsz = sec->shdr.sh_size;
-		phdr.p_flags = 0;
-		if (sec->shdr.sh_flags & SHF_EXECINSTR)
-			phdr.p_flags |= PF_X | PF_R;
-		if (sec->shdr.sh_flags & SHF_WRITE)
-			phdr.p_flags |= PF_W;
-		phdr.p_align = sec->shdr.sh_addralign;
-		phdr_write(ew, &phdrs, &phdr);
 	}
 
+	write_phdrs(ew, &phdrs);
+
 	return 0;
 }



More information about the coreboot-gerrit mailing list