diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-09-14 18:23:12 +0200 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-09-14 18:23:12 +0200 |
commit | f6b9ba3fcf4611818b9aa53763cdc97e6cb654b0 (patch) | |
tree | c0a503936cb633349ab7e3bc0da2524c5727fd92 | |
parent | 729cea1e1e45c0c9eb546b32edc4ad005f50a8b4 (diff) |
add elf symbol parser
-rw-r--r-- | debian/patches/0001-dde-add-support-for-ELF-symbol-tables-XXX.patch | 439 | ||||
-rw-r--r-- | debian/patches/series | 1 |
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 |