Example #1
0
void
file_set_name(
    vmi_instance_t vmi,
    char *name)
{
    file_get_instance(vmi)->filename = strndup(name, 500);
}
Example #2
0
status_t
file_init(
    vmi_instance_t vmi)
{
    FILE *fhandle = NULL;
    int fd = -1;
    file_instance_t *fi = file_get_instance(vmi);

    /* open handle to memory file */
    if ((fhandle = fopen(fi->filename, "rb")) == NULL) {
        errprint("Failed to open file for reading.\n");
        goto fail;
    }
    fd = fileno(fhandle);

    fi->fhandle = fhandle;
    fi->fd = fd;
    memory_cache_init(vmi, file_get_memory, file_release_memory,
                      ULONG_MAX);
    //    memory_cache_init(vmi, file_get_memory, file_release_memory, 0);

#if USE_MMAP
    /* try memory mapped file I/O */
    uint64_t size = 0;

    if (VMI_FAILURE == file_get_memsize(vmi, &size)) {
        goto fail;
    }   // if

    int mmap_flags = (MAP_PRIVATE | MAP_NORESERVE | MAP_POPULATE);

#ifdef MMAP_HUGETLB // since kernel 2.6.32
    mmap_flags |= MMAP_HUGETLB;
#endif // MMAP_HUGETLB

    void *map = mmap(NULL,  // addr
                     size,  // len
                     PROT_READ, // prot
                     mmap_flags,    // flags
                     fd,    // file descriptor
                     (off_t) 0);    // offset

    if (MAP_FAILED == map) {
        perror("Failed to mmap file");
        goto fail;
    }
    fi->map = map;

    // Note: madvise(.., MADV_SEQUENTIAL | MADV_WILLNEED) does not seem to
    // improve performance

#endif // USE_MMAP

    vmi->hvm = 0;
    return VMI_SUCCESS;

fail:
    file_destroy(vmi);
    return VMI_FAILURE;
}
Example #3
0
status_t
file_get_name(
    vmi_instance_t vmi,
    char **name)
{
    *name = strdup(file_get_instance(vmi)->filename);
    return VMI_SUCCESS;
}
Example #4
0
void *
file_get_memory(
    vmi_instance_t vmi,
    addr_t paddr,
    uint32_t length)
{
    void *memory = 0;

    if (paddr + length >= vmi->max_physical_address) {
        dbprint
            (VMI_DEBUG_FILE, "--%s: request for PA range [0x%.16"PRIx64"-0x%.16"PRIx64"] reads past end of file\n",
             __FUNCTION__, paddr, paddr + length);
        goto error_noprint;
    }   // if

    memory = safe_malloc(length);

#if USE_MMAP
    (void) memcpy(memory,
                  ((uint8_t *) file_get_instance(vmi)->map) + paddr,
                  length);
#else
    off_t rc = lseek(file_get_instance(vmi)->fd, paddr, SEEK_SET);
    if ( rc < 0 || (addr_t)rc != paddr ) {
        goto error_print;
    }
    ssize_t rc2 = read(file_get_instance(vmi)->fd, memory, length);
    if ( rc2 < 0 || (size_t)rc2 != length ) {
        goto error_print;
    }
#endif // USE_MMAP

    return memory;

error_print:
    dbprint(VMI_DEBUG_WRITE, "%s: failed to read %d bytes at "
            "PA (offset) 0x%.16"PRIx64" [VM size 0x%.16"PRIx64"]\n", __FUNCTION__,
            length, paddr, vmi->allocated_ram_size);
error_noprint:
    if (memory)
        free(memory);
    return NULL;
}
Example #5
0
status_t
file_get_memsize(
    vmi_instance_t vmi,
    uint64_t *size)
{
    status_t ret = VMI_FAILURE;
    struct stat s;

    if (fstat(file_get_instance(vmi)->fd, &s) == -1) {
        errprint("Failed to stat file.\n");
        goto error_exit;
    }
    *size = s.st_size;
    ret = VMI_SUCCESS;

error_exit:
    return ret;
}
Example #6
0
void
file_destroy(
    vmi_instance_t vmi)
{
    file_instance_t *fi = file_get_instance(vmi);

#if USE_MMAP
    if (fi->map) {
        (void) munmap(fi->map, vmi->size);
        fi->map = 0;
    }
#endif // USE_MMAP
    // fi->fhandle refers to fi->fd; closing both would be an error
    if (fi->fhandle) {
        fclose(fi->fhandle);
        fi->fhandle = 0;
        fi->fd = 0;
    }
}
Example #7
0
status_t
file_get_memsize(
    vmi_instance_t vmi,
    uint64_t *allocated_ram_size,
    addr_t *max_physical_address)
{
    status_t ret = VMI_FAILURE;
    struct stat s;

    if (fstat(file_get_instance(vmi)->fd, &s) == -1) {
        errprint("Failed to stat file.\n");
        goto error_exit;
    }
    *allocated_ram_size = s.st_size;
    *max_physical_address = s.st_size;
    ret = VMI_SUCCESS;

error_exit:
    return ret;
}