These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / roms / ipxe / src / core / image.c
index ec44802..529e3d7 100644 (file)
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
  */
 
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 #include <stddef.h>
 #include <string.h>
@@ -153,6 +157,32 @@ int image_set_cmdline ( struct image *image, const char *cmdline ) {
        return 0;
 }
 
+/**
+ * Determine image type
+ *
+ * @v image            Executable image
+ * @ret rc             Return status code
+ */
+static int image_probe ( struct image *image ) {
+       struct image_type *type;
+       int rc;
+
+       /* Try each type in turn */
+       for_each_table_entry ( type, IMAGE_TYPES ) {
+               if ( ( rc = type->probe ( image ) ) == 0 ) {
+                       image->type = type;
+                       DBGC ( image, "IMAGE %s is %s\n",
+                              image->name, type->name );
+                       break;
+               }
+               DBGC ( image, "IMAGE %s is not %s: %s\n", image->name,
+                      type->name, strerror ( rc ) );
+       }
+
+       DBGC ( image, "IMAGE %s format not recognised\n", image->name );
+       return -ENOTSUP;
+}
+
 /**
  * Register executable image
  *
@@ -185,6 +215,14 @@ int register_image ( struct image *image ) {
               image->name, user_to_phys ( image->data, 0 ),
               user_to_phys ( image->data, image->len ) );
 
+       /* Try to detect image type, if applicable.  Ignore failures,
+        * since we expect to handle some unrecognised images
+        * (e.g. kernel initrds, multiboot modules, random files
+        * provided via our EFI virtual filesystem, etc).
+        */
+       if ( ! image->type )
+               image_probe ( image );
+
        return 0;
 }
 
@@ -222,36 +260,6 @@ struct image * find_image ( const char *name ) {
        return NULL;
 }
 
-/**
- * Determine image type
- *
- * @v image            Executable image
- * @ret rc             Return status code
- */
-int image_probe ( struct image *image ) {
-       struct image_type *type;
-       int rc;
-
-       /* Succeed if we already have a type */
-       if ( image->type )
-               return 0;
-
-       /* Try each type in turn */
-       for_each_table_entry ( type, IMAGE_TYPES ) {
-               if ( ( rc = type->probe ( image ) ) == 0 ) {
-                       image->type = type;
-                       DBGC ( image, "IMAGE %s is %s\n",
-                              image->name, type->name );
-                       return 0;
-               }
-               DBGC ( image, "IMAGE %s is not %s: %s\n", image->name,
-                      type->name, strerror ( rc ) );
-       }
-
-       DBGC ( image, "IMAGE %s format not recognised\n", image->name );
-       return -ENOEXEC;
-}
-
 /**
  * Execute image
  *
@@ -284,9 +292,11 @@ int image_exec ( struct image *image ) {
         */
        current_image = image_get ( image );
 
-       /* Check that this image can be selected for execution */
-       if ( ( rc = image_select ( image ) ) != 0 )
+       /* Check that this image can be executed */
+       if ( ! ( image->type && image->type->exec ) ) {
+               rc = -ENOEXEC;
                goto err;
+       }
 
        /* Check that image is trusted (if applicable) */
        if ( require_trusted_images && ! ( image->flags & IMAGE_TRUSTED ) ) {
@@ -378,8 +388,8 @@ int image_replace ( struct image *replacement ) {
        }
 
        /* Check that the replacement image can be executed */
-       if ( ( rc = image_probe ( replacement ) ) != 0 )
-               return rc;
+       if ( ! ( replacement->type && replacement->type->exec ) )
+               return -ENOEXEC;
 
        /* Clear any existing replacement */
        image_put ( image->replacement );
@@ -400,16 +410,13 @@ int image_replace ( struct image *replacement ) {
  */
 int image_select ( struct image *image ) {
        struct image *tmp;
-       int rc;
 
        /* Unselect all other images */
        for_each_image ( tmp )
                tmp->flags &= ~IMAGE_SELECTED;
 
        /* Check that this image can be executed */
-       if ( ( rc = image_probe ( image ) ) != 0 )
-               return rc;
-       if ( ! image->type->exec )
+       if ( ! ( image->type && image->type->exec ) )
                return -ENOEXEC;
 
        /* Mark image as selected */
@@ -468,9 +475,7 @@ int image_pixbuf ( struct image *image, struct pixel_buffer **pixbuf ) {
        int rc;
 
        /* Check that this image can be used to create a pixel buffer */
-       if ( ( rc = image_probe ( image ) ) != 0 )
-               return rc;
-       if ( ! image->type->pixbuf )
+       if ( ! ( image->type && image->type->pixbuf ) )
                return -ENOTSUP;
 
        /* Try creating pixel buffer */