image.c
Go to the documentation of this file.
/*
* libspe2 - A wrapper library to adapt the JSRE SPU usage model to SPUFS
* Copyright (C) 2005 IBM Corp.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License,
* or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include "elf_loader.h"
#include "spebase.h"
struct image_handle {
spe_program_handle_t speh;
unsigned int map_size;
};
spe_program_handle_t *_base_spe_image_open(const char *filename)
{
/* allocate an extra integer in the spe handle to keep the mapped size information */
struct image_handle *ret;
int binfd = -1, f_stat;
struct stat statbuf;
size_t ps = getpagesize ();
ret = malloc(sizeof(struct image_handle));
if (!ret)
return NULL;
ret->speh.handle_size = sizeof(spe_program_handle_t);
ret->speh.toe_shadow = NULL;
binfd = open(filename, O_RDONLY);
if (binfd < 0)
goto ret_err;
f_stat = fstat(binfd, &statbuf);
if (f_stat < 0)
goto ret_err;
/* Sanity: is it executable ?
*/
if(!(statbuf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
errno=EACCES;
goto ret_err;
}
/* now store the size at the extra allocated space */
ret->map_size = (statbuf.st_size + ps - 1) & ~(ps - 1);
ret->speh.elf_image = mmap(NULL, ret->map_size,
PROT_WRITE | PROT_READ,
MAP_PRIVATE, binfd, 0);
if (ret->speh.elf_image == MAP_FAILED)
goto ret_err;
/*Verify that this is a valid SPE ELF object*/
if((_base_spe_verify_spe_elf_image((spe_program_handle_t *)ret)))
goto ret_err;
if (_base_spe_toe_ear(&ret->speh))
goto ret_err;
/* ok */
close(binfd);
return (spe_program_handle_t *)ret;
/* err & cleanup */
ret_err:
if (binfd >= 0)
close(binfd);
free(ret);
return NULL;
}
int _base_spe_image_close(spe_program_handle_t *handle)
{
int ret = 0;
struct image_handle *ih;
if (!handle) {
errno = EINVAL;
return -1;
}
ih = (struct image_handle *)handle;
if (!ih->speh.elf_image || !ih->map_size) {
errno = EINVAL;
return -1;
}
if (ih->speh.toe_shadow)
free(ih->speh.toe_shadow);
ret = munmap(ih->speh.elf_image, ih->map_size );
free(handle);
return ret;
}