Add a few helper functions for zeroing kernel space and reading
from specified file offsets. Make use of these in load_elf.c.
This commit is contained in:
parent
a53b524bb4
commit
c0b43624d5
@ -76,6 +76,9 @@ char *unargv(int argc, char *argv[]);
|
||||
void hexdump(caddr_t region, size_t len);
|
||||
size_t strlenout(vm_offset_t str);
|
||||
char *strdupout(vm_offset_t str);
|
||||
void kern_bzero(vm_offset_t dest, size_t len);
|
||||
int kern_pread(int fd, vm_offset_t dest, size_t len, off_t off);
|
||||
void *alloc_pread(int fd, off_t off, size_t len);
|
||||
|
||||
/* bcache.c */
|
||||
int bcache_init(u_int nblks, size_t bsize);
|
||||
|
@ -241,10 +241,8 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off)
|
||||
int ret;
|
||||
vm_offset_t firstaddr;
|
||||
vm_offset_t lastaddr;
|
||||
void *buf;
|
||||
size_t resid, chunk;
|
||||
size_t chunk;
|
||||
ssize_t result;
|
||||
vm_offset_t dest;
|
||||
Elf_Addr ssym, esym;
|
||||
Elf_Dyn *dp;
|
||||
Elf_Addr adp;
|
||||
@ -305,14 +303,10 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off)
|
||||
phdr[i].p_vaddr + off, fpcopy);
|
||||
}
|
||||
if (phdr[i].p_filesz > fpcopy) {
|
||||
if (lseek(ef->fd, (off_t)(phdr[i].p_offset + fpcopy),
|
||||
SEEK_SET) == -1) {
|
||||
printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadexec: cannot seek\n");
|
||||
goto out;
|
||||
}
|
||||
if (archsw.arch_readin(ef->fd, phdr[i].p_vaddr + off + fpcopy,
|
||||
phdr[i].p_filesz - fpcopy) != (ssize_t)(phdr[i].p_filesz - fpcopy)) {
|
||||
printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadexec: archsw.readin failed\n");
|
||||
if (kern_pread(ef->fd, phdr[i].p_vaddr + off + fpcopy,
|
||||
phdr[i].p_filesz - fpcopy, phdr[i].p_offset + fpcopy) != 0) {
|
||||
printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
|
||||
"_loadimage: read failed\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@ -324,22 +318,8 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off)
|
||||
(long)(phdr[i].p_vaddr + off + phdr[i].p_memsz - 1));
|
||||
#endif
|
||||
|
||||
/* no archsw.arch_bzero */
|
||||
buf = malloc(PAGE_SIZE);
|
||||
if (buf == NULL) {
|
||||
printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: malloc() failed\n");
|
||||
goto out;
|
||||
}
|
||||
bzero(buf, PAGE_SIZE);
|
||||
resid = phdr[i].p_memsz - phdr[i].p_filesz;
|
||||
dest = phdr[i].p_vaddr + off + phdr[i].p_filesz;
|
||||
while (resid > 0) {
|
||||
chunk = min(PAGE_SIZE, resid);
|
||||
archsw.arch_copyin(buf, dest, chunk);
|
||||
resid -= chunk;
|
||||
dest += chunk;
|
||||
}
|
||||
free(buf);
|
||||
kern_bzero(phdr[i].p_vaddr + off + phdr[i].p_filesz,
|
||||
phdr[i].p_memsz - phdr[i].p_filesz);
|
||||
}
|
||||
#ifdef ELF_VERBOSE
|
||||
printf("\n");
|
||||
@ -361,16 +341,10 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off)
|
||||
chunk = ehdr->e_shnum * ehdr->e_shentsize;
|
||||
if (chunk == 0 || ehdr->e_shoff == 0)
|
||||
goto nosyms;
|
||||
shdr = malloc(chunk);
|
||||
if (shdr == NULL)
|
||||
goto nosyms;
|
||||
if (lseek(ef->fd, (off_t)ehdr->e_shoff, SEEK_SET) == -1) {
|
||||
printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: cannot lseek() to section headers");
|
||||
goto nosyms;
|
||||
}
|
||||
result = read(ef->fd, shdr, chunk);
|
||||
if (result < 0 || (size_t)result != chunk) {
|
||||
printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: read section headers failed");
|
||||
shdr = alloc_pread(ef->fd, ehdr->e_shoff, chunk);
|
||||
if (shdr == NULL) {
|
||||
printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
|
||||
"_loadimage: failed to read section headers");
|
||||
goto nosyms;
|
||||
}
|
||||
symtabindex = -1;
|
||||
|
@ -93,6 +93,74 @@ strdupout(vm_offset_t str)
|
||||
return(result);
|
||||
}
|
||||
|
||||
/* Zero a region in kernel space. */
|
||||
void
|
||||
kern_bzero(vm_offset_t dest, size_t len)
|
||||
{
|
||||
char buf[256];
|
||||
size_t chunk, resid;
|
||||
|
||||
bzero(buf, sizeof(buf));
|
||||
resid = len;
|
||||
while (resid > 0) {
|
||||
chunk = min(sizeof(buf), resid);
|
||||
archsw.arch_copyin(buf, dest, chunk);
|
||||
resid -= chunk;
|
||||
dest += chunk;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the specified part of a file to kernel space. Unlike regular
|
||||
* pread, the file pointer is advanced to the end of the read data,
|
||||
* and it just returns 0 if successful.
|
||||
*/
|
||||
int
|
||||
kern_pread(int fd, vm_offset_t dest, size_t len, off_t off)
|
||||
{
|
||||
ssize_t nread;
|
||||
|
||||
if (lseek(fd, off, SEEK_SET) == -1) {
|
||||
printf("\nlseek failed\n");
|
||||
return (-1);
|
||||
}
|
||||
nread = archsw.arch_readin(fd, dest, len);
|
||||
if (nread != len) {
|
||||
printf("\nreadin failed\n");
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the specified part of a file to a malloced buffer. The file
|
||||
* pointer is advanced to the end of the read data.
|
||||
*/
|
||||
void *
|
||||
alloc_pread(int fd, off_t off, size_t len)
|
||||
{
|
||||
void *buf;
|
||||
ssize_t nread;
|
||||
|
||||
buf = malloc(len);
|
||||
if (buf == NULL) {
|
||||
printf("\nmalloc(%d) failed\n", (int)len);
|
||||
return (NULL);
|
||||
}
|
||||
if (lseek(fd, off, SEEK_SET) == -1) {
|
||||
printf("\nlseek failed\n");
|
||||
free(buf);
|
||||
return (NULL);
|
||||
}
|
||||
nread = read(fd, buf, len);
|
||||
if (nread != len) {
|
||||
printf("\nread failed\n");
|
||||
free(buf);
|
||||
return (NULL);
|
||||
}
|
||||
return (buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Display a region in traditional hexdump format.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user