[CRIU] [PATCH 14/16] pie: piegen -- Only copy required sections

Cyrill Gorcunov gorcunov at openvz.org
Thu Jun 4 14:04:15 PDT 2015


From: Laurent Dufour <ldufour at linux.vnet.ibm.com>

When building the blob in the generated header file, we may
shrink the output blobk and only copy the sections with the SHF_ALLOC
bit set, the other ones are not needed at runtime.

Signed-off-by: Laurent Dufour <ldufour at linux.vnet.ibm.com>
Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 pie/piegen/elf.c | 42 ++++++++++++++++++++++++++++++------------
 1 file changed, 30 insertions(+), 12 deletions(-)

diff --git a/pie/piegen/elf.c b/pie/piegen/elf.c
index 33ca3e12eb54..3c93b2ce951c 100644
--- a/pie/piegen/elf.c
+++ b/pie/piegen/elf.c
@@ -191,7 +191,7 @@ int handle_elf(const piegen_opt_t *opts, void *mem, size_t size)
 #endif
 					pr_out("#define %s%s 0x%lx\n",
 					       opts->prefix_name, name,
-					       (unsigned long)(sym->st_value + sh_src->sh_offset));
+					       (unsigned long)(sym->st_value + sh_src->sh_addr));
 			}
 		}
 	}
@@ -244,7 +244,7 @@ int handle_elf(const piegen_opt_t *opts, void *mem, size_t size)
 				 (unsigned long)r->rel.r_offset, (unsigned long)r->rel.r_info,
 				 (unsigned long)ELF_R_SYM(r->rel.r_info),
 				 (unsigned long)ELF_R_TYPE(r->rel.r_info),
-				 (unsigned long)sh_src->sh_offset);
+				 (unsigned long)sh_rel->sh_addr);
 
 			if (sym->st_shndx == SHN_UNDEF) {
 #ifdef ELF_PPC64
@@ -263,7 +263,6 @@ int handle_elf(const piegen_opt_t *opts, void *mem, size_t size)
 #endif
 			}
 
-			ptr_func_exit((mem + sh_rel->sh_offset + r->rel.r_offset));
 			if (sh->sh_type == SHT_REL) {
 				addend32 = *(s32 *)where;
 				addend64 = *(s64 *)where;
@@ -272,13 +271,13 @@ int handle_elf(const piegen_opt_t *opts, void *mem, size_t size)
 				addend64 = (s64)r->rela.r_addend;
 			}
 
-			place = where - mem;
+			place = sh_rel->sh_addr + r->rel.r_offset;
 
 			pr_debug("\t\t\tvalue 0x%-8lx addend32 %-4d addend64 %-8ld symname %s\n",
 				 (unsigned long)sym->st_value, addend32, (long)addend64, name);
 
-			value32 = (s32)sh_src->sh_offset + (s32)sym->st_value;
-			value64 = (s64)sh_src->sh_offset + (s64)sym->st_value;
+			value32 = (s32)sh_src->sh_addr + (s32)sym->st_value;
+			value64 = (s64)sh_src->sh_addr + (s64)sym->st_value;
 
 #ifdef ELF_PPC64
 /* Snippet from the OpenPOWER ABI for Linux Supplement:
@@ -461,13 +460,32 @@ int handle_elf(const piegen_opt_t *opts, void *mem, size_t size)
 	pr_out("static __maybe_unused size_t %s = %zd;\n", opts->nrgotpcrel_name, nr_gotpcrel);
 
 	pr_out("static __maybe_unused const char %s[] = {\n\t", opts->stream_name);
-	for (i = 0; i < ALIGN(size, 8); i++) {
-		if (i && (i % 8) == 0)
-			pr_out("\n\t");
-		if (i < size)
-			pr_out("0x%02x,", ((unsigned char *)mem)[i]);
-		else
+
+	for (i=0, k=0; i < hdr->e_shnum; i++) {
+		size_t j;
+		Shdr_t *sh = mem + hdr->e_shoff + hdr->e_shentsize * i;
+		unsigned char *shdata = mem + sh->sh_offset;
+
+		if (!(sh->sh_flags & SHF_ALLOC) || !sh->sh_size)
+			continue;
+
+		pr_debug("Copying section '%s'\n" \
+			 "\tstart:0x%lx (gap:0x%lx) size:0x%lx\n",
+			 &secstrings[sh->sh_name], (unsigned long) sh->sh_addr,
+			 (unsigned long)(sh->sh_addr - k), sh->sh_size);
+
+		/* write 0 in the gap between the 2 sections */
+		for (;k < sh->sh_addr; k++) {
+			if (k && (k % 8) == 0)
+				pr_out("\n\t");
 			pr_out("0x00,");
+		}
+
+		for (j=0; j < sh->sh_size; j++, k++) {
+			if (k && (k % 8) == 0)
+				pr_out("\n\t");
+			pr_out("0x%02x,", shdata[j]);
+		}
 	}
 	pr_out("};\n");
 
-- 
2.4.2



More information about the CRIU mailing list