[RFC 02/12] kvm tools: Fixes for symbol resolving module

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

 



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

Signed-off-by: Sasha Levin <levinsasha928@xxxxxxxxx>
---
 tools/kvm/builtin-run.c        |   31 ++++++++++++++-------
 tools/kvm/include/kvm/symbol.h |    7 +++-
 tools/kvm/symbol.c             |   59 +++++++++++++++++++++++++++++++---------
 tools/kvm/x86/kvm-cpu.c        |   10 +++++--
 4 files changed, 79 insertions(+), 28 deletions(-)

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index 0234879..3d046d7 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -851,7 +851,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);
@@ -946,8 +946,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) {
@@ -1047,7 +1045,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_error("symbol__init() failed with error %d\n", r);
+		goto fail;
+	}
 
 	ioport__setup_arch();
 
@@ -1130,7 +1133,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)
@@ -1160,10 +1164,16 @@ static int kvm_cmd_run_work(void)
 	return r;
 }
 
-static int kvm_cmd_run_uninit(int guest_ret)
+static void kvm_cmd_run_uninit(int guest_ret)
 {
+	int r = 0;
+
 	compat__print_all_messages();
 
+	r = symbol__uninit(kvm);
+	if (r < 0)
+		pr_warning("symbol__uninit() failed with error %d\n", r);
+
 	fb__stop();
 
 	virtio_blk__delete_all(kvm);
@@ -1174,17 +1184,18 @@ static int kvm_cmd_run_uninit(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)
+		goto fail;
 	ret = kvm_cmd_run_work();
-	r = kvm_cmd_run_uninit(ret);
+	kvm_cmd_run_uninit(ret);
 
+fail:
 	return ret;
 }
diff --git a/tools/kvm/include/kvm/symbol.h b/tools/kvm/include/kvm/symbol.h
index 5bc2221..062f411 100644
--- a/tools/kvm/include/kvm/symbol.h
+++ b/tools/kvm/include/kvm/symbol.h
@@ -6,14 +6,17 @@
 
 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__uninit(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 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;
 }
diff --git a/tools/kvm/symbol.c b/tools/kvm/symbol.c
index a2b1e67..54691a4 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,13 +79,15 @@ 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);
 
-	section = bfd_get_section_by_name(abfd, ".debug_aranges");
+	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__uninit(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);
 
-- 
1.7.8

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux