1 /*
2 * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 FILE_LICENCE ( GPL2_OR_LATER );
20
21 #include <stddef.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <errno.h>
26 #include <assert.h>
27 #include <libgen.h>
28 #include <gpxe/list.h>
29 #include <gpxe/umalloc.h>
30 #include <gpxe/uri.h>
31 #include <gpxe/image.h>
32
33 /** @file
34 *
35 * Executable/loadable images
36 *
37 */
38
39 /** List of registered images */
40 struct list_head images = LIST_HEAD_INIT ( images );
41
42 /**
43 * Free executable/loadable image
44 *
45 * @v refcnt Reference counter
46 */
free_image(struct refcnt * refcnt)47 static void free_image ( struct refcnt *refcnt ) {
48 struct image *image = container_of ( refcnt, struct image, refcnt );
49
50 uri_put ( image->uri );
51 ufree ( image->data );
52 image_put ( image->replacement );
53 free ( image );
54 DBGC ( image, "IMAGE %p freed\n", image );
55 }
56
57 /**
58 * Allocate executable/loadable image
59 *
60 * @ret image Executable/loadable image
61 */
alloc_image(void)62 struct image * alloc_image ( void ) {
63 struct image *image;
64
65 image = zalloc ( sizeof ( *image ) );
66 if ( image ) {
67 image->refcnt.free = free_image;
68 }
69 return image;
70 }
71
72 /**
73 * Set image URI
74 *
75 * @v image Image
76 * @v URI New image URI
77 * @ret rc Return status code
78 *
79 * If no name is set, the name will be updated to the base name of the
80 * URI path (if any).
81 */
image_set_uri(struct image * image,struct uri * uri)82 int image_set_uri ( struct image *image, struct uri *uri ) {
83 const char *path = uri->path;
84
85 /* Replace URI reference */
86 uri_put ( image->uri );
87 image->uri = uri_get ( uri );
88
89 /* Set name if none already specified */
90 if ( path && ( ! image->name[0] ) )
91 image_set_name ( image, basename ( ( char * ) path ) );
92
93 return 0;
94 }
95
96 /**
97 * Set image command line
98 *
99 * @v image Image
100 * @v cmdline New image command line
101 * @ret rc Return status code
102 */
image_set_cmdline(struct image * image,const char * cmdline)103 int image_set_cmdline ( struct image *image, const char *cmdline ) {
104 free ( image->cmdline );
105 image->cmdline = strdup ( cmdline );
106 if ( ! image->cmdline )
107 return -ENOMEM;
108 return 0;
109 }
110
111 /**
112 * Register executable/loadable image
113 *
114 * @v image Executable/loadable image
115 * @ret rc Return status code
116 */
register_image(struct image * image)117 int register_image ( struct image *image ) {
118 static unsigned int imgindex = 0;
119
120 /* Create image name if it doesn't already have one */
121 if ( ! image->name[0] ) {
122 snprintf ( image->name, sizeof ( image->name ), "img%d",
123 imgindex++ );
124 }
125
126 /* Add to image list */
127 image_get ( image );
128 list_add_tail ( &image->list, &images );
129 DBGC ( image, "IMAGE %p at [%lx,%lx) registered as %s\n",
130 image, user_to_phys ( image->data, 0 ),
131 user_to_phys ( image->data, image->len ), image->name );
132
133 return 0;
134 }
135
136 /**
137 * Unregister executable/loadable image
138 *
139 * @v image Executable/loadable image
140 */
unregister_image(struct image * image)141 void unregister_image ( struct image *image ) {
142 DBGC ( image, "IMAGE %p unregistered\n", image );
143 list_del ( &image->list );
144 image_put ( image );
145 }
146
147 /**
148 * Find image by name
149 *
150 * @v name Image name
151 * @ret image Executable/loadable image, or NULL
152 */
find_image(const char * name)153 struct image * find_image ( const char *name ) {
154 struct image *image;
155
156 list_for_each_entry ( image, &images, list ) {
157 if ( strcmp ( image->name, name ) == 0 )
158 return image;
159 }
160
161 return NULL;
162 }
163
164 /**
165 * Load executable/loadable image into memory
166 *
167 * @v image Executable/loadable image
168 * @v type Executable/loadable image type
169 * @ret rc Return status code
170 */
image_load_type(struct image * image,struct image_type * type)171 static int image_load_type ( struct image *image, struct image_type *type ) {
172 int rc;
173
174 /* Check image is actually loadable */
175 if ( ! type->load )
176 return -ENOEXEC;
177
178 /* Try the image loader */
179 if ( ( rc = type->load ( image ) ) != 0 ) {
180 DBGC ( image, "IMAGE %p could not load as %s: %s\n",
181 image, type->name, strerror ( rc ) );
182 return rc;
183 }
184
185 /* Flag as loaded */
186 image->flags |= IMAGE_LOADED;
187 return 0;
188 }
189
190 /**
191 * Load executable/loadable image into memory
192 *
193 * @v image Executable/loadable image
194 * @ret rc Return status code
195 */
image_load(struct image * image)196 int image_load ( struct image *image ) {
197
198 assert ( image->type != NULL );
199
200 return image_load_type ( image, image->type );
201 }
202
203 /**
204 * Autodetect image type and load executable/loadable image into memory
205 *
206 * @v image Executable/loadable image
207 * @ret rc Return status code
208 */
image_autoload(struct image * image)209 int image_autoload ( struct image *image ) {
210 struct image_type *type;
211 int rc;
212
213 /* If image already has a type, use it */
214 if ( image->type )
215 return image_load ( image );
216
217 /* Otherwise probe for a suitable type */
218 for_each_table_entry ( type, IMAGE_TYPES ) {
219 DBGC ( image, "IMAGE %p trying type %s\n", image, type->name );
220 rc = image_load_type ( image, type );
221 if ( image->type == NULL )
222 continue;
223 return rc;
224 }
225
226 DBGC ( image, "IMAGE %p format not recognised\n", image );
227 return -ENOEXEC;
228 }
229
230 /**
231 * Execute loaded image
232 *
233 * @v image Loaded image
234 * @ret rc Return status code
235 */
image_exec(struct image * image)236 int image_exec ( struct image *image ) {
237 struct image *replacement;
238 struct uri *old_cwuri;
239 int rc;
240
241 /* Image must be loaded first */
242 if ( ! ( image->flags & IMAGE_LOADED ) ) {
243 DBGC ( image, "IMAGE %p could not execute: not loaded\n",
244 image );
245 return -ENOTTY;
246 }
247
248 assert ( image->type != NULL );
249
250 /* Check that image is actually executable */
251 if ( ! image->type->exec )
252 return -ENOEXEC;
253
254 /* Switch current working directory to be that of the image itself */
255 old_cwuri = uri_get ( cwuri );
256 churi ( image->uri );
257
258 /* Take out a temporary reference to the image. This allows
259 * the image to unregister itself if necessary, without
260 * automatically freeing itself.
261 */
262 image_get ( image );
263
264 /* Try executing the image */
265 if ( ( rc = image->type->exec ( image ) ) != 0 ) {
266 DBGC ( image, "IMAGE %p could not execute: %s\n",
267 image, strerror ( rc ) );
268 /* Do not return yet; we still have clean-up to do */
269 }
270
271 /* Pick up replacement image before we drop the original
272 * image's temporary reference.
273 */
274 replacement = image->replacement;
275
276 /* Drop temporary reference to the original image */
277 image_put ( image );
278
279 /* Reset current working directory */
280 churi ( old_cwuri );
281 uri_put ( old_cwuri );
282
283 /* Tail-recurse into replacement image, if one exists */
284 if ( replacement ) {
285 DBGC ( image, "IMAGE %p replacing self with IMAGE %p\n",
286 image, replacement );
287 if ( ( rc = image_exec ( replacement ) ) != 0 )
288 return rc;
289 }
290
291 return rc;
292 }
293
294 /**
295 * Register and autoload an image
296 *
297 * @v image Image
298 * @ret rc Return status code
299 */
register_and_autoload_image(struct image * image)300 int register_and_autoload_image ( struct image *image ) {
301 int rc;
302
303 if ( ( rc = register_image ( image ) ) != 0 )
304 return rc;
305
306 if ( ( rc = image_autoload ( image ) ) != 0 )
307 return rc;
308
309 return 0;
310 }
311
312 /**
313 * Register and autoexec an image
314 *
315 * @v image Image
316 * @ret rc Return status code
317 */
register_and_autoexec_image(struct image * image)318 int register_and_autoexec_image ( struct image *image ) {
319 int rc;
320
321 if ( ( rc = register_and_autoload_image ( image ) ) != 0 )
322 return rc;
323
324 if ( ( rc = image_exec ( image ) ) != 0 )
325 return rc;
326
327 return 0;
328 }
329