PATCH: Re: ia64 ltoff22x/ldxmov relaxation

H. J. Lu hjl@lucon.org
Mon Apr 28 20:07:00 GMT 2003


On Mon, Apr 28, 2003 at 03:14:16PM +0200, Andreas Schwab wrote:
> "H. J. Lu" <hjl@lucon.org> writes:
> 
> |> On Thu, Apr 24, 2003 at 06:09:56PM +0200, Andreas Schwab wrote:
> |> > Richard Henderson <rth@redhat.com> writes:
> |> > 
> |> > |> Also misses properly choosing a new gp when jump buffers are added.
> |> > |> Technically this is a potential correctness issue.  Failures will
> |> > |> be caught by relocate_section in the form of GPREL22 overflows.
> |> > |> However this should should work well in practice because of the default
> |> > |> 2**61 byte separation of the text and data segments in executables.
> |> > |> In order for this to be fixed, I need a callback from the main ld
> |> > |> relaxation loop at the start of a new round of relaxation.
> |> > 
> |> > Unfortunately, this bites with large shared libraries where this text/data
> |> > separation does not exist.  For example, we get GPREL22 overflows when
> |> > linking libjava from gcc mainline.  I can prepare a test case if you need.
> |> > 
> |> 
> |> Yes, plase. I am interested in a testcase for that.
> 
> You can download it from
> <ftp://ftp.suse.com/pub/people/schwab/libjava-test.tar.bz2>.
> Unfortunately it is quite big, but I couldn't reduce it without the bug
> going away.  Unpack the archive and run link-java, you will get these
> errors:
> 

This patch seems to work for me.


H.J.
-------------- next part --------------
bfd/

2003-04-28  H.J. Lu <hjl@gnu.org>

	* elfxx-ia64.c (elfNN_ia64_relax_section): Relax ldxmov during
	the relax finalize pass.

	* section.c (struct sec): Add need_finalize_relax and remove
	flag11.
	(STD_SECTION): Update struct sec initializer.
	* bfd-in2.h: Regenerated.

include/

2003-04-18  H.J. Lu <hjl@gnu.org>

	* bfdlink.h (bfd_link_info): Add relax_finalizing.

ld/

2003-04-18  H.J. Lu <hjl@gnu.org>

	* ldlang.c (lang_process): Add the relax finalize pass.

	* ldmain.c (main): Initialize link_info.relax_finalizing to
	FALSE.

--- binutils/bfd/elfxx-ia64.c.fr	2003-04-28 07:49:17.000000000 -0700
+++ binutils/bfd/elfxx-ia64.c	2003-04-28 12:58:14.000000000 -0700
@@ -704,9 +704,12 @@ elfNN_ia64_relax_section (abfd, sec, lin
   if (link_info->hash->creator->flavour != bfd_target_elf_flavour)
     return FALSE;
 
-  /* Nothing to do if there are no relocations.  */
+  /* Nothing to do if there are no relocations or there is no need for
+     the relax finalize pass.  */
   if ((sec->flags & SEC_RELOC) == 0
-      || sec->reloc_count == 0)
+      || sec->reloc_count == 0
+      || (link_info->relax_finalizing
+	  && sec->need_finalize_relax == 0))
     return TRUE;
 
   /* If this is the first time we have been called for this section,
@@ -756,11 +759,16 @@ elfNN_ia64_relax_section (abfd, sec, lin
 	case R_IA64_PCREL21BI:
 	case R_IA64_PCREL21M:
 	case R_IA64_PCREL21F:
+	  if (link_info->relax_finalizing)
+	    continue;
 	  is_branch = TRUE;
 	  break;
 
 	case R_IA64_LTOFF22X:
 	case R_IA64_LDXMOV:
+	  sec->need_finalize_relax = 1;
+	  if (!link_info->relax_finalizing)
+	    continue;
 	  is_branch = FALSE;
 	  break;
 
@@ -1047,6 +1055,9 @@ elfNN_ia64_relax_section (abfd, sec, lin
       /* ??? Resize .rela.got too.  */
     }
 
+  if (link_info->relax_finalizing && sec->need_finalize_relax == 1)
+    sec->need_finalize_relax = 0;
+
   *again = changed_contents || changed_relocs;
   return TRUE;
 
--- binutils/bfd/section.c.fr	2003-02-27 11:27:05.000000000 -0800
+++ binutils/bfd/section.c	2003-04-28 07:49:18.000000000 -0700
@@ -396,8 +396,10 @@ CODE_FRAGMENT
 .  {* Bits used by various backends.  *}
 .  unsigned int has_tls_reloc:1;
 .
+.  {* Nonzero if this section needs the relax finalize pass.  *}
+.  unsigned int need_finalize_relax:1;
+.
 .  {* Usused bits.  *}
-.  unsigned int flag11:1;
 .  unsigned int flag12:1;
 .  unsigned int flag13:1;
 .  unsigned int flag14:1;
@@ -615,8 +617,8 @@ static const asymbol global_syms[] =
     /* linker_mark, linker_has_input, gc_mark, segment_mark,         */	\
        0,           0,                1,       0,			\
 									\
-    /* sec_info_type, use_rela_p, has_tls_reloc, flag11, flag12,     */ \
-       0,	      0,	  0,		 0,	 0,		\
+    /* sec_info_type, use_rela_p, has_tls_reloc, need_finalize_relax, flag12,     */ \
+       0,	      0,	  0,		 0,		      0,		\
 									\
     /* flag13, flag14, flag15, flag16, flag20, flag24,               */ \
        0,      0,      0,      0,      0,      0,			\
--- binutils/include/bfdlink.h.fr	2003-04-24 14:19:07.000000000 -0700
+++ binutils/include/bfdlink.h	2003-04-28 07:49:18.000000000 -0700
@@ -288,6 +288,9 @@ struct bfd_link_info
   /* TRUE if global symbols in discarded sections should be stripped.  */
   unsigned int strip_discarded: 1;
 
+  /* TRUE if relaxation is being finalized.  */
+  unsigned int relax_finalizing: 1;
+
   /* Which symbols to strip.  */
   enum bfd_link_strip strip;
 
--- binutils/ld/ldlang.c.fr	2003-04-01 14:29:10.000000000 -0800
+++ binutils/ld/ldlang.c	2003-04-28 07:49:18.000000000 -0700
@@ -4393,6 +4393,14 @@ lang_process ()
 			      abs_output_section,
 			      &statement_list.head, 0, (bfd_vma) 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);
 
--- binutils/ld/ldmain.c.fr	2003-04-24 14:19:08.000000000 -0700
+++ binutils/ld/ldmain.c	2003-04-28 07:49:18.000000000 -0700
@@ -329,6 +329,7 @@ main (argc, argv)
   link_info.spare_dynamic_tags = 5;
   link_info.flags = (bfd_vma) 0;
   link_info.flags_1 = (bfd_vma) 0;
+  link_info.relax_finalizing = FALSE;
 
   ldfile_add_arch ("");
 


More information about the Binutils mailing list