summaryrefslogtreecommitdiff
path: root/arch/x86/machine/strace.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/machine/strace.c')
-rw-r--r--arch/x86/machine/strace.c212
1 files changed, 14 insertions, 198 deletions
diff --git a/arch/x86/machine/strace.c b/arch/x86/machine/strace.c
index cfb237e1..3031e544 100644
--- a/arch/x86/machine/strace.c
+++ b/arch/x86/machine/strace.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2012-2014 Richard Braun.
+ * Copyright (c) 2018 Agustina Arzille.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,15 +17,10 @@
*/
#include <stddef.h>
+#include <stdint.h>
#include <stdio.h>
-#include <string.h>
-#include <kern/init.h>
-#include <kern/kmem.h>
-#include <kern/log.h>
-#include <kern/macros.h>
-#include <machine/elf.h>
-#include <machine/multiboot.h>
+#include <kern/symbol.h>
#include <machine/pmap.h>
#include <machine/strace.h>
#include <machine/types.h>
@@ -36,56 +32,26 @@
#define STRACE_ADDR_FORMAT "%#010lx"
#endif /* __LP64__ */
-static const struct multiboot_raw_info *strace_mbi __initdata;
-
-static struct elf_sym *strace_symtab __read_mostly;
-static struct elf_sym *strace_symtab_end __read_mostly;
-static char *strace_strtab __read_mostly;
-
-static const char *
-strace_lookup(uintptr_t addr, uintptr_t *offset, uintptr_t *size)
-{
- struct elf_sym *sym;
-
- for (sym = strace_symtab; sym < strace_symtab_end; sym++) {
- if ((sym->size != 0)
- && (addr >= sym->value)
- && (addr <= (sym->value + sym->size))) {
- break;
- }
- }
-
- if (sym >= strace_symtab_end) {
- return NULL;
- }
-
- if (sym->name == 0) {
- return NULL;
- }
-
- *offset = addr - sym->value;
- *size = sym->size;
- return &strace_strtab[sym->name];
-}
-
static void
-strace_show_one(unsigned int index, unsigned long ip)
+strace_show_one(unsigned int index, uintptr_t ip)
{
- uintptr_t offset, size;
- const char *name;
+ const struct symbol *symbol;
+ uintptr_t offset;
- name = strace_lookup(ip, &offset, &size);
+ symbol = symbol_lookup(ip);
- if (name == NULL) {
- printf("#%u [" STRACE_ADDR_FORMAT "]\n", index, ip);
+ if (!symbol) {
+ printf("#%u [" STRACE_ADDR_FORMAT "]\n", index, (unsigned long)ip);
} else {
+ offset = ip - symbol->addr;
printf("#%u [" STRACE_ADDR_FORMAT "] %s+%#lx/%#lx\n",
- index, ip, name, (unsigned long)offset, (unsigned long)size);
+ index, (unsigned long)ip, symbol->name,
+ (unsigned long)offset, (unsigned long)symbol->size);
}
}
void
-strace_show(unsigned long ip, unsigned long bp)
+strace_show(uintptr_t ip, uintptr_t bp)
{
phys_addr_t pa;
void **frame;
@@ -109,7 +75,7 @@ strace_show(unsigned long ip, unsigned long bp)
break;
}
- strace_show_one(i, (unsigned long)frame[1]);
+ strace_show_one(i, (uintptr_t)frame[1]);
error = pmap_kextract((uintptr_t)frame, &pa);
if (error) {
@@ -121,153 +87,3 @@ strace_show(unsigned long ip, unsigned long bp)
frame = frame[0];
}
}
-
-static void * __init
-strace_copy_section(const struct elf_shdr *shdr)
-{
- uintptr_t map_addr;
- size_t map_size;
- const void *src;
- void *copy;
-
- src = vm_kmem_map_pa(shdr->addr, shdr->size, &map_addr, &map_size);
-
- if (src == NULL) {
- log_err("strace: unable to map section");
- goto error_map;
- }
-
- copy = kmem_alloc(shdr->size);
-
- if (copy == NULL) {
- log_err("strace: unable to allocate section copy");
- goto error_copy;
- }
-
- memcpy(copy, src, shdr->size);
- vm_kmem_unmap_pa(map_addr, map_size);
- return copy;
-
-error_copy:
- vm_kmem_unmap_pa(map_addr, map_size);
-error_map:
- return NULL;
-}
-
-static const struct elf_shdr * __init
-strace_lookup_section(const struct multiboot_raw_info *mbi, const void *table,
- const char *shstrtab, const char *name)
-{
- const struct elf_shdr *shdr;
- unsigned int i;
- const char *shdr_name;
-
- for (i = 0; i < mbi->shdr_num; i++) {
- shdr = table + (i * mbi->shdr_size);
- shdr_name = &shstrtab[shdr->name];
-
- if (strcmp(shdr_name, name) == 0) {
- return shdr;
- }
- }
-
- return NULL;
-}
-
-void __init
-strace_set_mbi(const struct multiboot_raw_info *mbi)
-{
- strace_mbi = mbi;
-}
-
-static int __init
-strace_setup(void)
-{
- const struct elf_shdr *shstrtab_hdr, *symtab_hdr, *strtab_hdr;
- const struct multiboot_raw_info *mbi;
- uintptr_t map_addr, shstrtab_map_addr;
- size_t size, map_size, shstrtab_map_size;
- const char *shstrtab;
- const void *table;
-
- mbi = strace_mbi;
-
- if (!(mbi->flags & MULTIBOOT_LOADER_SHDR) || (mbi->shdr_num == 0)) {
- goto no_syms;
- }
-
- size = mbi->shdr_num * mbi->shdr_size;
- table = vm_kmem_map_pa(mbi->shdr_addr, size, &map_addr, &map_size);
-
- if (table == NULL) {
- log_err("strace: unable to map section headers table");
- goto no_syms;
- }
-
- if (mbi->shdr_strndx >= mbi->shdr_num) {
- log_err("strace: invalid section names index");
- goto error_shstrndx;
- }
-
- shstrtab_hdr = table + (mbi->shdr_strndx * mbi->shdr_size);
- shstrtab = vm_kmem_map_pa(shstrtab_hdr->addr, shstrtab_hdr->size,
- &shstrtab_map_addr, &shstrtab_map_size);
-
- if (shstrtab == NULL) {
- log_err("strace: unable to map section names");
- goto error_shstrtab;
- }
-
- symtab_hdr = strace_lookup_section(mbi, table, shstrtab, ".symtab");
-
- if (symtab_hdr == NULL) {
- log_err("strace: unable to find symbol table");
- goto error_symtab_lookup;
- }
-
- strtab_hdr = strace_lookup_section(mbi, table, shstrtab, ".strtab");
-
- if (strtab_hdr == NULL) {
- log_err("strace: unable to find symbol string table");
- goto error_strtab_lookup;
- }
-
- strace_symtab = strace_copy_section(symtab_hdr);
-
- if (strace_symtab == NULL) {
- goto error_symtab;
- }
-
- strace_symtab_end = (void *)strace_symtab + symtab_hdr->size;
- strace_strtab = strace_copy_section(strtab_hdr);
-
- if (strace_strtab == NULL) {
- goto error_strtab;
- }
-
- vm_kmem_unmap_pa(shstrtab_map_addr, shstrtab_map_size);
- vm_kmem_unmap_pa(map_addr, map_size);
- return 0;
-
-error_strtab:
- kmem_free(strace_symtab, symtab_hdr->size);
-error_symtab:
-error_strtab_lookup:
-error_symtab_lookup:
- vm_kmem_unmap_pa(shstrtab_map_addr, shstrtab_map_size);
-error_shstrtab:
-error_shstrndx:
- vm_kmem_unmap_pa(map_addr, map_size);
-no_syms:
- strace_symtab = NULL;
- strace_symtab_end = NULL;
- strace_strtab = NULL;
- return 0;
-}
-
-INIT_OP_DEFINE(strace_setup,
- INIT_OP_DEP(kmem_setup, true),
- INIT_OP_DEP(log_setup, true),
- INIT_OP_DEP(pmap_bootstrap, true),
- INIT_OP_DEP(printf_setup, true),
- INIT_OP_DEP(vm_kmem_setup, true));