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);
if (!script)
script = DEFAULT_SCRIPT;
- symbol__init(vmlinux_filename);
-
term_init();
if (!guest_name) {
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();
thread_pool__init(nr_online_cpus);
ioeventfd__start();
- return 0;
+fail:
+ return r;
}
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);
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)
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 */
#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];
return symbol;
}
- return NULL;
+ return ERR_PTR(r);
}
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;
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;
goto not_found;
symbol = lookup(syms, nr_syms, func);
- if (!symbol)
+ if (IS_ERR(symbol))
goto not_found;
sym_start = bfd_asymbol_value(symbol);
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;
}
#include <asm/msr-index.h>
#include <asm/apicdef.h>
-
+#include <linux/err.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <signal.h>
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;
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);