public inbox for linux-ia64@vger.kernel.org
 help / color / mirror / Atom feed
* [Linux-ia64] gas generates incorrect ia64 unwind rlen values
@ 2002-12-16  1:24 Keith Owens
  2002-12-16  3:38 ` Grant Grundler
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Keith Owens @ 2002-12-16  1:24 UTC (permalink / raw)
  To: linux-ia64

Using binutils-2.11.90.0.8-12 (old I know, but it is the only version
supported on Redhat ia64), the rlen field in the body part of the
unwind descriptors is incorrect, it is short of the real body size.
Any function calls after the short body rlen are unwound incorrectly.
The unwind code is correct but the invalid rlen makes unwind think that
the calling function has reached its epilogue.  That results in an
attempt to unwind using the 'return address' in b0 which is no longer
valid.

Commands to demonstrate the problem.  Kernel is a native compile of
2.4.19-ia64-020821 plus SGI changes, the SGI changes have not touched
unwind or binutils.  I have also verified the bug on a standard
2.4.19-ia64-020821 kernel, using both native and 386->ia64 cross
compilers.

For system verification reasons, upgrading to binutils 2.13 is not an
option.  Also a check of the binutils changelog, mailing list archives
and bugzilla found no mention of this bug, AFAICT 2.13 has no fix.

# cd arch/ia64/kernel
# gcc -D__KERNEL__ -I/usr/src/redhat/lbs/linux/include  -Wall \
        -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing \
        -fno-common -fomit-frame-pointer -pipe -ffixed-r13 \
        -mfixed-rangeñ0-f15,f32-f127 -falign-functions2 \
        -DSGI_SN_EXECUTABLE_STACKS -mconstant-gp -nostdinc \
	-I /usr/lib/gcc-lib/ia64-redhat-linux/2.96/include \
        -DKBUILD_BASENAME=traps -c -o traps.o traps.c -v

Reading specs from /usr/lib/gcc-lib/ia64-redhat-linux/2.96/specs
gcc version 2.96 20000731 (Red Hat Linux 7.2 2.96-108.7.2)
 /usr/lib/gcc-lib/ia64-redhat-linux/2.96/cpp0 -lang-c -nostdinc -v \
 	-I/usr/src/redhat/lbs/linux/include \
	-I /usr/lib/gcc-lib/ia64-redhat-linux/2.96/include \
	-D__GNUC__=2 -D__GNUC_MINOR__– -D__GNUC_PATCHLEVEL__=0 \
	-D__ia64 -D__ia64__ -D__linux -D__linux__ -D_LONGLONG -Dlinux \
	-Dunix -D__LP64__ -D__ELF__ -D__ia64 -D__ia64__ -D__linux \
	-D__linux__ -D_LONGLONG -D__linux__ -D__unix__ -D__LP64__ \
	-D__ELF__ -D__linux -D__unix -Asystem(linux) -Acpu(ia64) \
	-Amachine(ia64) -D__OPTIMIZE__ -Wall -Wstrict-prototypes \
	-Wno-trigraphs -D__LONG_MAX__’23372036854775807L -D__KERNEL__ \
	-DSGI_SN_EXECUTABLE_STACKS -DKBUILD_BASENAME=traps traps.c | \
 /usr/lib/gcc-lib/ia64-redhat-linux/2.96/cc1 -mb-step -quiet -dumpbase \
 	traps.c -mfixed-rangeñ0-f15,f32-f127 -mconstant-gp -O2 -Wall \
	-Wstrict-prototypes -Wno-trigraphs -version -fno-strict-aliasing \
	-fno-common -fomit-frame-pointer -ffixed-r13 \
	-falign-functions2 -o - | \
 as -x -mconstant-gp -o traps.o -
GNU CPP version 2.96 20000731 (Red Hat Linux 7.2 2.96-108.7.2) (cpplib) (IA-64)
#include "..." search starts here:
#include <...> search starts here:
 /usr/src/redhat/lbs/linux/include
 /usr/lib/gcc-lib/ia64-redhat-linux/2.96/include
End of search list.
GNU C version 2.96 20000731 (Red Hat Linux 7.2 2.96-108.7.2) (ia64-redhat-linux) compiled by GNU C version 2.96 20000731 (Red Hat Linux 7.2 2.96-108.7.2).
bash-2.05# as -v
GNU assembler version 2.11.90.0.8 (ia64-redhat-linux) using BFD version 2.11.90.0.8

Using the 2.13 readelf to print the unwind data.  readelf is correct,
the encoded rlen in unwind info really is 475.

# /usr/src/redhat/BUILD/binutils-2.13.90.0.2/binutils/readelf -u traps.o

Unwind section '.IA_64.unwind' at offset 0x2600 contains 8 entries:
...
<ia64_fault>: [0x1300-0x1dd0), info at +0xc8
  v1, flags=0x0 ( ), len\x16 bytes
    R2:prologue_gr(mask=[rp,ar.pfs],grsave=r37,rlen=8)
	P7:pfs_when(t=0)
	P7:mem_stack_f(t=2,size%6)
	P7:rp_when(t=7)
    R3:body(rlenG5)
	B2:epilogue(t=2,ecount=0)
    R1:prologue(rlen=0)

ia64_fault is 2768 bytes long, 519 slots.  The total of the prologue
and body rlen is only 483 slots.  Any calls past slot 483 are not
unwound correctly.  Unfortunately that includes the call to
die_if_kernel().

# /usr/src/redhat/BUILD/binutils-2.13.90.0.2/binutils/objdump -Sr traps.o
...
0000000000001300 <ia64_fault>:
    1300:	0c 30 31 0e 80 05	[MFI]	    alloc r38=ar.pfs,12,7,0
    1306:	00 00 00 02 00 80		    nop.f 0x0
    130c:	01 60 f8 8c			    adds r12=-256,r12
    1310:	04 00 00 00 01 00	[MLX]	    nop.m 0x0
    1316:	00 08 00 00 00 c0		    movl r14=0x80000000f
    131c:	f1 00 00 60
    1320:	02 00 00 00 01 00	[MII]	    nop.m 0x0
    1326:	50 02 00 62 00 c0		    mov r37°;;
== 8 slots, end of prologue, correct
    132c:	e1 08 31 80			    and r14=r14,r33
    1330:	05 00 00 00 01 00	[MLX]	    nop.m 0x0
    1336:	00 08 00 00 00 e0		    movl r15=0x800000004;;
    133c:	41 00 00 60
.......
			1cd2: PCREL21B	printk
    1cd6:	00 00 00 02 00 00		    nop.f 0x0
    1cdc:	08 00 00 50			    br.call.sptk.many b0\x1cd0 <ia64_fault+0x9d0>;;
    1ce0:	01 70 20 48 00 21	[MII]	    adds r14=8,r36
			1ce1: LTOFF22	.LC40
    1ce6:	70 02 04 00 48 20		    addl r39=0,r1
    1cec:	05 10 01 84			    mov r41=r34;;
    1cf0:	08 40 01 1c 18 10	[MMI]	    ld8 r40=[r14]
    1cf6:	70 02 9c 30 20 40		    ld8 r39=[r39]
    1cfc:	05 08 01 84			    mov r42=r33
    1d00:	1d 58 01 46 00 21	[MFB]	    mov r43=r35
			1d02: PCREL21B	printk
    1d06:	00 00 00 02 00 00		    nop.f 0x0
    1d0c:	08 00 00 50			    br.call.sptk.many b0\x1d00 <ia64_fault+0xa00>;;
== unwind says this (slot 483) is end of body, wrong!
    1d10:	11 38 2d 00 00 24	[MIB]	    mov r39\x11	
			1d12: PCREL21B	force_sig
    1d16:	80 02 34 00 42 00		    mov r40=r13
    1d1c:	08 00 00 50			    br.call.sptk.many b0\x1d10 <ia64_fault+0xa10>;;
    1d20:	1c 00 00 00 01 00	[MFB]	    nop.m 0x0
    1d26:	00 00 00 02 00 00		    nop.f 0x0
    1d2c:	90 00 00 40			    br.few 1db0 <ia64_fault+0xab0>
    1d30:	01 10 41 18 01 21	[MII]	    adds r34\x144,r12
			1d31: LTOFF22	.LC41
    1d36:	80 02 04 00 48 20		    addl r40=0,r1
    1d3c:	05 0a bd 52			    shr.u r41=r33,16;;
    1d40:	19 38 01 44 00 21	[MMB]	    mov r39=r34
			1d42: PCREL21B	sprintf
    1d46:	80 02 a0 30 20 00		    ld8 r40=[r40]
    1d4c:	08 00 00 50			    br.call.sptk.many b0\x1d40 <ia64_fault+0xa40>;;
    1d50:	1c 00 00 00 01 00	[MFB]	    nop.m 0x0
    1d56:	00 00 00 02 00 00		    nop.f 0x0
    1d5c:	30 00 00 40			    br.few 1d80 <ia64_fault+0xa80>
    1d60:	01 10 41 18 01 21	[MII]	    adds r34\x144,r12
			1d61: LTOFF22	.LC42
    1d66:	80 02 04 00 48 20		    addl r40=0,r1
    1d6c:	05 00 01 84			    mov r41=r32;;
    1d70:	19 38 01 44 00 21	[MMB]	    mov r39=r34
			1d72: PCREL21B	sprintf
    1d76:	80 02 a0 30 20 00		    ld8 r40=[r40]
    1d7c:	08 00 00 50			    br.call.sptk.many b0\x1d70 <ia64_fault+0xa70>;;
    1d80:	00 38 01 44 00 21	[MII]	    mov r39=r34
    1d86:	80 02 90 00 42 20		    mov r40=r36
    1d8c:	05 08 01 84			    mov r41=r33
    1d90:	1d 00 00 00 01 00	[MFB]	    nop.m 0x0
== this call to die_if_kernel() is treated as post epilogue and unwind gives up
			1d92: PCREL21B	die_if_kernel
    1d96:	00 00 00 02 00 00		    nop.f 0x0
    1d9c:	08 00 00 50			    br.call.sptk.many b0\x1d90 <ia64_fault+0xa90>;;
    1da0:	11 38 11 00 00 24	[MIB]	    mov r39=4
			1da2: PCREL21B	force_sig
    1da6:	80 02 34 00 42 00		    mov r40=r13
    1dac:	08 00 00 50			    br.call.sptk.many b0\x1da0 <ia64_fault+0xaa0>;;
    1db0:	00 00 00 00 01 00	[MII]	    nop.m 0x0
    1db6:	00 30 01 55 00 00		    mov.i ar.pfs=r38
    1dbc:	50 0a 00 07			    mov b0=r37
    1dc0:	1d 60 00 18 02 21	[MFB]	    adds r12%6,r12
    1dc6:	00 00 00 02 00 80		    nop.f 0x0
    1dcc:	08 00 84 00			    br.ret.sptk.many b0;;
    1dd0:	0c 00 00 00 01 00	[MFI]	    nop.m 0x0
    1dd6:	00 00 00 02 00 00		    nop.f 0x0
    1ddc:	00 00 04 00			    nop.i 0x0



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Linux-ia64] gas generates incorrect ia64 unwind rlen values
  2002-12-16  1:24 [Linux-ia64] gas generates incorrect ia64 unwind rlen values Keith Owens
@ 2002-12-16  3:38 ` Grant Grundler
  2002-12-16  4:46 ` Keith Owens
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Grant Grundler @ 2002-12-16  3:38 UTC (permalink / raw)
  To: linux-ia64

On Mon, Dec 16, 2002 at 12:24:03PM +1100, Keith Owens wrote:
> Using binutils-2.11.90.0.8-12 (old I know, but it is the only version
> supported on Redhat ia64)

Which RH IA64 are we talking about?

RH AS 2.1 seems to ship with binutils-2.12.90.0.15-37.
(not saying it's much better...just different).

grant


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Linux-ia64] gas generates incorrect ia64 unwind rlen values
  2002-12-16  1:24 [Linux-ia64] gas generates incorrect ia64 unwind rlen values Keith Owens
  2002-12-16  3:38 ` Grant Grundler
@ 2002-12-16  4:46 ` Keith Owens
  2002-12-16 21:25 ` Jim Wilson
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Keith Owens @ 2002-12-16  4:46 UTC (permalink / raw)
  To: linux-ia64

On Sun, 15 Dec 2002 19:38:45 -0800, 
grundler@cup.hp.com (Grant Grundler) wrote:
>On Mon, Dec 16, 2002 at 12:24:03PM +1100, Keith Owens wrote:
>> Using binutils-2.11.90.0.8-12 (old I know, but it is the only version
>> supported on Redhat ia64)
>
>Which RH IA64 are we talking about?

RH 7.2-ia64, Dec 15 2001.

>RH AS 2.1 seems to ship with binutils-2.12.90.0.15-37.
>(not saying it's much better...just different).

As I mentioned in the previous mail, I could not find any mail, bug
reports or changelog entries that mentioned ia64 unwind or rlen being
wrong.  Which makes me think that the bug exists in current binutils,
however I cannot test that at the moment.



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Linux-ia64] gas generates incorrect ia64 unwind rlen values
  2002-12-16  1:24 [Linux-ia64] gas generates incorrect ia64 unwind rlen values Keith Owens
  2002-12-16  3:38 ` Grant Grundler
  2002-12-16  4:46 ` Keith Owens
@ 2002-12-16 21:25 ` Jim Wilson
  2002-12-16 22:08 ` David Mosberger
  2002-12-16 22:11 ` David Mosberger
  4 siblings, 0 replies; 6+ messages in thread
From: Jim Wilson @ 2002-12-16 21:25 UTC (permalink / raw)
  To: linux-ia64

>RH 7.2-ia64, Dec 15 2001.

The tools for this release were based on Summer 2000 FSF sources with patches.
So they are about 2.5 years old now.

>As I mentioned in the previous mail, I could not find any mail, bug
>reports or changelog entries that mentioned ia64 unwind or rlen being
>wrong.  Which makes me think that the bug exists in current binutils,
>however I cannot test that at the moment.

There have been a number of fixes in this area in the last 2.5 years.

Are you sure this is an assembler problem?  If the compiler is emitting bad
unwind directives, then it could be a compiler problem.  You didn't mention
anything about looking at assembly code.

There was a compiler problem with block reordering (-freorder-blocks) that
could cause the epilogue to appear in the middle of the function, and then
we emitted bad unwind info that made half the function look like epilogue code.
This was fixed in March 2001.  This patch may not be in your compiler sources.

There was an assembler problem where it calculated rlen wrong when a function
spanned multiple frags.  This was fixed in November 2000.  This patch should
be in your assembler sources, but it is possible it got left out accidentally.

There were also other various bug fixes over the last few years that might
be related.

I will try looking at this, but since it requires kernel, compiler, and
assembler sources that I don't happen to have it may take me some time to
figure anything out.  If you could give a better bug report that would help.
For instance, an assembly source example that when assembled results in
incorrect unwind info.  At the moment, I am skeptical that anything is broken
in current binutils sources.  No proof of this has been presented yet.

Jim


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Linux-ia64] gas generates incorrect ia64 unwind rlen values
  2002-12-16  1:24 [Linux-ia64] gas generates incorrect ia64 unwind rlen values Keith Owens
                   ` (2 preceding siblings ...)
  2002-12-16 21:25 ` Jim Wilson
@ 2002-12-16 22:08 ` David Mosberger
  2002-12-16 22:11 ` David Mosberger
  4 siblings, 0 replies; 6+ messages in thread
From: David Mosberger @ 2002-12-16 22:08 UTC (permalink / raw)
  To: linux-ia64

>>>>> On Mon, 16 Dec 2002 12:24:03 +1100, Keith Owens <kaos@sgi.com> said:

  Keith> Using binutils-2.11.90.0.8-12 (old I know, but it is the only version
  Keith> supported on Redhat ia64), the rlen field in the body part of the
  Keith> unwind descriptors is incorrect, it is short of the real body size.

There have been many unwind-related bug fixes to the toolchain.  It's
one reason why 2.9x is hopelessly obsolete.  Distros should really
switch to gcc-3.2.

	--david


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Linux-ia64] gas generates incorrect ia64 unwind rlen values
  2002-12-16  1:24 [Linux-ia64] gas generates incorrect ia64 unwind rlen values Keith Owens
                   ` (3 preceding siblings ...)
  2002-12-16 22:08 ` David Mosberger
@ 2002-12-16 22:11 ` David Mosberger
  4 siblings, 0 replies; 6+ messages in thread
From: David Mosberger @ 2002-12-16 22:11 UTC (permalink / raw)
  To: linux-ia64

>>>>> On Mon, 16 Dec 2002 15:46:27 +1100, Keith Owens <kaos@sgi.com> said:

  Keith> As I mentioned in the previous mail, I could not find any mail, bug
  Keith> reports or changelog entries that mentioned ia64 unwind or rlen being
  Keith> wrong.  Which makes me think that the bug exists in current binutils,
  Keith> however I cannot test that at the moment.

Trust me: there were at least 2 or 3 fixes; some in the compiler, some
in binutils.  Here is an example from gas:

2002-02-22  David Mosberger  <davidm@hpl.hp.com>

	* config/tc-ia64.c (dot_restore): Issue error message of epilogue
	count exceeds prologue count.
	(md_show_usage): Describe -mconstant-gp and -mauto-pic.
	(unwind.label_prologue_count): New member.

	Based on a patch by Hans Boehm <hboehm@hpl.hp.com>:

	(get_saved_prologue_count): New function.
	(save_prologue_count): New function.
	(free_saved_prologue_count): New function.
	(dot_label_state): Record state label by calling save_prologue_count().
	(dot_copy_state): Restore prologue count by calling
	get_saved_prologue_count().
	(generate_unwind_image): Free up list of saved prologue
	counts by calling free_saved_prologue_counts().

  --david


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2002-12-16 22:11 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-12-16  1:24 [Linux-ia64] gas generates incorrect ia64 unwind rlen values Keith Owens
2002-12-16  3:38 ` Grant Grundler
2002-12-16  4:46 ` Keith Owens
2002-12-16 21:25 ` Jim Wilson
2002-12-16 22:08 ` David Mosberger
2002-12-16 22:11 ` David Mosberger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox