/** * Read elf32 program headers. */ static struct elf32_phdr * read_program_headers(file_t * file, struct elf32_header * elfhdr) { vnode_t * vn = file->vnode; struct uio uio; size_t phsize; struct elf32_phdr * phdr = NULL; phsize = elfhdr->e_phnum * sizeof(struct elf32_phdr); phdr = kmalloc(phsize); if (!phdr) goto fail; if (vn->vnode_ops->lseek(file, elfhdr->e_phoff, SEEK_SET) < 0) goto fail; uio_init_kbuf(&uio, phdr, phsize); if (vn->vnode_ops->read(file, &uio, phsize) != (ssize_t)phsize) goto fail; return phdr; fail: kfree(phdr); return NULL; }
/** * Read elf32 headers. * @param[out] elfhdr is the target struct for elf headers. * @param file is the file containing an elf image. */ static int read_elf32_header(struct elf32_header * elfhdr, file_t * file) { vnode_t * vn = file->vnode; struct uio uio; const size_t elf32_header_size = sizeof(struct elf32_header); /* Read elf header */ if (vn->vnode_ops->lseek(file, 0, SEEK_SET) < 0) return -ENOEXEC; uio_init_kbuf(&uio, elfhdr, elf32_header_size); if (vn->vnode_ops->read(file, &uio, elf32_header_size) != elf32_header_size) return -ENOEXEC; /* Verify elf header */ return check_header(elfhdr); }
/** * Read sector(s). * @param pdrv is a (physical) drive nmuber to identify the drive. * @param buff is a data buffer to store read data. * @param sector is a sector address in LBA. * @param count is the number of bytes to read. * */ DRESULT fatfs_disk_read(uint8_t pdrv, uint8_t * buff, DWORD sector, unsigned int count) { file_t * file; vnode_t * vnode; struct uio uio; ssize_t retval; if (pdrv >= configFATFS_MAX_MOUNTS || !fatfs_sb_arr[pdrv]) return RES_PARERR; file = &fatfs_sb_arr[pdrv]->ff_devfile; vnode = file->vnode; retval = vnode->vnode_ops->lseek(file, sector, SEEK_SET); if (retval < 0) { #ifdef configFATFS_DEBUG KERROR(KERROR_ERR, "%s(): err %i\n", __func__, retval); #endif return RES_ERROR; } uio_init_kbuf(&uio, buff, count); retval = file->vnode->vnode_ops->read(file, &uio, count); if (retval < 0) { #ifdef configFATFS_DEBUG KERROR(KERROR_ERR, "fatfs_disk_read(): err %i\n", retval); #endif return RES_ERROR; } if (retval != (ssize_t)count) { #ifdef configFATFS_DEBUG KERROR(KERROR_WARN, "retval(%i) != count(%i)\n", (uint32_t)retval, (uint32_t)count); #endif return RES_PARERR; } return 0; }
static int read_block_0(uint8_t * block_0, file_t * file) { struct uio uio; int ret; uio_init_kbuf(&uio, block_0, MBR_SIZE); /* Read the first 512 bytes. */ ret = dev_read(file, &uio, MBR_SIZE); if (ret < 0) { KERROR(KERROR_ERR, "MBR: block_read failed (%i)\n", ret); return ret; } else if (ret != MBR_SIZE) { KERROR(KERROR_ERR, "MBR: Failed to read %d bytes, only %d bytes read\n", MBR_SIZE, ret); return -ENOENT; } return 0; }
static struct procfs_stream * read_dyndebug(const struct procfs_info * spec) { struct _kerror_dyndebug_msg * msg_opt = &__start_set_debug_msg_sect; struct _kerror_dyndebug_msg * stop = &__stop_set_debug_msg_sect; const size_t nr_msg = ((size_t)stop - (size_t)msg_opt) / sizeof(struct _kerror_dyndebug_msg); size_t bufsize = nr_msg * DD_MAX_LINE; struct buf * streambuf; struct procfs_stream * stream; struct uio uio; size_t bytes = 0; if (msg_opt == stop) return NULL; streambuf = geteblk(bufsize); if (!streambuf) return NULL; bufsize -= sizeof(struct buf *); stream = (struct procfs_stream *)streambuf->b_data + sizeof(struct buf *); uio_init_kbuf(&uio, &stream->buf, bufsize); while (msg_opt < stop) { int len; len = ksprintf(stream->buf + bytes, bufsize - bytes, "%u:%s:%d\n", msg_opt->flags, msg_opt->file, msg_opt->line); bytes += len; msg_opt++; } stream->bytes = bytes; return stream; }
static int load_section(struct buf ** region, file_t * file, uintptr_t rbase, struct elf32_phdr * phdr) { vnode_t * vn = file->vnode; int prot; struct buf * sect; if (phdr->p_memsz < phdr->p_filesz) return -ENOEXEC; prot = elf32_trans_prot(phdr->p_flags); sect = vm_newsect(phdr->p_vaddr + rbase, phdr->p_memsz, prot); if (!sect) return -ENOMEM; if (phdr->p_filesz > 0) { int err; void * ldp; struct uio uio; if (vn->vnode_ops->lseek(file, phdr->p_offset, SEEK_SET) < 0) return -ENOEXEC; ldp = (void *)(sect->b_data + (phdr->p_vaddr - sect->b_mmu.vaddr)); uio_init_kbuf(&uio, ldp, phdr->p_filesz); err = vn->vnode_ops->read(file, &uio, phdr->p_filesz); if (err < 0) { if (sect->vm_ops->rfree) sect->vm_ops->rfree(sect); return -ENOEXEC; } } *region = sect; return 0; }