summary refs log tree commit diff stats
path: root/hw/core
diff options
context:
space:
mode:
Diffstat (limited to 'hw/core')
-rw-r--r--hw/core/loader.c30
-rw-r--r--hw/core/qdev.c20
2 files changed, 37 insertions, 13 deletions
diff --git a/hw/core/loader.c b/hw/core/loader.c
index e1c3f3a860..b323c0c7b8 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -284,12 +284,30 @@ static void *load_at(int fd, int offset, int size)
 #define SZ		64
 #include "hw/elf_ops.h"
 
+const char *load_elf_strerror(int error)
+{
+    switch (error) {
+    case 0:
+        return "No error";
+    case ELF_LOAD_FAILED:
+        return "Failed to load ELF";
+    case ELF_LOAD_NOT_ELF:
+        return "The image is not ELF";
+    case ELF_LOAD_WRONG_ARCH:
+        return "The image is from incompatible architecture";
+    case ELF_LOAD_WRONG_ENDIAN:
+        return "The image has incorrect endianness";
+    default:
+        return "Unknown error";
+    }
+}
+
 /* return < 0 if error, otherwise the number of bytes loaded in memory */
 int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t),
              void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
              uint64_t *highaddr, int big_endian, int elf_machine, int clear_lsb)
 {
-    int fd, data_order, target_data_order, must_swab, ret;
+    int fd, data_order, target_data_order, must_swab, ret = ELF_LOAD_FAILED;
     uint8_t e_ident[EI_NIDENT];
 
     fd = open(filename, O_RDONLY | O_BINARY);
@@ -302,8 +320,10 @@ int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t),
     if (e_ident[0] != ELFMAG0 ||
         e_ident[1] != ELFMAG1 ||
         e_ident[2] != ELFMAG2 ||
-        e_ident[3] != ELFMAG3)
+        e_ident[3] != ELFMAG3) {
+        ret = ELF_LOAD_NOT_ELF;
         goto fail;
+    }
 #ifdef HOST_WORDS_BIGENDIAN
     data_order = ELFDATA2MSB;
 #else
@@ -317,6 +337,7 @@ int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t),
     }
 
     if (target_data_order != e_ident[EI_DATA]) {
+        ret = ELF_LOAD_WRONG_ENDIAN;
         goto fail;
     }
 
@@ -329,12 +350,9 @@ int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t),
                          pentry, lowaddr, highaddr, elf_machine, clear_lsb);
     }
 
-    close(fd);
-    return ret;
-
  fail:
     close(fd);
-    return -1;
+    return ret;
 }
 
 static void bswap_uboot_header(uboot_image_header_t *hdr)
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index c0b857fbd4..380976a066 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -440,27 +440,33 @@ DeviceState *qdev_find_recursive(BusState *bus, const char *id)
 static void qbus_realize(BusState *bus, DeviceState *parent, const char *name)
 {
     const char *typename = object_get_typename(OBJECT(bus));
+    BusClass *bc;
     char *buf;
-    int i,len;
+    int i, len, bus_id;
 
     bus->parent = parent;
 
     if (name) {
         bus->name = g_strdup(name);
     } else if (bus->parent && bus->parent->id) {
-        /* parent device has id -> use it for bus name */
+        /* parent device has id -> use it plus parent-bus-id for bus name */
+        bus_id = bus->parent->num_child_bus;
+
         len = strlen(bus->parent->id) + 16;
         buf = g_malloc(len);
-        snprintf(buf, len, "%s.%d", bus->parent->id, bus->parent->num_child_bus);
+        snprintf(buf, len, "%s.%d", bus->parent->id, bus_id);
         bus->name = buf;
     } else {
-        /* no id -> use lowercase bus type for bus name */
+        /* no id -> use lowercase bus type plus global bus-id for bus name */
+        bc = BUS_GET_CLASS(bus);
+        bus_id = bc->automatic_ids++;
+
         len = strlen(typename) + 16;
         buf = g_malloc(len);
-        len = snprintf(buf, len, "%s.%d", typename,
-                       bus->parent ? bus->parent->num_child_bus : 0);
-        for (i = 0; i < len; i++)
+        len = snprintf(buf, len, "%s.%d", typename, bus_id);
+        for (i = 0; i < len; i++) {
             buf[i] = qemu_tolower(buf[i]);
+        }
         bus->name = buf;
     }