This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[patch] fix collect2 not to drag every archived object with eh tables


Hello,

This is a recap and resubmission of a patch suggested a while ago to address
an issue first raised here:

   http://gcc.gnu.org/ml/gcc/2006-09/msg00483.html

After a couple of events, the patch was last submitted in two parts:

  http://gcc.gnu.org/ml/gcc-patches/2008-07/msg01957.html
  + http://gcc.gnu.org/ml/gcc-patches/2008-08/msg00047.html

--

The initial issue is still visible with a recent mainline: on AIX:

  << To address

      /* The AIX linker will discard static constructors in object files if
	 nothing else in the file is referenced [...] */

    collect2 builds the ctor/dtor tables from an explicit scan of
    all the objects and libraries.

    The scan also considers frame tables, so we end up dragging every object
    with such tables even if the object is not needed at all for other
    reasons.

    For instance, with a recent mainline on aix 5.3 we see:

       /* useless.cc */
       extern void nowhere ();
       static void useless ()
       {
	 nowhere ();
       }

       /* main.cc */
       int main ()
       {
	 return 0;
       }

       $ g++ -c useless.cc
       $ ar rv libuseless.a useless.o
       ar: creating an archive file libuseless.a
       a - useless.o

       $ g++ -o m main.cc -L. -luseless
       ld: 0711-317 ERROR: Undefined symbol: .nowhere()
       ...
       collect2: ld returned 8 exit status

    -Wl,-debug reads:

	 List of libraries:
	    ./libuseless.a,
	 ...
	 extern void *x7 __asm__ ("_GLOBAL__F_useless.cc_00000000_03A3E4DF");
	 ...
	 static void *frame_table[] = {
		    &x7,

    The "useless" object has been included because of a reference to its
    frame tables out of collect2's processing for libuseless.a. 

    This behavior is problematic because it might cause the inclusion of
    loads of useless objects in general, with two consequences: executables
    potentially much larger than needed and unexpected dependencies.

    We noticed this while working on DWARF2 exceptions support for Ada
    with a static run-time library: almost the full library ends up
    included in every executable, causing a significant waste in space and
    forcing to systematically link with at least libm.
  >>

The functional principle is the same as in the initial submission:

  in collect2, when early searching for static ctors to prevent their
  garbage collection, arrange not to reference all the frame tables
  from every object and lib,

  in the compiler, arrange to link the tables to their associated
  functions, so that they come together when a function is linked in,

  in collect2, perform a first pass link and scan to find the eh
  tables as on other targets.

On the collect2 side, the first pass link and scan control is now
achieved on all targets by manipulations on a simple scan-filter mask
instead of the previous tricky "ifdef COLLECT_EXPORT_LIST" sequences.
This makes it easier to understand/follow IMO and allows greater
flexibilty.

In particular, this helps taking care of the need to grab all the tables in
the shared_obj case, which has its own specific processing scheme already.
This is now pretty easily achieved by controlling the early scan filter on
this condition.

On the compiler side, the table/code link is emitted from within the FDE loop
in output_call_frame_info, using fde->decl to get at the function declaration,
switching to the proper section, then back into the frame table section. This
requires a bit of care for targets like AIX that emit frame tables in the data
section, to make sure the table identifying label is emitted the first time
only.

This was bootstrapped and regression tested on powerpc-ibm-aix5.3.0.0,
hppa1.1-hp-hpux11.0 and x86_64-suse-linux. I also sanity checked that the Ada
ZCX static library case now works as expected.

Thanks in advance,

With Kind Regards,

Olivier

2009-07-06  Olivier Hainque  <hainque@adacore.com>

	* collect2.c (DO_COLLECT_EXPORT_LIST): New internal macro,
	always defined.  Reflect definition or absence of such for
	COLLECT_EXPORT_LIST.  Readability helper.
	(scanfilter): New enum, to help control what symbols
	are to be considered or ignored by scan_prog_file.
	(enum pass): Rename as "scanpass", moved together with scanfilter
	prior to scan_prog_file's prototype.
	(scan_prog_file): Accept and honor scanpass and scanfilter arguments.
	Group prototype with the scanpass/scanfilter definitions, factorize
	head comments for the several implementations at the prototype.
	(main): Reorganize the first pass link control to let AIX
	drag only the needed frame tables in executables.  Prevent
	frame tables collection during the scan aimed at static ctors.
 	Pre-link and scan for frame tables later to compensate.
	* doc/tm.texi (ASM_OUTPUT_DWARF_TABLE_REF): New macro.
	A C statement to issue assembly directives that create a reference
	to the given DWARF table identifier label from the current function
	section.
	* dwarf2out.c (switch_to_eh_frame_section): Add a BACK argument
	to differentiate first time section entry.  Only emit a .data
	tables start identifier label the first time around.
	(switch_to_frame_table_section): New function.  Helper for
	output_call_frame_info to switch possibly BACK into the eh_frame
	or the debug_frame section depending on FOR_EH.
	(output_call_frame_info): Use helper to first enter the proper
	frame section. Use ASM_OUTPUT_DWARF_TABLE_REF when defined to
	emit a link to the frame table start label from each function
	section.
	* config/rs6000/rs6000.c (rs6000_aix_asm_output_dwarf_table_ref):
	New function.  Implementation of ASM_OUTPUT_DWARF_TABLE_REF.
	* config/rs6000/rs6000-protos.h: Declare it.
	* config/rs6000/aix.h (ASM_OUTPUT_DWARF_TABLE_REF): Define.

Attachment: collect-tables.dif
Description: Text document


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