* [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).