[tip:tools/kvm] kvm tools: Fixes for symbol resolving module

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

 



Commit-ID:  e45af6fe659fc592aae5eb0576524604e39ec755
Gitweb:     http://git.kernel.org/tip/e45af6fe659fc592aae5eb0576524604e39ec755
Author:     Sasha Levin <levinsasha928@xxxxxxxxx>
AuthorDate: Sun, 29 Jan 2012 09:37:23 -0500
Committer:  Sasha Levin <levinsasha928@xxxxxxxxx>
CommitDate: Sun, 29 Jan 2012 09:37:23 -0500

kvm tools: Fixes for symbol resolving module

Fixes include:
 - Error handling
 - Cleanup
 - Standard init/uninit

Signed-off-by: Sasha Levin <levinsasha928@xxxxxxxxx>
---
 tools/kvm/builtin-run.c        |   26 ++++++++++++------
 tools/kvm/include/kvm/symbol.h |   10 +++++--
 tools/kvm/symbol.c             |   57 +++++++++++++++++++++++++++++++--------
 tools/kvm/x86/kvm-cpu.c        |   10 +++++--
 4 files changed, 76 insertions(+), 27 deletions(-)

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index 67c9fa1..255562f 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -877,7 +877,7 @@ static int kvm_cmd_run_init(int argc, const char **argv)
 	struct framebuffer *fb = NULL;
 	unsigned int nr_online_cpus;
 	int max_cpus, recommended_cpus;
-	int i;
+	int i, r;
 
 	signal(SIGALRM, handle_sigalrm);
 	kvm_ipc__register_handler(KVM_IPC_DEBUG, handle_debug);
@@ -984,8 +984,6 @@ static int kvm_cmd_run_init(int argc, const char **argv)
 	if (!script)
 		script = DEFAULT_SCRIPT;
 
-	symbol__init(vmlinux_filename);
-
 	term_init();
 
 	if (!guest_name) {
@@ -1090,7 +1088,12 @@ static int kvm_cmd_run_init(int argc, const char **argv)
 				real_cmdline, vidmode))
 		die("unable to load kernel %s", kernel_filename);
 
-	kvm->vmlinux		= vmlinux_filename;
+	kvm->vmlinux = vmlinux_filename;
+	r = symbol__init(kvm);
+	if (r < 0) {
+		pr_err("symbol__init() failed with error %d\n", r);
+		goto fail;
+	}
 
 	ioport__setup_arch();
 
@@ -1173,7 +1176,8 @@ static int kvm_cmd_run_init(int argc, const char **argv)
 	thread_pool__init(nr_online_cpus);
 	ioeventfd__start();
 
-	return 0;
+fail:
+	return r;
 }
 
 static int kvm_cmd_run_work(void)
@@ -1206,10 +1210,16 @@ static int kvm_cmd_run_work(void)
 	return r;
 }
 
-static int kvm_cmd_run_exit(int guest_ret)
+static void kvm_cmd_run_exit(int guest_ret)
 {
+	int r = 0;
+
 	compat__print_all_messages();
 
+	r = symbol__exit(kvm);
+	if (r < 0)
+		pr_warning("symbol__exit() failed with error %d\n", r);
+
 	fb__stop();
 
 	virtio_blk__delete_all(kvm);
@@ -1221,13 +1231,11 @@ static int kvm_cmd_run_exit(int guest_ret)
 
 	if (guest_ret == 0)
 		printf("\n  # KVM session ended normally.\n");
-
-	return 0;
 }
 
 int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 {
-	int r, ret;
+	int r, ret = -EFAULT;
 
 	r = kvm_cmd_run_init(argc, argv);
 	if (r < 0)
diff --git a/tools/kvm/include/kvm/symbol.h b/tools/kvm/include/kvm/symbol.h
index 5bc2221..9cc3f95 100644
--- a/tools/kvm/include/kvm/symbol.h
+++ b/tools/kvm/include/kvm/symbol.h
@@ -6,17 +6,21 @@
 
 struct kvm;
 
+#define SYMBOL_DEFAULT_UNKNOWN "<unknown>"
+
 #ifdef CONFIG_HAS_BFD
-void symbol__init(const char *vmlinux);
+int symbol__init(struct kvm *kvm);
+int symbol__exit(struct kvm *kvm);
 char *symbol__lookup(struct kvm *kvm, unsigned long addr, char *sym, size_t size);
 #else
-static inline void symbol__init(const char *vmlinux) { }
+static inline int symbol__init(struct kvm *kvm) { return 0; }
 static inline char *symbol__lookup(struct kvm *kvm, unsigned long addr, char *sym, size_t size)
 {
-	char *s = strncpy(sym, "<unknown>", size);
+	char *s = strncpy(sym, SYMBOL_DEFAULT_UNKNOWN, size);
 	sym[size - 1] = '\0';
 	return s;
 }
+static inline int symbol__exit(struct kvm *kvm) { return 0; }
 #endif
 
 #endif /* KVM__SYMBOL_H */
diff --git a/tools/kvm/symbol.c b/tools/kvm/symbol.c
index a2b1e67..00a6fe2 100644
--- a/tools/kvm/symbol.c
+++ b/tools/kvm/symbol.c
@@ -2,6 +2,7 @@
 
 #include "kvm/kvm.h"
 
+#include <linux/err.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
@@ -9,19 +10,40 @@
 
 static bfd *abfd;
 
-void symbol__init(const char *vmlinux)
+int symbol__init(struct kvm *kvm)
 {
-	if (!vmlinux)
-		return;
+	int r = 0;
+
+	if (!kvm->vmlinux)
+		return -EINVAL;
 
 	bfd_init();
 
-	abfd = bfd_openr(vmlinux, NULL);
+	abfd = bfd_openr(kvm->vmlinux, NULL);
+	if (abfd == NULL) {
+		bfd_error_type err = bfd_get_error();
+
+		switch (err) {
+		case bfd_error_no_memory:
+			r = -ENOMEM;
+			break;
+		case bfd_error_invalid_target:
+			r = -EINVAL;
+			break;
+		default:
+			r = -EFAULT;
+			break;
+		}
+	}
+
+	return r;
 }
 
 static asymbol *lookup(asymbol **symbols, int nr_symbols, const char *symbol_name)
 {
-	int i;
+	int i, r;
+
+	r = -ENOENT;
 
 	for (i = 0; i < nr_symbols; i++) {
 		asymbol *symbol = symbols[i];
@@ -30,7 +52,7 @@ static asymbol *lookup(asymbol **symbols, int nr_symbols, const char *symbol_nam
 			return symbol;
 	}
 
-	return NULL;
+	return ERR_PTR(r);
 }
 
 char *symbol__lookup(struct kvm *kvm, unsigned long addr, char *sym, size_t size)
@@ -44,9 +66,9 @@ char *symbol__lookup(struct kvm *kvm, unsigned long addr, char *sym, size_t size
 	long symtab_size;
 	asymbol *symbol;
 	asymbol **syms;
-	int nr_syms;
-	char *s;
+	int nr_syms, r;
 
+	r = -ENOENT;
 	if (!abfd)
 		goto not_found;
 
@@ -57,12 +79,14 @@ char *symbol__lookup(struct kvm *kvm, unsigned long addr, char *sym, size_t size
 	if (!symtab_size)
 		goto not_found;
 
+	r = -ENOMEM;
 	syms = malloc(symtab_size);
 	if (!syms)
 		goto not_found;
 
 	nr_syms = bfd_canonicalize_symtab(abfd, syms);
 
+	r = -ENOENT;
 	section = bfd_get_section_by_name(abfd, ".debug_aranges");
 	if (!section)
 		goto not_found;
@@ -74,7 +98,7 @@ char *symbol__lookup(struct kvm *kvm, unsigned long addr, char *sym, size_t size
 		goto not_found;
 
 	symbol = lookup(syms, nr_syms, func);
-	if (!symbol)
+	if (IS_ERR(symbol))
 		goto not_found;
 
 	sym_start = bfd_asymbol_value(symbol);
@@ -90,9 +114,18 @@ char *symbol__lookup(struct kvm *kvm, unsigned long addr, char *sym, size_t size
 	return sym;
 
 not_found:
-	s = strncpy(sym, "<unknown>", size);
+	return ERR_PTR(r);
+}
 
-	sym[size - 1] = '\0';
+int symbol__exit(struct kvm *kvm)
+{
+	bfd_boolean r = TRUE;
+
+	if (abfd)
+		r = bfd_close(abfd);
+
+	if (r == TRUE)
+		return 0;
 
-	return s;
+	return -EFAULT;
 }
diff --git a/tools/kvm/x86/kvm-cpu.c b/tools/kvm/x86/kvm-cpu.c
index 051699f..4aa1b9a 100644
--- a/tools/kvm/x86/kvm-cpu.c
+++ b/tools/kvm/x86/kvm-cpu.c
@@ -6,7 +6,7 @@
 
 #include <asm/msr-index.h>
 #include <asm/apicdef.h>
-
+#include <linux/err.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
 #include <signal.h>
@@ -324,7 +324,7 @@ void kvm_cpu__show_code(struct kvm_cpu *vcpu)
 	unsigned int code_bytes = 64;
 	unsigned int code_prologue = 43;
 	unsigned int code_len = code_bytes;
-	char sym[MAX_SYM_LEN];
+	char sym[MAX_SYM_LEN] = SYMBOL_DEFAULT_UNKNOWN, *psym;
 	unsigned char c;
 	unsigned int i;
 	u8 *ip;
@@ -340,7 +340,11 @@ void kvm_cpu__show_code(struct kvm_cpu *vcpu)
 	dprintf(debug_fd, "\n Code:\n");
 	dprintf(debug_fd,   " -----\n");
 
-	symbol__lookup(vcpu->kvm, vcpu->regs.rip, sym, MAX_SYM_LEN);
+	psym = symbol__lookup(vcpu->kvm, vcpu->regs.rip, sym, MAX_SYM_LEN);
+	if (IS_ERR(psym))
+		dprintf(debug_fd,
+			"Warning: symbol__lookup() failed to find symbol "
+			"with error: %ld\n", PTR_ERR(psym));
 
 	dprintf(debug_fd, " rip: [<%016lx>] %s\n\n", (unsigned long) vcpu->regs.rip, sym);
 
--
To unsubscribe from this list: send the line "unsubscribe linux-tip-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Stable Commits]     [Linux Stable Kernel]     [Linux Kernel]     [Linux USB Devel]     [Linux Video &Media]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux