libspe2 0.9a
image.c
Go to the documentation of this file.
00001 /*
00002  * libspe2 - A wrapper library to adapt the JSRE SPU usage model to SPUFS
00003  * Copyright (C) 2005 IBM Corp.
00004  *
00005  * This library is free software; you can redistribute it and/or modify it
00006  * under the terms of the GNU Lesser General Public License as published by
00007  * the Free Software Foundation; either version 2.1 of the License,
00008  * or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful, but
00011  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00012  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
00013  * License for more details.
00014  *
00015  * You should have received a copy of the GNU Lesser General Public License
00016  * along with this library; if not, write to the Free Software Foundation,
00017  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00018  */
00019 
00020 #include <errno.h>
00021 #include <fcntl.h>
00022 #include <stdlib.h>
00023 
00024 #include <sys/mman.h>
00025 #include <sys/stat.h>
00026 
00027 #include <unistd.h>
00028 
00029 #include "elf_loader.h"
00030 #include "spebase.h"
00031 
00032 struct image_handle {
00033         spe_program_handle_t speh;
00034         unsigned int map_size;
00035 };
00036 
00037 spe_program_handle_t *_base_spe_image_open(const char *filename)
00038 {
00039         /* allocate an extra integer in the spe handle to keep the mapped size information */
00040         struct image_handle *ret;
00041         int binfd = -1, f_stat;
00042         struct stat statbuf;
00043         size_t ps = getpagesize ();
00044 
00045         ret = malloc(sizeof(struct image_handle));
00046         if (!ret)
00047                 return NULL;
00048 
00049         ret->speh.handle_size = sizeof(spe_program_handle_t);
00050         ret->speh.toe_shadow = NULL;
00051 
00052         binfd = open(filename, O_RDONLY);
00053         if (binfd < 0)
00054                 goto ret_err;
00055 
00056         f_stat = fstat(binfd, &statbuf);
00057         if (f_stat < 0)
00058                 goto ret_err;
00059 
00060         /* Sanity: is it executable ?
00061          */
00062         if(!(statbuf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
00063                 errno=EACCES;
00064                 goto ret_err;
00065         }
00066         
00067         /* now store the size at the extra allocated space */
00068         ret->map_size = (statbuf.st_size + ps - 1) & ~(ps - 1);
00069 
00070         ret->speh.elf_image = mmap(NULL, ret->map_size,
00071                                                         PROT_WRITE | PROT_READ,
00072                                                         MAP_PRIVATE, binfd, 0);
00073         if (ret->speh.elf_image == MAP_FAILED)
00074                 goto ret_err;
00075 
00076         /*Verify that this is a valid SPE ELF object*/
00077         if((_base_spe_verify_spe_elf_image((spe_program_handle_t *)ret)))
00078                 goto ret_err;
00079 
00080         if (_base_spe_toe_ear(&ret->speh))
00081                 goto ret_err;
00082 
00083         /* ok */
00084         close(binfd);
00085         return (spe_program_handle_t *)ret;
00086 
00087         /* err & cleanup */
00088 ret_err:
00089         if (binfd >= 0)
00090                 close(binfd);
00091 
00092         free(ret);
00093         return NULL;
00094 }
00095 
00096 int _base_spe_image_close(spe_program_handle_t *handle)
00097 {
00098         int ret = 0;
00099         struct image_handle *ih;
00100 
00101         if (!handle) {
00102                 errno = EINVAL;
00103                 return -1;
00104         }
00105         
00106         ih = (struct image_handle *)handle;
00107 
00108         if (!ih->speh.elf_image || !ih->map_size) {
00109                 errno = EINVAL;
00110                 return -1;
00111         }
00112 
00113         if (ih->speh.toe_shadow)
00114                 free(ih->speh.toe_shadow);
00115 
00116         ret = munmap(ih->speh.elf_image, ih->map_size );
00117         free(handle);
00118 
00119         return ret;
00120 }
00121 
00122