summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2018-06-26 22:10:39 +0200
committerRichard Braun <rbraun@sceen.net>2018-06-26 22:10:39 +0200
commit186d6a966ea70997846a95dd8c34b2e3e7f74145 (patch)
tree7cf96ca7c6d3a3f46f3561a32ae736e752f2fc76
parentc518968ee15d845a6d8c2015aed643495045e551 (diff)
x86/strace: rework to use the embedded symbol table
-rw-r--r--arch/x86/machine/boot.c2
-rw-r--r--arch/x86/machine/strace.c212
-rw-r--r--arch/x86/machine/strace.h25
-rw-r--r--kern/panic.c3
4 files changed, 21 insertions, 221 deletions
diff --git a/arch/x86/machine/boot.c b/arch/x86/machine/boot.c
index d540d8d8..c1970f5d 100644
--- a/arch/x86/machine/boot.c
+++ b/arch/x86/machine/boot.c
@@ -70,7 +70,6 @@
#include <machine/pmap.h>
#include <machine/pmu_amd.h>
#include <machine/pmu_intel.h>
-#include <machine/strace.h>
#include <machine/uart.h>
#include <vm/vm_kmem.h>
@@ -495,7 +494,6 @@ void __init
boot_main(void)
{
arg_set_cmdline(boot_tmp_cmdline);
- strace_set_mbi(&boot_raw_mbi);
kernel_main();
/* Never reached */
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));
diff --git a/arch/x86/machine/strace.h b/arch/x86/machine/strace.h
index 482768b9..a5de664f 100644
--- a/arch/x86/machine/strace.h
+++ b/arch/x86/machine/strace.h
@@ -23,9 +23,9 @@
#ifndef X86_STRACE_H
#define X86_STRACE_H
-#include <kern/init.h>
+#include <stdint.h>
+
#include <kern/macros.h>
-#include <machine/multiboot.h>
/*
* Display a call trace.
@@ -33,7 +33,7 @@
* Attempt to resolve the given instruction pointer, then walk the calling
* chain from the given frame pointer.
*/
-void strace_show(unsigned long ip, unsigned long bp);
+void strace_show(uintptr_t ip, uintptr_t bp);
/*
* Display the current call trace.
@@ -41,24 +41,11 @@ void strace_show(unsigned long ip, unsigned long bp);
static __always_inline void
strace_dump(void)
{
- unsigned long ip;
+ uintptr_t ip, bp;
asm volatile("1: mov $1b, %0" : "=r" (ip));
- strace_show(ip, (unsigned long)__builtin_frame_address(0));
+ bp = (uintptr_t)__builtin_frame_address(0);
+ strace_show(ip, bp);
}
-/*
- * Pass the multiboot information structure.
- *
- * If available, the symbol table is extracted from the boot data, when
- * the strace module is initialized.
- */
-void strace_set_mbi(const struct multiboot_raw_info *mbi);
-
-/*
- * This init operation provides :
- * - module fully initialized
- */
-INIT_OP_DECLARE(strace_setup);
-
#endif /* X86_STRACE_H */
diff --git a/kern/panic.c b/kern/panic.c
index c610e3fa..bd1f6658 100644
--- a/kern/panic.c
+++ b/kern/panic.c
@@ -64,5 +64,4 @@ panic_setup(void)
INIT_OP_DEFINE(panic_setup,
INIT_OP_DEP(cpu_setup, true),
- INIT_OP_DEP(printf_setup, true),
- INIT_OP_DEP(strace_setup, true));
+ INIT_OP_DEP(printf_setup, true));