[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v1 01/13] Export hypervisor symbols
Export Xen's symbols in format similar to Linux' /proc/kallsyms. Signed-off-by: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx> --- xen/arch/x86/Makefile | 8 ++-- xen/arch/x86/platform_hypercall.c | 14 ++++++ xen/arch/x86/x86_64/platform_hypercall.c | 2 +- xen/common/symbols-dummy.c | 1 + xen/common/symbols.c | 78 ++++++++++++++++++++++++++++++-- xen/include/public/platform.h | 21 +++++++++ xen/include/xen/symbols.h | 4 ++ xen/tools/symbols.c | 4 ++ 8 files changed, 123 insertions(+), 9 deletions(-) diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index d502bdf..a27ac44 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -102,11 +102,11 @@ $(BASEDIR)/common/symbols-dummy.o: $(TARGET)-syms: prelink.o xen.lds $(BASEDIR)/common/symbols-dummy.o $(LD) $(LDFLAGS) -T xen.lds -N prelink.o \ $(BASEDIR)/common/symbols-dummy.o -o $(@D)/.$(@F).0 - $(NM) -n $(@D)/.$(@F).0 | $(BASEDIR)/tools/symbols >$(@D)/.$(@F).0.S + $(NM) -n $(@D)/.$(@F).0 | $(BASEDIR)/tools/symbols --all-symbols >$(@D)/.$(@F).0.S $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).0.o $(LD) $(LDFLAGS) -T xen.lds -N prelink.o \ $(@D)/.$(@F).0.o -o $(@D)/.$(@F).1 - $(NM) -n $(@D)/.$(@F).1 | $(BASEDIR)/tools/symbols >$(@D)/.$(@F).1.S + $(NM) -n $(@D)/.$(@F).1 | $(BASEDIR)/tools/symbols --all-symbols >$(@D)/.$(@F).1.S $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).1.o $(LD) $(LDFLAGS) -T xen.lds -N prelink.o \ $(@D)/.$(@F).1.o -o $@ @@ -129,13 +129,13 @@ $(TARGET).efi: prelink-efi.o efi.lds efi/relocs-dummy.o $(BASEDIR)/common/symbol $(guard) $(LD) $(call EFI_LDFLAGS,$(base)) -T efi.lds -N $< efi/relocs-dummy.o \ $(BASEDIR)/common/symbols-dummy.o -o $(@D)/.$(@F).$(base).0 &&) : $(guard) efi/mkreloc $(foreach base,$(VIRT_BASE) $(ALT_BASE),$(@D)/.$(@F).$(base).0) >$(@D)/.$(@F).0r.S - $(guard) $(NM) -n $(@D)/.$(@F).$(VIRT_BASE).0 | $(guard) $(BASEDIR)/tools/symbols >$(@D)/.$(@F).0s.S + $(guard) $(NM) -n $(@D)/.$(@F).$(VIRT_BASE).0 | $(guard) $(BASEDIR)/tools/symbols --all-symbols >$(@D)/.$(@F).0s.S $(guard) $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).0r.o $(@D)/.$(@F).0s.o $(foreach base, $(VIRT_BASE) $(ALT_BASE), \ $(guard) $(LD) $(call EFI_LDFLAGS,$(base)) -T efi.lds -N $< \ $(@D)/.$(@F).0r.o $(@D)/.$(@F).0s.o -o $(@D)/.$(@F).$(base).1 &&) : $(guard) efi/mkreloc $(foreach base,$(VIRT_BASE) $(ALT_BASE),$(@D)/.$(@F).$(base).1) >$(@D)/.$(@F).1r.S - $(guard) $(NM) -n $(@D)/.$(@F).$(VIRT_BASE).1 | $(guard) $(BASEDIR)/tools/symbols >$(@D)/.$(@F).1s.S + $(guard) $(NM) -n $(@D)/.$(@F).$(VIRT_BASE).1 | $(guard) $(BASEDIR)/tools/symbols --all-symbols >$(@D)/.$(@F).1s.S $(guard) $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).1r.o $(@D)/.$(@F).1s.o $(guard) $(LD) $(call EFI_LDFLAGS,$(VIRT_BASE)) -T efi.lds -N $< \ $(@D)/.$(@F).1r.o $(@D)/.$(@F).1s.o -o $@ diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c index 7175a82..492dc98 100644 --- a/xen/arch/x86/platform_hypercall.c +++ b/xen/arch/x86/platform_hypercall.c @@ -23,6 +23,7 @@ #include <xen/cpu.h> #include <xen/pmstat.h> #include <xen/irq.h> +#include <xen/symbols.h> #include <asm/current.h> #include <public/platform.h> #include <acpi/cpufreq/processor_perf.h> @@ -597,6 +598,19 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) } break; + case XENPF_get_symbols: + { + XEN_GUEST_HANDLE(char) gbuf; + + /* Buffer that holds the symbols */ + guest_from_compat_handle(gbuf, op->u.symdata.buf); + + ret = xensyms_read(guest_handle_to_param(gbuf, char), &op->u.symdata); + if ( ret >= 0 && __copy_field_to_guest(u_xenpf_op, op, u.symdata) ) + ret = -EFAULT; + } + break; + default: ret = -ENOSYS; break; diff --git a/xen/arch/x86/x86_64/platform_hypercall.c b/xen/arch/x86/x86_64/platform_hypercall.c index aa2ad54..9ef705a 100644 --- a/xen/arch/x86/x86_64/platform_hypercall.c +++ b/xen/arch/x86/x86_64/platform_hypercall.c @@ -35,7 +35,7 @@ CHECK_pf_pcpu_version; #undef xen_pf_pcpu_version #define xenpf_enter_acpi_sleep compat_pf_enter_acpi_sleep - +#define xenpf_symdata compat_pf_symdata #define COMPAT #define _XEN_GUEST_HANDLE(t) XEN_GUEST_HANDLE(t) #define _XEN_GUEST_HANDLE_PARAM(t) XEN_GUEST_HANDLE_PARAM(t) diff --git a/xen/common/symbols-dummy.c b/xen/common/symbols-dummy.c index 5090c3b..52a86c7 100644 --- a/xen/common/symbols-dummy.c +++ b/xen/common/symbols-dummy.c @@ -12,6 +12,7 @@ const unsigned int symbols_offsets[1]; const unsigned long symbols_addresses[1]; #endif const unsigned int symbols_num_syms; +const unsigned long symbols_names_bytes; const u8 symbols_names[1]; const u8 symbols_token_table[1]; diff --git a/xen/common/symbols.c b/xen/common/symbols.c index 83b2b58..85d90b0 100644 --- a/xen/common/symbols.c +++ b/xen/common/symbols.c @@ -17,6 +17,8 @@ #include <xen/lib.h> #include <xen/string.h> #include <xen/spinlock.h> +#include <public/platform.h> +#include <xen/guest_access.h> #ifdef SYMBOLS_ORIGIN extern const unsigned int symbols_offsets[1]; @@ -26,6 +28,7 @@ extern const unsigned long symbols_addresses[]; #define symbols_address(n) symbols_addresses[n] #endif extern const unsigned int symbols_num_syms; +extern const unsigned long symbols_names_bytes; extern const u8 symbols_names[]; extern const u8 symbols_token_table[]; @@ -110,10 +113,7 @@ const char *symbols_lookup(unsigned long addr, namebuf[KSYM_NAME_LEN] = 0; namebuf[0] = 0; - if (!is_active_kernel_text(addr)) - return NULL; - - /* do a binary search on the sorted symbols_addresses array */ + /* do a binary search on the sorted symbols_addresses array */ low = 0; high = symbols_num_syms; @@ -174,3 +174,73 @@ void __print_symbol(const char *fmt, unsigned long address) spin_unlock_irqrestore(&lock, flags); } + +/* + * Get symbol type information. This is encoded as a single char at the + * beginning of the symbol name. + */ +static char symbols_get_symbol_type(unsigned int off) +{ + /* + * Get just the first code, look it up in the token table, + * and return the first char from this token. + */ + return symbols_token_table[symbols_token_index[symbols_names[off + 1]]]; +} + +/* + * Returns XENSYMS_SZ bytes worth of symbols to dom0 + */ +int xensyms_read(XEN_GUEST_HANDLE_PARAM(char) gbuf, + struct xenpf_symdata *symdata) +{ + int ret, len = 0, str_len; + unsigned long next_off; + char namebuf[KSYM_NAME_LEN + 1]; + char type; + char *buf; + + buf = xzalloc_bytes(XENSYMS_SZ); + if ( !buf ) + return -ENOMEM; + + if ( symdata->xen_symnum > symbols_num_syms || + symdata->xen_offset > symbols_names_bytes ) + return -EINVAL; + + /* + * Go symbol by symbol, until either reach end of symbol table or fill + * whole XENSYMS_SZ worth of buffer + */ + while ( 1 ) + { + type = symbols_get_symbol_type(symdata->xen_offset); + next_off = symbols_expand_symbol(symdata->xen_offset, namebuf); + + if ( namebuf[0] == '\0' ) + break; + + /* "%016lx %c %s\n" */ + str_len = 16 + 1 + 1 + 1 + strlen(namebuf) + 1 + 1; + + if ( len + str_len >= XENSYMS_SZ ) + break; + + snprintf(&buf[len], str_len, "%016lx %c %s\n", + symbols_offsets[symdata->xen_symnum] + SYMBOLS_ORIGIN, + type, namebuf); + + len += str_len; + symdata->xen_offset = next_off; + symdata->xen_symnum++; + } + + ret = copy_to_guest(gbuf, buf, XENSYMS_SZ) ? -EFAULT : 0; + + xfree(buf); + + if ( ret == 0 ) + return len; + else + return ret; +} diff --git a/xen/include/public/platform.h b/xen/include/public/platform.h index 4341f54..f1782be 100644 --- a/xen/include/public/platform.h +++ b/xen/include/public/platform.h @@ -527,6 +527,26 @@ struct xenpf_core_parking { typedef struct xenpf_core_parking xenpf_core_parking_t; DEFINE_XEN_GUEST_HANDLE(xenpf_core_parking_t); +#define XENPF_get_symbols 61 + +#define XENSYMS_SZ 4096 +struct xenpf_symdata { + /* + * offset into Xen's symbol data and symbol number from + * last call. Used only by Xen. + */ + uint64_t xen_offset; + uint64_t xen_symnum; + + /* + * Symbols data, formatted similar to /proc/kallsyms: + * <address> <type> <name> + */ + XEN_GUEST_HANDLE(char) buf; +}; +typedef struct xenpf_symdata xenpf_symdata_t; +DEFINE_XEN_GUEST_HANDLE(xenpf_symdata_t); + /* * ` enum neg_errnoval * ` HYPERVISOR_platform_op(const struct xen_platform_op*); @@ -553,6 +573,7 @@ struct xen_platform_op { struct xenpf_cpu_hotadd cpu_add; struct xenpf_mem_hotadd mem_add; struct xenpf_core_parking core_parking; + struct xenpf_symdata symdata; uint8_t pad[128]; } u; }; diff --git a/xen/include/xen/symbols.h b/xen/include/xen/symbols.h index 37cf6bf..a0e36d0 100644 --- a/xen/include/xen/symbols.h +++ b/xen/include/xen/symbols.h @@ -2,6 +2,8 @@ #define _XEN_SYMBOLS_H #include <xen/types.h> +#include <public/xen.h> +#include <public/platform.h> #define KSYM_NAME_LEN 127 @@ -34,4 +36,6 @@ do { \ __print_symbol(fmt, addr); \ } while(0) +extern int xensyms_read(XEN_GUEST_HANDLE_PARAM(char) gbuf, struct xenpf_symdata *symdata); + #endif /*_XEN_SYMBOLS_H*/ diff --git a/xen/tools/symbols.c b/xen/tools/symbols.c index f39c906..818204d 100644 --- a/xen/tools/symbols.c +++ b/xen/tools/symbols.c @@ -272,6 +272,10 @@ static void write_src(void) } printf("\n"); + output_label("symbols_names_bytes"); + printf("\t.long\t%d\n", off); + printf("\n"); + output_label("symbols_markers"); for (i = 0; i < ((table_cnt + 255) >> 8); i++) printf("\t.long\t%d\n", markers[i]); -- 1.8.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |