diff options
Diffstat (limited to 'sys/boot/common')
-rw-r--r-- | sys/boot/common/Makefile.inc | 7 | ||||
-rw-r--r-- | sys/boot/common/load_elf_obj.c | 37 |
2 files changed, 37 insertions, 7 deletions
diff --git a/sys/boot/common/Makefile.inc b/sys/boot/common/Makefile.inc index 9893278..be6c3301 100644 --- a/sys/boot/common/Makefile.inc +++ b/sys/boot/common/Makefile.inc @@ -44,8 +44,15 @@ SRCS+= pnp.c # Forth interpreter .if defined(BOOT_FORTH) SRCS+= interp_forth.c +MAN+= ../forth/beastie.4th.8 +MAN+= ../forth/brand.4th.8 +MAN+= ../forth/check-password.4th.8 +MAN+= ../forth/color.4th.8 +MAN+= ../forth/delay.4th.8 MAN+= ../forth/loader.conf.5 MAN+= ../forth/loader.4th.8 +MAN+= ../forth/menu.4th.8 +MAN+= ../forth/version.4th.8 .endif .if defined(BOOT_PROMPT_123) diff --git a/sys/boot/common/load_elf_obj.c b/sys/boot/common/load_elf_obj.c index dcd71ef..54d9b10 100644 --- a/sys/boot/common/load_elf_obj.c +++ b/sys/boot/common/load_elf_obj.c @@ -196,7 +196,7 @@ static int __elfN(obj_loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off) { Elf_Ehdr *hdr; - Elf_Shdr *shdr; + Elf_Shdr *shdr, *cshdr, *lshdr; vm_offset_t firstaddr, lastaddr; int i, nsym, res, ret, shdrbytes, symstrindex; @@ -294,12 +294,35 @@ __elfN(obj_loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off) /* Clear the whole area, including bss regions. */ kern_bzero(firstaddr, lastaddr - firstaddr); - /* Now read it all in. */ - for (i = 0; i < hdr->e_shnum; i++) { - if (shdr[i].sh_addr == 0 || shdr[i].sh_type == SHT_NOBITS) - continue; - if (kern_pread(ef->fd, (vm_offset_t)shdr[i].sh_addr, - shdr[i].sh_size, (off_t)shdr[i].sh_offset) != 0) { + /* Figure section with the lowest file offset we haven't loaded yet. */ + for (cshdr = NULL; /* none */; /* none */) + { + /* + * Find next section to load. The complexity of this loop is + * O(n^2), but with the number of sections being typically + * small, we do not care. + */ + lshdr = cshdr; + + for (i = 0; i < hdr->e_shnum; i++) { + if (shdr[i].sh_addr == 0 || + shdr[i].sh_type == SHT_NOBITS) + continue; + /* Skip sections that were loaded already. */ + if (lshdr != NULL && + lshdr->sh_offset >= shdr[i].sh_offset) + continue; + /* Find section with smallest offset. */ + if (cshdr == lshdr || + cshdr->sh_offset > shdr[i].sh_offset) + cshdr = &shdr[i]; + } + + if (cshdr == lshdr) + break; + + if (kern_pread(ef->fd, (vm_offset_t)cshdr->sh_addr, + cshdr->sh_size, (off_t)cshdr->sh_offset) != 0) { printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_obj_loadimage: read failed\n"); goto out; |