public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Enhance collect2 to preserve ro outputs as the linker would
@ 2008-05-21 10:19 Olivier Hainque
  2008-05-21 23:06 ` Ian Lance Taylor
  0 siblings, 1 reply; 9+ messages in thread
From: Olivier Hainque @ 2008-05-21 10:19 UTC (permalink / raw)
  To: gcc-patches; +Cc: hainque

[-- Attachment #1: Type: text/plain, Size: 1703 bytes --]

Hello,

While some target linkers silently replace read-only output files,
others report an error in such circumstances. For instance, on AIX
with a dummy program in m.c:

    $ gcc -c m.c
    $ ld -o m m.o /lib/crt0.o -lc
    $ chmod -w m
    $ ld -o m m.o /lib/crt0.o -lc
    ld: 0711-931 SEVERE ERROR: Output file: m
	    The file is write-protected.

collect2 doesn't mimic this behavior and always replaces, which might
cause suprises to some users. The attached patch is a suggestion to
improve this situation, with two parts:

    1/ Enhance collect2 so that it mimics the target linker's
       behavior, as reflected by a new "COLLECT_PRESERVE_RO_OUTPUT"
       target macro definition.

    2/ Define the macro for ppc-aix.

After which the behavior on this target is

    $ gcc -o m m.c
    $ chmod -w m
    $ gcc -o m m.c
    collect2: output file m exists and is read-only

Bootstrapped and regression tested on both powerpc-ibm-aix5.3 and
x86_64-suse-linux.

Thanks in advance,

Olivier

2008-05-21  Olivier Hainque  <hainque@adacore.com>

	* doc/tm.texi (COLLECT_PRESERVE_RO_OUTPUT):  New macro.  Wether
        collect2 should preserve an existing read-only output file and
        return on error if one is found, typically as the target linker
        would.
        * collect2.c (collect_exit): Honor an extra KEEP_OUTPUT argument,
        preserve the output_file if non-zero.
        (fatal_perror, fatal, collect_wait, do_wait): Adjust callers.
        (main): Adjust calls and honor COLLECT_PRESERVE_RO_OUTPUT.
        * collect2.h (collect_exit): Adjust prototype.
        * tlink.c (do_tlink): Adjust callers.

	* config/rs6000/aix.h (COLLECT_PRESERVE_RO_OUTPUT): Define.







[-- Attachment #2: collect-ro.dif --]
[-- Type: text/plain, Size: 5576 bytes --]

Index: doc/tm.texi
===================================================================
*** doc/tm.texi	(revision 135576)
--- doc/tm.texi	(working copy)
*************** object files that are not referenced fro
*** 10296,10301 ****
--- 10296,10306 ----
  lists.
  @end defmac
  
+ @defmac COLLECT_PRESERVE_RO_OUTPUT
+ If defined, @code{collect2} will preserve an existing read-only output
+ file and return on error when one is found.
+ @end defmac
+ 
  @defmac MODIFY_JNI_METHOD_CALL (@var{mdecl})
  Define this macro to a C expression representing a variant of the
  method call @var{mdecl}, if Java Native Interface (JNI) methods
Index: collect2.c
===================================================================
*** collect2.c	(revision 135576)
--- collect2.c	(working copy)
*************** static char *resolve_lib_name (const cha
*** 277,286 ****
  #endif
  static char *extract_string (const char **);
  \f
! /* Delete tempfiles and exit function.  */
  
  void
! collect_exit (int status)
  {
    if (c_file != 0 && c_file[0])
      maybe_unlink (c_file);
--- 277,287 ----
  #endif
  static char *extract_string (const char **);
  \f
! /* Delete tempfiles, the output file unless KEEP_OUTPUT is non-zero,
!    and exit function.  */
  
  void
! collect_exit (int status, int keep_output)
  {
    if (c_file != 0 && c_file[0])
      maybe_unlink (c_file);
*************** collect_exit (int status)
*** 305,311 ****
        maybe_unlink (lderrout);
      }
  
!   if (status != 0 && output_file != 0 && output_file[0])
      maybe_unlink (output_file);
  
    if (response_file)
--- 306,312 ----
        maybe_unlink (lderrout);
      }
  
!   if (status != 0 && !keep_output && output_file != 0 && output_file[0])
      maybe_unlink (output_file);
  
    if (response_file)
*************** fatal_perror (const char * cmsgid, ...)
*** 340,346 ****
    fprintf (stderr, ": %s\n", xstrerror (e));
    va_end (ap);
  
!   collect_exit (FATAL_EXIT_CODE);
  }
  
  /* Just die.  */
--- 341,347 ----
    fprintf (stderr, ": %s\n", xstrerror (e));
    va_end (ap);
  
!   collect_exit (FATAL_EXIT_CODE, 0);
  }
  
  /* Just die.  */
*************** fatal (const char * cmsgid, ...)
*** 356,362 ****
    fprintf (stderr, "\n");
    va_end (ap);
  
!   collect_exit (FATAL_EXIT_CODE);
  }
  
  /* Write error message.  */
--- 357,363 ----
    fprintf (stderr, "\n");
    va_end (ap);
  
!   collect_exit (FATAL_EXIT_CODE, 0);
  }
  
  /* Write error message.  */
*************** main (int argc, char **argv)
*** 1241,1246 ****
--- 1242,1258 ----
  #endif
  	}
      }
+   
+   /* If we are to preserve an existing read-only output file, do so.  */
+ #ifdef COLLECT_PRESERVE_RO_OUTPUT
+   if (output_file
+       && access (output_file, F_OK) == 0
+       && access (output_file, W_OK) != 0)
+     {
+       error ("output file %s exists and is read-only", output_file);
+       collect_exit (FATAL_EXIT_CODE, 1);
+     }
+ #endif
  
  #ifdef COLLECT_EXPORT_LIST
    /* This is added only for debugging purposes.  */
*************** collect_wait (const char *prog, struct p
*** 1526,1532 ****
  	  error ("%s terminated with signal %d [%s]%s",
  		 prog, sig, strsignal(sig),
  		 WCOREDUMP(status) ? ", core dumped" : "");
! 	  collect_exit (FATAL_EXIT_CODE);
  	}
  
        if (WIFEXITED (status))
--- 1538,1544 ----
  	  error ("%s terminated with signal %d [%s]%s",
  		 prog, sig, strsignal(sig),
  		 WCOREDUMP(status) ? ", core dumped" : "");
! 	  collect_exit (FATAL_EXIT_CODE, 0);
  	}
  
        if (WIFEXITED (status))
*************** do_wait (const char *prog, struct pex_ob
*** 1542,1548 ****
    if (ret != 0)
      {
        error ("%s returned %d exit status", prog, ret);
!       collect_exit (ret);
      }
  
    if (response_file)
--- 1554,1560 ----
    if (ret != 0)
      {
        error ("%s returned %d exit status", prog, ret);
!       collect_exit (ret, 0);
      }
  
    if (response_file)
Index: collect2.h
===================================================================
*** collect2.h	(revision 135576)
--- collect2.h	(working copy)
*************** extern void do_tlink (char **, char **);
*** 25,31 ****
  extern struct pex_obj *collect_execute (const char *, char **, const char *,
  					const char *);
  
! extern void collect_exit (int) ATTRIBUTE_NORETURN;
  
  extern int collect_wait (const char *, struct pex_obj *);
  
--- 25,31 ----
  extern struct pex_obj *collect_execute (const char *, char **, const char *,
  					const char *);
  
! extern void collect_exit (int, int) ATTRIBUTE_NORETURN;
  
  extern int collect_wait (const char *, struct pex_obj *);
  
Index: tlink.c
===================================================================
*** tlink.c	(revision 135576)
--- tlink.c	(working copy)
*************** do_tlink (char **ld_argv, char **object_
*** 799,804 ****
    if (exit)
      {
        error ("ld returned %d exit status", exit);
!       collect_exit (exit);
      }
  }
--- 799,804 ----
    if (exit)
      {
        error ("ld returned %d exit status", exit);
!       collect_exit (exit, 0);
      }
  }
Index: config/rs6000/aix.h
===================================================================
*** config/rs6000/aix.h	(revision 135576)
--- config/rs6000/aix.h	(working copy)
***************
*** 43,48 ****
--- 43,51 ----
     collect has a chance to see them, so scan the object files directly.  */
  #define COLLECT_EXPORT_LIST
  
+ /* The AIX linker preserves read-only executables.  */
+ #define COLLECT_PRESERVE_RO_OUTPUT
+ 
  /* Handle #pragma weak and #pragma pack.  */
  #define HANDLE_SYSV_PRAGMA 1
  

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Enhance collect2 to preserve ro outputs as the linker would
  2008-05-21 10:19 [PATCH] Enhance collect2 to preserve ro outputs as the linker would Olivier Hainque
@ 2008-05-21 23:06 ` Ian Lance Taylor
  2008-05-22 13:19   ` Olivier Hainque
  0 siblings, 1 reply; 9+ messages in thread
From: Ian Lance Taylor @ 2008-05-21 23:06 UTC (permalink / raw)
  To: Olivier Hainque; +Cc: gcc-patches

Olivier Hainque <hainque@adacore.com> writes:

> While some target linkers silently replace read-only output files,
> others report an error in such circumstances. For instance, on AIX
> with a dummy program in m.c:
>
>     $ gcc -c m.c
>     $ ld -o m m.o /lib/crt0.o -lc
>     $ chmod -w m
>     $ ld -o m m.o /lib/crt0.o -lc
>     ld: 0711-931 SEVERE ERROR: Output file: m
> 	    The file is write-protected.
>
> collect2 doesn't mimic this behavior and always replaces, which might
> cause suprises to some users. The attached patch is a suggestion to
> improve this situation, with two parts:
>
>     1/ Enhance collect2 so that it mimics the target linker's
>        behavior, as reflected by a new "COLLECT_PRESERVE_RO_OUTPUT"
>        target macro definition.
>
>     2/ Define the macro for ppc-aix.
>
> After which the behavior on this target is
>
>     $ gcc -o m m.c
>     $ chmod -w m
>     $ gcc -o m m.c
>     collect2: output file m exists and is read-only

I don't really like having this be target dependent.  I think that
instead you should change collect2 so that it only removes the output
file if it believes that it created the output file.  That is,
introduce some global variable which says whether to delete the output
file, and initialize it to false.  If tlink_execute succeeds, then set
the variable to true, so that the output file is deleted if collect2
fails.  If tlink_execute fails, don't have collect2 delete the output
file; let the invoked linker make the decision in that case.

Ian

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Enhance collect2 to preserve ro outputs as the linker would
  2008-05-21 23:06 ` Ian Lance Taylor
@ 2008-05-22 13:19   ` Olivier Hainque
  2008-05-22 16:28     ` Ian Lance Taylor
  0 siblings, 1 reply; 9+ messages in thread
From: Olivier Hainque @ 2008-05-22 13:19 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc-patches, hainque


Hello Ian,

First of all, thanks much for your feedback.

Ian Lance Taylor wrote:

> I think that instead you should change collect2 so that it only
> removes the output file if it believes that it created the output
> file.  That is, introduce some global variable which says whether to
> delete the output file, and initialize it to false.  If
> tlink_execute succeeds, then set the variable to true, so that the
> output file is deleted if collect2 fails.  If tlink_execute fails,
> don't have collect2 delete the output file; let the invoked linker
> make the decision in that case.
 
 I agree something along those lines this would be nicer (seems like
 an alternate path avoiding the global variable would be to retain the
 "keep_output" argument to collect_exit and pass 1 from the call in
 do_tlink only).

 It unfortunately doesn't quite work in the current state on AIX because
 we sometimes don't get to do_tlink/tlink_execute before

      main ()
      ...
      /* Sort ctor and dtor lists by priority.  */
      ...
      maybe_unlink(output_file);
 
 I ended up inserting a simple early guard to make sure there was
 no risk of overlooking other possible paths of this sort.

 We actually have another patch that would change this, and I
 think facilitate going to the approach you suggest.

 This other patch is what we are currently using to address the
 issue raised a while ago about collect2 dragging too many objects
 from archives

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

 We have been using this pretty successfully for a while to
 offer dwarf tables eh support for GNAT while retaining a static
 version of the runtime library.

 I'd certainly be happy to send it for discussion and possible
 integration first.

 Please let me know how you'd like me to proceed.

 Thanks again for your feedback,

 Olivier


 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Enhance collect2 to preserve ro outputs as the linker would
  2008-05-22 13:19   ` Olivier Hainque
@ 2008-05-22 16:28     ` Ian Lance Taylor
  2008-05-23 16:47       ` Olivier Hainque
  0 siblings, 1 reply; 9+ messages in thread
From: Ian Lance Taylor @ 2008-05-22 16:28 UTC (permalink / raw)
  To: Olivier Hainque; +Cc: gcc-patches

Olivier Hainque <hainque@adacore.com> writes:

>  We actually have another patch that would change this, and I
>  think facilitate going to the approach you suggest.
>
>  This other patch is what we are currently using to address the
>  issue raised a while ago about collect2 dragging too many objects
>  from archives
>
>    http://gcc.gnu.org/ml/gcc/2006-09/msg00483.html
>
>  We have been using this pretty successfully for a while to
>  offer dwarf tables eh support for GNAT while retaining a static
>  version of the runtime library.
>
>  I'd certainly be happy to send it for discussion and possible
>  integration first.

If you like that patch better, then, sure, send it in.  Thanks.

Ian

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Enhance collect2 to preserve ro outputs as the linker would
  2008-05-22 16:28     ` Ian Lance Taylor
@ 2008-05-23 16:47       ` Olivier Hainque
  2008-06-30 21:25         ` Ian Lance Taylor
  0 siblings, 1 reply; 9+ messages in thread
From: Olivier Hainque @ 2008-05-23 16:47 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc-patches, hainque

[-- Attachment #1: Type: text/plain, Size: 2841 bytes --]

Ian Lance Taylor wrote:
> If you like that patch better, then, sure, send it in.  Thanks.

 OK (thanks !), so before the read-only output issue, here is the bulk
 of our changes to support dwarf2 eh.

 This is more involved, was initially based on GCC 4.1 and has been
 minimally adjusted to bootstrap on mainline. No testing there yet,
 and maybe a bit rough (at least documentation-wise).

 I'd be happy to discuss the approach, modify as requested and
 perform the regular testing cycle when considered appropriate.

 The general idea is summarized in two comments in collect2.c:

  /* The AIX linker will discard static constructors in object files if
     nothing else in the file is referenced, so look at them first.  Skip
     frame tables when doing so, to prevent dragging every object with such
     tables that would not have been dragged otherwise.  This is a potentially
     large set of actually useless objects, de-facto making executables larger
     and possibly adding spurious dependencies to other libraries.  */
  ...
  /* We used not to tlink here on AIX because we have to do it later in any
     case and used to have scanned for static constructors and frame tables
     already.  We now skip frame tables during the static constructor scan,
     so now link here on AIX as well to allow a frame-tables-only scan below.

     We expect frame tables associated with needed functions to be included
     (not garbage collected) in the result of this link, which GCC achieves
     by forcing a reference to the tables from the functions' CSECTs. */

 We have a couple of other changes for proper eh runtime behavior but
 not related to the collect2 aspects (e.g. MD_UNWIND_SUPPORT).

 Thanks for your feedback,

 Olivier

	Enhancements to table based EH for Ada ZCX support:
	* collect2.c (scan_flags): New enum, with ORDINARY, SKIP_FRAME_TABLES
	and FRAME_TABLES_ONLY values to control the behavior of ...
	(scan_prog_file, proto): Add scan_flags argument.
	(main): Adjust sequence for AIX: prevent frame tables from being
	collected during the scan aimed at collecting the static constructors.
	Pre-link and scan for frame tables only later to compensate.
	(scan_prog_file, !coff): Accept scan_flags, without effect.
	(scan_libraries): Pass proper scan_flags in calls to scan_prog_file.
	(scan_prog_file, coff): Accept scan_flags and honor it.
	* dwarf2out.c (output_call_frame_info): Add support for new macro,
	DWARF2_EMIT_FRAME_TABLE_ASM_REF, to emit an asm statememt forcing a
	reference to the frame table label from the current function text
	section.
	* config/rs6000/aix.h (DWARF2_EMIT_FRAME_TABLE_ASM_REF): Define to ...
	* config/rs6000/rs6000-protos.h (rs6000_aix_emit_frame_table_asm_ref):
	New function - add prototype.
	* config/rs6000/rs6000.c (rs6000_aix_emit_frame_table_asm_ref):
	Implement.






[-- Attachment #2: dw2eh-aix.dif --]
[-- Type: text/plain, Size: 13959 bytes --]

Index: collect2.c
===================================================================
*** collect2.c	(revision 135576)
--- collect2.c	(working copy)
*************** static void write_c_file_stat (FILE *, c
*** 261,267 ****
  #ifndef LD_INIT_SWITCH
  static void write_c_file_glob (FILE *, const char *);
  #endif
! static void scan_prog_file (const char *, enum pass);
  #ifdef SCAN_LIBRARIES
  static void scan_libraries (const char *);
  #endif
--- 261,275 ----
  #ifndef LD_INIT_SWITCH
  static void write_c_file_glob (FILE *, const char *);
  #endif
! 
! enum scan_flags {
!   ORDINARY          = 0x0,
!   SKIP_FRAME_TABLES = 0x1,
!   FRAME_TABLES_ONLY = 0x2
! };
! 
! static void scan_prog_file (const char *, enum pass, enum scan_flags);
! 
  #ifdef SCAN_LIBRARIES
  static void scan_libraries (const char *);
  #endif
*************** main (int argc, char **argv)
*** 1251,1268 ****
      }
  
    /* The AIX linker will discard static constructors in object files if
!      nothing else in the file is referenced, so look at them first.  */
    {
        const char **export_object_lst = (const char **)object_lst;
  
        while (export_object_lst < object)
! 	scan_prog_file (*export_object_lst++, PASS_OBJ);
    }
    {
      struct id *list = libs.first;
  
      for (; list; list = list->next)
!       scan_prog_file (list->name, PASS_FIRST);
    }
  
    if (exports.first)
--- 1259,1280 ----
      }
  
    /* The AIX linker will discard static constructors in object files if
!      nothing else in the file is referenced, so look at them first.  Skip
!      frame tables when doing so, to prevent dragging every object with such
!      tables that would not have been dragged otherwise.  This is a potentially
!      large set of actually useless objects, de-facto making executables larger
!      and possibly adding spurious dependencies to other libraries.  */
    {
        const char **export_object_lst = (const char **)object_lst;
  
        while (export_object_lst < object)
! 	scan_prog_file (*export_object_lst++, PASS_OBJ, SKIP_FRAME_TABLES);
    }
    {
      struct id *list = libs.first;
  
      for (; list; list = list->next)
!       scan_prog_file (list->name, PASS_FIRST, SKIP_FRAME_TABLES);
    }
  
    if (exports.first)
*************** main (int argc, char **argv)
*** 1334,1344 ****
  
    /* Load the program, searching all libraries and attempting to provide
       undefined symbols from repository information.  */
- 
-   /* On AIX we do this later.  */
- #ifndef COLLECT_EXPORT_LIST
    do_tlink (ld1_argv, object_lst);
! #endif
  
    /* If -r or they will be run via some other method, do not build the
       constructor or destructor list, just return now.  */
--- 1346,1361 ----
  
    /* Load the program, searching all libraries and attempting to provide
       undefined symbols from repository information.  */
    do_tlink (ld1_argv, object_lst);
! 
!   /* We used not to tlink here on AIX because we have to do it later in any
!      case and used to have scanned for static constructors and frame tables
!      already.  We now skip frame tables during the static constructor scan,
!      so now link here on AIX as well to allow a frame-tables-only scan below.
! 
!      We expect frame tables associated with needed functions to be included
!      (not garbage collected) in the result of this link, which GCC achieves
!      by forcing a reference to the tables from the functions' CSECTs. */
  
    /* If -r or they will be run via some other method, do not build the
       constructor or destructor list, just return now.  */
*************** main (int argc, char **argv)
*** 1349,1358 ****
        )
      {
  #ifdef COLLECT_EXPORT_LIST
!       /* Do the link we avoided above if we are exiting.  */
!       do_tlink (ld1_argv, object_lst);
! 
!       /* But make sure we delete the export file we may have created.  */
        if (export_file != 0 && export_file[0])
  	maybe_unlink (export_file);
  #endif
--- 1366,1372 ----
        )
      {
  #ifdef COLLECT_EXPORT_LIST
!       /* Make sure we delete the export file we may have created.  */
        if (export_file != 0 && export_file[0])
  	maybe_unlink (export_file);
  #endif
*************** main (int argc, char **argv)
*** 1361,1374 ****
        return 0;
      }
  
!   /* Examine the namelist with nm and search it for static constructors
!      and destructors to call.
!      Write the constructor and destructor tables to a .s file and reload.  */
  
!   /* On AIX we already scanned for global constructors/destructors.  */
! #ifndef COLLECT_EXPORT_LIST
!   scan_prog_file (output_file, PASS_FIRST);
  #endif
  
  #ifdef SCAN_LIBRARIES
    scan_libraries (output_file);
--- 1375,1392 ----
        return 0;
      }
  
!   /* Examine the namelist with nm and search it for static constructors and
!      destructors to call. Write the constructor and destructor tables to a .s
!      file and reload.  On AIX we already scanned for global c/dtors and now
!      need to scan for frame tables.  */
!   {
!     enum scan_flags flags = ORDINARY;
  
! #ifdef COLLECT_EXPORT_LIST
!     flags |= FRAME_TABLES_ONLY;
  #endif
+     scan_prog_file (output_file, PASS_FIRST, flags);
+   }
  
  #ifdef SCAN_LIBRARIES
    scan_libraries (output_file);
*************** main (int argc, char **argv)
*** 1391,1400 ****
  #endif
        )
      {
- #ifdef COLLECT_EXPORT_LIST
-       /* Do tlink without additional code generation.  */
-       do_tlink (ld1_argv, object_lst);
- #endif
        /* Strip now if it was requested on the command line.  */
        if (strip_flag)
  	{
--- 1409,1414 ----
*************** main (int argc, char **argv)
*** 1485,1491 ****
  
    fork_execute ("gcc",  c_argv);
  #ifdef COLLECT_EXPORT_LIST
!   /* On AIX we must call tlink because of possible templates resolution.  */
    do_tlink (ld2_argv, object_lst);
  #else
    /* Otherwise, simply call ld because tlink is already done.  */
--- 1499,1507 ----
  
    fork_execute ("gcc",  c_argv);
  #ifdef COLLECT_EXPORT_LIST
!   /* On AIX we must call tlink because of possible templates resolution.
!      ??? We have already called it once to allow a frame tables scan.  Do
!      we really need it again here ?  */
    do_tlink (ld2_argv, object_lst);
  #else
    /* Otherwise, simply call ld because tlink is already done.  */
*************** main (int argc, char **argv)
*** 1493,1499 ****
  
    /* Let scan_prog_file do any final mods (OSF/rose needs this for
       constructors/destructors in shared libraries.  */
!   scan_prog_file (output_file, PASS_SECOND);
  #endif
  
    maybe_unlink (c_file);
--- 1509,1515 ----
  
    /* Let scan_prog_file do any final mods (OSF/rose needs this for
       constructors/destructors in shared libraries.  */
!   scan_prog_file (output_file, PASS_SECOND, ORDINARY);
  #endif
  
    maybe_unlink (c_file);
*************** write_aix_file (FILE *stream, struct id 
*** 2075,2081 ****
     destructor table has the same format, and begins at __DTOR_LIST__.  */
  
  static void
! scan_prog_file (const char *prog_name, enum pass which_pass)
  {
    void (*int_handler) (int);
  #ifdef SIGQUIT
--- 2091,2098 ----
     destructor table has the same format, and begins at __DTOR_LIST__.  */
  
  static void
! scan_prog_file (const char *prog_name, enum pass which_pass,
! 		enum scan_flags flags ATTRIBUTE_UNUSED)
  {
    void (*int_handler) (int);
  #ifdef SIGQUIT
*************** scan_libraries (const char *prog_name)
*** 2345,2351 ****
    /* Now iterate through the library list adding their symbols to
       the list.  */
    for (list = libraries.first; list; list = list->next)
!     scan_prog_file (list->name, PASS_LIB);
  }
  
  #endif /* LDD_SUFFIX */
--- 2362,2368 ----
    /* Now iterate through the library list adding their symbols to
       the list.  */
    for (list = libraries.first; list; list = list->next)
!     scan_prog_file (list->name, PASS_LIB, ORDINARY);
  }
  
  #endif /* LDD_SUFFIX */
*************** extern char *ldgetname (LDFILE *, GCC_SY
*** 2456,2462 ****
     destructor table has the same format, and begins at __DTOR_LIST__.  */
  
  static void
! scan_prog_file (const char *prog_name, enum pass which_pass)
  {
    LDFILE *ldptr = NULL;
    int sym_index, sym_count;
--- 2473,2480 ----
     destructor table has the same format, and begins at __DTOR_LIST__.  */
  
  static void
! scan_prog_file (const char *prog_name, enum pass which_pass,
! 		enum scan_flags flags)
  {
    LDFILE *ldptr = NULL;
    int sym_index, sym_count;
*************** scan_prog_file (const char *prog_name, e
*** 2520,2525 ****
--- 2538,2546 ----
  		      switch (is_ctor_dtor (name))
  			{
  			case 1:
+ 			  if (flags & FRAME_TABLES_ONLY)
+ 			    break;
+ 
  			  if (! is_shared)
  			    add_to_list (&constructors, name);
  #if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
*************** scan_prog_file (const char *prog_name, e
*** 2529,2534 ****
--- 2550,2558 ----
  			  break;
  
  			case 2:
+ 			  if (flags & FRAME_TABLES_ONLY)
+ 			    break;
+ 
  			  if (! is_shared)
  			    add_to_list (&destructors, name);
  #if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
*************** scan_prog_file (const char *prog_name, e
*** 2539,2544 ****
--- 2563,2571 ----
  
  #ifdef COLLECT_EXPORT_LIST
  			case 3:
+ 			  if (flags & FRAME_TABLES_ONLY)
+ 			    break;
+ 
  #ifndef LD_INIT_SWITCH
  			  if (is_shared)
  			    add_to_list (&constructors, name);
*************** scan_prog_file (const char *prog_name, e
*** 2546,2551 ****
--- 2573,2581 ----
  			  break;
  
  			case 4:
+ 			  if (flags & FRAME_TABLES_ONLY)
+ 			    break;
+ 
  #ifndef LD_INIT_SWITCH
  			  if (is_shared)
  			    add_to_list (&destructors, name);
*************** scan_prog_file (const char *prog_name, e
*** 2554,2559 ****
--- 2584,2592 ----
  #endif
  
  			case 5:
+ 			  if (flags & SKIP_FRAME_TABLES)
+ 			    break;
+ 
  			  if (! is_shared)
  			    add_to_list (&frame_tables, name);
  #if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
*************** scan_prog_file (const char *prog_name, e
*** 2563,2568 ****
--- 2596,2603 ----
  			  break;
  
  			default:	/* not a constructor or destructor */
+ 			  if (flags & FRAME_TABLES_ONLY)
+ 			    break;
  #ifdef COLLECT_EXPORT_LIST
  			  /* Explicitly export all global symbols when
  			     building a shared object on AIX, but do not
*************** scan_prog_file (const char *prog_name, e
*** 2578,2587 ****
  
  		      if (debug)
  #if !defined(EXTENDED_COFF)
! 			fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
! 				 symbol.n_scnum, symbol.n_sclass,
  				 (symbol.n_type ? "0" : ""), symbol.n_type,
! 				 name);
  #else
  			fprintf (stderr,
  				 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
--- 2613,2625 ----
  
  		      if (debug)
  #if !defined(EXTENDED_COFF)
! 			fprintf (stderr, "%s\nsec=%d class=%d type=%s%o %-80s"
! 				 "skip_tables=%d tables_only=%d\n",
! 				 prog_name, symbol.n_scnum, symbol.n_sclass,
  				 (symbol.n_type ? "0" : ""), symbol.n_type,
! 				 name,
! 				 flags & SKIP_FRAME_TABLES,
! 				 flags & FRAME_TABLES_ONLY);
  #else
  			fprintf (stderr,
  				 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
Index: dwarf2out.c
===================================================================
*** dwarf2out.c	(revision 135576)
--- dwarf2out.c	(working copy)
*************** output_call_frame_info (int for_eh)
*** 2586,2591 ****
--- 2586,2596 ----
    ASM_OUTPUT_ALIGN (asm_out_file, 0);
  #endif
  
+ #ifdef DWARF2_EMIT_FRAME_TABLE_ASM_REF
+   switch_to_section (current_function_section ());
+   DWARF2_EMIT_FRAME_TABLE_ASM_REF (section_start_label);
+ #endif
+ 
    /* Turn off app to make assembly quicker.  */
    if (flag_debug_asm)
      app_disable ();
Index: config/rs6000/aix.h
===================================================================
*** config/rs6000/aix.h	(revision 135576)
--- config/rs6000/aix.h	(working copy)
***************
*** 43,48 ****
--- 43,54 ----
     collect has a chance to see them, so scan the object files directly.  */
  #define COLLECT_EXPORT_LIST
  
+ /* Emit an asm statememt forcing a reference to FRAME_TABLE_LABEL from the
+    current function text section.  This is defined to ensure we drag frame
+    frame tables associated with needed function bodies in a link with garbage
+    collection activated.  */
+ #define DWARF2_EMIT_FRAME_TABLE_ASM_REF rs6000_aix_emit_frame_table_asm_ref
+ 
  /* Handle #pragma weak and #pragma pack.  */
  #define HANDLE_SYSV_PRAGMA 1
  
Index: config/rs6000/rs6000-protos.h
===================================================================
*** config/rs6000/rs6000-protos.h	(revision 135576)
--- config/rs6000/rs6000-protos.h	(working copy)
*************** extern bool rs6000_tls_referenced_p (rtx
*** 169,174 ****
--- 169,176 ----
  extern int rs6000_hard_regno_nregs (int, enum machine_mode);
  extern void rs6000_conditional_register_usage (void);
  
+ extern void rs6000_aix_emit_frame_table_asm_ref (char * frame_table_label);
+ 
  /* Declare functions in rs6000-c.c */
  
  extern void rs6000_pragma_longcall (struct cpp_reader *);
Index: config/rs6000/rs6000.c
===================================================================
*** config/rs6000/rs6000.c	(revision 135576)
--- config/rs6000/rs6000.c	(working copy)
*************** create_TOC_reference (rtx symbol)
*** 15197,15202 ****
--- 15197,15211 ----
  		 gen_rtx_SYMBOL_REF (Pmode, toc_label_name))));
  }
  
+ /* Emit an asm statememt forcing a reference to FRAME_TABLE_LABEL from the
+    current function text section.  */
+ void
+ rs6000_aix_emit_frame_table_asm_ref (char * frame_table_label)
+ {
+   fprintf (asm_out_file, "\t.ref %s\n",
+ 	   TARGET_STRIP_NAME_ENCODING (frame_table_label));
+ }
+ 
  /* If _Unwind_* has been called from within the same module,
     toc register is not guaranteed to be saved to 40(1) on function
     entry.  Save it there in that case.  */

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Enhance collect2 to preserve ro outputs as the linker would
  2008-05-23 16:47       ` Olivier Hainque
@ 2008-06-30 21:25         ` Ian Lance Taylor
  2008-07-01 10:21           ` Olivier Hainque
  0 siblings, 1 reply; 9+ messages in thread
From: Ian Lance Taylor @ 2008-06-30 21:25 UTC (permalink / raw)
  To: Olivier Hainque; +Cc: gcc-patches

Olivier Hainque <hainque@adacore.com> writes:

> 	Enhancements to table based EH for Ada ZCX support:
> 	* collect2.c (scan_flags): New enum, with ORDINARY, SKIP_FRAME_TABLES
> 	and FRAME_TABLES_ONLY values to control the behavior of ...
> 	(scan_prog_file, proto): Add scan_flags argument.
> 	(main): Adjust sequence for AIX: prevent frame tables from being
> 	collected during the scan aimed at collecting the static constructors.
> 	Pre-link and scan for frame tables only later to compensate.
> 	(scan_prog_file, !coff): Accept scan_flags, without effect.
> 	(scan_libraries): Pass proper scan_flags in calls to scan_prog_file.
> 	(scan_prog_file, coff): Accept scan_flags and honor it.
> 	* dwarf2out.c (output_call_frame_info): Add support for new macro,
> 	DWARF2_EMIT_FRAME_TABLE_ASM_REF, to emit an asm statememt forcing a
> 	reference to the frame table label from the current function text
> 	section.
> 	* config/rs6000/aix.h (DWARF2_EMIT_FRAME_TABLE_ASM_REF): Define to ...
> 	* config/rs6000/rs6000-protos.h (rs6000_aix_emit_frame_table_asm_ref):
> 	New function - add prototype.
> 	* config/rs6000/rs6000.c (rs6000_aix_emit_frame_table_asm_ref):
> 	Implement.

This is OK if it passes bootstrap and testing on AIX and on some
non-AIX platform.

Also you need to add documentation for DWARF2_EMIT_FRAME_TABLE_ASM_REF
to doc/tm.texi.

Thanks.

Ian

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Enhance collect2 to preserve ro outputs as the linker would
  2008-06-30 21:25         ` Ian Lance Taylor
@ 2008-07-01 10:21           ` Olivier Hainque
  2008-07-09 10:08             ` [PATCH] collect2 vs table-based eh on aix Olivier Hainque
  0 siblings, 1 reply; 9+ messages in thread
From: Olivier Hainque @ 2008-07-01 10:21 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc-patches, hainque

Ian Lance Taylor wrote:
> > 	Enhancements to table based EH:
> > 	* collect2.c (scan_flags): New enum,
[...]
> This is OK if it passes bootstrap and testing on AIX and on some
> non-AIX platform.

 Great :)

> Also you need to add documentation for DWARF2_EMIT_FRAME_TABLE_ASM_REF
> to doc/tm.texi.

 Sure. Adjustments and testing on the way.

 Thanks much for your review.

 Olivier

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] collect2 vs table-based eh on aix
  2008-07-01 10:21           ` Olivier Hainque
@ 2008-07-09 10:08             ` Olivier Hainque
  2008-07-18 11:12               ` Olivier Hainque
  0 siblings, 1 reply; 9+ messages in thread
From: Olivier Hainque @ 2008-07-09 10:08 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc-patches, hainque

[Enhancements to collect2 for table based EH on AIX]

> Adjustments and testing on the way.

 Ouch, this breaks the shared_obj case, which has its own set of
 intricate path variants :-/

 Olivier



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] collect2 vs table-based eh on aix
  2008-07-09 10:08             ` [PATCH] collect2 vs table-based eh on aix Olivier Hainque
@ 2008-07-18 11:12               ` Olivier Hainque
  0 siblings, 0 replies; 9+ messages in thread
From: Olivier Hainque @ 2008-07-18 11:12 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc-patches, hainque


Short status note ...

Olivier Hainque wrote:
> > Adjustments and testing on the way.
> 
>  Ouch, this breaks the shared_obj case, which has its own set of
>  intricate path variants :-/

 I have an improved version which addresses this issue and is
 cleaner overall. Testing revealed another kind of problem, on the
 compiler side of things with -ffunction-sections:

 << #ifdef DWARF2_EMIT_FRAME_TABLE_ASM_REF
      switch_to_section (current_function_section ());
      DWARF2_EMIT_FRAME_TABLE_ASM_REF (section_start_label);
 >>

 the switch gets us back to ".text" and not to the function specific
 csect, so the link attempt is inoperative.


 


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2008-07-18  9:28 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-05-21 10:19 [PATCH] Enhance collect2 to preserve ro outputs as the linker would Olivier Hainque
2008-05-21 23:06 ` Ian Lance Taylor
2008-05-22 13:19   ` Olivier Hainque
2008-05-22 16:28     ` Ian Lance Taylor
2008-05-23 16:47       ` Olivier Hainque
2008-06-30 21:25         ` Ian Lance Taylor
2008-07-01 10:21           ` Olivier Hainque
2008-07-09 10:08             ` [PATCH] collect2 vs table-based eh on aix Olivier Hainque
2008-07-18 11:12               ` Olivier Hainque

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).