qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 02/40] elf: Add notes implementation


From: Alexander Graf
Subject: [Qemu-devel] [PATCH 02/40] elf: Add notes implementation
Date: Mon, 1 Nov 2010 16:01:15 +0100

---
 hw/elf_ops.h |   61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 hw/loader.c  |    7 ++++++
 hw/loader.h  |    3 ++
 3 files changed, 70 insertions(+), 1 deletions(-)

diff --git a/hw/elf_ops.h b/hw/elf_ops.h
index 8b63dfc..645d058 100644
--- a/hw/elf_ops.h
+++ b/hw/elf_ops.h
@@ -189,6 +189,44 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int 
fd, int must_swab,
     return -1;
 }
 
+static void glue(elf_read_notes, SZ)(uint8_t *data, int data_len,
+                                     ElfHandlers *handlers, int must_swab)
+{
+    uint8_t *p = data;
+
+    while ((ulong)&p[3] < (ulong)&data[data_len]) {
+        uint32_t *cur = (uint32_t *)p;
+        uint32_t namesz = cur[0];
+        uint32_t descsz = cur[1];
+        uint32_t type   = cur[2];
+        uint8_t *name;
+        uint8_t *desc;
+
+        p += 3 * sizeof(uint32_t);
+
+        if (must_swab) {
+            namesz = bswap32(namesz);
+            descsz = bswap32(descsz);
+            type   = bswap32(type);
+        }
+
+        namesz = (namesz + 3) & ~3;
+        descsz = (descsz + 3) & ~3;
+
+        name = p;
+        p += namesz;
+        desc = p;
+        p += descsz;
+
+        if ((ulong)p > (ulong)&data[data_len]) {
+            break;
+        }
+
+        handlers->note_fn(handlers->note_opaque, name, namesz, desc, descsz,
+                          type);
+    }
+}
+
 static int glue(load_elf, SZ)(const char *name, int fd,
                               ElfHandlers *handlers,
                               int must_swab, uint64_t *pentry,
@@ -252,7 +290,8 @@ static int glue(load_elf, SZ)(const char *name, int fd,
     total_size = 0;
     for(i = 0; i < ehdr.e_phnum; i++) {
         ph = &phdr[i];
-        if (ph->p_type == PT_LOAD) {
+        switch (ph->p_type) {
+        case PT_LOAD:
             mem_size = ph->p_memsz;
             /* XXX: avoid allocating */
             data = qemu_mallocz(mem_size);
@@ -278,6 +317,26 @@ static int glue(load_elf, SZ)(const char *name, int fd,
 
             qemu_free(data);
             data = NULL;
+            break;
+
+        case PT_NOTE:
+            mem_size = ph->p_memsz;
+            if (!mem_size) {
+                break;
+            }
+            data = qemu_mallocz(mem_size);
+            if (ph->p_filesz > 0) {
+                if (lseek(fd, ph->p_offset, SEEK_SET) < 0)
+                    goto fail;
+                if (read(fd, data, ph->p_filesz) != ph->p_filesz)
+                    goto fail;
+            }
+
+            glue(elf_read_notes, SZ)(data, ph->p_memsz, handlers, must_swab);
+
+            qemu_free(data);
+            data = NULL;
+            break;
         }
     }
     qemu_free(phdr);
diff --git a/hw/loader.c b/hw/loader.c
index 50b43a0..cb430e0 100644
--- a/hw/loader.c
+++ b/hw/loader.c
@@ -229,6 +229,11 @@ int load_aout(const char *filename, target_phys_addr_t 
addr, int max_sz,
 
 /* ELF loader */
 
+static void elf_default_note(void *opaque, uint8_t *name, uint32_t name_len,
+                             uint8_t *desc, uint32_t desc_len, uint32_t type)
+{
+}
+
 static uint64_t elf_default_translate(void *opaque, uint64_t addr)
 {
     return addr;
@@ -237,6 +242,8 @@ static uint64_t elf_default_translate(void *opaque, 
uint64_t addr)
 ElfHandlers elf_default_handlers = {
     .translate_fn = elf_default_translate,
     .translate_opaque = NULL,
+    .note_fn = elf_default_note,
+    .note_opaque = NULL,
 };
 
 
diff --git a/hw/loader.h b/hw/loader.h
index 27a2c36..29d5c71 100644
--- a/hw/loader.h
+++ b/hw/loader.h
@@ -9,6 +9,9 @@ int load_image_targphys(const char *filename, 
target_phys_addr_t, int max_sz);
 typedef struct ElfHandlers {
     uint64_t (*translate_fn)(void *opaque, uint64_t address);
     void *translate_opaque;
+    void (*note_fn)(void *opaque, uint8_t *name, uint32_t name_len,
+                    uint8_t *desc, uint32_t desc_len, uint32_t type);
+    void *note_opaque;
 } ElfHandlers;
 
 extern ElfHandlers elf_default_handlers;
-- 
1.6.0.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]