direct-io.hg

changeset 11239:58b5141c8309

[TOOLS] Add a simple tool to display the Xen specific ELF notes.

Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
author Ian Campbell <ian.campbell@xensource.com>
date Wed Aug 23 14:43:48 2006 +0100 (2006-08-23)
parents faadbf5ba8d6
children 61eea55dce65
files .hgignore tools/xcutils/Makefile tools/xcutils/readnotes.c
line diff
     1.1 --- a/.hgignore	Wed Aug 23 14:41:05 2006 +0100
     1.2 +++ b/.hgignore	Wed Aug 23 14:43:48 2006 +0100
     1.3 @@ -151,6 +151,7 @@
     1.4  ^tools/vtpm_manager/manager/vtpm_managerd$
     1.5  ^tools/xcutils/xc_restore$
     1.6  ^tools/xcutils/xc_save$
     1.7 +^tools/xcutils/readnotes$
     1.8  ^tools/xenmon/xentrace_setmask$
     1.9  ^tools/xenmon/xenbaked$
    1.10  ^tools/xenstat/xentop/xentop$
     2.1 --- a/tools/xcutils/Makefile	Wed Aug 23 14:41:05 2006 +0100
     2.2 +++ b/tools/xcutils/Makefile	Wed Aug 23 14:43:48 2006 +0100
     2.3 @@ -26,7 +26,7 @@ CFLAGS += $(INCLUDES)
     2.4  CFLAGS += -Wp,-MD,.$(@F).d
     2.5  PROG_DEP = .*.d
     2.6  
     2.7 -PROGRAMS		= xc_restore xc_save
     2.8 +PROGRAMS		= xc_restore xc_save readnotes
     2.9  
    2.10  LDLIBS			= -L$(XEN_LIBXC) -lxenguest -lxenctrl
    2.11  
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/xcutils/readnotes.c	Wed Aug 23 14:43:48 2006 +0100
     3.3 @@ -0,0 +1,307 @@
     3.4 +#include <elf.h>
     3.5 +#include <errno.h>
     3.6 +#include <fcntl.h>
     3.7 +#include <inttypes.h>
     3.8 +#include <stdio.h>
     3.9 +#include <stdlib.h>
    3.10 +#include <string.h>
    3.11 +#include <unistd.h>
    3.12 +
    3.13 +#include <sys/types.h>
    3.14 +#include <sys/stat.h>
    3.15 +#include <sys/mman.h>
    3.16 +
    3.17 +#include <xen/elfnote.h>
    3.18 +
    3.19 +#define ELFNOTE_NAME(_n_) ((void*)(_n_) + sizeof(*(_n_)))
    3.20 +#define ELFNOTE_DESC(_n_) (ELFNOTE_NAME(_n_) + (((_n_)->n_namesz+3)&~3))
    3.21 +#define ELFNOTE_NEXT(_n_) (ELFNOTE_DESC(_n_) + (((_n_)->n_descsz+3)&~3))
    3.22 +
    3.23 +#if defined(__i386__)
    3.24 +typedef Elf32_Ehdr Elf_Ehdr;
    3.25 +typedef Elf32_Nhdr Elf_Nhdr;
    3.26 +typedef Elf32_Half Elf_Half;
    3.27 +typedef Elf32_Word Elf_Word;
    3.28 +#elif defined(__x86_64__)
    3.29 +typedef Elf64_Ehdr Elf_Ehdr;
    3.30 +typedef Elf64_Nhdr Elf_Nhdr;
    3.31 +typedef Elf64_Half Elf_Half;
    3.32 +typedef Elf64_Word Elf_Word;
    3.33 +#else
    3.34 +#error "Unknown architecture"
    3.35 +#endif
    3.36 +
    3.37 +static void print_string_note(const char *prefix, Elf_Nhdr *note)
    3.38 +{
    3.39 +	printf("%s: %s\n", prefix, (const char *)ELFNOTE_DESC(note));
    3.40 +}
    3.41 +
    3.42 +static void print_numeric_note(const char *prefix,Elf_Nhdr *note)
    3.43 +{
    3.44 +	switch (note->n_descsz)
    3.45 +	{
    3.46 +	case 4:
    3.47 +		printf("%s: %#010" PRIx32 " (4 bytes)\n",
    3.48 +		       prefix, *(uint32_t *)ELFNOTE_DESC(note));
    3.49 +		break;
    3.50 +	case 8:
    3.51 +		printf("%s: %#018" PRIx64 " (8 bytes)\n",
    3.52 +		       prefix, *(uint64_t *)ELFNOTE_DESC(note));
    3.53 +		break;
    3.54 +	default:
    3.55 +		printf("%s: unknown data size %#x\n", prefix, note->n_descsz);
    3.56 +		break;
    3.57 +	}
    3.58 +}
    3.59 +
    3.60 +static inline unsigned char ehdr_class(void *image)
    3.61 +{
    3.62 +	Elf_Ehdr *ehdr = image;
    3.63 +	switch (ehdr->e_ident[EI_CLASS])
    3.64 +	{
    3.65 +	case ELFCLASS32:
    3.66 +	case ELFCLASS64:
    3.67 +		return ehdr->e_ident[EI_CLASS];
    3.68 +		break;
    3.69 +	default:
    3.70 +		fprintf(stderr, "Unknown ELF class %d\n",
    3.71 +			ehdr->e_ident[EI_CLASS]);
    3.72 +		exit(1);
    3.73 +	}
    3.74 +}
    3.75 +
    3.76 +static inline Elf_Half ehdr_shnum(void *image)
    3.77 +{
    3.78 +	switch (ehdr_class(image))
    3.79 +	{
    3.80 +	case ELFCLASS32:
    3.81 +		return ((Elf32_Ehdr *)image)->e_shnum;
    3.82 +	case ELFCLASS64:
    3.83 +		return ((Elf64_Ehdr *)image)->e_shnum;
    3.84 +	default:
    3.85 +		exit(1);
    3.86 +	}
    3.87 +}
    3.88 +
    3.89 +static inline Elf_Word shdr_type(void *image, int shnum)
    3.90 +{
    3.91 +	switch (ehdr_class(image))
    3.92 +	{
    3.93 +	case ELFCLASS32:
    3.94 +	{
    3.95 +		Elf32_Ehdr *ehdr = (Elf32_Ehdr *)image;
    3.96 +		Elf32_Shdr *shdr = (Elf32_Shdr*)(image + ehdr->e_shoff +
    3.97 +						 (shnum*ehdr->e_shentsize));
    3.98 +		return shdr->sh_type;
    3.99 +	}
   3.100 +	case ELFCLASS64:
   3.101 +	{
   3.102 +		Elf64_Ehdr *ehdr = (Elf64_Ehdr *)image;
   3.103 +		Elf64_Shdr *shdr = (Elf64_Shdr*)(image + ehdr->e_shoff +
   3.104 +						 (shnum*ehdr->e_shentsize));
   3.105 +		return shdr->sh_type;
   3.106 +	}
   3.107 +	default:
   3.108 +		exit(1);
   3.109 +	}
   3.110 +}
   3.111 +
   3.112 +static inline const char *shdr_name(void *image, int shnum)
   3.113 +{
   3.114 +	const char *shstrtab;
   3.115 +
   3.116 +	switch (ehdr_class(image))
   3.117 +	{
   3.118 +	case ELFCLASS32:
   3.119 +	{
   3.120 +		Elf32_Ehdr *ehdr = (Elf32_Ehdr *)image;
   3.121 +		Elf32_Shdr *shdr;
   3.122 +		/* Find the section-header strings table. */
   3.123 +		if ( ehdr->e_shstrndx == SHN_UNDEF )
   3.124 +			return NULL;
   3.125 +		shdr = (Elf32_Shdr *)(image + ehdr->e_shoff +
   3.126 +				      (ehdr->e_shstrndx*ehdr->e_shentsize));
   3.127 +		shstrtab = image + shdr->sh_offset;
   3.128 +
   3.129 +		shdr= (Elf32_Shdr*)(image + ehdr->e_shoff +
   3.130 +				    (shnum*ehdr->e_shentsize));
   3.131 +		return &shstrtab[shdr->sh_name];
   3.132 +	}
   3.133 +	case ELFCLASS64:
   3.134 +	{
   3.135 +		Elf64_Ehdr *ehdr = (Elf64_Ehdr *)image;
   3.136 +		Elf64_Shdr *shdr;
   3.137 +		/* Find the section-header strings table. */
   3.138 +		if ( ehdr->e_shstrndx == SHN_UNDEF )
   3.139 +			return NULL;
   3.140 +		shdr = (Elf64_Shdr *)(image + ehdr->e_shoff +
   3.141 +				      (ehdr->e_shstrndx*ehdr->e_shentsize));
   3.142 +		shstrtab = image + shdr->sh_offset;
   3.143 +
   3.144 +		shdr= (Elf64_Shdr*)(image + ehdr->e_shoff +
   3.145 +				    (shnum*ehdr->e_shentsize));
   3.146 +		return &shstrtab[shdr->sh_name];
   3.147 +	}
   3.148 +	default:
   3.149 +		exit(1);
   3.150 +	}
   3.151 +}
   3.152 +static inline void *shdr_start(void *image, int shnum)
   3.153 +{
   3.154 +	switch (ehdr_class(image))
   3.155 +	{
   3.156 +	case ELFCLASS32:
   3.157 +	{
   3.158 +		Elf32_Ehdr *ehdr = (Elf32_Ehdr *)image;
   3.159 +		Elf32_Shdr *shdr = (Elf32_Shdr*)(image + ehdr->e_shoff +
   3.160 +						 (shnum*ehdr->e_shentsize));
   3.161 +		return image + shdr->sh_offset;
   3.162 +	}
   3.163 +	case ELFCLASS64:
   3.164 +	{
   3.165 +		Elf64_Ehdr *ehdr = (Elf64_Ehdr *)image;
   3.166 +		Elf64_Shdr *shdr = (Elf64_Shdr*)(image + ehdr->e_shoff +
   3.167 +						 (shnum*ehdr->e_shentsize));
   3.168 +		return image + shdr->sh_offset;
   3.169 +	}
   3.170 +	default:
   3.171 +		exit(1);
   3.172 +	}
   3.173 +}
   3.174 +
   3.175 +static inline void *shdr_end(void *image, int shnum)
   3.176 +{
   3.177 +	switch (ehdr_class(image))
   3.178 +	{
   3.179 +	case ELFCLASS32:
   3.180 +	{
   3.181 +		Elf32_Ehdr *ehdr = (Elf32_Ehdr *)image;
   3.182 +		Elf32_Shdr *shdr = (Elf32_Shdr*)(image + ehdr->e_shoff +
   3.183 +						 (shnum*ehdr->e_shentsize));
   3.184 +		return image + shdr->sh_offset + shdr->sh_size;
   3.185 +	}
   3.186 +	case ELFCLASS64:
   3.187 +	{
   3.188 +		Elf64_Ehdr *ehdr = (Elf64_Ehdr *)image;
   3.189 +		Elf64_Shdr *shdr = (Elf64_Shdr*)(image + ehdr->e_shoff +
   3.190 +						 (shnum*ehdr->e_shentsize));
   3.191 +		return image + shdr->sh_offset + shdr->sh_size;
   3.192 +	}
   3.193 +	default:
   3.194 +		exit(1);
   3.195 +	}
   3.196 +}
   3.197 +
   3.198 +int main(int argc, char **argv)
   3.199 +{
   3.200 +	const char *f;
   3.201 +	int fd,h;
   3.202 +	void *image;
   3.203 +	struct stat st;
   3.204 +	Elf_Ehdr *ehdr;
   3.205 +	Elf_Nhdr *note;
   3.206 +
   3.207 +	if (argc != 2)
   3.208 +	{
   3.209 +		fprintf(stderr, "Usage: readnotes <elfimage>\n");
   3.210 +		return 1;
   3.211 +	}
   3.212 +	f = argv[1];
   3.213 +
   3.214 +	fd = open(f, O_RDONLY);
   3.215 +	if (fd == -1)
   3.216 +	{
   3.217 +		fprintf(stderr, "Unable to open %s: %s\n", f, strerror(errno));
   3.218 +		return 1;
   3.219 +	}
   3.220 +	if (fstat(fd, &st) == -1)
   3.221 +	{
   3.222 +		fprintf(stderr, "Unable to determine size of %s: %s\n",
   3.223 +			f, strerror(errno));
   3.224 +		return 1;
   3.225 +	}
   3.226 +
   3.227 +	image = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
   3.228 +	if (image == MAP_FAILED)
   3.229 +	{
   3.230 +		fprintf(stderr, "Unable to map %s: %s\n", f, strerror(errno));
   3.231 +		return 1;
   3.232 +	}
   3.233 +
   3.234 +	ehdr = image;
   3.235 +	if (ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
   3.236 +	    ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
   3.237 +	    ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
   3.238 +	    ehdr->e_ident[EI_MAG3] != ELFMAG3)
   3.239 +	{
   3.240 +		fprintf(stderr, "File %s is not an ELF image\n", f);
   3.241 +		return 1;
   3.242 +	}
   3.243 +
   3.244 +	for ( h=0; h < ehdr_shnum(image); h++)
   3.245 +	{
   3.246 +		if (shdr_type(image,h) != SHT_NOTE)
   3.247 +			continue;
   3.248 +		for (note = (Elf_Nhdr*)shdr_start(image,h);
   3.249 +		     note < (Elf_Nhdr*)shdr_end(image,h);
   3.250 +		     note = (Elf_Nhdr*)(ELFNOTE_NEXT(note)))
   3.251 +		{
   3.252 +			switch(note->n_type)
   3.253 +			{
   3.254 +			case XEN_ELFNOTE_INFO:
   3.255 +				print_string_note("INFO", note);
   3.256 +				break;
   3.257 +			case XEN_ELFNOTE_ENTRY:
   3.258 +				print_numeric_note("ENTRY", note);
   3.259 +				break;
   3.260 +			case XEN_ELFNOTE_HYPERCALL_PAGE:
   3.261 +				print_numeric_note("HYPERCALL_PAGE", note);
   3.262 +				break;
   3.263 +			case XEN_ELFNOTE_VIRT_BASE:
   3.264 +				print_numeric_note("VIRT_BASE", note);
   3.265 +				break;
   3.266 +			case XEN_ELFNOTE_PADDR_OFFSET:
   3.267 +				print_numeric_note("PADDR_OFFSET", note);
   3.268 +				break;
   3.269 +			case XEN_ELFNOTE_XEN_VERSION:
   3.270 +				print_string_note("XEN_VERSION", note);
   3.271 +				break;
   3.272 +			case XEN_ELFNOTE_GUEST_OS:
   3.273 +				print_string_note("GUEST_OS", note);
   3.274 +				break;
   3.275 +			case XEN_ELFNOTE_GUEST_VERSION:
   3.276 +				print_string_note("GUEST_VERSION", note);
   3.277 +				break;
   3.278 +			case XEN_ELFNOTE_LOADER:
   3.279 +				print_string_note("LOADER", note);
   3.280 +				break;
   3.281 +			case XEN_ELFNOTE_PAE_MODE:
   3.282 +				print_string_note("PAE_MODE", note);
   3.283 +				break;
   3.284 +			case XEN_ELFNOTE_FEATURES:
   3.285 +				print_string_note("FEATURES", note);
   3.286 +				break;
   3.287 +			default:
   3.288 +				printf("unknown note type %#x\n", note->n_type);
   3.289 +				break;
   3.290 +			}
   3.291 +		}
   3.292 +	}
   3.293 +
   3.294 +	for ( h=0; h < ehdr_shnum(image); h++)
   3.295 +	{
   3.296 +		const char *name = shdr_name(image,h);
   3.297 +
   3.298 +		if ( name == NULL )
   3.299 +			continue;
   3.300 +		if ( strcmp(name, "__xen_guest") != 0 )
   3.301 +			continue;
   3.302 +
   3.303 +		printf("__xen_guest: %s\n", (const char *)shdr_start(image, h));
   3.304 +		break;
   3.305 +	}
   3.306 +
   3.307 +	return 0;
   3.308 +}
   3.309 +
   3.310 +