summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2014-09-14 18:23:12 +0200
committerJustus Winter <4winter@informatik.uni-hamburg.de>2014-09-14 18:23:12 +0200
commitf6b9ba3fcf4611818b9aa53763cdc97e6cb654b0 (patch)
treec0a503936cb633349ab7e3bc0da2524c5727fd92
parent729cea1e1e45c0c9eb546b32edc4ad005f50a8b4 (diff)
add elf symbol parser
-rw-r--r--debian/patches/0001-dde-add-support-for-ELF-symbol-tables-XXX.patch439
-rw-r--r--debian/patches/series1
2 files changed, 440 insertions, 0 deletions
diff --git a/debian/patches/0001-dde-add-support-for-ELF-symbol-tables-XXX.patch b/debian/patches/0001-dde-add-support-for-ELF-symbol-tables-XXX.patch
new file mode 100644
index 0000000..b24388e
--- /dev/null
+++ b/debian/patches/0001-dde-add-support-for-ELF-symbol-tables-XXX.patch
@@ -0,0 +1,439 @@
+From a3ea6b3189514d463f655d400215cc6d752778e0 Mon Sep 17 00:00:00 2001
+From: Justus Winter <4winter@informatik.uni-hamburg.de>
+Date: Sun, 14 Sep 2014 13:35:50 +0200
+Subject: [PATCH] dde: add support for ELF symbol tables XXX
+
+---
+ Makefrag.am | 2 +
+ ddb/db_elf.c | 230 ++++++++++++++++++++++++++++++++++++++++++++++++
+ ddb/db_elf.h | 52 +++++++++++
+ ddb/db_sym.c | 12 ++-
+ ddb/db_sym.h | 7 ++
+ i386/i386at/model_dep.c | 25 ++++++
+ 6 files changed, 327 insertions(+), 1 deletion(-)
+ create mode 100644 ddb/db_elf.c
+ create mode 100644 ddb/db_elf.h
+
+diff --git a/Makefrag.am b/Makefrag.am
+index d6dd77f..5e98b21 100644
+--- a/Makefrag.am
++++ b/Makefrag.am
+@@ -25,6 +25,8 @@ libkernel_a_SOURCES += \
+ ddb/db_access.h \
+ ddb/db_aout.c \
+ ddb/db_aout.h \
++ ddb/db_elf.c \
++ ddb/db_elf.h \
+ ddb/db_break.c \
+ ddb/db_break.h \
+ ddb/db_command.c \
+diff --git a/ddb/db_elf.c b/ddb/db_elf.c
+new file mode 100644
+index 0000000..43160f0
+--- /dev/null
++++ b/ddb/db_elf.c
+@@ -0,0 +1,230 @@
++/*
++ * Copyright (C) 2014 Free Software Foundation, Inc.
++ *
++ * 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 the Free Software Foundation; either version 2, or (at
++ * your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program. If not, see <http://www.gnu.org/licenses/>.
++ */
++/*
++ * Mach Operating System
++ * Copyright (c) 1991,1990 Carnegie Mellon University
++ * All Rights Reserved.
++ *
++ * Permission to use, copy, modify and distribute this software and its
++ * documentation is hereby granted, provided that both the copyright
++ * notice and this permission notice appear in all copies of the
++ * software, derivative works or modified versions, and any portions
++ * thereof, and that both notices appear in supporting documentation.
++ *
++ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
++ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
++ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
++ *
++ * Carnegie Mellon requests users of this software to return to
++ *
++ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
++ * School of Computer Science
++ * Carnegie Mellon University
++ * Pittsburgh PA 15213-3890
++ *
++ * any improvements or extensions that they make and grant Carnegie Mellon
++ * the rights to redistribute these changes.
++ */
++/*
++ * Author: David B. Golub, Carnegie Mellon University
++ * Date: 7/90
++ */
++
++#if MACH_KDB
++
++/*
++ * Symbol table routines for ELF format files.
++ */
++
++#include <string.h>
++#include <mach/std_types.h>
++#include <mach/exec/elf.h>
++#include <machine/db_machdep.h> /* data types */
++#include <machine/vm_param.h>
++#include <ddb/db_output.h>
++#include <ddb/db_sym.h>
++#include <ddb/db_elf.h>
++
++#ifndef DB_NO_ELF
++
++struct db_symtab_elf {
++ int type;
++ Elf32_Sym *start;
++ Elf32_Sym *end;
++ char *strings;
++ char *map_pointer; /* symbols are for this map only,
++ if not null */
++ char name[SYMTAB_NAME_LEN];
++ /* symtab name */
++};
++
++boolean_t
++elf_db_sym_init (unsigned shdr_num,
++ vm_size_t shdr_size,
++ vm_offset_t shdr_addr,
++ unsigned shdr_shndx)
++{
++ Elf32_Shdr *shdr, *symtab, *strtab;
++ const char *shstrtab;
++ int i;
++
++ if (shdr_num == 0)
++ return FALSE;
++
++ if (shdr_size != sizeof *shdr)
++ return FALSE;
++
++ shdr = (Elf32_Shdr *) shdr_addr;
++
++ if (shdr[shdr_shndx].sh_type != SHT_STRTAB)
++ return FALSE;
++
++ shstrtab = (const char *) phystokv (shdr[shdr_shndx].sh_addr);
++
++ symtab = strtab = NULL;
++ for (i = 0; i < shdr_num; i++)
++ switch (shdr[i].sh_type) {
++ case SHT_SYMTAB:
++ if (symtab)
++ db_printf ("Ignoring additional ELF symbol table at %d\n", i);
++ else
++ symtab = &shdr[i];
++ break;
++
++ case SHT_STRTAB:
++ if (strcmp (&shstrtab[shdr[i].sh_name], ".strtab") == 0) {
++ if (strtab)
++ db_printf ("Ignoring additional ELF string table at %d\n", i);
++ else
++ strtab = &shdr[i];
++ }
++ break;
++ }
++
++ if (symtab == NULL || strtab == NULL)
++ return FALSE;
++
++ if (db_add_symbol_table (SYMTAB_ELF,
++ (char *) phystokv (symtab->sh_addr),
++ (char *) phystokv (symtab->sh_addr)+symtab->sh_size,
++ "ELF",
++ (char *) phystokv (strtab->sh_addr),
++ 0)) {
++ db_printf ("Loaded ELF symbol table (%d symbols)\n",
++ symtab->sh_size / sizeof (Elf32_Sym));
++ return TRUE;
++ }
++
++ return FALSE;
++}
++
++/*
++ * lookup symbol by name
++ */
++db_sym_t
++elf_db_lookup (db_symtab_t *stab,
++ char *symstr)
++{
++ struct db_symtab_elf *self = (struct db_symtab_elf *) stab;
++ Elf32_Sym *s;
++
++ for (s = self->start; s < self->end; s++)
++ if (strcmp (symstr, &self->strings[s->st_name]) == 0)
++ return (db_sym_t) s;
++
++ return NULL;
++}
++
++db_sym_t
++elf_db_search_symbol (db_symtab_t *stab,
++ db_addr_t off,
++ db_strategy_t strategy,
++ db_expr_t *diffp) /* in/out */
++{
++ struct db_symtab_elf *self = (struct db_symtab_elf *) stab;
++ unsigned long diff = *diffp;
++ Elf32_Sym *s, *symp = NULL;
++
++ for (s = self->start; s < self->end; s++) {
++ if (s->st_name == 0)
++ continue;
++
++ if (strategy == DB_STGY_XTRN && (s->st_info & STB_GLOBAL) == 0)
++ continue;
++
++ if (off >= s->st_value) {
++ if (s->st_info == STT_FUNC)
++ continue;
++
++ if (off - s->st_value < diff) {
++ diff = off - s->st_value;
++ symp = s;
++ if (diff == 0 && (s->st_info & STB_GLOBAL))
++ break;
++ } else if (off - s->st_value == diff) {
++ if (symp == NULL)
++ symp = s;
++ else if ((symp->st_info & STB_GLOBAL) == 0
++ && (s->st_info & STB_GLOBAL) != 0)
++ symp = s; /* pick the external symbol */
++ }
++ }
++ }
++
++ if (symp == NULL)
++ *diffp = off;
++ else
++ *diffp = diff;
++
++ return (db_sym_t) symp;
++}
++
++/*
++ * Return the name and value for a symbol.
++ */
++void
++elf_db_symbol_values (db_symtab_t *stab,
++ db_sym_t sym,
++ char **namep,
++ db_expr_t *valuep)
++{
++ struct db_symtab_elf *self = (struct db_symtab_elf *) stab;
++ Elf32_Sym *s = (Elf32_Sym *) sym;
++
++ if (namep)
++ *namep = &self->strings[s->st_name];
++ if (valuep)
++ *valuep = s->st_value;
++}
++
++/*
++ * Find filename and lineno within, given the current pc.
++ */
++boolean_t
++elf_db_line_at_pc (db_symtab_t *stab,
++ db_sym_t sym,
++ char **file,
++ int *line,
++ db_addr_t pc)
++{
++ /* XXX Parse DWARF information. */
++ return FALSE;
++}
++
++#endif /* DB_NO_ELF */
++
++#endif /* MACH_KDB */
+diff --git a/ddb/db_elf.h b/ddb/db_elf.h
+new file mode 100644
+index 0000000..12b8286
+--- /dev/null
++++ b/ddb/db_elf.h
+@@ -0,0 +1,52 @@
++/*
++ * Copyright (c) 2013 Free Software Foundation.
++ *
++ * 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
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License along
++ * with this program; if not, write to the Free Software Foundation, Inc.,
++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
++ */
++
++#ifndef _DDB_DB_ELF_H_
++#define _DDB_DB_ELF_H_
++
++#include <ddb/db_sym.h>
++#include <machine/db_machdep.h>
++
++extern boolean_t
++elf_db_line_at_pc(
++ db_symtab_t *stab,
++ db_sym_t sym,
++ char **file,
++ int *line,
++ db_addr_t pc);
++
++extern db_sym_t
++elf_db_lookup(
++ db_symtab_t *stab,
++ char * symstr);
++
++extern db_sym_t
++elf_db_search_symbol(
++ db_symtab_t * symtab,
++ db_addr_t off,
++ db_strategy_t strategy,
++ db_expr_t *diffp);
++
++extern void
++elf_db_symbol_values(
++ db_symtab_t *stab,
++ db_sym_t sym,
++ char **namep,
++ db_expr_t *valuep);
++
++#endif /* _DDB_DB_ELF_H_ */
+diff --git a/ddb/db_sym.c b/ddb/db_sym.c
+index 7d97d15..3c1a7a0 100644
+--- a/ddb/db_sym.c
++++ b/ddb/db_sym.c
+@@ -38,6 +38,7 @@
+ #include <ddb/db_sym.h>
+ #include <ddb/db_task_thread.h>
+ #include <ddb/db_aout.h>
++#include <ddb/db_elf.h>
+
+ #include <vm/vm_map.h> /* vm_map_t */
+
+@@ -507,6 +508,8 @@ void db_free_symbol(db_sym_t s)
+ */
+
+ void dummy_db_free_symbol(db_sym_t symbol) { }
++boolean_t dummy_db_sym_init(char *a, char *b, char *c, char *d) { return FALSE; }
++
+
+ struct db_sym_switch x_db[] = {
+
+@@ -521,7 +524,14 @@ struct db_sym_switch x_db[] = {
+ { 0,},
+
+ /* Machdep, not inited here */
+- { 0,}
++ { 0,},
++
++#ifdef DB_NO_ELF
++ { 0,},
++#else /* DB_NO_ELF */
++ { dummy_db_sym_init, elf_db_lookup, elf_db_search_symbol,
++ elf_db_line_at_pc, elf_db_symbol_values, dummy_db_free_symbol },
++#endif /* DB_NO_ELF */
+
+ };
+
+diff --git a/ddb/db_sym.h b/ddb/db_sym.h
+index 2c3e10a..a0bbf80 100644
+--- a/ddb/db_sym.h
++++ b/ddb/db_sym.h
+@@ -46,6 +46,7 @@ typedef struct {
+ #define SYMTAB_AOUT 0
+ #define SYMTAB_COFF 1
+ #define SYMTAB_MACHDEP 2
++#define SYMTAB_ELF 3
+ char *start; /* symtab location */
+ char *end;
+ char *private; /* optional machdep pointer */
+@@ -243,6 +244,12 @@ extern boolean_t aout_db_sym_init(
+ char *name,
+ char *task_addr);
+
++extern boolean_t elf_db_sym_init (
++ unsigned shdr_num,
++ vm_size_t shdr_size,
++ vm_offset_t shdr_addr,
++ unsigned shdr_shndx);
++
+ db_sym_t db_lookup(char *);
+
+ db_sym_t
+diff --git a/i386/i386at/model_dep.c b/i386/i386at/model_dep.c
+index 209cfb1..40d6b79 100644
+--- a/i386/i386at/model_dep.c
++++ b/i386/i386at/model_dep.c
+@@ -82,7 +82,16 @@
+ #if MACH_KDB
+ #include <ddb/db_sym.h>
+ #include <i386/db_interface.h>
++
++/* a.out symbol table */
+ static vm_offset_t kern_sym_start, kern_sym_end;
++
++/* ELF section header */
++static unsigned elf_shdr_num;
++static vm_size_t elf_shdr_size;
++static vm_offset_t elf_shdr_addr;
++static unsigned elf_shdr_shndx;
++
+ #else /* MACH_KDB */
+ #define kern_sym_start 0
+ #define kern_sym_end 0
+@@ -570,6 +579,17 @@ void c_boot_entry(vm_offset_t bi)
+ kern_sym_start, kern_sym_end,
+ symtab_size, strtab_size);
+ }
++
++ if ((boot_info.flags & MULTIBOOT_ELF_SHDR)
++ && boot_info.syms.e.num)
++ {
++ elf_shdr_num = boot_info.syms.e.num;
++ elf_shdr_size = boot_info.syms.e.size;
++ elf_shdr_addr = (vm_offset_t)phystokv(boot_info.syms.e.addr);
++ elf_shdr_shndx = boot_info.syms.e.shndx;
++
++ printf("ELF section header table at %08lx\n", elf_shdr_addr);
++ }
+ #endif /* MACH_KDB */
+ #endif /* MACH_XEN */
+
+@@ -588,6 +608,11 @@ void c_boot_entry(vm_offset_t bi)
+ {
+ aout_db_sym_init((char *)kern_sym_start, (char *)kern_sym_end, "mach", (char *)0);
+ }
++
++ if (elf_shdr_num)
++ {
++ elf_db_sym_init(elf_shdr_num, elf_shdr_size, elf_shdr_addr, elf_shdr_shndx);
++ }
+ #endif /* MACH_KDB */
+
+ machine_slot[0].is_cpu = TRUE;
+--
+2.1.0
+
diff --git a/debian/patches/series b/debian/patches/series
index 35ec82b..0ca1372 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -9,3 +9,4 @@ Add-some-padding-to-make-objects-fit-a-single-cache-.patch
0001-ddb-add-show-all-tasks-command.patch
0002-ddb-add-db_check_task_address_valid.patch
0003-ddb-add-kill-command.patch
+0001-dde-add-support-for-ELF-symbol-tables-XXX.patch