Module Name: src Committed By: simonb Date: Wed Sep 23 09:52:02 UTC 2020
Modified Files: src/sys/arch/mips/mips: mips_stacktrace.c src/sys/kern: kern_ksyms.c src/sys/sys: ksyms.h Log Message: The current MIPS DDB stacktrace code doesn't work if no symbols are available, so fall back to old-fashioned unwind code if no symbols. To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.5 src/sys/arch/mips/mips/mips_stacktrace.c cvs rdiff -u -r1.88 -r1.89 src/sys/kern/kern_ksyms.c cvs rdiff -u -r1.37 -r1.38 src/sys/sys/ksyms.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/mips/mips/mips_stacktrace.c diff -u src/sys/arch/mips/mips/mips_stacktrace.c:1.4 src/sys/arch/mips/mips/mips_stacktrace.c:1.5 --- src/sys/arch/mips/mips/mips_stacktrace.c:1.4 Mon Aug 17 21:50:14 2020 +++ src/sys/arch/mips/mips/mips_stacktrace.c Wed Sep 23 09:52:02 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: mips_stacktrace.c,v 1.4 2020/08/17 21:50:14 mrg Exp $ */ +/* $NetBSD: mips_stacktrace.c,v 1.5 2020/09/23 09:52:02 simonb Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -40,7 +40,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: mips_stacktrace.c,v 1.4 2020/08/17 21:50:14 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mips_stacktrace.c,v 1.5 2020/09/23 09:52:02 simonb Exp $"); #ifdef _KERNEL_OPT #include "opt_ddb.h" @@ -322,60 +322,66 @@ loop: } #ifdef DDB - /* - * Check the kernel symbol table to see the beginning of - * the current subroutine. - */ - diff = 0; - sym = db_search_symbol(pc, DB_STGY_ANY, &diff); - if (sym != DB_SYM_NULL && diff == 0) { - /* check func(foo) __attribute__((__noreturn__)) case */ - if (!kdbpeek(pc - 2 * sizeof(unsigned), &instr)) - return; - i.word = instr; - if (i.JType.op == OP_JAL) { - sym = db_search_symbol(pc - sizeof(int), - DB_STGY_ANY, &diff); - if (sym != DB_SYM_NULL && diff != 0) - diff += sizeof(int); + if (ksyms_available()) { + /* + * Check the kernel symbol table to see the beginning of + * the current subroutine. + */ + diff = 0; + sym = db_search_symbol(pc, DB_STGY_ANY, &diff); + if (sym != DB_SYM_NULL && diff == 0) { + /* check func(foo) __attribute__((__noreturn__)) case */ + if (!kdbpeek(pc - 2 * sizeof(unsigned), &instr)) + return; + i.word = instr; + if (i.JType.op == OP_JAL) { + sym = db_search_symbol(pc - sizeof(int), + DB_STGY_ANY, &diff); + if (sym != DB_SYM_NULL && diff != 0) + diff += sizeof(int); + } } - } - if (sym == DB_SYM_NULL) { - ra = 0; - goto done; - } - va = pc - diff; -#else - /* - * Find the beginning of the current subroutine by scanning backwards - * from the current PC for the end of the previous subroutine. - * - * XXX This won't work well because nowadays gcc is so aggressive - * as to reorder instruction blocks for branch-predict. - * (i.e. 'jr ra' wouldn't indicate the end of subroutine) - */ - va = pc; - do { - va -= sizeof(int); - if (va <= (vaddr_t)verylocore) - goto finish; - if (!kdbpeek(va, &instr)) - return; - if (instr == MIPS_ERET) - goto mips3_eret; - } while (instr != MIPS_JR_RA && instr != MIPS_JR_K0); - /* skip back over branch & delay slot */ - va += sizeof(int); + if (sym == DB_SYM_NULL) { + ra = 0; + goto done; + } + va = pc - diff; + } else { +#endif /* DDB */ + /* + * Find the beginning of the current subroutine by + * scanning backwards from the current PC for the end + * of the previous subroutine. + * + * XXX This won't work well because nowadays gcc is so + * aggressive as to reorder instruction blocks for + * branch-predict. (i.e. 'jr ra' wouldn't indicate + * the end of subroutine) + */ + va = pc; + do { + va -= sizeof(int); + if (va <= (vaddr_t)verylocore) + goto finish; + if (!kdbpeek(va, &instr)) + return; + if (instr == MIPS_ERET) + goto mips3_eret; + } while (instr != MIPS_JR_RA && instr != MIPS_JR_K0); + /* skip back over branch & delay slot */ + va += sizeof(int); mips3_eret: - va += sizeof(int); - /* skip over nulls which might separate .o files */ - instr = 0; - while (instr == 0) { - if (!kdbpeek(va, &instr)) - return; va += sizeof(int); + /* skip over nulls which might separate .o files */ + instr = 0; + while (instr == 0) { + if (!kdbpeek(va, &instr)) + return; + va += sizeof(int); + } +#ifdef DDB } -#endif +#endif /* DDB */ subr = va; /* scan forwards to find stack size and any saved registers */ Index: src/sys/kern/kern_ksyms.c diff -u src/sys/kern/kern_ksyms.c:1.88 src/sys/kern/kern_ksyms.c:1.89 --- src/sys/kern/kern_ksyms.c:1.88 Sun Jan 5 21:12:34 2020 +++ src/sys/kern/kern_ksyms.c Wed Sep 23 09:52:02 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_ksyms.c,v 1.88 2020/01/05 21:12:34 pgoyette Exp $ */ +/* $NetBSD: kern_ksyms.c,v 1.89 2020/09/23 09:52:02 simonb Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -73,7 +73,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_ksyms.c,v 1.88 2020/01/05 21:12:34 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_ksyms.c,v 1.89 2020/09/23 09:52:02 simonb Exp $"); #if defined(_KERNEL) && defined(_KERNEL_OPT) #include "opt_copy_symtab.h" @@ -247,6 +247,16 @@ ksyms_init(void) } /* + * Are any symbols available? + */ +bool +ksyms_available(void) +{ + + return ksyms_loaded; +} + +/* * Add a symbol table. * This is intended for use when the symbol table and its corresponding * string table are easily available. If they are embedded in an ELF Index: src/sys/sys/ksyms.h diff -u src/sys/sys/ksyms.h:1.37 src/sys/sys/ksyms.h:1.38 --- src/sys/sys/ksyms.h:1.37 Mon Nov 6 17:56:25 2017 +++ src/sys/sys/ksyms.h Wed Sep 23 09:52:02 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: ksyms.h,v 1.37 2017/11/06 17:56:25 christos Exp $ */ +/* $NetBSD: ksyms.h,v 1.38 2020/09/23 09:52:02 simonb Exp $ */ /* * Copyright (c) 2001, 2003 Anders Magnusson (ra...@ludd.luth.se). @@ -144,6 +144,7 @@ int ksyms_delsymtab(const char *); void ksyms_init(void); void ksyms_addsyms_elf(int, void *, void *); void ksyms_addsyms_explicit(void *, void *, size_t, void *, size_t); +bool ksyms_available(void); int ksyms_sift(char *, char *, int); void ksyms_modload(const char *, void *, vsize_t, char *, vsize_t); void ksyms_modunload(const char *);