diff options
author | rgrimes <rgrimes@FreeBSD.org> | 1993-06-12 14:58:17 +0000 |
---|---|---|
committer | rgrimes <rgrimes@FreeBSD.org> | 1993-06-12 14:58:17 +0000 |
commit | 25062ba061871945759b3baa833fe64969383e40 (patch) | |
tree | 2d1c31051ed0dbaad984013c9fe695b1a01e1c39 /sys/ddb/db_aout.c | |
parent | f078b88a160c467761b3f3641f05dfd0aa3f7753 (diff) | |
download | FreeBSD-src-25062ba061871945759b3baa833fe64969383e40.zip FreeBSD-src-25062ba061871945759b3baa833fe64969383e40.tar.gz |
Initial import, 0.1 + pk 0.2.4-B1
Diffstat (limited to 'sys/ddb/db_aout.c')
-rw-r--r-- | sys/ddb/db_aout.c | 309 |
1 files changed, 309 insertions, 0 deletions
diff --git a/sys/ddb/db_aout.c b/sys/ddb/db_aout.c new file mode 100644 index 0000000..88f4b03 --- /dev/null +++ b/sys/ddb/db_aout.c @@ -0,0 +1,309 @@ +/* + * 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 + * 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 the + * rights to redistribute these changes. + */ +/* + * HISTORY + * $Log: db_aout.c,v $ + * Revision 1.1 1992/03/25 21:44:55 pace + * Initial revision + * + * Revision 2.3 91/02/05 17:05:55 mrt + * Changed to new Mach copyright + * [91/01/31 16:16:44 mrt] + * + * Revision 2.2 90/08/27 21:48:35 dbg + * Created. + * [90/08/17 dbg] + * + */ +/* + * Author: David B. Golub, Carnegie Mellon University + * Date: 7/90 + */ +/* + * Symbol table routines for a.out format files. + */ + +#include "param.h" +#include "proc.h" +#include <machine/db_machdep.h> /* data types */ +#include <ddb/db_sym.h> + +#ifndef DB_NO_AOUT + +#define _AOUT_INCLUDE_ +#include "nlist.h" + +/* + * An a.out symbol table as loaded into the kernel debugger: + * + * symtab -> size of symbol entries, in bytes + * sp -> first symbol entry + * ... + * ep -> last symbol entry + 1 + * strtab == start of string table + * size of string table in bytes, + * including this word + * -> strings + */ + +/* + * Find pointers to the start and end of the symbol entries, + * given a pointer to the start of the symbol table. + */ +#define db_get_aout_symtab(symtab, sp, ep) \ + (sp = (struct nlist *)((symtab) + 1), \ + ep = (struct nlist *)((char *)sp + *(symtab))) + +#define SYMTAB_SPACE 63000 +int db_symtabsize = SYMTAB_SPACE; +char db_symtab[SYMTAB_SPACE] = { 1 }; + +X_db_sym_init(symtab, esymtab, name) + int * symtab; /* pointer to start of symbol table */ + char * esymtab; /* pointer to end of string table, + for checking - rounded up to integer + boundary */ + char * name; +{ + register struct nlist *sym_start, *sym_end; + register struct nlist *sp; + register char * strtab; + register int strlen; + + if (*symtab < 4) { + printf ("DDB: no symbols\n"); + return; + } + + db_get_aout_symtab(symtab, sym_start, sym_end); + + strtab = (char *)sym_end; + strlen = *(int *)strtab; + +#if 0 + if (strtab + ((strlen + sizeof(int) - 1) & ~(sizeof(int)-1)) + != esymtab) + { + db_printf("[ %s symbol table not valid ]\n", name); + return; + } + + db_printf("[ preserving %#x bytes of %s symbol table ]\n", + esymtab - (char *)symtab, name); +#endif + + for (sp = sym_start; sp < sym_end; sp++) { + register int strx; + strx = sp->n_un.n_strx; + if (strx != 0) { + if (strx > strlen) { + db_printf("Bad string table index (%#x)\n", strx); + sp->n_un.n_name = 0; + continue; + } + sp->n_un.n_name = strtab + strx; + } + } + + db_add_symbol_table(sym_start, sym_end, name, (char *)symtab); +} + +db_sym_t +X_db_lookup(stab, symstr) + db_symtab_t *stab; + char * symstr; +{ + register struct nlist *sp, *ep; + + sp = (struct nlist *)stab->start; + ep = (struct nlist *)stab->end; + + for (; sp < ep; sp++) { + if (sp->n_un.n_name == 0) + continue; + if ((sp->n_type & N_STAB) == 0 && + sp->n_un.n_name != 0 && + db_eqname(sp->n_un.n_name, symstr, '_')) + { + return ((db_sym_t)sp); + } + } + return ((db_sym_t)0); +} + +db_sym_t +X_db_search_symbol(symtab, off, strategy, diffp) + db_symtab_t * symtab; + register + db_addr_t off; + db_strategy_t strategy; + db_expr_t *diffp; /* in/out */ +{ + register unsigned int diff = *diffp; + register struct nlist *symp = 0; + register struct nlist *sp, *ep; + + sp = (struct nlist *)symtab->start; + ep = (struct nlist *)symtab->end; + + for (; sp < ep; sp++) { + if (sp->n_un.n_name == 0) + continue; + if ((sp->n_type & N_STAB) != 0) + continue; + if (off >= sp->n_value) { + if (off - sp->n_value < diff) { + diff = off - sp->n_value; + symp = sp; + if (diff == 0) + break; + } + else if (off - sp->n_value == diff) { + if (symp == 0) + symp = sp; + else if ((symp->n_type & N_EXT) == 0 && + (sp->n_type & N_EXT) != 0) + symp = sp; /* pick the external symbol */ + } + } + } + if (symp == 0) { + *diffp = off; + } + else { + *diffp = diff; + } + return ((db_sym_t)symp); +} + +/* + * Return the name and value for a symbol. + */ +void +X_db_symbol_values(sym, namep, valuep) + db_sym_t sym; + char **namep; + db_expr_t *valuep; +{ + register struct nlist *sp; + + sp = (struct nlist *)sym; + if (namep) + *namep = sp->n_un.n_name; + if (valuep) + *valuep = sp->n_value; +} + +boolean_t +X_db_line_at_pc() +{ + return (FALSE); +} + +/* + * Initialization routine for a.out files. + */ +kdb_init() +{ +#if 0 + extern char *esym; + extern int end; + + if (esym > (char *)&end) { + X_db_sym_init((int *)&end, esym, "mach"); + } +#endif + + X_db_sym_init (db_symtab, 0, "mach"); +} + +#if 0 +/* + * Read symbol table from file. + * (should be somewhere else) + */ +#include <boot_ufs/file_io.h> +#include <vm/vm_kern.h> + +read_symtab_from_file(fp, symtab_name) + struct file *fp; + char * symtab_name; +{ + vm_size_t resid; + kern_return_t result; + vm_offset_t symoff; + vm_size_t symsize; + vm_offset_t stroff; + vm_size_t strsize; + vm_size_t table_size; + vm_offset_t symtab; + + if (!get_symtab(fp, &symoff, &symsize)) { + boot_printf("[ error %d reading %s file header ]\n", + result, symtab_name); + return; + } + + stroff = symoff + symsize; + result = read_file(fp, (vm_offset_t)stroff, + (vm_offset_t)&strsize, sizeof(strsize), &resid); + if (result || resid) { + boot_printf("[ no valid symbol table present for %s ]\n", + symtab_name); + return; + } + + table_size = sizeof(int) + symsize + strsize; + table_size = (table_size + sizeof(int)-1) & ~(sizeof(int)-1); + + symtab = kmem_alloc_wired(kernel_map, table_size); + + *(int *)symtab = symsize; + + result = read_file(fp, symoff, + symtab + sizeof(int), symsize, &resid); + if (result || resid) { + boot_printf("[ error %d reading %s symbol table ]\n", + result, symtab_name); + return; + } + + result = read_file(fp, stroff, + symtab + sizeof(int) + symsize, strsize, &resid); + if (result || resid) { + boot_printf("[ error %d reading %s string table ]\n", + result, symtab_name); + return; + } + + X_db_sym_init((int *)symtab, + (char *)(symtab + table_size), + symtab_name); + +} +#endif + +#endif /* DB_NO_AOUT */ |