NetBSD Problem Report #43273

From martin@duskware.de  Thu May  6 22:12:17 2010
Return-Path: <martin@duskware.de>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
	by www.NetBSD.org (Postfix) with ESMTP id 7A8E763B8FE
	for <gnats-bugs@gnats.NetBSD.org>; Thu,  6 May 2010 22:12:17 +0000 (UTC)
Message-Id: <20100506221217.0EA0863B23A@mail.netbsd.org>
Date: Thu,  6 May 2010 22:12:16 +0000 (UTC)
From: martin@NetBSD.org
Reply-To: martin@NetBSD.org
To: gnats-bugs@gnats.NetBSD.org
Subject: ld.elf_so frame handling breaks exception unwinding for C++
X-Send-Pr-Version: 3.95

>Number:         43273
>Notify-List:    uwe@NetBSD.org
>Category:       port-vax
>Synopsis:       ld.elf_so frame handling breaks exception unwinding for C++
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    port-vax-maintainer
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu May 06 22:15:00 +0000 2010
>Closed-Date:    Wed Apr 03 14:33:44 +0000 2019
>Last-Modified:  Wed Apr 03 14:33:44 +0000 2019
>Originator:     Martin Husemann
>Release:        NetBSD 5.99.27
>Organization:
The NetBSD Foundation, Inc.
>Environment:
System: NetBSD dead-to-the-world.duskware.de 5.99.27 NetBSD 5.99.27 (DEAD) #29: Wed Apr 28 10:12:36 CEST 2010 martin@night-porter.duskware.de:/usr/src/sys/arch/vax/compile/DEAD vax
Architecture: vax
Machine: vax
>Description:

Exception handling for dynamically linke C++ applications is broken on VAX
(there are more problems, statically linked programs fail for other reasons).
Looking at the call stack during a throw operation:

#0  0x7f6b2c57 in _Unwind_RaiseException (2134913164)
   from /usr/lib/libgcc_s.so.1
#1  0x7f7e29be in _rtld_bind_start (2134913164) from /usr/libexec/ld.elf_so
#2  0x7f78c501 in __cxa_throw (2134913184, 135644, 2138606296)
   from /usr/lib/libstdc++.so.7
#3  0x00010cfd in main (1, 2147478568, 2147478576) at test.cpp:14

Obviously frame #1 should not be there. This breaks unwinding, since
_Unwind_RaiseException() uses __builtin_return_address(0) == 0x7f7e29be
and tries to find a frame desription for it. It expects to get 0x7f78c501
here, and with that value it would be able to find a frame description.
With the pc in ld.elf_so (which can't have frame descriptions), it fails
and assumes it has walked out of the stack and terminates the app.

>How-To-Repeat:
throw C++ exceptions on VAX, watch the catch handler not being called.

>Fix:
n/a

>Release-Note:

>Audit-Trail:
From: "Valeriy E. Ushakov" <uwe@stderr.spb.ru>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-vax/43273: ld.elf_so frame handling breaks exception unwinding for C++
Date: Fri, 12 Nov 2010 21:05:16 +0300

 This was a private mail, but since things stalled, I guess I paste it
 here for the record...

 The code in question is in libexec/ld.elf_so/arch/vax/rtld_start.S

 ----8<--------8<----
 Currently VAX plt entries look likes this:

   40 00        - mask = <DV=0, IV=1, no regs>
   16           - JSB
   ef           - (PC) + ...
   e0 ff ff ff  - ... displacement
   0c 00 00 00

 Since there are no registers saved on entry to the plt trampoline, the
 shortcut in _rtld_bind_start will never work (the comparison is also
 wrong b/c it doesn't mask out the SPA and S bits saved in the stack
 frame).

 Perhaps we can change plt entry mask to save all registers, i.e. to
 0x7fff = <DV=0, IV=1, R0..R11>?

 We also need to fix the comparison that triggers the shortcut:

 In the stack frame the halfword at 6(%fp) is:

   111 1 11
   543 2 109876543210
   SPA S  saved regs (== all 1s with the changed plt mask)

 The mask at the beginning of the procedure at (%r0) is:

   1 1 11 11
   5 4 32 109876543210
   D I MBZ saved regs
   V V

 So we need to

 1) only compare low 12 bits of the arguments

 2) if we take the shortcut, we need to set DV and IV bits of the PSW
    according to DV and IV bits according to the procedure mask (using
    bispsw/bicpsw/movpsl i guess)

 -uwe

From: "Valeriy E. Ushakov" <uwe@stderr.spb.ru>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-vax/43273: ld.elf_so frame handling breaks exception unwinding for C++
Date: Tue, 23 Nov 2010 06:44:26 +0300

 After some investigation it turns out that exceptions on VAX are
 completely broken, or rather not even implemented.

 I have some initial gcc patches that make unwinding work, but VAX also
 needs eh_return instruction pattern to properly adjust stack on
 return.  My knowledge of how to write gcc's machine descriptions is
 unfortunately non-existent.

 With exceptions fixed in general case, we can either provide manually
 written .eh_frame DWARF2 bits for _rtld_bind_start so that unwinder
 can walk through it, or implement fallback unwinder that would use
 call frame instead of DWARF2 descriptions.

 -uwe

State-Changed-From-To: open->closed
State-Changed-By: uwe@NetBSD.org
State-Changed-When: Wed, 03 Apr 2019 14:33:44 +0000
State-Changed-Why:
matt@ implemented necessary changes in libexec/ld.elf_so/arch/vax/rtld_start.S
in March 2014


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.43 2018/01/16 07:36:43 maya Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2017 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.