📄 db_aout.cxx
字号:
/* $NetBSD: db_aout.c,v 1.12 1994/10/09 08:19:31 mycroft Exp $ *//* * 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. */#error "No attempt has been made to clean up this file for EROS yet."#include <machine/db_machdep.hxx> /* data types */#include <ddb/db_sym.hxx>#ifndef DB_NO_AOUT#define _AOUT_INCLUDE_#include <nlist.hxx>#include <stab.hxx>/* * 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 */#ifdef SYMTAB_SPACEint db_symtabsize = SYMTAB_SPACE;int db_symtab[SYMTAB_SPACE/sizeof(int)] = { 0, 1 };#endif/* * Find the symbol table and strings; tell ddb about them. */X_db_sym_init(int *symtab, /* pointer to start of symbol table */ char *esymtab, /* pointer to end of string table, for checking - rounded up to integer boundary */ const char *name ){ register struct nlist *sym_start, *sym_end; register struct nlist *sp; register char * strtab; register int strlen; char * estrtab;#ifdef SYMTAB_SPACE if (*symtab < sizeof(int)) { printf ("OPTION_DDB: no symbols\n"); return; }#endif /* * Find pointers to the start and end of the symbol entries, * given a pointer to the start of the symbol table. */ sym_start = (struct nlist *)(symtab + 1); sym_end = (struct nlist *)((char *)sym_start + *symtab); strtab = (char *)sym_end; strlen = *(int *)strtab;#ifdef SYMTAB_SPACE printf("OPTION_DDB: found symbols [%d + %d bytes]\n", *symtab, strlen); if ((*symtab + strlen) > db_symtabsize) { printf("OPTION_DDB: symbols larger than SYMTAB_SPACE?\n"); return; }#else estrtab = strtab + strlen;#define round_to_size(x) \ (((vm_offset_t)(x) + sizeof(vm_size_t) - 1) & ~(sizeof(vm_size_t) - 1)) if (round_to_size(estrtab) != round_to_size(esymtab)) { db_printf("[ %s symbol table not valid ]\n", name); return; }#undef round_to_size #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; } } if (db_add_symbol_table((char *)sym_start, (char *)sym_end, name, (char *)symtab) != -1) {#ifndef SYMTAB_SPACE db_printf("[ preserving %d bytes of %s symbol table ]\n", esymtab - (char *)symtab, name);#endif }}db_sym_tX_db_lookup(db_symtab_t *stab, const 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_tX_db_search_symbol(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 || (sp->n_type & N_TYPE) == N_FN) continue; if (off >= sp->n_value) { if (off - sp->n_value < diff) { diff = off - sp->n_value; symp = sp; if (diff == 0 && (strategy == DB_STGY_PROC && sp->n_type == (N_TEXT|N_EXT) || strategy == DB_STGY_ANY && (sp->n_type & N_EXT))) 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. */voidX_db_symbol_values(db_sym_t sym, const 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;}boolX_db_line_at_pc(db_symtab_t *symtab, db_sym_t cursym, const char **filename, int *linenum, db_expr_t off){ register struct nlist *sp, *ep; register struct nlist *sym = (struct nlist *)cursym; unsigned long sodiff = -1UL, lndiff = -1UL, ln = 0; char *fname = NULL; sp = (struct nlist *)symtab->start; ep = (struct nlist *)symtab->end;/* XXX - gcc specific */#define NEWSRC(str) ((str) != NULL && \ (str)[0] == 'g' && strcmp((str), "gcc_compiled.") == 0) for (; sp < ep; sp++) { /* * Prevent bogus linenumbers in case module not compiled * with debugging options */#if 0 if (sp->n_value <= off && (off - sp->n_value) <= sodiff && NEWSRC(sp->n_un.n_name)) {#endif if ((sp->n_type & N_TYPE) == N_FN || NEWSRC(sp->n_un.n_name)) { sodiff = lndiff = -1UL; ln = 0; fname = NULL; } if (sp->n_type == N_SO) { if (sp->n_value <= off && (off - sp->n_value) < sodiff) { sodiff = off - sp->n_value; fname = sp->n_un.n_name; } continue; } if (sp->n_type != N_SLINE) continue; if (sp->n_value > off) break; if (off - sp->n_value < lndiff) { lndiff = off - sp->n_value; ln = sp->n_desc; } } if (fname != NULL && ln != 0) { *filename = fname; *linenum = ln; return true; } return (false);}boolX_db_sym_numargs(db_symtab_t *symtab, db_sym_t cursym, int *nargp, const char **argnamep){ register struct nlist *sp, *ep; u_long addr; int maxnarg = *nargp, nargs = 0; if (cursym == NULL) return false; addr = ((struct nlist *)cursym)->n_value; sp = (struct nlist *)symtab->start; ep = (struct nlist *)symtab->end; for (; sp < ep; sp++) { if (sp->n_type == N_FUN && sp->n_value == addr) { while (++sp < ep && sp->n_type == N_PSYM) { if (nargs >= maxnarg) break; nargs++; *argnamep++ = sp->n_un.n_name?sp->n_un.n_name:"???"; { /* XXX - remove trailers */ char *cp = *(argnamep-1); while (*cp != '\0' && *cp != ':') cp++; if (*cp == ':') *cp = '\0'; } } *nargp = nargs; return true; } } return false;}/* * Initialization routine for a.out files. */ddb_init(){#ifndef SYMTAB_SPACE extern char *esym; extern int end; if (esym > (char *)&end) { X_db_sym_init((int *)&end, esym, "netbsd"); }#else X_db_sym_init (db_symtab, 0, "netbsd");#endif}#endif /* DB_NO_AOUT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -