This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[committed] Fix excessive memory allocation on AIX


I was trying to bootstrap GCC on AIX with binutils, but forgot to set
LDR_CNTRL=MAXDATA=X beforehand.  The linker then ran out of memory trying
to link cc1plus during stage 2.

I was curious why, and the immediate problem turned out to be the
flinfo.contents buffer allocated by _bfd_xcoff_bfd_final_link.
This buffer is allocated for one reason only: to give xcoff_link_input_bfd
somewhere where it can swap in the section contents.  Presumably the
allocation is done here for speed reasons.

The buffer therefore has to be as big as the largest section that
xcoff_link_input_bfd swaps in.  But the current calculation includes
_all_ sections.  In the case of cc1plus (and probably most other
binaries with debug information), the debug section is far and away
the biggest, but its contents are held separately, so xcoff_link_input_bfd
doesn't need to swap them in.

More generally, xcoff_link_input_bfd swaps in contents that don't
have the SEC_IN_MEMORY flag, so we can skip all sections that do.

Unfortunately, it's still necessary to set LDR_CNTRL=MAXDATA=X
after this patch, but at least it's an improvement.

Tested on powerpc-ibm-aix5.3.0 and applied.

Richard


bfd/
	* xcofflink.c (_bfd_xcoff_bfd_final_link): When calculating
	max_contents_size, only consider sections whose contents must
	be swapped in.

Index: bfd/xcofflink.c
===================================================================
--- bfd/xcofflink.c	2010-01-12 20:29:37.000000000 +0000
+++ bfd/xcofflink.c	2010-02-08 19:43:53.000000000 +0000
@@ -5872,10 +5872,13 @@ _bfd_xcoff_bfd_final_link (bfd *abfd, st
 
 	      o->reloc_count += sec->reloc_count;
 
-	      if (sec->rawsize > max_contents_size)
-		max_contents_size = sec->rawsize;
-	      if (sec->size > max_contents_size)
-		max_contents_size = sec->size;
+	      if ((sec->flags & SEC_IN_MEMORY) == 0)
+		{
+		  if (sec->rawsize > max_contents_size)
+		    max_contents_size = sec->rawsize;
+		  if (sec->size > max_contents_size)
+		    max_contents_size = sec->size;
+		}
 	      if (coff_section_data (sec->owner, sec) != NULL
 		  && xcoff_section_data (sec->owner, sec) != NULL
 		  && (xcoff_section_data (sec->owner, sec)->lineno_count


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]