Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 25 Jun 2010 11:46:08 +0300
From:      Andriy Gapon <avg@freebsd.org>
To:        freebsd-hackers@freebsd.org
Cc:        "Bjoern A. Zeeb" <bz@freebsd.org>, Navdeep Parhar <np@freebsd.org>, Peter Wemm <peter@freebsd.org>
Subject:   elf obj load: skip zero-sized sections early
Message-ID:  <4C246CD0.3020606@freebsd.org>

next in thread | raw e-mail | index | archive | help

Proposed patch skips zero sized sections without going into trouble of
allocating section entry (progtab), doing zero-sized memory allocs and copies.
I observe that sometimes zero-sized set_pcpu sections are produced in module
objects, maybe when a module doesn't create any per cpu data of its one, but
references external pcpu data.  Not sure.

Main goal of this patch is to play nice with external debugging tools (e.g.
kgdb) which ignore zero-sized sections outright.  Current code effectively
ignores but may apply their alignment to the next non-zero section if its
required alignment is smaller.  So the patch should get rid of that side effect
as well as do some very tiny resource conservation.

This work is based on np@'s investigation and original patch:
http://lists.freebsd.org/pipermail/freebsd-hackers/2009-November/030093.html

diff --git a/sys/boot/common/load_elf_obj.c b/sys/boot/common/load_elf_obj.c
index 4b3aaea..6f3b349 100644
--- a/sys/boot/common/load_elf_obj.c
+++ b/sys/boot/common/load_elf_obj.c
@@ -221,6 +221,8 @@ __elfN(obj_loadimage)(struct preloaded_file *fp, elf_file_t
ef, u_int64_t off)
 	for (i = 0; i < hdr->e_shnum; i++)
 		shdr[i].sh_addr = 0;
 	for (i = 0; i < hdr->e_shnum; i++) {
+		if (shdr[i].sh_size == 0)
+			continue;
 		switch (shdr[i].sh_type) {
 		case SHT_PROGBITS:
 		case SHT_NOBITS:
diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c
index a337fd0..b0df57d 100644
--- a/sys/kern/link_elf_obj.c
+++ b/sys/kern/link_elf_obj.c
@@ -555,6 +555,8 @@ link_elf_load_file(linker_class_t cls, const char *filename,
 	symtabindex = -1;
 	symstrindex = -1;
 	for (i = 0; i < hdr->e_shnum; i++) {
+		if (shdr[i].sh_size == 0)
+			continue;
 		switch (shdr[i].sh_type) {
 		case SHT_PROGBITS:
 		case SHT_NOBITS:
@@ -677,6 +679,8 @@ link_elf_load_file(linker_class_t cls, const char *filename,
 	/* Size up code/data(progbits) and bss(nobits). */
 	alignmask = 0;
 	for (i = 0; i < hdr->e_shnum; i++) {
+		if (shdr[i].sh_size == 0)
+			continue;
 		switch (shdr[i].sh_type) {
 		case SHT_PROGBITS:
 		case SHT_NOBITS:
@@ -737,6 +741,8 @@ link_elf_load_file(linker_class_t cls, const char *filename,
 	ra = 0;
 	alignmask = 0;
 	for (i = 0; i < hdr->e_shnum; i++) {
+		if (shdr[i].sh_size == 0)
+			continue;
 		switch (shdr[i].sh_type) {
 		case SHT_PROGBITS:
 		case SHT_NOBITS:

-- 
Andriy Gapon



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4C246CD0.3020606>