libspe2 0.9a
|
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