NetBSD Problem Report #43314

From martin@duskware.de  Sun May 16 11:04: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 735D063BC69
	for <gnats-bugs@gnats.NetBSD.org>; Sun, 16 May 2010 11:04:17 +0000 (UTC)
Message-Id: <20100516110416.B108D63B1B2@mail.netbsd.org>
Date: Sun, 16 May 2010 11:04:16 +0000 (UTC)
From: martin@NetBSD.org
Reply-To: martin@NetBSD.org
To: gnats-bugs@gnats.NetBSD.org
Subject: pc relative relocations are "off by 1*size" on vax
X-Send-Pr-Version: 3.95

>Number:         43314
>Notify-List:    uwe@NetBSD.org
>Category:       toolchain
>Synopsis:       pc relative relocations are "off by 1*size" on vax
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    toolchain-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun May 16 11:05:00 +0000 2010
>Closed-Date:    
>Last-Modified:  Sat Nov 25 12:10:04 +0000 2023
>Originator:     Martin Husemann
>Release:        NetBSD 5.99.29
>Organization:
The NetBSD Foundation, Inc.
>Environment:
System: NetBSD dead-to-the-world.duskware.de 5.99.29 NetBSD 5.99.29 (DEAD) #31: Wed May 12 19:07:50 CEST 2010 martin@night-porter.duskware.de:/usr/src/sys/arch/vax/compile/DEAD vax
Architecture: vax
Machine: vax
>Description:

While analyzing the broken C++ exception handling on vax I ran into this
problem (.eh* frame descriptions use 32bit pc relative references to a
32bit value storing the function pointer to call as "personality" function,
but the unwinding code dereferences a 32bit value 4 bytes below that pointer
and crashes).

I couldn't find the ultimate reference describing the %pcrel() asm pseudo
op, so I'm not sure if this is a bug in binutils, or if gcc should be
modified (patch below) to output different references.

>How-To-Repeat:

Run this small sample program and wonder, why the relative addresses are
4, 2 or 1 byte lower than expected:

--8<--
/*
 * demo program to show strange %pcrel behaviour on vax:
 * exception handling frame descriptors include code like
 *  .4byte  %pcrel32(DW.ref.__gxx_personality_v0)
 * to reference pc relatvie to a 4 byte value containing a pointer
 * to __gxx_personality_v0 (a "peronality" function), but the unwinding
 * code ends up dereferencing the memory 4 byte below that value.
 */


#include <stdio.h>
#include <inttypes.h>

int main(int argc, char **argv)
{
	const char *str;
	extern const long ref4;
	extern const short ref2;
	extern const signed char ref1;

__asm(
 ".section .rodata\n"
 ".globl ref_string\n"
 "ref_string: .string \"abcdefghijklmnopq\"\n"
 ".globl ref4\n"
 "ref4:\n"
 ".4byte  %%pcrel32(ref_string+8)\n"
 ".globl ref2\n"
 "ref2:\n"
 ".2byte %%pcrel16(ref_string+6)\n"
 ".globl ref1\n"
 "ref1:\n"
 ".byte %%pcrel8(ref_string+5)\n"
 ".text" ::); 

	/* Test 4 byte pcrelative access */
	str = (const char*)((uintptr_t)&ref4 + ref4);
	printf("pcrel32 at %p value %ld pointing to %p -> %s\n",
		&ref4, ref4, str, str);
	str = (const char*)((uintptr_t)&ref2 + ref2);
	printf("pcrel16 at %p value %d pointing to %p -> %s\n",
		&ref2, ref2, str, str);
	str = (const char*)((uintptr_t)&ref1 + ref1);
	printf("pcrel8 at %p value %d pointing to %p -> %s\n",
		&ref1, ref1, str, str);

	return 0;
}
-->8--

It prints:

pcrel32 at 0x272c8 value -14 pointing to 0x272ba -> efghijklmnopq
pcrel16 at 0x272cc value -18 pointing to 0x272ba -> efghijklmnopq
pcrel8 at 0x272ce value -20 pointing to 0x272ba -> efghijklmnopq

but the output should start at ref_string+8 ("ijkl...") etc.

>Fix:
If this is not considered a binutils bug, we could adjust gcc like this
(untested):

Index: elf.h
===================================================================
RCS file: /cvsroot/src/gnu/dist/gcc4/gcc/config/vax/elf.h,v
retrieving revision 1.3
diff -c -u -r1.3 elf.h
--- elf.h	31 Mar 2007 05:55:11 -0000	1.3
+++ elf.h	16 May 2010 10:56:13 -0000
@@ -107,5 +107,5 @@
     fputs (integer_asm_op (SIZE, FALSE), FILE);		\
     fprintf (FILE, "%%pcrel%d(", SIZE * 8);		\
     assemble_name (FILE, LABEL);			\
-    fputc (')', FILE);					\
+    fprintf (FILE, "+%d)", SIZE);			\
   } while (0)

>Release-Note:

>Audit-Trail:

From: "Valeriy E. Ushakov" <uwe@stderr.spb.ru>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: toolchain/43314: pc relative relocations are "off by 1*size" on vax
Date: Sun, 28 Nov 2010 20:30:21 +0300

 Readelf also needs something like the patch below to correctly show
 DWARF2 frame info (-wf and -wF) in relocatable files.

 --- readelf.c	17 Feb 2006 16:14:25 +0300	1.2
 +++ readelf.c	28 Nov 2010 03:34:10 +0300	
 @@ -10261,11 +10261,15 @@
  	    encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);

  	  fc->pc_begin = get_encoded_value (start, fc->fde_encoding);
 -	  if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel
 +	  if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel)
 +	    {
 +	      if (elf_header.e_type != ET_REL)
 +		fc->pc_begin += section->sh_addr + (start - section_start);
  	      /* Don't adjust for ET_REL since there's invariably a pcrel
  		 reloc here, which we haven't applied.  */
 -	      && elf_header.e_type != ET_REL)
 -	    fc->pc_begin += section->sh_addr + (start - section_start);
 +	      else if (elf_header.e_machine == EM_VAX)
 +		fc->pc_begin -= 4;
 +	    }
  	  start += encoded_ptr_size;
  	  fc->pc_range = byte_get (start, encoded_ptr_size);
  	  start += encoded_ptr_size;
 @@ -10464,9 +10468,13 @@

  	    case DW_CFA_set_loc:
  	      vma = get_encoded_value (start, fc->fde_encoding);
 -	      if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel
 -		  && elf_header.e_type != ET_REL)
 -		vma += section->sh_addr + (start - section_start);
 +	      if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel)
 +		{
 +		  if (elf_header.e_type != ET_REL)
 +		    vma += section->sh_addr + (start - section_start);
 +		  else if (elf_header.e_machine == EM_VAX)
 +		    vma -= 4;
 +		}
  	      start += encoded_ptr_size;
  	      if (do_debug_frames_interp)
  		frame_display_row (fc, &need_col_headers, &max_regs);


 -uwe

State-Changed-From-To: open->feedback
State-Changed-By: dholland@NetBSD.org
State-Changed-When: Sat, 31 Dec 2011 20:36:19 +0000
State-Changed-Why:
What's the status of this since the toolchain changes?


From: "Valeriy E. Ushakov" <uwe@stderr.spb.ru>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: toolchain/43314 (pc relative relocations are "off by 1*size" on vax)
Date: Fri, 27 Jan 2012 23:59:14 +0400

 On Sat, Dec 31, 2011 at 20:36:22 +0000, dholland@NetBSD.org wrote:

 > State-Changed-From-To: open->feedback
 > State-Changed-By: dholland@NetBSD.org
 > State-Changed-When: Sat, 31 Dec 2011 20:36:19 +0000
 > State-Changed-Why:
 > What's the status of this since the toolchain changes?

 The change is not applied to gcc 4.5 it seems.

 http://mail-index.netbsd.org/source-changes/2010/12/22/msg016170.html

 -uwe

From: "Valeriy E. Ushakov" <uwe@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/43314 CVS commit: src/external/gpl3/gcc/dist/gcc/config/vax
Date: Sat, 28 Jan 2012 11:24:05 +0000

 Module Name:	src
 Committed By:	uwe
 Date:		Sat Jan 28 11:24:05 UTC 2012

 Modified Files:
 	src/external/gpl3/gcc/dist/gcc/config/vax: elf.h

 Log Message:
 Pull in revision 1.4 from src/gnu/dist/gcc4/gcc/config/vax/elf.h:

   Emit DWARF relocation in its expected form

 PR toolchain/43314


 To generate a diff of this commit:
 cvs rdiff -u -r1.1.1.1 -r1.2 src/external/gpl3/gcc/dist/gcc/config/vax/elf.h

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: feedback->closed
State-Changed-By: dholland@NetBSD.org
State-Changed-When: Sat, 25 Aug 2012 19:10:36 +0000
State-Changed-Why:
Fixed (right?)


From: "Valeriy E. Ushakov" <uwe@stderr.spb.ru>
To: gnats-bugs@NetBSD.org
Cc: toolchain-manager@netbsd.org, netbsd-bugs@netbsd.org,
	gnats-admin@netbsd.org, dholland@NetBSD.org, martin@NetBSD.org
Subject: Re: toolchain/43314 (pc relative relocations are "off by 1*size" on vax)
Date: Sun, 26 Aug 2012 00:02:50 +0400

 On Sat, Aug 25, 2012 at 19:10:37 +0000, dholland@NetBSD.org wrote:

 > Synopsis: pc relative relocations are "off by 1*size" on vax
 > 
 > State-Changed-From-To: feedback->closed
 > State-Changed-By: dholland@NetBSD.org
 > State-Changed-When: Sat, 25 Aug 2012 19:10:36 +0000
 > State-Changed-Why:
 > Fixed (right?)

 The main problem is fixed, but, iirc, readelf is not.

 -uwe

State-Changed-From-To: closed->open
State-Changed-By: dholland@NetBSD.org
State-Changed-When: Sat, 25 Aug 2012 20:42:15 +0000
State-Changed-Why:
not finished.


From: "Rin Okuyama" <rin@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/43314 CVS commit: src/external/gpl3/binutils/dist/gas/config
Date: Sat, 7 Oct 2023 12:04:09 +0000

 Module Name:	src
 Committed By:	rin
 Date:		Sat Oct  7 12:04:09 UTC 2023

 Modified Files:
 	src/external/gpl3/binutils/dist/gas/config: tc-vax.c

 Log Message:
 binutils/gas: vax: PR port-vax/57646 patch provided by Kalvis Duckmanton [11/21]

 PR toolchain/43314: pc relative relocations are "off by 1*size" on vax

 Address http://gnats.netbsd.org/43314


 To generate a diff of this commit:
 cvs rdiff -u -r1.17 -r1.18 \
     src/external/gpl3/binutils/dist/gas/config/tc-vax.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: "Rin Okuyama" <rin@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/43314 CVS commit: src/external/gpl3/gcc.old/dist/gcc/config/vax
Date: Sat, 7 Oct 2023 12:04:50 +0000

 Module Name:	src
 Committed By:	rin
 Date:		Sat Oct  7 12:04:50 UTC 2023

 Modified Files:
 	src/external/gpl3/gcc.old/dist/gcc/config/vax: elf.h

 Log Message:
 gcc.old: vax: PR port-vax/57646 patch provided by Kalvis Duckmanton [12/21]

 PR toolchain/43314: pc relative relocations are "off by 1*size" on vax

 Address http://gnats.netbsd.org/43314


 To generate a diff of this commit:
 cvs rdiff -u -r1.12 -r1.13 \
     src/external/gpl3/gcc.old/dist/gcc/config/vax/elf.h

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: "Rin Okuyama" <rin@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/43314 CVS commit: src/external/gpl3/binutils.old/dist/gas/config
Date: Sat, 25 Nov 2023 12:07:58 +0000

 Module Name:	src
 Committed By:	rin
 Date:		Sat Nov 25 12:07:58 UTC 2023

 Modified Files:
 	src/external/gpl3/binutils.old/dist/gas/config: tc-vax.c

 Log Message:
 binutils.old/gas: vax: PR port-vax/57646 patch provided by Kalvis Duckmanton [11/21]

 PR toolchain/43314: pc relative relocations are "off by 1*size" on vax

 Address http://gnats.netbsd.org/43314

 Taken from binutils/gas:
 https://mail-index.netbsd.org/source-changes/2023/10/07/msg147942.html


 To generate a diff of this commit:
 cvs rdiff -u -r1.9 -r1.10 \
     src/external/gpl3/binutils.old/dist/gas/config/tc-vax.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2023 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.