Commit d8f3540a authored by Charles Jacobsen's avatar Charles Jacobsen Committed by Vikram Narayanan

stack-trace: Stack trace 90 percent there. Wow, that was ugly.

I fought this thing until late in the morning. Since we're
working with a copy of the module image (.ko), some of the fields
in the struct module have to be updated (symbol and string table
fields). Then, everything works.

Still getting weird trace symbol for return address at the
bottom of the stack.
parent 64c36706
......@@ -807,9 +807,5 @@ static inline bool module_sig_ok(struct module *module)
int do_sys_delete_module(const char *name, unsigned int flags, int for_lcd);
int do_sys_init_module(void __user *umod, unsigned long len,
const char __user *uargs, int for_lcd);
const char *get_ksymbol(struct module *mod,
unsigned long addr,
unsigned long *size,
unsigned long *offset);
#endif /* _LINUX_MODULE_H */
......@@ -4054,7 +4054,6 @@ const char *get_ksymbol(struct module *mod,
*offset = addr - kallsyms->symtab[best].st_value;
return symname(kallsyms, best);
}
EXPORT_SYMBOL(get_ksymbol);
/* For kallsyms to ask for address resolution. NULL means not found. Careful
* not to lock to avoid deadlock on oopses, simply disable preemption. */
......
......@@ -11,6 +11,7 @@
#include <asm/vmx.h>
#include <linux/mutex.h>
#include <linux/module.h>
#include <lcd_domains/types.h>
struct lcd_arch_vmcs {
u32 revision_id;
......
......@@ -29,6 +29,15 @@ static inline gva_t stack_bottom(gva_t sp)
sizeof(unsigned long));
}
static inline gva_t stack_trace_bottom(gva_t sp)
{
gva_t sbottom = stack_bottom(sp);
/*
* We don't want to look up the 0x0 ret addr
*/
return __gva(gva_val(sbottom) - sizeof(unsigned long));
}
static inline int stack_addr_gva2hva(struct lcd_arch *lcd, gva_t gva,
hva_t *hva_out)
{
......@@ -45,20 +54,18 @@ static inline int stack_addr_gva2hva(struct lcd_arch *lcd, gva_t gva,
static int print_one_addr(gva_t addr, struct lcd_arch *lcd)
{
int ret;
hva_t addr_hva;
char symname[KSYM_SYMBOL_LEN];
/*
* Resolve address on stack to hva
*/
ret = stack_addr_gva2hva(lcd, addr, &addr_hva);
if (ret)
return ret;
/*
* Resove address to symbol info
*
* Since we map the code in the same location inside
* the LCD as it is in the host, gva == hva!
*/
if (__lcd_sprint_symbol(symname, addr_hva, lcd->kernel_module))
printk("[<0x%016lx>] %s", gva_val(addr), symname);
if (__lcd_sprint_symbol(symname, __hva(gva_val(addr)),
lcd->kernel_module))
printk(" [<0x%016lx>] %s\n", gva_val(addr), symname);
else
printk(" [<0x%016lx>] ??\n", gva_val(addr));
return 0;
}
......@@ -103,7 +110,7 @@ static void _show_trace(struct lcd_arch *lcd, gva_t sp,
gva_t __maybe_unused bp)
{
hva_t stack_hva;
gva_t stack_bottom_gva = stack_bottom(sp);
gva_t stack_bottom_gva = stack_trace_bottom(sp);
gva_t addr;
hva_t addr_hva;
......@@ -131,7 +138,7 @@ static void _show_trace(struct lcd_arch *lcd, gva_t sp,
int ret;
/* Bounds for range of valid frame pointer. */
gva_t low = sp, high = stack_bottom(sp);
gva_t low = sp, high = stack_trace_bottom(sp);
/* The initial frame pointer. */
frame_gva = bp;
......
......@@ -9,6 +9,7 @@
#include <lcd_config/pre_hook.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <libcap.h>
......@@ -515,14 +516,29 @@ fail1:
}
#ifndef LCD_ISOLATE
static void fix_struct_module_addrs(struct module *mod, void *m_core_bits)
{
unsigned long symtab_offset, strtab_offset;
/*
* Point symbol table and string table to new home
*/
symtab_offset = ((unsigned long)mod->symtab) -
((unsigned long)mod->module_core);
strtab_offset = ((unsigned long)mod->strtab) -
((unsigned long)mod->module_core);
mod->symtab = m_core_bits + symtab_offset;
mod->strtab = m_core_bits + strtab_offset;
}
static int set_struct_module(cptr_t lcd, void *m_core_bits,
unsigned long m_struct_module_core_offset)
{
hva_t m_hva;
struct module *mod = m_core_bits + m_struct_module_core_offset;
fix_struct_module_addrs(mod, m_core_bits);
m_hva = __hva((unsigned long)(m_core_bits +
m_struct_module_core_offset));
return lcd_set_struct_module_hva(lcd, m_hva);
return lcd_set_struct_module_hva(lcd, mod);
}
#endif
......
......@@ -814,18 +814,19 @@ void __lcd_console_exit(void);
* __lcd_set_struct_module_hva -- Set pointer to the struct module for @lcd
* @caller: LCD doing the setting
* @lcd: LCD who is using struct module
* @module_addr: host virtual address of the struct module copy
* @mod: host virtual address of the struct module copy
*
* For motivation, see liblcd version of this function.
*/
int __lcd_set_struct_module_hva(struct lcd *caller, cptr_t lcd,
hva_t module_addr);
struct module *mod);
/**
* __lcd_sprint_symbol -- Resolve a host virtual address to a symbol name
* @buffer: char buff to print symbol info to; must be at least KSYM_SYMBOL_LEN
* in length
* @module: the struct module to use for module symbol resolution
* @hva: the address to resolve
* @new_m_core_addr: the host virtual address where the core is now mapped
*
* Returns length of string data written to @buffer.
*
......
......@@ -105,10 +105,13 @@ int lcd_memory_grant_and_map(cptr_t lcd, cptr_t mo, cptr_t dest_slot,
* @dest: slot in LCD's cspace where capability should be stored
*/
int lcd_cap_grant(cptr_t lcd, cptr_t src, cptr_t dest);
struct module;
/**
* lcd_set_struct_module_hva -- Remember the hva of the struct module copy
* @lcd: LCD that is using the module
* @hva: the host virtual address of the struct module copy
* @mod: the host virtual address of the struct module copy
*
* Motivation: We unload the modules from the host now after they have been
* loaded into the LCD. But the struct module is still around, its just in
......@@ -120,7 +123,7 @@ int lcd_cap_grant(cptr_t lcd, cptr_t src, cptr_t dest);
*
* For isolated code calling this function, also returns error.
*/
int lcd_set_struct_module_hva(cptr_t lcd, hva_t hva);
int lcd_set_struct_module_hva(cptr_t lcd, struct module *mod);
/**
* lcd_run -- Run an LCD
* @lcd: the LCD to run
......
......@@ -1134,9 +1134,9 @@ int lcd_cap_grant(cptr_t lcd, cptr_t src, cptr_t dest)
return __lcd_cap_grant(current->lcd, lcd, src, dest);
}
int lcd_set_struct_module_hva(cptr_t lcd, hva_t hva)
int lcd_set_struct_module_hva(cptr_t lcd, struct module *mod)
{
return __lcd_set_struct_module_hva(current->lcd, lcd, hva);
return __lcd_set_struct_module_hva(current->lcd, lcd, mod);
}
int lcd_run(cptr_t lcd)
......
......@@ -66,7 +66,7 @@ int lcd_cap_grant(cptr_t lcd, cptr_t src, cptr_t dest)
return lcd_syscall_cap_grant(lcd, src, dest);
}
int lcd_set_struct_module_hva(cptr_t lcd, hva_t hva)
int lcd_set_struct_module_hva(cptr_t lcd, struct module *mod)
{
return -ENOSYS; /* not allowed in isolated (for now I suppose) */
}
......
......@@ -11,7 +11,7 @@
#include <linux/kallsyms.h>
int __lcd_set_struct_module_hva(struct lcd *caller, cptr_t lcd,
hva_t module_addr)
struct module *mod)
{
struct cnode *cnode;
struct lcd *lcd_struct;
......@@ -35,7 +35,7 @@ int __lcd_set_struct_module_hva(struct lcd *caller, cptr_t lcd,
/*
* Store module address in lcd_arch
*/
lcd_struct->lcd_arch->kernel_module = hva2va(module_addr);
lcd_struct->lcd_arch->kernel_module = mod;
__lcd_put(caller, cnode, lcd_struct);
......@@ -47,23 +47,72 @@ fail1:
return ret;
}
static inline const char *adjust_addr(const char *addr, struct module *mod,
hva_t new_m_core_addr)
{
/* unsigned long offset; */
/*
* Compute offset into module's core
*/
return addr;
/* offset = ((unsigned long)addr) - ((unsigned long)mod->module_core); */
/* /\* */
/* * Add to new core location */
/* *\/ */
/* return (const char *)(hva_val(new_m_core_addr) + offset); */
}
static const char *get_ksymbol(struct module *mod,
hva_t addr,
unsigned long *size,
unsigned long *offset)
{
unsigned int i, best = 0;
unsigned long nextval;
/* At worse, next value is at end of module */
if (within_module_init(hva_val(addr), mod))
nextval = (unsigned long)mod->module_init+mod->init_text_size;
else
nextval = (unsigned long)mod->module_core+mod->core_text_size;
/* Scan for closest preceding symbol, and next symbol. (ELF
starts real symbols at 1). */
for (i = 1; i < mod->num_symtab; i++) {
if (mod->symtab[i].st_shndx == SHN_UNDEF)
continue;
/* We ignore unnamed symbols: they're uninformative
* and inserted at a whim. */
if (mod->symtab[i].st_value <= hva_val(addr)
&& mod->symtab[i].st_value > mod->symtab[best].st_value &&
*(mod->strtab + mod->symtab[i].st_name) != '\0')
best = i;
if (mod->symtab[i].st_value > hva_val(addr)
&& mod->symtab[i].st_value < nextval
&& *(mod->strtab + mod->symtab[i].st_name) != '\0')
nextval = mod->symtab[i].st_value;
}
if (!best)
return NULL;
if (size)
*size = nextval - mod->symtab[best].st_value;
if (offset)
*offset = hva_val(addr) - mod->symtab[best].st_value;
return mod->strtab + mod->symtab[best].st_name;
}
static inline int in_module(struct module *module, hva_t hva)
{
/*
* XXX: Danger section: The struct module is inside the LCD; it
* could have messed with these fields. This is for debug only.
*/
/* in module's init? */
if(hva2va(hva) >= module->module_init &&
hva2va(hva) < (module->module_init + module->init_size))
return 1;
/* in module's core? */
if(hva2va(hva) >= module->module_core &&
hva2va(hva) < (module->module_core + module->core_size))
return 1;
/* not in module */
return 0;
return within_module_init(hva_val(hva), module) ||
within_module_core(hva_val(hva), module);
}
unsigned long
......@@ -85,8 +134,10 @@ __lcd_sprint_symbol(char *buffer, hva_t hva, struct module *extra_module)
* XXX: Danger: This is for debug only. The struct module
* is mapped inside an LCD which could mess with it.
*/
sym_name = get_ksymbol(extra_module, hva_val(hva),
sym_name = get_ksymbol(extra_module, hva,
&size, &offset);
if (!sym_name)
return 0;
modname = extra_module->name;
strncpy(buffer, sym_name, KSYM_NAME_LEN - 1);
} else {
......@@ -96,7 +147,7 @@ __lcd_sprint_symbol(char *buffer, hva_t hva, struct module *extra_module)
sym_name = kallsyms_lookup(hva_val(hva), &size, &offset,
&modname, buffer);
if (!sym_name)
return sprintf(buffer, "0x%lx", hva_val(hva));
return 0;
if (sym_name != buffer)
strcpy(buffer, sym_name);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment