]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
kvm tools: Fixes for symbol resolving module
authorSasha Levin <levinsasha928@gmail.com>
Sun, 29 Jan 2012 14:37:23 +0000 (09:37 -0500)
committerSasha Levin <levinsasha928@gmail.com>
Sun, 29 Jan 2012 14:37:23 +0000 (09:37 -0500)
Fixes include:
 - Error handling
 - Cleanup
 - Standard init/uninit

Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
tools/kvm/builtin-run.c
tools/kvm/include/kvm/symbol.h
tools/kvm/symbol.c
tools/kvm/x86/kvm-cpu.c

index 67c9fa15c409aa886294353b76ca71a4f386d591..255562fc5a3427eca1867ddd91c93b0395662b9b 100644 (file)
@@ -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)
index 5bc2221b8ace68d2cec6838b81c230ca0473e273..9cc3f954b4bf00e6ece9763ab864ab303480daab 100644 (file)
@@ -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 */
index a2b1e67032ce087a7cea7d2649f6183f1c47d51d..00a6fe2e1042de2d48f53159924361259f7007e1 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "kvm/kvm.h"
 
+#include <linux/err.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 
 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;
 }
index 051699f3fe8c40780d876fc44ab9c04af0ef157c..4aa1b9a248703c84675e8325bfd58f7d22f384ea 100644 (file)
@@ -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);