[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |