Пример #1
0
ssize_t sys_pread(int fd, char* buf, size_t n, off_t offset)
{
  ssize_t r = -EBADF;
  file_t* f = file_get(fd);

  if (f)
  {
    r = file_pread(f, buf, n, offset);
    file_decref(f);
  }

  return r;
}
Пример #2
0
ssize_t pread(int fd, FAR void *buf, size_t nbytes, off_t offset)
{
  FAR struct file *filep;

  /* Get the file structure corresponding to the file descriptor. */

  filep = fs_getfilep(fd);
  if (!filep)
    {
      /* The errno value has already been set */

      return (ssize_t)ERROR;
    }

  /* Let file_pread do the real work */

  return file_pread(filep, buf, nbytes, offset);
}
Пример #3
0
int main(int argc, char *argv[])
{
	int ret;
	struct stat st;
	struct file_context *src;
	struct file_context *dst;
	uint64_t off;
	int64_t count;
	
#ifdef WIN32
	if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
		printf("Failed to start Winsock2\n");
		return 10;
	}
#endif

#ifdef AROS
	aros_init_socket();
#endif

	if (argc != 3) {
		usage();
	}

	src = open_file(argv[1], O_RDONLY);
	if (src == NULL) {
		fprintf(stderr, "Failed to open %s\n", argv[1]);
		return 10;
	}

	dst = open_file(argv[2], O_WRONLY|O_CREAT|O_TRUNC);
	if (dst == NULL) {
		fprintf(stderr, "Failed to open %s\n", argv[2]);
		free_file_context(src);
		return 10;
	}

	if (fstat_file(src, &st) != 0) {
		fprintf(stderr, "Failed to fstat source file\n");
		free_file_context(src);
		free_file_context(dst);
		return 10;
	}

	off = 0;
	while (off < st.st_size) {
		count = st.st_size - off;
		if (count > BUFSIZE) {
			count = BUFSIZE;
		}
		count = file_pread(src, buf, count, off);
		if (count < 0) {
			fprintf(stderr, "Failed to read from source file\n");
			free_file_context(src);
			free_file_context(dst);
			return 10;
		}
		count = file_pwrite(dst, buf, count, off);
		if (count < 0) {
			fprintf(stderr, "Failed to write to dest file\n");
			free_file_context(src);
			free_file_context(dst);
			return 10;
		}

		off += count;
	}
	printf("copied %d bytes\n", (int)off);

	free_file_context(src);
	free_file_context(dst);

	return 0;
}
Пример #4
0
static int
blockset_open_file(struct blockstore *blockStore,
                   struct blockset *bs)
{
   uint64 offset;
   mtime_t ts;
   int res;

   res = file_open(bs->filename, 0 /* R/O */, 0 /* !unbuf */, &bs->desc);
   if (res) {
      return res;
   }

   bs->filesize = file_getsize(bs->desc);
   if (bs->filesize < 0) {
      return errno;
   }

   if (bs->filesize > 0) {
      char *s = print_size(bs->filesize);
      char *name = file_getname(bs->filename);
      Log(LGPFX" reading file %s -- %s -- %llu headers.\n",
          name, s, bs->filesize / sizeof(btc_block_header));
      free(name);
      free(s);
   }

   ts = time_get();
   offset = 0;
   while (offset < bs->filesize) {
      btc_block_header buf[10000];
      size_t numRead;
      size_t numBytes;
      int numHeaders;
      int i;

      numBytes = MIN(bs->filesize - offset, sizeof buf);

      res = file_pread(bs->desc, offset, buf, numBytes, &numRead);
      if (res != 0) {
         break;
      }

      if (btc->stop != 0) {
         res = 1;
         NOT_TESTED();
         break;
      }

      numHeaders = numRead / sizeof(btc_block_header);
      for (i = 0; i < numHeaders; i++) {
         struct blockentry *be;
         uint256 hash;

         be = blockstore_alloc_entry(buf + i);
         be->written = 1;
         hash256_calc(buf + i, sizeof buf[0], &hash);

         if (!blockstore_validate_chkpt(&hash, blockStore->height + 1)) {
            return 1;
         }

         blockstore_add_entry(blockStore, be, &hash);

         if (i == numHeaders - 1) {
            bitcui_set_status("loading headers .. %llu%%",
                             (offset + numBytes) * 100 / bs->filesize);
         }
         if (i == numHeaders - 1 ||
             (numBytes < sizeof buf && i > numHeaders - 256)) {
            bitcui_set_last_block_info(&hash, blockStore->height,
                                      be->header.timestamp);
         }
      }

      offset += numRead;
   }

   ts = time_get() - ts;

   char hashStr[80];
   char *latStr;

   uint256_snprintf_reverse(hashStr, sizeof hashStr, &blockStore->best_hash);
   Log(LGPFX" loaded blocks up to %s\n", hashStr);
   latStr = print_latency(ts);
   Log(LGPFX" this took %s\n", latStr);
   free(latStr);

   return res;
}
Пример #5
0
void load_elf(const char* fn, elf_info* info)
{
  file_t* file = file_open(fn, O_RDONLY, 0);
  if (IS_ERR_VALUE(file))
    goto fail;

  Elf64_Ehdr eh64;
  ssize_t ehdr_size = file_pread(file, &eh64, sizeof(eh64), 0);
  if (ehdr_size < (ssize_t)sizeof(eh64) ||
      !(eh64.e_ident[0] == '\177' && eh64.e_ident[1] == 'E' &&
        eh64.e_ident[2] == 'L'    && eh64.e_ident[3] == 'F'))
    goto fail;

  uintptr_t min_vaddr = -1, max_vaddr = 0;

  #define LOAD_ELF do { \
    eh = (typeof(eh))&eh64; \
    size_t phdr_size = eh->e_phnum*sizeof(*ph); \
    if (phdr_size > info->phdr_size) \
      goto fail; \
    ssize_t ret = file_pread(file, (void*)info->phdr, phdr_size, eh->e_phoff); \
    if (ret < (ssize_t)phdr_size) \
      goto fail; \
    info->phnum = eh->e_phnum; \
    info->phent = sizeof(*ph); \
    ph = (typeof(ph))info->phdr; \
    info->is_supervisor = (eh->e_entry >> (8*sizeof(eh->e_entry)-1)) != 0; \
    if (info->is_supervisor) \
      info->first_free_paddr = ROUNDUP(info->first_free_paddr, SUPERPAGE_SIZE); \
    for (int i = 0; i < eh->e_phnum; i++) \
      if (ph[i].p_type == PT_LOAD && ph[i].p_memsz && ph[i].p_vaddr < min_vaddr) \
        min_vaddr = ph[i].p_vaddr; \
    if (info->is_supervisor) \
      min_vaddr = ROUNDDOWN(min_vaddr, SUPERPAGE_SIZE); \
    else \
      min_vaddr = ROUNDDOWN(min_vaddr, RISCV_PGSIZE); \
    uintptr_t bias = 0; \
    if (info->is_supervisor || eh->e_type == ET_DYN) \
      bias = info->first_free_paddr - min_vaddr; \
    info->entry = eh->e_entry; \
    if (!info->is_supervisor) { \
      info->entry += bias; \
      min_vaddr += bias; \
    } \
    info->bias = bias; \
    int flags = MAP_FIXED | MAP_PRIVATE; \
    if (info->is_supervisor) \
      flags |= MAP_POPULATE; \
    for (int i = eh->e_phnum - 1; i >= 0; i--) { \
      if(ph[i].p_type == PT_LOAD && ph[i].p_memsz) { \
        uintptr_t prepad = ph[i].p_vaddr % RISCV_PGSIZE; \
        uintptr_t vaddr = ph[i].p_vaddr + bias; \
        if (vaddr + ph[i].p_memsz > max_vaddr) \
          max_vaddr = vaddr + ph[i].p_memsz; \
        if (info->is_supervisor) { \
          if (!__valid_user_range(vaddr - prepad, vaddr + ph[i].p_memsz)) \
            goto fail; \
          ret = file_pread(file, (void*)vaddr, ph[i].p_filesz, ph[i].p_offset); \
          if (ret < (ssize_t)ph[i].p_filesz) \
            goto fail; \
          memset((void*)vaddr - prepad, 0, prepad); \
          memset((void*)vaddr + ph[i].p_filesz, 0, ph[i].p_memsz - ph[i].p_filesz); \
        } else { \
          int flags2 = flags | (prepad ? MAP_POPULATE : 0); \
          if (__do_mmap(vaddr - prepad, ph[i].p_filesz + prepad, -1, flags2, file, ph[i].p_offset - prepad) != vaddr - prepad) \
            goto fail; \
          memset((void*)vaddr - prepad, 0, prepad); \
          size_t mapped = ROUNDUP(ph[i].p_filesz + prepad, RISCV_PGSIZE) - prepad; \
          if (ph[i].p_memsz > mapped) \
            if (__do_mmap(vaddr + mapped, ph[i].p_memsz - mapped, -1, flags|MAP_ANONYMOUS, 0, 0) != vaddr + mapped) \
              goto fail; \
        } \
      } \
    } \
  } while(0)

  info->elf64 = IS_ELF64(eh64);
  if (info->elf64)
  {
    Elf64_Ehdr* eh;
    Elf64_Phdr* ph;
    LOAD_ELF;
  }
  else if (IS_ELF32(eh64))
  {
    Elf32_Ehdr* eh;
    Elf32_Phdr* ph;
    LOAD_ELF;
  }
  else
    goto fail;

  info->first_user_vaddr = min_vaddr;
  info->first_vaddr_after_user = ROUNDUP(max_vaddr - info->bias, RISCV_PGSIZE);
  info->brk_min = max_vaddr;

  file_decref(file);
  return;

fail:
    panic("couldn't open ELF program: %s!", fn);
}
Пример #6
0
int file_execute_request(sb_request_t *sb_req, int thread_id)
{
  FILE_DESCRIPTOR    fd;
  sb_file_request_t *file_req = &sb_req->u.file_request;
  log_msg_t          msg;
  log_msg_oper_t     op_msg;
  
  if (sb_globals.debug)
  {
    log_text(LOG_DEBUG,
             "Executing request, operation: %d, file_id: %d, pos: %d, "
             "size: %d",
             file_req->operation,
             file_req->file_id,
             (int)file_req->pos,
             (int)file_req->size);
  }
  
  /* Check request parameters */
  if (file_req->file_id > num_files)
  {
    log_text(LOG_FATAL, "Incorrect file discovered in request");
    return 1;
  }
  if (file_req->pos + file_req->size > file_size)
  {
    log_text(LOG_FATAL, "Too large position discovered in request!");
    return 1;
  }
  
  fd = files[file_req->file_id];

  /* Prepare log message */
  msg.type = LOG_MSG_TYPE_OPER;
  msg.data = &op_msg;

  switch (file_req->operation) {
    case FILE_OP_TYPE_NULL:
      log_text(LOG_FATAL, "Execute of NULL request called !, aborting");
      return 1;
    case FILE_OP_TYPE_WRITE:

      /* Store checksum and offset in a buffer when in validation mode */
      if (sb_globals.validate)
        file_fill_buffer(buffer, file_req->size, file_req->pos);
                         
      LOG_EVENT_START(msg, thread_id);
      if(file_pwrite(file_req->file_id, buffer, file_req->size, file_req->pos,
                     thread_id)
         != (ssize_t)file_req->size)
      {
        log_errno(LOG_FATAL, "Failed to write file! file: " FD_FMT " pos: %lld", 
                  fd, (long long)file_req->pos);
        return 1;
      }
      /* Check if we have to fsync each write operation */
      if (file_fsync_all)
      {
        if (file_fsync(file_req->file_id, thread_id))
        {
          log_errno(LOG_FATAL, "Failed to fsync file! file: " FD_FMT, fd);
          return 1;
        }
      }
      LOG_EVENT_STOP(msg, thread_id);

      SB_THREAD_MUTEX_LOCK();
      write_ops++;
      real_write_ops++;
      bytes_written += file_req->size;
      if (file_fsync_all)
        other_ops++;
      SB_THREAD_MUTEX_UNLOCK();

      break;
    case FILE_OP_TYPE_READ:
      LOG_EVENT_START(msg, thread_id);
      if(file_pread(file_req->file_id, buffer, file_req->size, file_req->pos,
                    thread_id)
         != (ssize_t)file_req->size)
      {
        log_errno(LOG_FATAL, "Failed to read file! file: " FD_FMT " pos: %lld",
                  fd, (long long)file_req->pos);
        return 1;
      }
      LOG_EVENT_STOP(msg, thread_id);

      /* Validate block if run with validation enabled */
      if (sb_globals.validate &&
          file_validate_buffer(buffer, file_req->size, file_req->pos))
      {
        log_text(LOG_FATAL,
          "Validation failed on file " FD_FMT ", block offset 0x%x, exiting...",
           file_req->file_id, file_req->pos);
        return 1;
      }
      
      SB_THREAD_MUTEX_LOCK();
      read_ops++;
      real_read_ops++;
      bytes_read += file_req->size;

      SB_THREAD_MUTEX_UNLOCK();

      break;
    case FILE_OP_TYPE_FSYNC:
      /* Ignore fsync requests if we are already fsync'ing each operation */
      if (file_fsync_all)
        break;
      if(file_fsync(file_req->file_id, thread_id))
      {
        log_errno(LOG_FATAL, "Failed to fsync file! file: " FD_FMT, fd);
        return 1;
      }
    
      SB_THREAD_MUTEX_LOCK();
      other_ops++;
      SB_THREAD_MUTEX_UNLOCK();
    
      break;         
    default:
      log_text(LOG_FATAL, "Execute of UNKNOWN file request type called (%d)!, "
               "aborting", file_req->operation);
      return 1;
  }
  return 0;

}
Пример #7
0
void load_elf(const char* fn, elf_info* info)
{
  sysret_t ret = file_open(fn, O_RDONLY, 0);
  file_t* file = (file_t*)ret.result;
  if (ret.result == -1)
    goto fail;

  Elf64_Ehdr eh64;
  ssize_t ehdr_size = file_pread(file, &eh64, sizeof(eh64), 0).result;
  if (ehdr_size < (ssize_t)sizeof(eh64) ||
      !(eh64.e_ident[0] == '\177' && eh64.e_ident[1] == 'E' &&
        eh64.e_ident[2] == 'L'    && eh64.e_ident[3] == 'F'))
    goto fail;

  #define LOAD_ELF do { \
    eh = (typeof(eh))&eh64; \
    size_t phdr_size = eh->e_phnum*sizeof(*ph); \
    if (info->phdr_top - phdr_size < info->stack_bottom) \
      goto fail; \
    info->phdr = info->phdr_top - phdr_size; \
    ssize_t ret = file_pread(file, (void*)info->phdr, phdr_size, eh->e_phoff).result; \
    if (ret < (ssize_t)phdr_size) goto fail; \
    info->entry = eh->e_entry; \
    info->phnum = eh->e_phnum; \
    info->phent = sizeof(*ph); \
    ph = (typeof(ph))info->phdr; \
    for(int i = 0; i < eh->e_phnum; i++, ph++) { \
      if(ph->p_type == SHT_PROGBITS && ph->p_memsz) { \
        info->brk_min = MAX(info->brk_min, ph->p_vaddr + ph->p_memsz); \
        size_t vaddr = ROUNDDOWN(ph->p_vaddr, RISCV_PGSIZE), prepad = ph->p_vaddr - vaddr; \
        size_t memsz = ph->p_memsz + prepad, filesz = ph->p_filesz + prepad; \
        size_t offset = ph->p_offset - prepad; \
        if (__do_mmap(vaddr, filesz, -1, MAP_FIXED|MAP_PRIVATE, file, offset) != vaddr) \
          goto fail; \
        size_t mapped = ROUNDUP(filesz, RISCV_PGSIZE); \
        if (memsz > mapped) \
          if (__do_mmap(vaddr + mapped, memsz - mapped, -1, MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, 0, 0) != vaddr + mapped) \
            goto fail; \
      } \
    } \
  } while(0)

  info->elf64 = IS_ELF64(eh64);
  if (info->elf64)
  {
    Elf64_Ehdr* eh;
    Elf64_Phdr* ph;
    LOAD_ELF;
  }
  else if (IS_ELF32(eh64))
  {
    Elf32_Ehdr* eh;
    Elf32_Phdr* ph;
    LOAD_ELF;
  }
  else
    goto fail;

  file_decref(file);
  return;

fail:
    panic("couldn't open ELF program: %s!", fn);
}
Пример #8
0
void load_elf(const char* fn, elf_info* info)
{
  file_t* file = file_open(fn, O_RDONLY, 0);
  if (IS_ERR_VALUE(file))
    goto fail;

  Elf_Ehdr eh;
  ssize_t ehdr_size = file_pread(file, &eh, sizeof(eh), 0);
  if (ehdr_size < (ssize_t)sizeof(eh) ||
      !(eh.e_ident[0] == '\177' && eh.e_ident[1] == 'E' &&
        eh.e_ident[2] == 'L'    && eh.e_ident[3] == 'F'))
    goto fail;

#if __riscv_xlen == 64
  assert(IS_ELF64(eh));
#else
  assert(IS_ELF32(eh));
#endif

#ifndef __riscv_compressed
  assert(!(eh.e_flags & EF_RISCV_RVC));
#endif

  size_t phdr_size = eh.e_phnum * sizeof(Elf_Phdr);
  if (phdr_size > info->phdr_size)
    goto fail;
  ssize_t ret = file_pread(file, (void*)info->phdr, phdr_size, eh.e_phoff);
  if (ret < (ssize_t)phdr_size)
    goto fail;
  info->phnum = eh.e_phnum;
  info->phent = sizeof(Elf_Phdr);
  Elf_Phdr* ph = (typeof(ph))info->phdr;

  // compute highest VA in ELF
  uintptr_t max_vaddr = 0;
  for (int i = 0; i < eh.e_phnum; i++)
    if (ph[i].p_type == PT_LOAD && ph[i].p_memsz)
      max_vaddr = MAX(max_vaddr, ph[i].p_vaddr + ph[i].p_memsz);
  max_vaddr = ROUNDUP(max_vaddr, RISCV_PGSIZE);

  // don't load dynamic linker at 0, else we can't catch NULL pointer derefs
  uintptr_t bias = 0;
  if (eh.e_type == ET_DYN)
    bias = RISCV_PGSIZE;

  info->entry = eh.e_entry + bias;
  int flags = MAP_FIXED | MAP_PRIVATE;
  for (int i = eh.e_phnum - 1; i >= 0; i--) {
    if(ph[i].p_type == PT_LOAD && ph[i].p_memsz) {
      uintptr_t prepad = ph[i].p_vaddr % RISCV_PGSIZE;
      uintptr_t vaddr = ph[i].p_vaddr + bias;
      if (vaddr + ph[i].p_memsz > info->brk_min)
        info->brk_min = vaddr + ph[i].p_memsz;
      int flags2 = flags | (prepad ? MAP_POPULATE : 0);
      int prot = get_prot(ph[i].p_flags);
      if (__do_mmap(vaddr - prepad, ph[i].p_filesz + prepad, prot | PROT_WRITE, flags2, file, ph[i].p_offset - prepad) != vaddr - prepad)
        goto fail;
      memset((void*)vaddr - prepad, 0, prepad);
      if (!(prot & PROT_WRITE))
        if (do_mprotect(vaddr - prepad, ph[i].p_filesz + prepad, prot))
          goto fail;
      size_t mapped = ROUNDUP(ph[i].p_filesz + prepad, RISCV_PGSIZE) - prepad;
      if (ph[i].p_memsz > mapped)
        if (__do_mmap(vaddr + mapped, ph[i].p_memsz - mapped, prot, flags|MAP_ANONYMOUS, 0, 0) != vaddr + mapped)
          goto fail;
    }
  }

  file_decref(file);
  return;

fail:
  panic("couldn't open ELF program: %s!", fn);
}