* Copyright (c) 1991,1990 Carnegie Mellon University
* 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.
* $Id: db_aout.c,v 1.5 1994/01/03 07:54:08 davidg Exp $
* Author: David B. Golub, Carnegie Mellon University
* Symbol table routines for a.out format files.
* 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,
* 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 73000
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
register struct nlist
*sym_start
, *sym_end
;
register struct nlist
*sp
;
printf ("DDB: no symbols\n");
db_get_aout_symtab(symtab
, sym_start
, sym_end
);
strtab
= (char *)sym_end
;
if (strtab
+ ((strlen
+ sizeof(int) - 1) & ~(sizeof(int)-1))
db_printf("[ %s symbol table not valid ]\n", name
);
db_printf("[ preserving %#x bytes of %s symbol table ]\n",
esymtab
- (char *)symtab
, name
);
for (sp
= sym_start
; sp
< sym_end
; sp
++) {
db_printf("Bad string table index (%#x)\n", strx
);
sp
->n_un
.n_name
= strtab
+ strx
;
db_add_symbol_table(sym_start
, sym_end
, name
, (char *)symtab
);
X_db_lookup(stab
, symstr
)
register struct nlist
*sp
, *ep
;
sp
= (struct nlist
*)stab
->start
;
ep
= (struct nlist
*)stab
->end
;
if (sp
->n_un
.n_name
== 0)
if ((sp
->n_type
& N_STAB
) == 0 &&
db_eqname(sp
->n_un
.n_name
, symstr
, '_'))
X_db_search_symbol(symtab
, off
, strategy
, diffp
)
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
;
if (sp
->n_un
.n_name
== 0)
if ((sp
->n_type
& N_STAB
) != 0 || (sp
->n_type
& N_TYPE
) == N_FN
)
if (off
>= sp
->n_value
) {
if (off
- sp
->n_value
< diff
) {
diff
= off
- sp
->n_value
;
(strategy
== DB_STGY_PROC
&&
sp
->n_type
== (N_TEXT
|N_EXT
) ||
strategy
== DB_STGY_ANY
&&
else if (off
- sp
->n_value
== diff
) {
else if ((symp
->n_type
& N_EXT
) == 0 &&
(sp
->n_type
& N_EXT
) != 0)
symp
= sp
; /* pick the external symbol */
* Return the name and value for a symbol.
X_db_symbol_values(sym
, namep
, valuep
)
register struct nlist
*sp
;
sp
= (struct nlist
*)sym
;
*namep
= sp
->n_un
.n_name
;
X_db_line_at_pc(symtab
, cursym
, filename
, linenum
, off
)
register struct nlist
*sp
, *ep
;
register struct nlist
*sym
= (struct nlist
*)cursym
;
unsigned long sodiff
= -1UL, lndiff
= -1UL, ln
= 0;
sp
= (struct nlist
*)symtab
->start
;
ep
= (struct nlist
*)symtab
->end
;
#define NEWSRC(str) ((str) != NULL && \
(str)[0] == 'g' && strcmp((str), "gcc_compiled.") == 0)
* Prevent bogus linenumbers in case module not compiled
if (sp
->n_value
<= off
&& (off
- sp
->n_value
) <= sodiff
&&
NEWSRC(sp
->n_un
.n_name
)) {
if ((sp
->n_type
& N_TYPE
) == N_FN
|| NEWSRC(sp
->n_un
.n_name
)) {
if (sp
->n_type
== N_SO
) {
if (sp
->n_value
<= off
&& (off
- sp
->n_value
) < sodiff
) {
sodiff
= off
- sp
->n_value
;
if (sp
->n_type
!= N_SLINE
)
if (off
- sp
->n_value
< lndiff
) {
lndiff
= off
- sp
->n_value
;
if (fname
!= NULL
&& ln
!= 0) {
X_db_sym_numargs(symtab
, cursym
, nargp
, argnamep
)
register struct nlist
*sp
, *ep
;
int maxnarg
= *nargp
, nargs
= 0;
addr
= ((struct nlist
*)cursym
)->n_value
;
sp
= (struct nlist
*)symtab
->start
;
ep
= (struct nlist
*)symtab
->end
;
if (sp
->n_type
== N_FUN
&& sp
->n_value
== addr
) {
while (++sp
< ep
&& sp
->n_type
== N_PSYM
) {
*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';
* Initialization routine for a.out files.
if (esym
> (char *)&end
) {
X_db_sym_init((int *)&end
, esym
, "386bsd");
X_db_sym_init (db_symtab
, 0, "386bsd");
* Read symbol table from file.
* (should be somewhere else)
#include <boot_ufs/file_io.h>
read_symtab_from_file(fp
, symtab_name
)
if (!get_symtab(fp
, &symoff
, &symsize
)) {
boot_printf("[ error %d reading %s file header ]\n",
stroff
= symoff
+ symsize
;
result
= read_file(fp
, (vm_offset_t
)stroff
,
(vm_offset_t
)&strsize
, sizeof(strsize
), &resid
);
boot_printf("[ no valid symbol table present for %s ]\n",
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
);
boot_printf("[ error %d reading %s symbol table ]\n",
result
= read_file(fp
, stroff
,
symtab
+ sizeof(int) + symsize
, strsize
, &resid
);
boot_printf("[ error %d reading %s string table ]\n",
X_db_sym_init((int *)symtab
,
(char *)(symtab
+ table_size
),