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

[Xen-changelog] [xen-unstable] [TOOLS] Add a simple tool to display the Xen specific ELF notes.



# HG changeset patch
# User Ian Campbell <ian.campbell@xxxxxxxxxxxxx>
# Node ID 58b5141c8309fdfe2069b98923686223d6fcbf2d
# Parent  faadbf5ba8d6a823aa60b2a65f44cef0f576d3ce
[TOOLS] Add a simple tool to display the Xen specific ELF notes.

Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxxxxx>
---
 .hgignore                 |    1 
 tools/xcutils/Makefile    |    2 
 tools/xcutils/readnotes.c |  307 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 309 insertions(+), 1 deletion(-)

diff -r faadbf5ba8d6 -r 58b5141c8309 .hgignore
--- a/.hgignore Wed Aug 23 14:41:05 2006 +0100
+++ b/.hgignore Wed Aug 23 14:43:48 2006 +0100
@@ -151,6 +151,7 @@
 ^tools/vtpm_manager/manager/vtpm_managerd$
 ^tools/xcutils/xc_restore$
 ^tools/xcutils/xc_save$
+^tools/xcutils/readnotes$
 ^tools/xenmon/xentrace_setmask$
 ^tools/xenmon/xenbaked$
 ^tools/xenstat/xentop/xentop$
diff -r faadbf5ba8d6 -r 58b5141c8309 tools/xcutils/Makefile
--- a/tools/xcutils/Makefile    Wed Aug 23 14:41:05 2006 +0100
+++ b/tools/xcutils/Makefile    Wed Aug 23 14:43:48 2006 +0100
@@ -26,7 +26,7 @@ CFLAGS += -Wp,-MD,.$(@F).d
 CFLAGS += -Wp,-MD,.$(@F).d
 PROG_DEP = .*.d
 
-PROGRAMS               = xc_restore xc_save
+PROGRAMS               = xc_restore xc_save readnotes
 
 LDLIBS                 = -L$(XEN_LIBXC) -lxenguest -lxenctrl
 
diff -r faadbf5ba8d6 -r 58b5141c8309 tools/xcutils/readnotes.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xcutils/readnotes.c Wed Aug 23 14:43:48 2006 +0100
@@ -0,0 +1,307 @@
+#include <elf.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include <xen/elfnote.h>
+
+#define ELFNOTE_NAME(_n_) ((void*)(_n_) + sizeof(*(_n_)))
+#define ELFNOTE_DESC(_n_) (ELFNOTE_NAME(_n_) + (((_n_)->n_namesz+3)&~3))
+#define ELFNOTE_NEXT(_n_) (ELFNOTE_DESC(_n_) + (((_n_)->n_descsz+3)&~3))
+
+#if defined(__i386__)
+typedef Elf32_Ehdr Elf_Ehdr;
+typedef Elf32_Nhdr Elf_Nhdr;
+typedef Elf32_Half Elf_Half;
+typedef Elf32_Word Elf_Word;
+#elif defined(__x86_64__)
+typedef Elf64_Ehdr Elf_Ehdr;
+typedef Elf64_Nhdr Elf_Nhdr;
+typedef Elf64_Half Elf_Half;
+typedef Elf64_Word Elf_Word;
+#else
+#error "Unknown architecture"
+#endif
+
+static void print_string_note(const char *prefix, Elf_Nhdr *note)
+{
+       printf("%s: %s\n", prefix, (const char *)ELFNOTE_DESC(note));
+}
+
+static void print_numeric_note(const char *prefix,Elf_Nhdr *note)
+{
+       switch (note->n_descsz)
+       {
+       case 4:
+               printf("%s: %#010" PRIx32 " (4 bytes)\n",
+                      prefix, *(uint32_t *)ELFNOTE_DESC(note));
+               break;
+       case 8:
+               printf("%s: %#018" PRIx64 " (8 bytes)\n",
+                      prefix, *(uint64_t *)ELFNOTE_DESC(note));
+               break;
+       default:
+               printf("%s: unknown data size %#x\n", prefix, note->n_descsz);
+               break;
+       }
+}
+
+static inline unsigned char ehdr_class(void *image)
+{
+       Elf_Ehdr *ehdr = image;
+       switch (ehdr->e_ident[EI_CLASS])
+       {
+       case ELFCLASS32:
+       case ELFCLASS64:
+               return ehdr->e_ident[EI_CLASS];
+               break;
+       default:
+               fprintf(stderr, "Unknown ELF class %d\n",
+                       ehdr->e_ident[EI_CLASS]);
+               exit(1);
+       }
+}
+
+static inline Elf_Half ehdr_shnum(void *image)
+{
+       switch (ehdr_class(image))
+       {
+       case ELFCLASS32:
+               return ((Elf32_Ehdr *)image)->e_shnum;
+       case ELFCLASS64:
+               return ((Elf64_Ehdr *)image)->e_shnum;
+       default:
+               exit(1);
+       }
+}
+
+static inline Elf_Word shdr_type(void *image, int shnum)
+{
+       switch (ehdr_class(image))
+       {
+       case ELFCLASS32:
+       {
+               Elf32_Ehdr *ehdr = (Elf32_Ehdr *)image;
+               Elf32_Shdr *shdr = (Elf32_Shdr*)(image + ehdr->e_shoff +
+                                                (shnum*ehdr->e_shentsize));
+               return shdr->sh_type;
+       }
+       case ELFCLASS64:
+       {
+               Elf64_Ehdr *ehdr = (Elf64_Ehdr *)image;
+               Elf64_Shdr *shdr = (Elf64_Shdr*)(image + ehdr->e_shoff +
+                                                (shnum*ehdr->e_shentsize));
+               return shdr->sh_type;
+       }
+       default:
+               exit(1);
+       }
+}
+
+static inline const char *shdr_name(void *image, int shnum)
+{
+       const char *shstrtab;
+
+       switch (ehdr_class(image))
+       {
+       case ELFCLASS32:
+       {
+               Elf32_Ehdr *ehdr = (Elf32_Ehdr *)image;
+               Elf32_Shdr *shdr;
+               /* Find the section-header strings table. */
+               if ( ehdr->e_shstrndx == SHN_UNDEF )
+                       return NULL;
+               shdr = (Elf32_Shdr *)(image + ehdr->e_shoff +
+                                     (ehdr->e_shstrndx*ehdr->e_shentsize));
+               shstrtab = image + shdr->sh_offset;
+
+               shdr= (Elf32_Shdr*)(image + ehdr->e_shoff +
+                                   (shnum*ehdr->e_shentsize));
+               return &shstrtab[shdr->sh_name];
+       }
+       case ELFCLASS64:
+       {
+               Elf64_Ehdr *ehdr = (Elf64_Ehdr *)image;
+               Elf64_Shdr *shdr;
+               /* Find the section-header strings table. */
+               if ( ehdr->e_shstrndx == SHN_UNDEF )
+                       return NULL;
+               shdr = (Elf64_Shdr *)(image + ehdr->e_shoff +
+                                     (ehdr->e_shstrndx*ehdr->e_shentsize));
+               shstrtab = image + shdr->sh_offset;
+
+               shdr= (Elf64_Shdr*)(image + ehdr->e_shoff +
+                                   (shnum*ehdr->e_shentsize));
+               return &shstrtab[shdr->sh_name];
+       }
+       default:
+               exit(1);
+       }
+}
+static inline void *shdr_start(void *image, int shnum)
+{
+       switch (ehdr_class(image))
+       {
+       case ELFCLASS32:
+       {
+               Elf32_Ehdr *ehdr = (Elf32_Ehdr *)image;
+               Elf32_Shdr *shdr = (Elf32_Shdr*)(image + ehdr->e_shoff +
+                                                (shnum*ehdr->e_shentsize));
+               return image + shdr->sh_offset;
+       }
+       case ELFCLASS64:
+       {
+               Elf64_Ehdr *ehdr = (Elf64_Ehdr *)image;
+               Elf64_Shdr *shdr = (Elf64_Shdr*)(image + ehdr->e_shoff +
+                                                (shnum*ehdr->e_shentsize));
+               return image + shdr->sh_offset;
+       }
+       default:
+               exit(1);
+       }
+}
+
+static inline void *shdr_end(void *image, int shnum)
+{
+       switch (ehdr_class(image))
+       {
+       case ELFCLASS32:
+       {
+               Elf32_Ehdr *ehdr = (Elf32_Ehdr *)image;
+               Elf32_Shdr *shdr = (Elf32_Shdr*)(image + ehdr->e_shoff +
+                                                (shnum*ehdr->e_shentsize));
+               return image + shdr->sh_offset + shdr->sh_size;
+       }
+       case ELFCLASS64:
+       {
+               Elf64_Ehdr *ehdr = (Elf64_Ehdr *)image;
+               Elf64_Shdr *shdr = (Elf64_Shdr*)(image + ehdr->e_shoff +
+                                                (shnum*ehdr->e_shentsize));
+               return image + shdr->sh_offset + shdr->sh_size;
+       }
+       default:
+               exit(1);
+       }
+}
+
+int main(int argc, char **argv)
+{
+       const char *f;
+       int fd,h;
+       void *image;
+       struct stat st;
+       Elf_Ehdr *ehdr;
+       Elf_Nhdr *note;
+
+       if (argc != 2)
+       {
+               fprintf(stderr, "Usage: readnotes <elfimage>\n");
+               return 1;
+       }
+       f = argv[1];
+
+       fd = open(f, O_RDONLY);
+       if (fd == -1)
+       {
+               fprintf(stderr, "Unable to open %s: %s\n", f, strerror(errno));
+               return 1;
+       }
+       if (fstat(fd, &st) == -1)
+       {
+               fprintf(stderr, "Unable to determine size of %s: %s\n",
+                       f, strerror(errno));
+               return 1;
+       }
+
+       image = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
+       if (image == MAP_FAILED)
+       {
+               fprintf(stderr, "Unable to map %s: %s\n", f, strerror(errno));
+               return 1;
+       }
+
+       ehdr = image;
+       if (ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
+           ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
+           ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
+           ehdr->e_ident[EI_MAG3] != ELFMAG3)
+       {
+               fprintf(stderr, "File %s is not an ELF image\n", f);
+               return 1;
+       }
+
+       for ( h=0; h < ehdr_shnum(image); h++)
+       {
+               if (shdr_type(image,h) != SHT_NOTE)
+                       continue;
+               for (note = (Elf_Nhdr*)shdr_start(image,h);
+                    note < (Elf_Nhdr*)shdr_end(image,h);
+                    note = (Elf_Nhdr*)(ELFNOTE_NEXT(note)))
+               {
+                       switch(note->n_type)
+                       {
+                       case XEN_ELFNOTE_INFO:
+                               print_string_note("INFO", note);
+                               break;
+                       case XEN_ELFNOTE_ENTRY:
+                               print_numeric_note("ENTRY", note);
+                               break;
+                       case XEN_ELFNOTE_HYPERCALL_PAGE:
+                               print_numeric_note("HYPERCALL_PAGE", note);
+                               break;
+                       case XEN_ELFNOTE_VIRT_BASE:
+                               print_numeric_note("VIRT_BASE", note);
+                               break;
+                       case XEN_ELFNOTE_PADDR_OFFSET:
+                               print_numeric_note("PADDR_OFFSET", note);
+                               break;
+                       case XEN_ELFNOTE_XEN_VERSION:
+                               print_string_note("XEN_VERSION", note);
+                               break;
+                       case XEN_ELFNOTE_GUEST_OS:
+                               print_string_note("GUEST_OS", note);
+                               break;
+                       case XEN_ELFNOTE_GUEST_VERSION:
+                               print_string_note("GUEST_VERSION", note);
+                               break;
+                       case XEN_ELFNOTE_LOADER:
+                               print_string_note("LOADER", note);
+                               break;
+                       case XEN_ELFNOTE_PAE_MODE:
+                               print_string_note("PAE_MODE", note);
+                               break;
+                       case XEN_ELFNOTE_FEATURES:
+                               print_string_note("FEATURES", note);
+                               break;
+                       default:
+                               printf("unknown note type %#x\n", note->n_type);
+                               break;
+                       }
+               }
+       }
+
+       for ( h=0; h < ehdr_shnum(image); h++)
+       {
+               const char *name = shdr_name(image,h);
+
+               if ( name == NULL )
+                       continue;
+               if ( strcmp(name, "__xen_guest") != 0 )
+                       continue;
+
+               printf("__xen_guest: %s\n", (const char *)shdr_start(image, h));
+               break;
+       }
+
+       return 0;
+}
+
+

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.