SNSS_RETURN_CODE
SNSS_CloseFile (SNSS_FILE **snssFile)
{
  int prevLoc;
  SNSS_RETURN_CODE code;
  
  /* file was never open, so this should indicate success- kinda. */
  if (NULL == *snssFile)
      return SNSS_OK;
  
  if (SNSS_OPEN_WRITE == (*snssFile)->mode)
  {
    prevLoc = vfs_tell((*snssFile)->fp);
    vfs_seek((*snssFile)->fp, 0, VFS_SEEK_SET);
    
    /* write the header again to get block count correct */
    if (SNSS_OK != (code = SNSS_WriteFileHeader(*snssFile)))
      return SNSS_CLOSE_FAILED;
    
    vfs_seek((*snssFile)->fp, prevLoc, VFS_SEEK_SET);
  }
  
  vfs_close ((*snssFile)->fp);
  
  NES_FREE(*snssFile);
  *snssFile = NULL;
  
  return SNSS_OK;
}
/////////////////////////////////////////////////////////////////////
// Mapper 20
bool
NES_mapper20::initialize (NES *parent, NES_PPU *ppu)
{
  hfile_t fp = NULL;
  uint8 header[16];
  
  if (!(NES_mapper::initialize (parent, ppu)))
    goto error;
  
  fp = vfs_open (parent->disksys_rom_filename, VFS_READ);
  if (!fp)
  {
    ERROR("no disksys.rom");
    ERROR(parent->disksys_rom_filename);
    goto error;
  }
  
  if (vfs_read(header, sizeof(header), 1, fp) != sizeof(header))
    goto error;
  
  if (!NES_MEMCMP (header, "NES", 3))
    vfs_seek(fp, 0x6010, VFS_SEEK_SET);
  else
    vfs_seek(fp, 0, VFS_SEEK_SET);
  
  if (vfs_read(bios, 0x2000, 1, fp) != 0x2000)
    goto error;
  
  vfs_close(fp);
  return true;
  
error:
  if (fp) vfs_close(fp);
  return false;
}
Example #3
0
struct VFS_HANDLE * vfs_open( char * filename, int mode )
{
	struct VFS_HANDLE * handle;
	struct VFS_MOUNTPOINT * mount;
	char name[VFS_MAXFILENAME], * name_ptr;
	// copy the name so we can modify it
	name_ptr = (char *)&name;
	strcpy( name_ptr, filename );
	// find the correct mountpoint for this file
	mount = vfs_file2mountpoint( name_ptr );
	if( mount == NULL )
		return NULL;
	// advance the filname past the mount point
	name_ptr = (char *)( name_ptr + strlen(mount->mountpoint) );
	// call the file system driver to open
	if( mount->fs->calltable.open == NULL )
		return NULL;
	// create the new virtual file handle	
	handle = (struct VFS_HANDLE *)mm_kmalloc( sizeof(struct VFS_HANDLE) );
	handle->mount = mount;
	handle->mode = mode;
	// try to open the file on the mounted file system
	if( mount->fs->calltable.open( handle, name_ptr ) != NULL )
	{	
		// set the file position to the end of the file if in append mode
		if( (handle->mode & VFS_MODE_APPEND) == VFS_MODE_APPEND )
			vfs_seek( handle, 0, VFS_SEEK_END );
		return handle;
	}
	else
	{
		// if we fail to open the file but are in create mode, we can create the file
		//     TO-DO: test the failed open() result for a value like FILE_NOT_FOUND
		//     otherwise we could end up in an infinite recurive loop
		if( (handle->mode & VFS_MODE_CREATE) == VFS_MODE_CREATE )
		{	
			if( mount->fs->calltable.create != NULL )
			{
				// try to create it
				name_ptr = (char *)&name;
				strcpy( name_ptr, filename );
				name_ptr = (char *)( name_ptr + strlen(mount->mountpoint) );

				if( mount->fs->calltable.create( mount, name_ptr ) != FAIL )
				{
					if( mount->fs->calltable.open( handle, name_ptr ) != NULL )
					{
						if( (handle->mode & VFS_MODE_APPEND) == VFS_MODE_APPEND )
							vfs_seek( handle, 0, VFS_SEEK_END );
						return handle;
					}
				}
			}
		}		
	}
	// if we fail, free the handle and return NULL
	mm_kfree( handle );
	return NULL;
}
Example #4
0
// Kludge to push changes in VFS memobj back out to disk
errval_t memobj_flush_vfs(struct memobj *memobj, struct vregion *vregion)
{
    errval_t err;

    assert(memobj->type == MEMOBJ_VFS);

    struct memobj_vfs *mv    = (struct memobj_vfs *)memobj;
    struct vspace *vspace    = vregion_get_vspace(vregion);
    struct pmap *pmap        = vspace_get_pmap(vspace);
    genvaddr_t vregion_base  = vregion_get_base_addr(vregion);
    lvaddr_t vregion_lbase   = vspace_genvaddr_to_lvaddr(vregion_base);
    genvaddr_t vregion_off   = vregion_get_offset(vregion);

    assert(vregion_off == 0); // not sure if we handle this correctly

    /* TODO: mv->size instead of BASE_PAGE_SIZE?*/
    for (genvaddr_t off = 0; off < mv->filesize ; off += BASE_PAGE_SIZE){
        genvaddr_t retvaddr;
        size_t retsize;
        vregion_flags_t retflags;

        // For each page check if it's in memory
        err = pmap->f.lookup(pmap, vregion_base + off, &retvaddr, &retsize,
                             NULL, NULL, &retflags);
        if (err_is_fail(err)) {
            continue; // Page not in memory
#if 0 /* this optimisation may not be correct if flags were changed -AB */
        } else if ((retflags & VREGION_FLAGS_WRITE) == 0) {
            continue; // Not writable
#endif
        }

        //TRACE("Flushing page at address: %lx\n", vregion_base + off);

        // seek file handle
        err = vfs_seek(mv->vh, VFS_SEEK_SET, off + mv->offset);
        if (err_is_fail(err)) {
            return err;
        }

        // write contents to file
        size_t rsize, pos = 0;
        size_t nbytes = mv->filesize - off;
        if (nbytes > BASE_PAGE_SIZE) {
            nbytes = BASE_PAGE_SIZE;
        }

        do {
            err = vfs_write(mv->vh, (char *)vregion_lbase + off + pos,
                            nbytes - pos, &rsize);
            if (err_is_fail(err)) {
                return err;
            }
            pos += rsize;
        } while(rsize > 0 && pos < nbytes);
        assert(pos==nbytes);
    }

    return SYS_ERR_OK;
}
SNSS_RETURN_CODE 
SNSS_SkipNextBlock (SNSS_FILE *snssFile)
{
  SnssBlockHeader header;
  
  if (SNSS_ReadBlockHeader (&header, snssFile) != SNSS_OK)
    return SNSS_READ_FAILED;
  
  vfs_seek (snssFile->fp, header.blockLength, VFS_SEEK_CUR);
  
  return SNSS_OK;
}
SNSS_RETURN_CODE 
SNSS_GetNextBlockType (SNSS_BLOCK_TYPE *blockType, SNSS_FILE *snssFile)
{
  char tagBuffer[TAG_LENGTH + 1];
  int pos = vfs_tell(snssFile->fp);

  if (vfs_read (tagBuffer, TAG_LENGTH, 1, snssFile->fp) != TAG_LENGTH) 
    return SNSS_READ_FAILED;
  tagBuffer[TAG_LENGTH] = '\0';
   
  /* reset the file pointer to the start of the block */
  vfs_seek (snssFile->fp, -TAG_LENGTH, VFS_SEEK_CUR);
  
  if (pos != vfs_tell(snssFile->fp))
    return SNSS_READ_FAILED;
  
  /* figure out which type of block it is */
  if (strcmp (tagBuffer, "BASR") == 0) 
  {
    *blockType = SNSS_BASR;
    return SNSS_OK;
  } 
  else if (strcmp (tagBuffer, "VRAM") == 0) 
  {
    *blockType = SNSS_VRAM;
    return SNSS_OK;
  }
  else if (strcmp (tagBuffer, "SRAM") == 0) 
  {
    *blockType = SNSS_SRAM;
    return SNSS_OK;
  }
  else if (strcmp (tagBuffer, "MPRD") == 0) 
  {
    *blockType = SNSS_MPRD;
    return SNSS_OK;
  }
  else if (strcmp (tagBuffer, "CNTR") == 0) 
  {
    *blockType = SNSS_CNTR;
    return SNSS_OK;
  }
  else if (strcmp (tagBuffer, "SOUN") == 0) 
  {
    *blockType = SNSS_SOUN;
    return SNSS_OK;
  }
  else 
  {
    *blockType = SNSS_UNKNOWN_BLOCK;
    return SNSS_OK;
  }
}
Example #7
0
off_t vfsfd_lseek(int fd, off_t offset, int whence)
{
    struct fdtab_entry *e = fdtab_get(fd);
    switch(e->type) {
    case FDTAB_TYPE_FILE:
        {
            enum vfs_seekpos vfs_whence;
            errval_t err;
            size_t retpos;

            switch(whence) {
            case SEEK_SET:
                vfs_whence = VFS_SEEK_SET;
                break;

            case SEEK_CUR:
                vfs_whence = VFS_SEEK_CUR;
                break;

            case SEEK_END:
                vfs_whence = VFS_SEEK_END;
                break;

            default:
                return -1;
            }

            err = vfs_seek((vfs_handle_t)e->handle, vfs_whence, offset);
            if(err_is_fail(err)) {
                DEBUG_ERR(err, "vfs_seek");
                return -1;
            }

            err = vfs_tell((vfs_handle_t)e->handle, &retpos);
            if(err_is_fail(err)) {
                DEBUG_ERR(err, "vfs_tell");
                return -1;
            }

            VFSFD_DEBUG("lseek(%d, %lld, %d) = %lu\n",
                         fd, offset, whence, retpos);

            return retpos;
        }
        break;

    default:
        return -1;
    }
}
Example #8
0
File: syscall.c Project: mrb852/osm
int syscall_seek(openfile_t file, int position) {
  int result = vfs_seek(file - 2, position);
  if (result < 0) {
    switch(result) {
      case VFS_UNUSABLE:
        kprintf("Error seeking in file. File system unusable.\n");
      break;
      case VFS_INVALID_PARAMS:
        kprintf("Error seeking in file: Invalid params\n");
      break;
      case VFS_NOT_OPEN:
        kprintf("Error seeking in file: File not open\n");
      break;
      default:
        kprintf("Error seeking in file: unknown error\n");
      break;
    }

  }
  return result;
}
Example #9
0
int vfs_write( struct VFS_HANDLE * handle, BYTE * buffer, DWORD size )
{
	int ret;
	if( handle == NULL )
		return FAIL;
	// test if the file ha been opened in read mode first
	if( (handle->mode & VFS_MODE_WRITE) != VFS_MODE_WRITE )
		return FAIL;
	// try to call the file system driver to write
	if( handle->mount->fs->calltable.write != NULL )
	{
		ret = handle->mount->fs->calltable.write( handle, buffer, size );
		if( ret != FAIL )
		{
			// set the file position to the end of the file if in append mode
			if( (handle->mode & VFS_MODE_APPEND) == VFS_MODE_APPEND )
				vfs_seek( handle, 0, VFS_SEEK_END );
			// return the write result
			return ret;
		}
	}
	// if we get here we have failed
	return FAIL;
}
Example #10
0
//--------------------------------------------------------------------------------------------
pip_t * load_one_pip_file_vfs( const char *szLoadName, pip_t * ppip )
{
    /// @details ZZ@> This function loads a particle template, returning bfalse if the file wasn't
    ///    found

    vfs_FILE* fileread;
    IDSZ idsz;
    char cTmp;

    fileread = vfs_openRead( szLoadName );
    if ( NULL == fileread )
    {
        return NULL;
    }

    pip_init( ppip );

    // set up the EGO_PROFILE_STUFF
    strncpy( ppip->name, szLoadName, SDL_arraysize( ppip->name ) );
    ppip->loaded = btrue;

    // read the 1 line comment at the top of the file
    vfs_gets( ppip->comment, SDL_arraysize( ppip->comment ) - 1, fileread );

    // rewind the file
    vfs_seek( fileread, 0 );

    // General data
    ppip->force = fget_next_bool( fileread );

    cTmp = fget_next_char( fileread );
    if ( 'L' == toupper( cTmp ) )  ppip->type = SPRITE_LIGHT;
    else if ( 'S' == toupper( cTmp ) )  ppip->type = SPRITE_SOLID;
    else if ( 'T' == toupper( cTmp ) )  ppip->type = SPRITE_ALPHA;

    ppip->image_base = fget_next_int( fileread );
    ppip->numframes = fget_next_int( fileread );
    ppip->image_add.base = fget_next_int( fileread );
    ppip->image_add.rand = fget_next_int( fileread );
    ppip->rotate_pair.base = fget_next_int( fileread );
    ppip->rotate_pair.rand = fget_next_int( fileread );
    ppip->rotate_add = fget_next_int( fileread );
    ppip->size_base = fget_next_int( fileread );
    ppip->size_add = fget_next_int( fileread );
    ppip->spdlimit = fget_next_float( fileread );
    ppip->facingadd = fget_next_int( fileread );

    // override the base rotation
    if ( ppip->image_base < 256 && prt_u != prt_direction[ ppip->image_base ] )
    {
        ppip->rotate_pair.base = prt_direction[ ppip->image_base ];
    };

    // Ending conditions
    ppip->end_water     = fget_next_bool( fileread );
    ppip->end_bump      = fget_next_bool( fileread );
    ppip->end_ground    = fget_next_bool( fileread );
    ppip->end_lastframe = fget_next_bool( fileread );
    ppip->end_time      = fget_next_int( fileread );

    // Collision data
    ppip->dampen     = fget_next_float( fileread );
    ppip->bump_money  = fget_next_int( fileread );
    ppip->bump_size   = fget_next_int( fileread );
    ppip->bump_height = fget_next_int( fileread );

    fget_next_range( fileread, &( ppip->damage ) );
    ppip->damagetype = fget_next_damage_type( fileread );

    // Lighting data
    cTmp = fget_next_char( fileread );
    if ( 'T' == toupper( cTmp ) ) ppip->dynalight.mode = DYNA_MODE_ON;
    else if ( 'L' == toupper( cTmp ) ) ppip->dynalight.mode = DYNA_MODE_LOCAL;
    else                             ppip->dynalight.mode = DYNA_MODE_OFF;

    ppip->dynalight.level   = fget_next_float( fileread );
    ppip->dynalight.falloff = fget_next_int( fileread );

    // Initial spawning of this particle
    ppip->facing_pair.base    = fget_next_int( fileread );
    ppip->facing_pair.rand    = fget_next_int( fileread );
    ppip->spacing_hrz_pair.base = fget_next_int( fileread );
    ppip->spacing_hrz_pair.rand = fget_next_int( fileread );
    ppip->spacing_vrt_pair.base  = fget_next_int( fileread );
    ppip->spacing_vrt_pair.rand  = fget_next_int( fileread );
    ppip->vel_hrz_pair.base     = fget_next_int( fileread );
    ppip->vel_hrz_pair.rand     = fget_next_int( fileread );
    ppip->vel_vrt_pair.base      = fget_next_int( fileread );
    ppip->vel_vrt_pair.rand      = fget_next_int( fileread );

    // Continuous spawning of other particles
    ppip->contspawn_delay      = fget_next_int( fileread );
    ppip->contspawn_amount    = fget_next_int( fileread );
    ppip->contspawn_facingadd = fget_next_int( fileread );
    ppip->contspawn_lpip       = fget_next_int( fileread );

    // End spawning of other particles
    ppip->endspawn_amount    = fget_next_int( fileread );
    ppip->endspawn_facingadd = fget_next_int( fileread );
    ppip->endspawn_lpip       = fget_next_int( fileread );

    // Bump spawning of attached particles
    ppip->bumpspawn_amount = fget_next_int( fileread );
    ppip->bumpspawn_lpip    = fget_next_int( fileread );

    // Random stuff  !!!BAD!!! Not complete
    ppip->daze_time    = fget_next_int( fileread );
    ppip->grog_time    = fget_next_int( fileread );
    ppip->spawnenchant = fget_next_bool( fileread );

    ppip->cause_roll    = fget_next_bool( fileread );  // !!Cause roll
    ppip->cause_pancake = fget_next_bool( fileread );

    ppip->needtarget         = fget_next_bool( fileread );
    ppip->targetcaster       = fget_next_bool( fileread );
    ppip->startontarget      = fget_next_bool( fileread );
    ppip->onlydamagefriendly = fget_next_bool( fileread );

    ppip->soundspawn = fget_next_int( fileread );

    ppip->end_sound = fget_next_int( fileread );

    ppip->friendlyfire = fget_next_bool( fileread );

    ppip->hateonly = fget_next_bool( fileread );

    ppip->newtargetonspawn = fget_next_bool( fileread );

    ppip->targetangle = fget_next_int( fileread ) >> 1;
    ppip->homing      = fget_next_bool( fileread );

    ppip->homingfriction = fget_next_float( fileread );
    ppip->homingaccel    = fget_next_float( fileread );
    ppip->rotatetoface   = fget_next_bool( fileread );

    goto_colon( NULL, fileread, bfalse );  // !!Respawn on hit is unused

    ppip->manadrain         = fget_next_int( fileread ) * 256;
    ppip->lifedrain         = fget_next_int( fileread ) * 256;

    // assume default end_wall
    ppip->end_wall = ppip->end_ground;

    // assume default damfx
    if ( ppip->homing )  ppip->damfx = DAMFX_NONE;

    // Read expansions
    while ( goto_colon( NULL, fileread, btrue ) )
    {
        idsz = fget_idsz( fileread );

        if ( idsz == MAKE_IDSZ( 'T', 'U', 'R', 'N' ) )       SET_BIT( ppip->damfx, DAMFX_NONE );        //ZF> This line doesnt do anything?
        else if ( idsz == MAKE_IDSZ( 'A', 'R', 'M', 'O' ) )  SET_BIT( ppip->damfx, DAMFX_ARMO );
        else if ( idsz == MAKE_IDSZ( 'B', 'L', 'O', 'C' ) )  SET_BIT( ppip->damfx, DAMFX_NBLOC );
        else if ( idsz == MAKE_IDSZ( 'A', 'R', 'R', 'O' ) )  SET_BIT( ppip->damfx, DAMFX_ARRO );
        else if ( idsz == MAKE_IDSZ( 'T', 'I', 'M', 'E' ) )  SET_BIT( ppip->damfx, DAMFX_TIME );
        else if ( idsz == MAKE_IDSZ( 'Z', 'S', 'P', 'D' ) )  ppip->zaimspd = fget_float( fileread );
        else if ( idsz == MAKE_IDSZ( 'F', 'S', 'N', 'D' ) )  ppip->end_sound_floor = fget_int( fileread );
        else if ( idsz == MAKE_IDSZ( 'W', 'S', 'N', 'D' ) )  ppip->end_sound_wall = fget_int( fileread );
        else if ( idsz == MAKE_IDSZ( 'W', 'E', 'N', 'D' ) )  ppip->end_wall = ( 0 != fget_int( fileread ) );
        else if ( idsz == MAKE_IDSZ( 'P', 'U', 'S', 'H' ) )  ppip->allowpush = ( 0 != fget_int( fileread ) );
        else if ( idsz == MAKE_IDSZ( 'D', 'L', 'E', 'V' ) )  ppip->dynalight.level_add = fget_int( fileread ) / 1000.0f;
        else if ( idsz == MAKE_IDSZ( 'D', 'R', 'A', 'D' ) )  ppip->dynalight.falloff_add = fget_int( fileread ) / 1000.0f;
        else if ( idsz == MAKE_IDSZ( 'I', 'D', 'A', 'M' ) )  ppip->intdamagebonus = ( 0 != fget_int( fileread ) );
        else if ( idsz == MAKE_IDSZ( 'W', 'D', 'A', 'M' ) )  ppip->wisdamagebonus = ( 0 != fget_int( fileread ) );
        else if ( idsz == MAKE_IDSZ( 'O', 'R', 'N', 'T' ) )
        {
            char cTmp = fget_first_letter( fileread );
            switch ( toupper( cTmp ) )
            {
                case 'X': ppip->orientation = ORIENTATION_X; break;  // put particle up along the world or body-fixed x-axis
                case 'Y': ppip->orientation = ORIENTATION_Y; break;  // put particle up along the world or body-fixed y-axis
                case 'Z': ppip->orientation = ORIENTATION_Z; break;  // put particle up along the world or body-fixed z-axis
                case 'V': ppip->orientation = ORIENTATION_V; break;  // vertical, like a candle
                case 'H': ppip->orientation = ORIENTATION_H; break;  // horizontal, like a plate
                case 'B': ppip->orientation = ORIENTATION_B; break;  // billboard
            }
        }
    }

    vfs_close( fileread );

    return ppip;
}
Example #11
0
static int
rand_bench_time(char *target, uint8_t *buffer, size_t filesize, size_t blocksize, size_t count, size_t randval, struct bench_res *result)
{
    size_t randbit;

    size_t rsize = 0;
    size_t wsize = 0;

    int ret = 0;


#define RAND_NEXT do {\
    randbit = ((randval >> 0) ^ (randval >> 3)) & 1;\
    randval = (randval >> 1) | (randbit << (sizeof(size_t) * CHAR_BIT - 1));\
} while (0)

#define RAND_BLOCK ((randval % (filesize / blocksize)) * blocksize)

    if (filesize % blocksize != 0) {
        printf("Please spcifiy the filesize as a multiple of blocksize\n");
        return 0;
    }

    errval_t err;
    vfs_handle_t f = NULL;
    char *path = vfs_path_mkabsolute(cwd, target);
    err = vfs_open(path, &f);

    if (err_is_fail(err)) {
        printf("%s: %s\n", path, err_getstring(err));
        return 1;
    }

#if defined(__x86_64__) || defined(__i386__)
    uint64_t tscperms;
    err = sys_debug_get_tsc_per_ms(&tscperms);
    assert(err_is_ok(err));

    //printf("ticks per millisec: %" PRIu64 "\n", tscperms);
    uint64_t start = rdtsc();
#endif

    size_t count2 = count;
    while (count2--) {
        RAND_NEXT;
        vfs_seek(f, VFS_SEEK_SET, RAND_BLOCK);

        err = vfs_read(f, buffer, blocksize, &rsize);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "error reading file");
            ret = 1;
            goto out;
        }

        assert(rsize == blocksize);
    }
#if defined(__x86_64__) || defined(__i386__)
    uint64_t stop = rdtsc();
    uint64_t elapsed_msecs = ((stop - start) / tscperms);
    double elapsed_secs = (double)elapsed_msecs/1000.0;

    result->read = elapsed_secs;

    start = rdtsc();
#endif

    count2 = count;
    while(count2--) {
        RAND_NEXT;
        vfs_seek(f, VFS_SEEK_SET, RAND_BLOCK);

        err = vfs_write(f, buffer, blocksize, &wsize);
        if (err_is_fail(err) || wsize == 0) {
            DEBUG_ERR(err, "error writing file");
            ret = 1;
            goto out;
        }

        assert(wsize == blocksize);
        vfs_flush(f);
    }

#if defined(__x86_64__) || defined(__i386__)
    stop = rdtsc();
    elapsed_msecs = ((stop - start) / tscperms);
    elapsed_secs = (double)elapsed_msecs/1000.0;

    result->write = elapsed_secs;
#endif

out:
    if (f != NULL) {
        err = vfs_close(f);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "in vfs_close");
        }
    }

    return ret;
}
Example #12
0
static int
shuffle_file(int argc, char *argv[])
{
    if (argc != 6) {
        printf("Usage: %s <file> <filesize> <blocksize> <count> <seed>\n", argv[0]);

        return 0;
    }

    size_t filesize = atoi(argv[2]);
    size_t blocksize = atoi(argv[3]);
    size_t count = atoi(argv[4]);
    size_t randval = atoi(argv[5]);
    size_t randbit;
    char * filename = argv[1];

    size_t rsize = 0;
    size_t wsize = 0;

    int ret = 0;


#define RAND_NEXT do {\
    randbit = ((randval >> 0) ^ (randval >> 3)) & 1;\
    randval = (randval >> 1) | (randbit << (sizeof(size_t) * CHAR_BIT - 1));\
} while (0)

#define RAND_BLOCK ((randval % (filesize / blocksize)) * blocksize)

    if (filesize % blocksize != 0) {
        printf("Please spcifiy the filesize as a multiple of blocksize\n");
        return 0;
    }

    uint8_t * buffer = malloc(blocksize);
    
    if (buffer == NULL) {
        printf("failed to allocate buffer of size %zd\n", blocksize);
        return 1;
    }

    errval_t err;
    vfs_handle_t f = NULL;
    char *path = vfs_path_mkabsolute(cwd, filename);
    err = vfs_open(path, &f);

    if (err_is_fail(err)) {
        printf("%s: %s\n", path, err_getstring(err));
        return 1;
    }

#if defined(__x86_64__) || defined(__i386__)
    uint64_t tscperms;
    err = sys_debug_get_tsc_per_ms(&tscperms);
    assert(err_is_ok(err));

    //printf("ticks per millisec: %" PRIu64 "\n", tscperms);
    uint64_t start = rdtsc();
#endif

    size_t count2 = count;
    while (count2--) {
        RAND_NEXT;
        vfs_seek(f, VFS_SEEK_SET, RAND_BLOCK);
        
        err = vfs_read(f, buffer, blocksize, &rsize);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "error reading file");
            ret = 1;
            goto out;
        }

        assert(rsize == blocksize);

        RAND_NEXT;
        vfs_seek(f, VFS_SEEK_SET, RAND_BLOCK);

        err = vfs_write(f, buffer, blocksize, &wsize);
        if (err_is_fail(err) || wsize == 0) {
            DEBUG_ERR(err, "error writing file");
            ret = 1;
            goto out;
        }

        assert(wsize == blocksize);
    }

#if defined(__x86_64__) || defined(__i386__)
    uint64_t stop = rdtsc();
    uint64_t elapsed_msecs = ((stop - start) / tscperms);
    double elapsed_secs = (double)elapsed_msecs/1000.0;

    printf("start: %" PRIu64 " stop: %" PRIu64 "\n", start, stop);

    double kbps = ((double)(count * blocksize) / 1024.0) / elapsed_secs;

    printf("%zu bytes read. %zu bytes written. %f s, %f kB/s\n", count * blocksize, count * blocksize, elapsed_secs, kbps); 
#endif

out:
    if (buffer != NULL)
        free(buffer);
    
    if (f != NULL) {
        err = vfs_close(f);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "in vfs_close");
        }
    }

    return ret;
}
Example #13
0
static errval_t
fill_bench(char *target, uint8_t *buffer, size_t blocksize, size_t count, struct bench_res *result)
{
    vfs_handle_t target_vh = NULL;

    size_t blocks_written = 0;
    size_t blocks_read = 0;

    size_t total_bytes_read = 0;
    size_t total_bytes_written = 0;

    uint64_t start = 0, stop = 0;
    errval_t err;

#if defined(__x86_64__) || defined(__i386__)
    uint64_t tscperms;
    err = sys_debug_get_tsc_per_ms(&tscperms);
    assert(err_is_ok(err));
#endif

    errval_t ret = 0;

    err = vfs_open(target, &target_vh);
    if (err_is_fail(err)) {
        printf("%s: %s (%ld)\n", target, err_getstring(err), err);
        return err;
    }

#if defined(__x86_64__) || defined(__i386__)
    start = rdtsc();
#endif

    if (buffer == NULL) {
        ret = -2;
        printf("failed to allocate buffer of size %zd\n", blocksize);
        goto out;
    }

    size_t wsize;
    do {
        // initialize buffer
        for (size_t i = 0; i < blocksize; i += sizeof(size_t))
            *((size_t *)(buffer + i)) = blocks_written;

        // write to file
        size_t wpos = 0;
        while (wpos < blocksize) {
            if (wpos > 0)
                printf("was unable to write the whole chunk of size %zd. Now at pos: %zd of buffer\n", blocksize, wpos);

            err = vfs_write(target_vh, &buffer[wpos], blocksize - wpos, &wsize);
            if (err_is_fail(err) || wsize == 0) {
                DEBUG_ERR(err, "error writing file");
                ret = err;
                goto out;
            }
            wpos += wsize;
            total_bytes_written += wsize;
        }

        blocks_written++;

    } while (blocksize > 0 && !(count > 0 && blocks_written >= count));

    err = vfs_close(target_vh);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "in vfs_close");
        goto out;
    }


#if defined(__x86_64__) || defined(__i386__)
    stop = rdtsc();
    {
        uint64_t elapsed_msecs = ((stop - start) / tscperms);
        double elapsed_secs = (double)elapsed_msecs/1000.0;

        result->write = ((double)total_bytes_written / 1024.0) / elapsed_secs;
	printf("%lf\n", result->write);
    }

#endif
    err = vfs_open(target, &target_vh);
    if (err_is_fail(err)) {
        printf("%s: %s (%ld)\n", target, err_getstring(err), err);
        goto out;
    }
    err = vfs_seek(target_vh, VFS_SEEK_SET, 0);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "seeking failed");
        ret = err;
        goto out;
    }
#if defined(__x86_64__) || defined(__i386__)
    start = rdtsc();
#endif

    size_t rsize;
    do {
        // read
        size_t rpos = 0;
        while (rpos < blocksize) {
            if (rpos > 0)
                printf("was unable to read whole chunk of size %zd. Now at pos: %zd of buffer\n", blocksize, rpos);

            err = vfs_read(target_vh, &buffer[rpos], blocksize - rpos, &rsize);
            if (err_is_fail(err) || wsize == 0) {
                DEBUG_ERR(err, "error reading file");
                ret = err;
                goto out;
            }
            rpos += rsize;
            total_bytes_read += rsize;
        }

        // verify data
        for (size_t i = 0; i < blocksize; i += sizeof(size_t)) {
            if (*((size_t *)(buffer + i)) != blocks_read) {
                printf("Verification failed! Block %zd, value %zd\n", blocks_read, *((size_t *)(buffer + i)) );
                ret = err;
                goto out;
            }
        }

        blocks_read++;
    } while (blocksize > 0 && !(count > 0 && blocks_read >= count));

out:
    if (target_vh != NULL) {
        err = vfs_close(target_vh);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "in vfs_close");
            ret = err;
        }
    }

#if defined(__x86_64__) || defined(__i386__)
    stop = rdtsc();
    {
        uint64_t elapsed_msecs = ((stop - start) / tscperms);
        double elapsed_secs = (double)elapsed_msecs/1000.0;

        result->read = ((double)total_bytes_read / 1024.0) / elapsed_secs;
	printf("%lf\n", result->read);
    }
#endif

    return ret;
}
Example #14
0
File: elf.c Project: PtxDK/OSM
/**
 * Parse useful information from a given ELF file into the ELF info
 * structure.
 *
 * @param file The ELF file
 *
 * @param elf Information found in the file is returned in this
 * structure. In case of error this structure may contain arbitrary
 * values.
 *
 * @return 0 on failure, other values indicate success.
 */
int elf_parse_header(elf_info_t *elf, openfile_t file)
{
  Elf32_Ehdr elf_hdr;
  Elf64_Ehdr elf_hdr64;
  Elf32_Phdr program_hdr;
  Elf64_Phdr program_hdr64;
  uint8_t use64 = 0;

  int i;
  int current_position;
  int segs = 0;
#define SEG_RO 1
#define SEG_RW 2

  /* Read the ELF header into the 32 bit, but size of 64 */
  if (vfs_read(file, &elf_hdr64, sizeof(elf_hdr64))
      != sizeof(elf_hdr64)) {
    return -1;
  }

  /* Nasty hack */
  memcopy(sizeof(elf_hdr), &elf_hdr, &elf_hdr64);

  /* Check that the ELF magic is correct. */
  if (from_big_endian32(elf_hdr.e_ident.i) != ELF_MAGIC) {
    return -2;
  }

  /* Not an executable file */
  if (elf_hdr.e_type != ET_EXEC) {
    return -3;
  }

  /* Now, check architecture */
  if (elf_hdr.e_ident.c[EI_CLASS] & ELFCLASS64) {
    use64 = 1;
  }

  /* No program headers */
  if (use64) {
    if (elf_hdr64.e_phnum == 0) {
      return -4;
    }
  }
  else {
    if (elf_hdr.e_phnum == 0) {
      return -4;
    }
  }

  /* Zero the return structure. Uninitialized data is bad(TM). */
  memoryset(elf, 0, sizeof(*elf));

  /* Get the entry point */
  if (use64)
    elf->entry_point = (uint32_t)elf_hdr64.e_entry;
  else
    elf->entry_point = elf_hdr.e_entry;

  /* Seek to the program header table */
  if (use64)
    current_position = (uint32_t)elf_hdr64.e_phoff;
  else
    current_position = elf_hdr.e_phoff;

  vfs_seek(file, current_position);

  /* Read the program headers. */
  if (use64) {
    for (i = 0; i < elf_hdr64.e_phnum; i++) {
      if (vfs_read(file, &program_hdr64, sizeof(program_hdr64))
          != sizeof(program_hdr64)) {
        return -6;
      }

      switch (program_hdr64.p_type) {
      case PT_NULL:
      case PT_NOTE:
      case PT_PHDR:
        /* These program headers can be ignored */
        break;
      case PT_LOAD:
        /* These are the ones we are looking for */

        /* The RW segment */
        if (program_hdr64.p_flags & PF_W) {
          if (segs & SEG_RW) { /* already have an RW segment*/
            return -7;
          }
          segs |= SEG_RW;

          elf->rw_location = program_hdr64.p_offset;
          elf->rw_size = program_hdr64.p_filesz;
          elf->rw_vaddr = program_hdr64.p_vaddr;
          /* memory size rounded up to the page boundary, in pages */
          elf->rw_pages =
            (program_hdr64.p_memsz + PAGE_SIZE - 1) / PAGE_SIZE;

          /* The RO segment */
        } else {
          if (segs & SEG_RO) { /* already have an RO segment*/
            return -8;
          }
          segs |= SEG_RO;

          elf->ro_location = program_hdr64.p_offset;
          elf->ro_size = program_hdr64.p_filesz;
          elf->ro_vaddr = program_hdr64.p_vaddr;
          /* memory size rounded up to the page boundary, in pages */
          elf->ro_pages =
            (program_hdr64.p_memsz + PAGE_SIZE - 1) / PAGE_SIZE;
        }

        break;
        /* Other program headers indicate an incompatible file *or* a file
           with extra headers.  Just ignore. */
      }

      /* In case the program header size is non-standard: */
      current_position += sizeof(program_hdr64);
      vfs_seek(file, current_position);
    }
  }
  else {
    for (i = 0; i < elf_hdr.e_phnum; i++) {
      if (vfs_read(file, &program_hdr, sizeof(program_hdr))
          != sizeof(program_hdr)) {
        return -6;
      }

      switch (program_hdr.p_type) {
      case PT_NULL:
      case PT_NOTE:
      case PT_PHDR:
        /* These program headers can be ignored */
        break;
      case PT_LOAD:
        /* These are the ones we are looking for */

        /* The RW segment */
        if (program_hdr.p_flags & PF_W) {
          if (segs & SEG_RW) { /* already have an RW segment*/
            return -7;
          }
          segs |= SEG_RW;

          elf->rw_location = program_hdr.p_offset;
          elf->rw_size = program_hdr.p_filesz;
          elf->rw_vaddr = program_hdr.p_vaddr;
          /* memory size rounded up to the page boundary, in pages */
          elf->rw_pages =
            (program_hdr.p_memsz + PAGE_SIZE - 1) / PAGE_SIZE;

          /* The RO segment */
        } else {
          if (segs & SEG_RO) { /* already have an RO segment*/
            return -8;
          }
          segs |= SEG_RO;

          elf->ro_location = program_hdr.p_offset;
          elf->ro_size = program_hdr.p_filesz;
          elf->ro_vaddr = program_hdr.p_vaddr;
          /* memory size rounded up to the page boundary, in pages */
          elf->ro_pages =
            (program_hdr.p_memsz + PAGE_SIZE - 1) / PAGE_SIZE;
        }

        break;
        /* Other program headers indicate an incompatible file *or* a file
           with extra headers.  Just ignore. */
      }

      /* In case the program header size is non-standard: */
      current_position += sizeof(program_hdr);
      vfs_seek(file, current_position);
    }
  }

  /* Make sure either RW or RO segment is present: */
  return (segs > 0);
}
Example #15
0
/**
 * Starts one userland process. The thread calling this function will
 * be used to run the process and will therefore never return from
 * this function. This function asserts that no errors occur in
 * process startup (the executable file exists and is a valid ecoff
 * file, enough memory is available, file operations succeed...).
 * Therefore this function is not suitable to allow startup of
 * arbitrary processes.
 *
 * @executable The name of the executable to be run in the userland
 * process
 */
void process_start(uint32_t pid)
{
    thread_table_t *my_entry;
    pagetable_t *pagetable;
    uint32_t phys_page;
    context_t user_context;
    uint32_t stack_bottom;
    elf_info_t elf;
    openfile_t file;
    const char* executable;

    int i;

    interrupt_status_t intr_status;

    my_entry = thread_get_current_thread_entry();
    my_entry->process_id = pid;
    executable = process_table[pid].executable;

    /* If the pagetable of this thread is not NULL, we are trying to
       run a userland process for a second time in the same thread.
       This is not possible. */
    KERNEL_ASSERT(my_entry->pagetable == NULL);

    pagetable = vm_create_pagetable(thread_get_current_thread());
    KERNEL_ASSERT(pagetable != NULL);

    intr_status = _interrupt_disable();
    my_entry->pagetable = pagetable;
    _interrupt_set_state(intr_status);

    file = vfs_open((char *)executable);
    /* Make sure the file existed and was a valid ELF file */
    KERNEL_ASSERT(file >= 0);
    KERNEL_ASSERT(elf_parse_header(&elf, file));

    /* Trivial and naive sanity check for entry point: */
    KERNEL_ASSERT(elf.entry_point >= PAGE_SIZE);

    /* Calculate the number of pages needed by the whole process
       (including userland stack). Since we don't have proper tlb
       handling code, all these pages must fit into TLB. */
    KERNEL_ASSERT(elf.ro_pages + elf.rw_pages + CONFIG_USERLAND_STACK_SIZE
		  <= _tlb_get_maxindex() + 1);

    /* Allocate and map stack */
    for(i = 0; i < CONFIG_USERLAND_STACK_SIZE; i++) {
        phys_page = pagepool_get_phys_page();
        KERNEL_ASSERT(phys_page != 0);
        vm_map(my_entry->pagetable, phys_page, 
               (USERLAND_STACK_TOP & PAGE_SIZE_MASK) - i*PAGE_SIZE, 1);
    }

    /* Allocate and map pages for the segments. We assume that
       segments begin at page boundary. (The linker script in tests
       directory creates this kind of segments) */
    for(i = 0; i < (int)elf.ro_pages; i++) {
        phys_page = pagepool_get_phys_page();
        KERNEL_ASSERT(phys_page != 0);
        vm_map(my_entry->pagetable, phys_page, 
               elf.ro_vaddr + i*PAGE_SIZE, 1);
    }

    for(i = 0; i < (int)elf.rw_pages; i++) {
        phys_page = pagepool_get_phys_page();
        KERNEL_ASSERT(phys_page != 0);
        vm_map(my_entry->pagetable, phys_page, 
               elf.rw_vaddr + i*PAGE_SIZE, 1);
    }

    /* Put the mapped pages into TLB. Here we again assume that the
       pages fit into the TLB. After writing proper TLB exception
       handling this call should be skipped. */
    //intr_status = _interrupt_disable();
    //tlb_fill(my_entry->pagetable);
    //_interrupt_set_state(intr_status);
    
    /* Now we may use the virtual addresses of the segments. */

    /* Zero the pages. */
    memoryset((void *)elf.ro_vaddr, 0, elf.ro_pages*PAGE_SIZE);
    memoryset((void *)elf.rw_vaddr, 0, elf.rw_pages*PAGE_SIZE);

    stack_bottom = (USERLAND_STACK_TOP & PAGE_SIZE_MASK) - 
        (CONFIG_USERLAND_STACK_SIZE-1)*PAGE_SIZE;
    memoryset((void *)stack_bottom, 0, CONFIG_USERLAND_STACK_SIZE*PAGE_SIZE);

    /* Copy segments */

    if (elf.ro_size > 0) {
	/* Make sure that the segment is in proper place. */
        KERNEL_ASSERT(elf.ro_vaddr >= PAGE_SIZE);
        KERNEL_ASSERT(vfs_seek(file, elf.ro_location) == VFS_OK);
        KERNEL_ASSERT(vfs_read(file, (void *)elf.ro_vaddr, elf.ro_size)
		      == (int)elf.ro_size);
    }

    if (elf.rw_size > 0) {
	/* Make sure that the segment is in proper place. */
        KERNEL_ASSERT(elf.rw_vaddr >= PAGE_SIZE);
        KERNEL_ASSERT(vfs_seek(file, elf.rw_location) == VFS_OK);
        KERNEL_ASSERT(vfs_read(file, (void *)elf.rw_vaddr, elf.rw_size)
		      == (int)elf.rw_size);
    }


    /* Set the dirty bit to zero (read-only) on read-only pages. */
    for(i = 0; i < (int)elf.ro_pages; i++) {
        vm_set_dirty(my_entry->pagetable, elf.ro_vaddr + i*PAGE_SIZE, 0);
    }

    /* Insert page mappings again to TLB to take read-only bits into use */
    //intr_status = _interrupt_disable();
    //tlb_fill(my_entry->pagetable);
    //_interrupt_set_state(intr_status);

    /* Initialize the user context. (Status register is handled by
       thread_goto_userland) */
    memoryset(&user_context, 0, sizeof(user_context));
    user_context.cpu_regs[MIPS_REGISTER_SP] = USERLAND_STACK_TOP;
    user_context.pc = elf.entry_point;

    vfs_close(file);

    thread_goto_userland(&user_context);

    KERNEL_PANIC("thread_goto_userland failed.");
}
Example #16
0
static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
{
	bool cont = true;
	
	/*
	 * The connection was opened via the IPC_CONNECT_ME_TO call.
	 * This call needs to be answered.
	 */
	async_answer_0(iid, EOK);
	
	while (cont) {
		ipc_call_t call;
		ipc_callid_t callid = async_get_call(&call);
		
		if (!IPC_GET_IMETHOD(call))
			break;
		
		switch (IPC_GET_IMETHOD(call)) {
		case VFS_IN_REGISTER:
			vfs_register(callid, &call);
			cont = false;
			break;
		case VFS_IN_MOUNT:
			vfs_mount(callid, &call);
			break;
		case VFS_IN_UNMOUNT:
			vfs_unmount(callid, &call);
			break;
		case VFS_IN_OPEN:
			vfs_open(callid, &call);
			break;
		case VFS_IN_CLOSE:
			vfs_close(callid, &call);
			break;
		case VFS_IN_READ:
			vfs_read(callid, &call);
			break;
		case VFS_IN_WRITE:
			vfs_write(callid, &call);
			break;
		case VFS_IN_SEEK:
			vfs_seek(callid, &call);
			break;
		case VFS_IN_TRUNCATE:
			vfs_truncate(callid, &call);
			break;
		case VFS_IN_FSTAT:
			vfs_fstat(callid, &call);
			break;
		case VFS_IN_STAT:
			vfs_stat(callid, &call);
			break;
		case VFS_IN_MKDIR:
			vfs_mkdir(callid, &call);
			break;
		case VFS_IN_UNLINK:
			vfs_unlink(callid, &call);
			break;
		case VFS_IN_RENAME:
			vfs_rename(callid, &call);
			break;
		case VFS_IN_SYNC:
			vfs_sync(callid, &call);
			break;
		case VFS_IN_DUP:
			vfs_dup(callid, &call);
			break;
		case VFS_IN_WAIT_HANDLE:
			vfs_wait_handle(callid, &call);
			break;
		case VFS_IN_MTAB_GET:
			vfs_get_mtab(callid, &call);
			break;
		default:
			async_answer_0(callid, ENOTSUP);
			break;
		}
	}
	
	/*
	 * Open files for this client will be cleaned up when its last
	 * connection fibril terminates.
	 */
}
Example #17
0
/* Set the reading or writing position of the open file represented by
   filehandle to the indicated absolute offset (in bytes from the
   beginning). Returns 0 on success, a negative number on
   error. Seeking beyond the end of the file sets the position to the
   end and produces an error return value. */
int syscall_seek(int filehandle, int offset){
    return vfs_seek((openfile_t)filehandle, offset);
}
Example #18
0
/* Return non-zero on error. */
int setup_new_process(TID_t thread,
                      const char *executable, const char **argv_src,
                      virtaddr_t *entry_point, virtaddr_t *stack_top)
{
  pagetable_t *pagetable;
  elf_info_t elf;
  openfile_t file;
  uintptr_t phys_page;
  int i, res;
  thread_table_t *thread_entry = thread_get_thread_entry(thread);

  int argc = 1;
  virtaddr_t argv_begin;
  virtaddr_t argv_dst;
  int argv_elem_size;
  virtaddr_t argv_elem_dst;

  file = vfs_open((char *)executable);

  /* Make sure the file existed and was a valid ELF file */
  if (file < 0) {
    return -1;
  }

  res = elf_parse_header(&elf, file);
  if (res < 0) {
    return -1;
  }

  /* Trivial and naive sanity check for entry point: */
  if (elf.entry_point < PAGE_SIZE) {
    return -1;
  }

  *entry_point = elf.entry_point;

  pagetable = vm_create_pagetable(thread);

  thread_entry->pagetable = pagetable;

  /* Allocate and map stack */
  for(i = 0; i < CONFIG_USERLAND_STACK_SIZE; i++) {
    phys_page = physmem_allocblock();
    KERNEL_ASSERT(phys_page != 0);
    /* Zero the page */
    memoryset((void*)ADDR_PHYS_TO_KERNEL(phys_page), 0, PAGE_SIZE);
    vm_map(pagetable, phys_page,
           (USERLAND_STACK_TOP & PAGE_SIZE_MASK) - i*PAGE_SIZE, 1);
  }

  /* Allocate and map pages for the segments. We assume that
     segments begin at page boundary. (The linker script in tests
     directory creates this kind of segments) */
  for(i = 0; i < (int)elf.ro_pages; i++) {
    int left_to_read = elf.ro_size - i*PAGE_SIZE;
    phys_page = physmem_allocblock();
    KERNEL_ASSERT(phys_page != 0);
    /* Zero the page */
    memoryset((void*)ADDR_PHYS_TO_KERNEL(phys_page), 0, PAGE_SIZE);
    /* Fill the page from ro segment */
    if (left_to_read > 0) {
      KERNEL_ASSERT(vfs_seek(file, elf.ro_location + i*PAGE_SIZE) == VFS_OK);
      KERNEL_ASSERT(vfs_read(file, (void*)ADDR_PHYS_TO_KERNEL(phys_page),
                             MIN(PAGE_SIZE, left_to_read))
                    == (int) MIN(PAGE_SIZE, left_to_read));
    }
    vm_map(pagetable, phys_page,
           elf.ro_vaddr + i*PAGE_SIZE, 0);
  }

  for(i = 0; i < (int)elf.rw_pages; i++) {
    int left_to_read = elf.rw_size - i*PAGE_SIZE;
    phys_page = physmem_allocblock();
    KERNEL_ASSERT(phys_page != 0);
    /* Zero the page */
    memoryset((void*)ADDR_PHYS_TO_KERNEL(phys_page), 0, PAGE_SIZE);
    /* Fill the page from rw segment */
    if (left_to_read > 0) {
      KERNEL_ASSERT(vfs_seek(file, elf.rw_location + i*PAGE_SIZE) == VFS_OK);
      KERNEL_ASSERT(vfs_read(file, (void*)ADDR_PHYS_TO_KERNEL(phys_page),
                             MIN(PAGE_SIZE, left_to_read))
                    == (int) MIN(PAGE_SIZE, left_to_read));
    }
    vm_map(pagetable, phys_page,
           elf.rw_vaddr + i*PAGE_SIZE, 1);
  }

  /* Set up argc and argv on the stack. */

  /* Start by preparing ancillary information for the new process argv. */
  if (argv_src != NULL)
    for (i = 0; argv_src[i] != NULL; i++) {
      argc++;
    }

  argv_begin = USERLAND_STACK_TOP - (argc * sizeof(virtaddr_t));
  argv_dst = argv_begin;

  /* Prepare for copying executable. */
  argv_elem_size = strlen(executable) + 1;
  argv_elem_dst = argv_dst - wordpad(argv_elem_size);

  /* Copy executable to argv[0] location. */
  vm_memwrite(pagetable,
              argv_elem_size,
              argv_elem_dst,
              executable);
  /* Set argv[i] */
  vm_memwrite(pagetable,
              sizeof(virtaddr_t),
              argv_dst,
              &argv_elem_dst);

  /* Move argv_dst to &argv[1]. */
  argv_dst += sizeof(virtaddr_t);

  if (argv_src != NULL) {
    for (i = 0; argv_src[i] != NULL; i++) {
      /* Compute the size of argv[i+1] */
      argv_elem_size = strlen(argv_src[i]) + 1;
      argv_elem_dst -= wordpad(argv_elem_size);

      /* Write the 'i+1'th element of argv */
      vm_memwrite(pagetable,
                  argv_elem_size,
                  argv_elem_dst,
                  argv_src[i]);

      /* Write argv[i+1] */
      vm_memwrite(pagetable,
                  sizeof(virtaddr_t),
                  argv_dst,
                  &argv_elem_dst);

      /* Move argv_dst to next element of argv. */
      argv_dst += sizeof(virtaddr_t);
    }
  }

  /* Write argc to the stack. */
  vm_memwrite(pagetable,
              sizeof(int),
              argv_elem_dst - sizeof(int),
              &argc);
  /* Write argv to the stack. */
  vm_memwrite(pagetable,
              sizeof(virtaddr_t),
              argv_elem_dst - sizeof(int) - sizeof(virtaddr_t),
              &argv_begin);

  /* Stack pointer points at argv. */
  *stack_top = argv_elem_dst - sizeof(int) - sizeof(virtaddr_t);

  return 0;
}
Example #19
0
File: io.c Project: mrb852/osm-exam
int io_seek(openfile_t file, int offset) {
  file -= 3;
  if (!process_has_open_file(file)) return VFS_NOT_OPEN_IN_PROCESS;
  return vfs_seek(file, offset);
}
Example #20
0
File: elf.c Project: Eckankar/OSM-G
/**
 * Parse useful information from a given ELF file into the ELF info
 * structure.
 *
 * @param file The ELF file
 *
 * @param elf Information found in the file is returned in this
 * structure. In case of error this structure may contain arbitrary
 * values.
 *
 * @return 0 on failure, other values indicate success.
 */
int elf_parse_header(elf_info_t *elf, openfile_t file)
{
    Elf32_Ehdr elf_hdr;
    Elf32_Phdr program_hdr;

    int i;
    int current_position;
    int segs = 0;
#define SEG_RO 1
#define SEG_RW 2

    /* Read the ELF header */
    if (vfs_read(file, &elf_hdr, sizeof(elf_hdr))
	!= sizeof(elf_hdr)) {
        return 0;
    }

    /* Check that the ELF magic is correct. */
    if (EI_MAGIC(elf_hdr.e_ident) != ELF_MAGIC) {
        return 0;
    }

    /* File data is not MIPS 32 bit big-endian */
    if (elf_hdr.e_ident[EI_CLASS] != ELFCLASS32
	|| elf_hdr.e_ident[EI_DATA] != ELFDATA2MSB
	|| elf_hdr.e_machine != EM_MIPS) {
	return 0;
    }

    /* Invalid ELF version */
    if (elf_hdr.e_version != EV_CURRENT 
	|| elf_hdr.e_ident[EI_VERSION] != EV_CURRENT) {
	return 0;
    }

    /* Not an executable file */
    if (elf_hdr.e_type != ET_EXEC) {
	return 0;
    }

    /* No program headers */
    if (elf_hdr.e_phnum == 0) {
	return 0;
    }

    /* Zero the return structure. Uninitialized data is bad(TM). */
    memoryset(elf, 0, sizeof(*elf));

    /* Get the entry point */
    elf->entry_point = elf_hdr.e_entry;

    /* Seek to the program header table */
    current_position = elf_hdr.e_phoff;
    vfs_seek(file, current_position);

    /* Read the program headers. */
    for (i = 0; i < elf_hdr.e_phnum; i++) {
	if (vfs_read(file, &program_hdr, sizeof(program_hdr))
	    != sizeof(program_hdr)) {
	    return 0;
	}

	switch (program_hdr.p_type) {
	case PT_NULL:
	case PT_NOTE:
	case PT_PHDR:
	    /* These program headers can be ignored */
	    break;
	case PT_LOAD:
	    /* These are the ones we are looking for */

	    /* The RW segment */
	    if (program_hdr.p_flags & PF_W) {
		if (segs & SEG_RW) { /* already have an RW segment*/
		    return 0;
		}
		segs |= SEG_RW;

		elf->rw_location = program_hdr.p_offset;
		elf->rw_size = program_hdr.p_filesz;
		elf->rw_vaddr = program_hdr.p_vaddr;
		/* memory size rounded up to the page boundary, in pages */
		elf->rw_pages = 
		    (program_hdr.p_memsz + PAGE_SIZE - 1) / PAGE_SIZE;

	    /* The RO segment */
	    } else {
		if (segs & SEG_RO) { /* already have an RO segment*/
		    return 0;
		}
		segs |= SEG_RO; 

		elf->ro_location = program_hdr.p_offset;
		elf->ro_size = program_hdr.p_filesz;
		elf->ro_vaddr = program_hdr.p_vaddr;
		/* memory size rounded up to the page boundary, in pages */
		elf->ro_pages = 
		    (program_hdr.p_memsz + PAGE_SIZE - 1) / PAGE_SIZE;
	    }

	    break;
	default:
	    /* Other program headers indicate an incompatible file */
	    return 0;
	}

	/* In case the program header size is non-standard: */
	current_position += sizeof(program_hdr);
	vfs_seek(file, current_position);
    }

    /* Make sure either RW or RO segment is present: */
    return (segs > 0);
}
Example #21
0
/**
 * \brief Page fault handler
 *
 * \param memobj  The memory object
 * \param region  The associated vregion
 * \param offset  Offset into memory object of the page fault
 * \param type    The fault type
 */
static errval_t pagefault(struct memobj *memobj, struct vregion *vregion,
                          genvaddr_t offset, vm_fault_type_t type)
{
    errval_t err;
    assert(memobj->type == MEMOBJ_VFS);
    struct memobj_vfs *mv = (struct memobj_vfs *)memobj;
    struct memobj_anon *anon = &mv->anon;
    struct vspace *vspace = vregion_get_vspace(vregion);
    struct pmap *pmap     = vspace_get_pmap(vspace);
    genvaddr_t vregion_base  = vregion_get_base_addr(vregion);
    genvaddr_t vregion_off   = vregion_get_offset(vregion);

    assert(vregion_off == 0); // not sure if we handle this correctly

    // Walk the ordered list to find the matching frame, but don't map it yet
    struct memobj_frame_list *walk = anon->frame_list;
    while (walk) {
        if (offset >= walk->offset && offset < walk->offset + walk->size) {
            break;
        }
        walk = walk->next;
    }

    if (walk == NULL) {
        return LIB_ERR_MEMOBJ_WRONG_OFFSET;
    }

    genvaddr_t map_offset = vregion_off + walk->offset;
    size_t nbytes = walk->size;

    // how much do we need to read from the file?
    if (map_offset >= mv->filesize) {
        // nothing
        goto do_map;
    } else if (map_offset + nbytes > mv->filesize) {
        // limit size of read to maximum mapping (rest is zero-filled)
        nbytes = mv->filesize - map_offset;
    }

#if 0
    debug_printf("fault at offset %lx, mapping at %lx-%lx from file data %lx-%lx\n",
                 offset, vregion_base + map_offset,
                 vregion_base + map_offset + walk->size,
                 map_offset + mv->offset,
                 map_offset + mv->offset + nbytes);
#endif

    // map frame writable at temporary location so that we can safely fill it
    void *buf;
    struct memobj *tmp_memobj = NULL;
    struct vregion *tmp_vregion = NULL;
    err = vspace_map_one_frame(&buf, walk->size, walk->frame,
                               &tmp_memobj, &tmp_vregion);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "error setting up temp mapping in mmap pagefault handler\n");
        return err; // XXX
    }

    // seek file handle
    err = vfs_seek(mv->vh, VFS_SEEK_SET, map_offset + mv->offset);
    if (err_is_fail(err)) {
        return err;
    }

    // read contents into frame
    size_t rsize, pos = 0;
    do {
        err = vfs_read(mv->vh, (char *)buf + pos, nbytes - pos, &rsize);
        if (err_is_fail(err)) {
            break;
        }
        pos += rsize;
    } while(rsize > 0 && pos < nbytes);

    // destroy temp mappings
    // FIXME: the API for tearing down mappings is really unclear! is this sufficient?
    err = vregion_destroy(tmp_vregion);
    assert(err_is_ok(err));
    err = memobj_destroy_one_frame(tmp_memobj);
    assert(err_is_ok(err));
    //free(tmp_vregion);
    //free(tmp_memobj);

do_map:
    // map at target address with appropriate flags
    err = pmap->f.map(pmap, vregion_base + map_offset, walk->frame, 0,
                      walk->size, vregion_get_flags(vregion), NULL, NULL);
    if (err_is_fail(err)) {
        return err_push(err, LIB_ERR_PMAP_MAP);
    }

    return SYS_ERR_OK;
}