PATCH: IA64 linker relaxation bug
H. J. Lu
hjl@lucon.org
Wed Nov 5 00:10:00 GMT 2003
On Sat, Nov 01, 2003 at 02:37:29AM +0100, Andreas Schwab wrote:
> The testcase at <ftp://ftp.suse.com/pub/people/schwab/ia64-relax.tar.bz2>
> demonstrates a bug in the linker relaxation on ia64:
>
> $ make
> ld -o temacs temacs.o libncurses.so libm.so libc.so elf-init.oS crtn.o
> elf-init.oS(.text+0x101): In function `__libc_csu_init':
> : relocation truncated to fit: GPREL22 __init_array_start
> make: *** [temacs] Error 1
>
> The problem is that __init_array_start is changing its value multiple
> times during linking, always alternating between 0x6000000000000430 and
> 0x6000000000004fa0. There is an LTOFF22X relocation against this symbol,
> and by the time the relaxing pass looks at this relocation the value of
> __init_array_start is 0x6000000000004fa0 which is close enough to the gp
> value. But the final value happens to be 0x6000000000000430, outside of
> the range of a GPREL22 relocation.
>
The problem is lang_do_assignments assigns 0x6000000000004fa0 and
lang_size_sections assigns 0x6000000000000430. The final one is
0x6000000000000430.
> This bug is reproducable both with mainline and 2.14 branch. I think it
> is a side effect of
> <http://sources.redhat.com/ml/binutils/2001-02/msg00304.html>.
>
I am testing this patch. Does this make any senses?
H.J.
-------------- next part --------------
2003-11-04 H.J. Lu <hongjiu.lu@intel.com>
* ldlang.c (lang_process): Move the relax finalize pass after
all sizes are finalized.
--- ld/ldlang.c.relax 2003-11-04 14:25:03.000000000 -0800
+++ ld/ldlang.c 2003-11-04 15:48:24.000000000 -0800
@@ -4257,14 +4257,6 @@ lang_process (void)
globals are, so can make a better guess. */
lang_size_sections (statement_list.head, abs_output_section,
&statement_list.head, 0, 0, &relax_again, FALSE);
-
- /* If the normal relax is done and the relax finalize pass
- is not performed yet, we perform another relax pass. */
- if (!relax_again && !link_info.relax_finalizing)
- {
- link_info.relax_finalizing = TRUE;
- relax_again = TRUE;
- }
}
while (relax_again);
@@ -4273,6 +4265,15 @@ lang_process (void)
lang_do_assignments (statement_list.head, abs_output_section, NULL, 0);
lang_size_sections (statement_list.head, abs_output_section,
&statement_list.head, 0, 0, NULL, TRUE);
+
+ /* The relax finalize pass should be done after all sizes are
+ finalized and cause no size change. */
+ link_info.relax_finalizing = TRUE;
+ relax_again = TRUE;
+ lang_reset_memory_regions ();
+ lang_size_sections (statement_list.head, abs_output_section,
+ &statement_list.head, 0, 0, &relax_again,
+ FALSE);
}
/* See if anything special should be done now we know how big
More information about the Binutils
mailing list