Changeset View
Changeset View
Standalone View
Standalone View
stand/common/load_elf_obj.c
Show First 20 Lines • Show All 138 Lines • ▼ Show 20 Lines | #endif | ||||
kfp = file_findfile(NULL, __elfN(obj_kerneltype)); | kfp = file_findfile(NULL, __elfN(obj_kerneltype)); | ||||
if (kfp == NULL) { | if (kfp == NULL) { | ||||
printf("elf" __XSTRING(__ELF_WORD_SIZE) | printf("elf" __XSTRING(__ELF_WORD_SIZE) | ||||
"_obj_loadfile: can't load module before kernel\n"); | "_obj_loadfile: can't load module before kernel\n"); | ||||
err = EPERM; | err = EPERM; | ||||
goto oerr; | goto oerr; | ||||
} | } | ||||
/* Read in the section headers. */ | |||||
ef.e_shdr = alloc_pread(ef.fd, (off_t)hdr->e_shoff, | |||||
hdr->e_shnum * hdr->e_shentsize); | |||||
if (ef.e_shdr == NULL) { | |||||
printf("\nelf" __XSTRING(__ELF_WORD_SIZE) | |||||
"_obj_loadfile: read section headers failed\n"); | |||||
err = errno; | |||||
goto oerr; | |||||
} | |||||
if (archsw.arch_loadaddr != NULL) | if (archsw.arch_loadaddr != NULL) | ||||
dest = archsw.arch_loadaddr(LOAD_ELF, hdr, dest); | dest = archsw.arch_loadaddr(LOAD_ELF, &ef, dest); | ||||
else | else | ||||
dest = roundup(dest, PAGE_SIZE); | dest = roundup(dest, PAGE_SIZE); | ||||
/* | /* | ||||
* Ok, we think we should handle this. | * Ok, we think we should handle this. | ||||
*/ | */ | ||||
fp = file_alloc(); | fp = file_alloc(); | ||||
if (fp == NULL) { | if (fp == NULL) { | ||||
Show All 26 Lines | |||||
out: | out: | ||||
close(ef.fd); | close(ef.fd); | ||||
if (ef.e_shdr != NULL) | if (ef.e_shdr != NULL) | ||||
free(ef.e_shdr); | free(ef.e_shdr); | ||||
return(err); | return(err); | ||||
} | } | ||||
size_t | |||||
__elfN(obj_imagesize)(void *ptr) | |||||
{ | |||||
elf_file_t ef = ptr; | |||||
Elf_Ehdr *hdr; | |||||
Elf_Shdr *shdr; | |||||
size_t size; | |||||
int i, nsym, symstrindex; | |||||
hdr = &ef->hdr; | |||||
shdr = ef->e_shdr; | |||||
size = 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: | |||||
#if defined(__i386__) || defined(__amd64__) | |||||
case SHT_X86_64_UNWIND: | |||||
#endif | |||||
if ((shdr[i].sh_flags & SHF_ALLOC) == 0) | |||||
break; | |||||
size = roundup(size, shdr[i].sh_addralign); | |||||
size += shdr[i].sh_size; | |||||
break; | |||||
} | |||||
} | |||||
/* Symbols. */ | |||||
nsym = 0; | |||||
for (i = 0; i < hdr->e_shnum; i++) { | |||||
switch (shdr[i].sh_type) { | |||||
case SHT_SYMTAB: | |||||
nsym++; | |||||
ef->symtabindex = i; | |||||
size += shdr[i].sh_size; | |||||
break; | |||||
} | |||||
} | |||||
if (nsym != 1) { | |||||
printf("\nelf" __XSTRING(__ELF_WORD_SIZE) | |||||
"_obj_imagesize: file has no valid symbol table\n"); | |||||
goto out; | |||||
} | |||||
size = roundup(size, shdr[ef->symtabindex].sh_addralign); | |||||
size += shdr[ef->symtabindex].sh_size; | |||||
symstrindex = shdr[ef->symtabindex].sh_link; | |||||
if (symstrindex < 0 || symstrindex >= hdr->e_shnum || | |||||
shdr[symstrindex].sh_type != SHT_STRTAB) { | |||||
printf("\nelf" __XSTRING(__ELF_WORD_SIZE) | |||||
"_obj_imagesize: file has invalid symbol strings\n"); | |||||
goto out; | |||||
} | |||||
size = roundup(size, shdr[symstrindex].sh_addralign); | |||||
size += shdr[symstrindex].sh_size; | |||||
/* Section names. */ | |||||
if (hdr->e_shstrndx == 0 || hdr->e_shstrndx >= hdr->e_shnum || | |||||
shdr[hdr->e_shstrndx].sh_type != SHT_STRTAB) { | |||||
printf("\nelf" __XSTRING(__ELF_WORD_SIZE) | |||||
"_obj_imagesize: file has no section names\n"); | |||||
goto out; | |||||
} | |||||
ef->shstrindex = hdr->e_shstrndx; | |||||
size = roundup(size, shdr[ef->shstrindex].sh_addralign); | |||||
size += shdr[ef->shstrindex].sh_size; | |||||
/* Relocation tables. */ | |||||
for (i = 0; i < hdr->e_shnum; i++) { | |||||
switch (shdr[i].sh_type) { | |||||
case SHT_REL: | |||||
case SHT_RELA: | |||||
if ((shdr[shdr[i].sh_info].sh_flags & SHF_ALLOC) == 0) | |||||
break; | |||||
size = roundup(size, shdr[i].sh_addralign); | |||||
size += shdr[i].sh_size; | |||||
break; | |||||
} | |||||
} | |||||
out: | |||||
return (size); | |||||
} | |||||
/* | /* | ||||
* With the file (fd) open on the image, and (ehdr) containing | * With the file (fd) open on the image, and (ehdr) containing | ||||
* the Elf header, load the image at (off) | * the Elf header, load the image at (off) | ||||
*/ | */ | ||||
static int | static int | ||||
__elfN(obj_loadimage)(struct preloaded_file *fp, elf_file_t ef, uint64_t off) | __elfN(obj_loadimage)(struct preloaded_file *fp, elf_file_t ef, uint64_t off) | ||||
{ | { | ||||
Elf_Ehdr *hdr; | Elf_Ehdr *hdr; | ||||
Elf_Shdr *shdr, *cshdr, *lshdr; | Elf_Shdr *shdr, *cshdr, *lshdr; | ||||
vm_offset_t firstaddr, lastaddr; | vm_offset_t firstaddr, lastaddr; | ||||
int i, nsym, res, ret, shdrbytes, symstrindex; | int i, nsym, res, ret, shdrbytes, symstrindex; | ||||
ret = 0; | ret = 0; | ||||
firstaddr = lastaddr = (vm_offset_t)off; | firstaddr = lastaddr = (vm_offset_t)off; | ||||
hdr = &ef->hdr; | hdr = &ef->hdr; | ||||
shdr = ef->e_shdr; | |||||
ef->off = (vm_offset_t)off; | ef->off = (vm_offset_t)off; | ||||
/* Read in the section headers. */ | |||||
shdrbytes = hdr->e_shnum * hdr->e_shentsize; | shdrbytes = hdr->e_shnum * hdr->e_shentsize; | ||||
shdr = alloc_pread(ef->fd, (off_t)hdr->e_shoff, shdrbytes); | |||||
if (shdr == NULL) { | |||||
printf("\nelf" __XSTRING(__ELF_WORD_SIZE) | |||||
"_obj_loadimage: read section headers failed\n"); | |||||
goto out; | |||||
} | |||||
ef->e_shdr = shdr; | |||||
/* | /* | ||||
* Decide where to load everything, but don't read it yet. | * Decide where to load everything, but don't read it yet. | ||||
* We store the load address as a non-zero sh_addr value. | * We store the load address as a non-zero sh_addr value. | ||||
* Start with the code/data and bss. | * Start with the code/data and bss. | ||||
*/ | */ | ||||
for (i = 0; i < hdr->e_shnum; i++) | for (i = 0; i < hdr->e_shnum; i++) | ||||
shdr[i].sh_addr = 0; | shdr[i].sh_addr = 0; | ||||
▲ Show 20 Lines • Show All 324 Lines • Show Last 20 Lines |