summaryrefslogtreecommitdiffstats
path: root/sys/boot
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2014-10-20 17:04:03 +0000
committermarcel <marcel@FreeBSD.org>2014-10-20 17:04:03 +0000
commitd2387926bad74ed69fd6276e007f3fe3177524e2 (patch)
tree3a50bd48ab8a770ba6e79126bc1edb6227bd78f8 /sys/boot
parentfbbd6ea1dce36d355ca0bd5788f5489b292fe9d3 (diff)
downloadFreeBSD-src-d2387926bad74ed69fd6276e007f3fe3177524e2.zip
FreeBSD-src-d2387926bad74ed69fd6276e007f3fe3177524e2.tar.gz
Fully support constructors for the purpose of code coverage analysis.
This involves: 1. Have the loader pass the start and size of the .ctors section to the kernel in 2 new metadata elements. 2. Have the linker backends look for and record the start and size of the .ctors section in dynamically loaded modules. 3. Have the linker backends call the constructors as part of the final work of initializing preloaded or dynamically loaded modules. Note that LLVM appends the priority of the constructors to the name of the .ctors section. Not so when compiling with GCC. The code currently works for GCC and not for LLVM. Submitted by: Dmitry Mikulin <dmitrym@juniper.net> Obtained from: Juniper Networks, Inc.
Diffstat (limited to 'sys/boot')
-rw-r--r--sys/boot/common/load_elf.c38
1 files changed, 34 insertions, 4 deletions
diff --git a/sys/boot/common/load_elf.c b/sys/boot/common/load_elf.c
index 8990d90..04a7dbe 100644
--- a/sys/boot/common/load_elf.c
+++ b/sys/boot/common/load_elf.c
@@ -240,6 +240,7 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off)
Elf_Ehdr *ehdr;
Elf_Phdr *phdr, *php;
Elf_Shdr *shdr;
+ char *shstr;
int ret;
vm_offset_t firstaddr;
vm_offset_t lastaddr;
@@ -248,6 +249,7 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off)
Elf_Addr ssym, esym;
Elf_Dyn *dp;
Elf_Addr adp;
+ Elf_Addr ctors;
int ndp;
int symstrindex;
int symtabindex;
@@ -383,10 +385,11 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off)
lastaddr = roundup(lastaddr, sizeof(long));
/*
- * Now grab the symbol tables. This isn't easy if we're reading a
- * .gz file. I think the rule is going to have to be that you must
- * strip a file to remove symbols before gzipping it so that we do not
- * try to lseek() on it.
+ * Get the section headers. We need this for finding the .ctors
+ * section as well as for loading any symbols. Both may be hard
+ * to do if reading from a .gz file as it involves seeking. I
+ * think the rule is going to have to be that you must strip a
+ * file to remove symbols before gzipping it.
*/
chunk = ehdr->e_shnum * ehdr->e_shentsize;
if (chunk == 0 || ehdr->e_shoff == 0)
@@ -399,6 +402,33 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off)
}
file_addmetadata(fp, MODINFOMD_SHDR, chunk, shdr);
+ /*
+ * Read the section string table and look for the .ctors section.
+ * We need to tell the kernel where it is so that it can call the
+ * ctors.
+ */
+ chunk = shdr[ehdr->e_shstrndx].sh_size;
+ if (chunk) {
+ shstr = alloc_pread(ef->fd, shdr[ehdr->e_shstrndx].sh_offset, chunk);
+ if (shstr) {
+ for (i = 0; i < ehdr->e_shnum; i++) {
+ if (strcmp(shstr + shdr[i].sh_name, ".ctors") != 0)
+ continue;
+ ctors = shdr[i].sh_addr;
+ file_addmetadata(fp, MODINFOMD_CTORS_ADDR, sizeof(ctors),
+ &ctors);
+ size = shdr[i].sh_size;
+ file_addmetadata(fp, MODINFOMD_CTORS_SIZE, sizeof(size),
+ &size);
+ break;
+ }
+ free(shstr);
+ }
+ }
+
+ /*
+ * Now load any symbols.
+ */
symtabindex = -1;
symstrindex = -1;
for (i = 0; i < ehdr->e_shnum; i++) {
OpenPOWER on IntegriCloud