|
|
1.1 root 1: /*
2: * Copyright (C) 2014 Free Software Foundation, Inc.
3: *
4: * This program is free software; you can redistribute it and/or
5: * modify it under the terms of the GNU General Public License as
6: * published by the Free Software Foundation; either version 2, or (at
7: * your option) any later version.
8: *
9: * This program is distributed in the hope that it will be useful, but
10: * WITHOUT ANY WARRANTY; without even the implied warranty of
11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12: * General Public License for more details.
13: *
14: * You should have received a copy of the GNU General Public License
15: * along with this program. If not, see <http://www.gnu.org/licenses/>.
16: */
17: /*
18: * Mach Operating System
19: * Copyright (c) 1991,1990 Carnegie Mellon University
20: * All Rights Reserved.
21: *
22: * Permission to use, copy, modify and distribute this software and its
23: * documentation is hereby granted, provided that both the copyright
24: * notice and this permission notice appear in all copies of the
25: * software, derivative works or modified versions, and any portions
26: * thereof, and that both notices appear in supporting documentation.
27: *
28: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
29: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
30: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
31: *
32: * Carnegie Mellon requests users of this software to return to
33: *
34: * Software Distribution Coordinator or [email protected]
35: * School of Computer Science
36: * Carnegie Mellon University
37: * Pittsburgh PA 15213-3890
38: *
39: * any improvements or extensions that they make and grant Carnegie Mellon
40: * the rights to redistribute these changes.
41: */
42: /*
43: * Author: David B. Golub, Carnegie Mellon University
44: * Date: 7/90
45: */
46:
47: #if MACH_KDB
48:
49: /*
50: * Symbol table routines for ELF format files.
51: */
52:
53: #include <string.h>
54: #include <mach/std_types.h>
55: #include <mach/exec/elf.h>
56: #include <machine/db_machdep.h> /* data types */
57: #include <machine/vm_param.h>
58: #include <ddb/db_output.h>
59: #include <ddb/db_sym.h>
60: #include <ddb/db_elf.h>
61:
62: #ifndef DB_NO_ELF
63:
64: struct db_symtab_elf {
65: int type;
66: Elf32_Sym *start;
67: Elf32_Sym *end;
68: char *strings;
69: char *map_pointer; /* symbols are for this map only,
70: if not null */
71: char name[SYMTAB_NAME_LEN];
72: /* symtab name */
73: };
74:
75: boolean_t
76: elf_db_sym_init (unsigned shdr_num,
77: vm_size_t shdr_size,
78: vm_offset_t shdr_addr,
79: unsigned shdr_shndx,
80: char *name,
81: char *task_addr)
82: {
83: Elf32_Shdr *shdr, *symtab, *strtab;
84: const char *shstrtab;
1.1.1.2 ! root 85: unsigned i;
1.1 root 86:
87: if (shdr_num == 0)
88: return FALSE;
89:
90: if (shdr_size != sizeof *shdr)
91: return FALSE;
92:
93: shdr = (Elf32_Shdr *) shdr_addr;
94:
95: if (shdr[shdr_shndx].sh_type != SHT_STRTAB)
96: return FALSE;
97:
98: shstrtab = (const char *) phystokv (shdr[shdr_shndx].sh_addr);
99:
100: symtab = strtab = NULL;
101: for (i = 0; i < shdr_num; i++)
102: switch (shdr[i].sh_type) {
103: case SHT_SYMTAB:
104: if (symtab)
105: db_printf ("Ignoring additional ELF symbol table at %d\n", i);
106: else
107: symtab = &shdr[i];
108: break;
109:
110: case SHT_STRTAB:
111: if (strcmp (&shstrtab[shdr[i].sh_name], ".strtab") == 0) {
112: if (strtab)
113: db_printf ("Ignoring additional ELF string table at %d\n", i);
114: else
115: strtab = &shdr[i];
116: }
117: break;
118: }
119:
120: if (symtab == NULL || strtab == NULL)
121: return FALSE;
122:
123: if (db_add_symbol_table (SYMTAB_ELF,
124: (char *) phystokv (symtab->sh_addr),
125: (char *) phystokv (symtab->sh_addr)+symtab->sh_size,
126: name,
127: (char *) phystokv (strtab->sh_addr),
128: task_addr)) {
129: db_printf ("Loaded ELF symbol table for %s (%d symbols)\n",
130: name, symtab->sh_size / sizeof (Elf32_Sym));
131: return TRUE;
132: }
133:
134: return FALSE;
135: }
136:
137: /*
138: * lookup symbol by name
139: */
140: db_sym_t
141: elf_db_lookup (db_symtab_t *stab,
142: char *symstr)
143: {
144: struct db_symtab_elf *self = (struct db_symtab_elf *) stab;
145: Elf32_Sym *s;
146:
147: for (s = self->start; s < self->end; s++)
148: if (strcmp (symstr, &self->strings[s->st_name]) == 0)
149: return (db_sym_t) s;
150:
151: return NULL;
152: }
153:
154: db_sym_t
155: elf_db_search_symbol (db_symtab_t *stab,
156: db_addr_t off,
157: db_strategy_t strategy,
158: db_expr_t *diffp) /* in/out */
159: {
160: struct db_symtab_elf *self = (struct db_symtab_elf *) stab;
161: unsigned long diff = *diffp;
162: Elf32_Sym *s, *symp = NULL;
163:
164: for (s = self->start; s < self->end; s++) {
165: if (s->st_name == 0)
166: continue;
167:
168: if (strategy == DB_STGY_XTRN && (s->st_info & STB_GLOBAL) == 0)
169: continue;
170:
171: if (off >= s->st_value) {
172: if (s->st_info == STT_FUNC)
173: continue;
174:
175: if (off - s->st_value < diff) {
176: diff = off - s->st_value;
177: symp = s;
178: if (diff == 0 && (s->st_info & STB_GLOBAL))
179: break;
180: } else if (off - s->st_value == diff) {
181: if (symp == NULL)
182: symp = s;
183: else if ((symp->st_info & STB_GLOBAL) == 0
184: && (s->st_info & STB_GLOBAL) != 0)
185: symp = s; /* pick the external symbol */
186: }
187: }
188: }
189:
190: if (symp == NULL)
191: *diffp = off;
192: else
193: *diffp = diff;
194:
195: return (db_sym_t) symp;
196: }
197:
198: /*
199: * Return the name and value for a symbol.
200: */
201: void
202: elf_db_symbol_values (db_symtab_t *stab,
203: db_sym_t sym,
204: char **namep,
205: db_expr_t *valuep)
206: {
207: struct db_symtab_elf *self = (struct db_symtab_elf *) stab;
208: Elf32_Sym *s = (Elf32_Sym *) sym;
209:
210: if (namep)
211: *namep = &self->strings[s->st_name];
212: if (valuep)
213: *valuep = s->st_value;
214: }
215:
216: /*
217: * Find filename and lineno within, given the current pc.
218: */
219: boolean_t
220: elf_db_line_at_pc (db_symtab_t *stab,
221: db_sym_t sym,
222: char **file,
223: int *line,
224: db_addr_t pc)
225: {
226: /* XXX Parse DWARF information. */
227: return FALSE;
228: }
229:
230: #endif /* DB_NO_ELF */
231:
232: #endif /* MACH_KDB */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.