Re: 2.6.3 Heisenbug in unwind.c

From: Keith Owens <kaos_at_sgi.com>
Date: 2004-03-16 21:42:55
On Mon, 15 Mar 2004 17:52:09 +1100, 
Keith Owens <kaos@sgi.com> wrote:
>One step further on.  The illegal unwind descriptors are being caused
>by the linker (GNU ld version 2.14.90.0.4 20030523) sometimes putting
>everything from .init.text onwards in an extra output program header.

Which of course it is entitled to do.  vmlinux.lds.S does not
explicitly assign sections to segments so ld is allowed to choose its
own mapping.  Most of the time the .text and .init.text sections are in
the same segment, but sometimes the linker assigns them to different
segments, depending on the precise contents of the input files.  When
those sections are in different segments _and_ you are using binutils
with buggy ia64 SEGREL code then the result is corrupt unwind data.

binutils-2.14.90.0.4-26.3 (RH AS3.0) is not good enough,
binutils-2.14.90.0.8-8.1 (Fedora) works.

Patch to 2.6.4 to prevent building with a buggy version of binutils.

Index: linux-2.6.4/arch/ia64/scripts/toolchain-flags
===================================================================
--- linux-2.6.4.orig/arch/ia64/scripts/toolchain-flags	2004-03-10 18:55:49.000000000 -0800
+++ linux-2.6.4/arch/ia64/scripts/toolchain-flags	2004-03-15 22:11:02.000000000 -0800
@@ -18,11 +18,6 @@
 rm -f $out
 if [ $res != 00000a00 ]; then
     CPPFLAGS="$CPPFLAGS -DHAVE_BUGGY_SEGREL"
-    cat >&2 <<EOF
-warning: your linker cannot handle cross-segment segment-relative relocations.
-         please upgrade to a newer version (it is safe to use this linker, but
-         the kernel will be bigger than strictly necessary).
-EOF
 fi
 
 # Check whether .align inside a function works as expected.
Index: linux-2.6.4/arch/ia64/kernel/gate.lds.S
===================================================================
--- linux-2.6.4.orig/arch/ia64/kernel/gate.lds.S	2004-03-10 18:55:24.000000000 -0800
+++ linux-2.6.4/arch/ia64/kernel/gate.lds.S	2004-03-15 21:21:02.000000000 -0800
@@ -46,12 +46,8 @@
   }									:readable
   .IA_64.unwind_info		: { *(.IA_64.unwind_info*) }
   .IA_64.unwind			: { *(.IA_64.unwind*) }			:readable :unwind
-#ifdef HAVE_BUGGY_SEGREL
-  .text (GATE_ADDR + PAGE_SIZE)	: { *(.text) *(.text.*) }		:readable
-#else
   . = ALIGN (PERCPU_PAGE_SIZE) + (. & (PERCPU_PAGE_SIZE - 1));
   .text				: { *(.text) *(.text.*) }		:epc
-#endif
 
   /DISCARD/			: {
   	*(.got.plt) *(.got)
@@ -69,9 +65,7 @@
 PHDRS
 {
   readable  PT_LOAD	FILEHDR	PHDRS	FLAGS(4);	/* PF_R */
-#ifndef HAVE_BUGGY_SEGREL
   epc	    PT_LOAD	FILEHDR PHDRS	FLAGS(1);	/* PF_X */
-#endif
   dynamic   PT_DYNAMIC			FLAGS(4);	/* PF_R */
   unwind    0x70000001; /* PT_IA_64_UNWIND, but ld doesn't match the name */
 }
Index: linux-2.6.4/arch/ia64/mm/init.c
===================================================================
--- linux-2.6.4.orig/arch/ia64/mm/init.c	2004-03-10 18:55:26.000000000 -0800
+++ linux-2.6.4/arch/ia64/mm/init.c	2004-03-15 21:21:18.000000000 -0800
@@ -265,12 +265,7 @@
 	 */
 	page = virt_to_page(ia64_imva(__start_gate_section));
 	put_kernel_page(page, GATE_ADDR, PAGE_READONLY);
-#ifdef HAVE_BUGGY_SEGREL
-	page = virt_to_page(ia64_imva(__start_gate_section + PAGE_SIZE));
-	put_kernel_page(page, GATE_ADDR + PAGE_SIZE, PAGE_GATE);
-#else
 	put_kernel_page(page, GATE_ADDR + PERCPU_PAGE_SIZE, PAGE_GATE);
-#endif
 	ia64_patch_gate();
 }
 
Index: linux-2.6.4/arch/ia64/Makefile
===================================================================
--- linux-2.6.4.orig/arch/ia64/Makefile	2004-03-11 22:29:00.000000000 -0800
+++ linux-2.6.4/arch/ia64/Makefile	2004-03-15 22:18:06.000000000 -0800
@@ -37,6 +37,12 @@
 		ftp://ftp.hpl.hp.com/pub/linux-ia64/gas-030124.tar.gz)
 endif
 
+ifneq ($(findstring -DHAVE_BUGGY_SEGREL,$(CPPFLAGS)),)
+$(error Sorry, you need a newer version of binutils, one that is built from	\
+	a source-tree that post-dates 17-Jul-2003.  binutils-2.14.90.0.8 is	\
+	known to work)
+endif
+
 ifeq ($(GCC_VERSION),2)
 $(error Sorry, your compiler is too old.  GCC v2.96 is known to generate bad code.)
 endif

-
To unsubscribe from this list: send the line "unsubscribe linux-ia64" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Received on Tue Mar 16 06:35:43 2004

This archive was generated by hypermail 2.1.8 : 2005-08-02 09:20:24 EST