From owner-svn-src-all@freebsd.org Fri Dec 4 20:14:26 2020 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 7D1184AAAE7; Fri, 4 Dec 2020 20:14:26 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4CnkSf2vw0z3k3g; Fri, 4 Dec 2020 20:14:26 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 56B7211C83; Fri, 4 Dec 2020 20:14:26 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 0B4KEQ1M030827; Fri, 4 Dec 2020 20:14:26 GMT (envelope-from jhb@FreeBSD.org) Received: (from jhb@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0B4KEQjY030826; Fri, 4 Dec 2020 20:14:26 GMT (envelope-from jhb@FreeBSD.org) Message-Id: <202012042014.0B4KEQjY030826@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jhb set sender to jhb@FreeBSD.org using -f From: John Baldwin Date: Fri, 4 Dec 2020 20:14:26 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r368347 - head/sys/mips/mips X-SVN-Group: head X-SVN-Commit-Author: jhb X-SVN-Commit-Paths: head/sys/mips/mips X-SVN-Commit-Revision: 368347 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 04 Dec 2020 20:14:26 -0000 Author: jhb Date: Fri Dec 4 20:14:25 2020 New Revision: 368347 URL: https://svnweb.freebsd.org/changeset/base/368347 Log: Various fixes for the MIPS DDB stack unwinder. - Fix kernel stack unwinding end-of-function false-positive The kernel stack unwinder assumes that any jr $ra indicates the end of the current function. However, modern compilers generate code that contains jr $ra at various places inside the function. - Handle LLD inter-function padding when looking for the start of a function. - Use call site for symbol name/offset when unwinding Currently we use the return address, which will normally just give an output that's off by 8 from the actual call site. However, for tail calls, this is particularly bad, as we end up printing the symbol name for the function that comes after the one that made the call. Instead we should go back two instructions from the return address for the unwound program counter. Submitted by: arichardson (1, 2), jrtc27 (3) Reviewed by: arichardson Obtained from: CheriBSD Sponsored by: DARPA Differential Revision: https://reviews.freebsd.org/D27363 Modified: head/sys/mips/mips/db_trace.c Modified: head/sys/mips/mips/db_trace.c ============================================================================== --- head/sys/mips/mips/db_trace.c Fri Dec 4 19:35:43 2020 (r368346) +++ head/sys/mips/mips/db_trace.c Fri Dec 4 20:14:25 2020 (r368347) @@ -67,11 +67,10 @@ extern char edata[]; || (((ins) & 0xffff8000) == 0x67bd8000)) /* - * MIPS ABI 3.0 requires that all functions return using the 'j ra' instruction - * - * XXX gcc doesn't do this for functions with __noreturn__ attribute. + * LLD will insert invalid instruction traps between functions. + * Currently this is 0xefefefef but it may change in the future. */ -#define MIPS_END_OF_FUNCTION(ins) ((ins) == 0x03e00008) +#define MIPS_LLD_PADDING_BETWEEN_FUNCTIONS(ins) ((ins) == 0xefefefef) #if defined(__mips_n64) # define MIPS_IS_VALID_KERNELADDR(reg) ((((reg) & 3) == 0) && \ @@ -183,27 +182,32 @@ loop: * subroutine. */ if (!subr) { - va = pc - sizeof(int); + va = pc; while (1) { instr = kdbpeek((int *)va); - if (MIPS_START_OF_FUNCTION(instr)) + /* LLD fills padding between functions with 0xefefefef */ + if (MIPS_LLD_PADDING_BETWEEN_FUNCTIONS(instr)) break; - if (MIPS_END_OF_FUNCTION(instr)) { - /* skip over branch-delay slot instruction */ - va += 2 * sizeof(int); + if (MIPS_START_OF_FUNCTION(instr)) break; - } va -= sizeof(int); } - /* skip over nulls which might separate .o files */ - while ((instr = kdbpeek((int *)va)) == 0) + /* + * Skip over nulls/trap padding which might separate + * object files or functions. + */ + instr = kdbpeek((int *)va); + while (instr == 0 || MIPS_LLD_PADDING_BETWEEN_FUNCTIONS(instr)) { va += sizeof(int); + instr = kdbpeek((int *)va); + } subr = va; } + /* scan forwards to find stack size and any saved registers */ stksize = 0; more = 3; @@ -374,10 +378,16 @@ done: (uintmax_t)cause, (uintmax_t)badvaddr); goto loop; } else if (ra) { - if (pc == ra && stksize == 0) + /* + * We subtract two instructions from ra to convert it + * from a return address to a calling address, + * accounting for the delay slot. + */ + register_t next_pc = ra - 2 * sizeof(int); + if (pc == next_pc && stksize == 0) db_printf("stacktrace: loop!\n"); else { - pc = ra; + pc = next_pc; sp += stksize; ra = next_ra; goto loop;