libspe2  0.9a
image.c
Go to the documentation of this file.
1 /*
2  * libspe2 - A wrapper library to adapt the JSRE SPU usage model to SPUFS
3  * Copyright (C) 2005 IBM Corp.
4  *
5  * This library is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation; either version 2.1 of the License,
8  * or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
13  * License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this library; if not, write to the Free Software Foundation,
17  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */
19 
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <stdlib.h>
23 
24 #include <sys/mman.h>
25 #include <sys/stat.h>
26 
27 #include <unistd.h>
28 
29 #include "elf_loader.h"
30 #include "spebase.h"
31 
32 struct image_handle {
34  unsigned int map_size;
35 };
36 
38 {
39  /* allocate an extra integer in the spe handle to keep the mapped size information */
40  struct image_handle *ret;
41  int binfd = -1, f_stat;
42  struct stat statbuf;
43  size_t ps = getpagesize ();
44 
45  ret = malloc(sizeof(struct image_handle));
46  if (!ret)
47  return NULL;
48 
49  ret->speh.handle_size = sizeof(spe_program_handle_t);
50  ret->speh.toe_shadow = NULL;
51 
52  binfd = open(filename, O_RDONLY);
53  if (binfd < 0)
54  goto ret_err;
55 
56  f_stat = fstat(binfd, &statbuf);
57  if (f_stat < 0)
58  goto ret_err;
59 
60  /* Sanity: is it executable ?
61  */
62  if(!(statbuf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
63  errno=EACCES;
64  goto ret_err;
65  }
66 
67  /* now store the size at the extra allocated space */
68  ret->map_size = (statbuf.st_size + ps - 1) & ~(ps - 1);
69 
70  ret->speh.elf_image = mmap(NULL, ret->map_size,
71  PROT_WRITE | PROT_READ,
72  MAP_PRIVATE, binfd, 0);
73  if (ret->speh.elf_image == MAP_FAILED)
74  goto ret_err;
75 
76  /*Verify that this is a valid SPE ELF object*/
78  goto ret_err;
79 
80  if (_base_spe_toe_ear(&ret->speh))
81  goto ret_err;
82 
83  /* ok */
84  close(binfd);
85  return (spe_program_handle_t *)ret;
86 
87  /* err & cleanup */
88 ret_err:
89  if (binfd >= 0)
90  close(binfd);
91 
92  free(ret);
93  return NULL;
94 }
95 
97 {
98  int ret = 0;
99  struct image_handle *ih;
100 
101  if (!handle) {
102  errno = EINVAL;
103  return -1;
104  }
105 
106  ih = (struct image_handle *)handle;
107 
108  if (!ih->speh.elf_image || !ih->map_size) {
109  errno = EINVAL;
110  return -1;
111  }
112 
113  if (ih->speh.toe_shadow)
114  free(ih->speh.toe_shadow);
115 
116  ret = munmap(ih->speh.elf_image, ih->map_size );
117  free(handle);
118 
119  return ret;
120 }
121 
122 
spe_program_handle_t speh
Definition: image.c:33
int _base_spe_verify_spe_elf_image(spe_program_handle_t *handle)
Definition: elf_loader.c:99
int _base_spe_image_close(spe_program_handle_t *handle)
Definition: image.c:96
struct spe_program_handle spe_program_handle_t
spe_program_handle_t * _base_spe_image_open(const char *filename)
Definition: image.c:37
int _base_spe_toe_ear(spe_program_handle_t *speh)
Definition: elf_loader.c:354
unsigned int handle_size
Definition: libspe2-types.h:49
unsigned int map_size
Definition: image.c:34