From 2b98e22bd8af0c0d0b0e02720a508dcea3672658 Mon Sep 17 00:00:00 2001 From: hainque Date: Fri, 4 May 2012 08:05:52 +0000 Subject: [PATCH] * collect2.c (may_unlink_output_file): New global. (maybe_unlink): Honor it. * collect2.h: Add extern for it. * tlink.c (do_tlink): Set it to true if the link succeeded. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@187148 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 +++++++ gcc/collect2.c | 23 ++++++++++++++++++----- gcc/collect2.h | 1 + gcc/tlink.c | 6 ++++++ 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7496a50..da6dede 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 2012-05-04 Olivier Hainque + * collect2.c (may_unlink_output_file): New global. + (maybe_unlink): Honor it. + * collect2.h: Add extern for it. + * tlink.c (do_tlink): Set it to true if the link succeeded. + +2012-05-04 Olivier Hainque + * gcc.c (eval_spec_function): Finalize/restore the current string obstack state as part of the context push/pop operations. diff --git a/gcc/collect2.c b/gcc/collect2.c index a52e95a..d0166a5 100644 --- a/gcc/collect2.c +++ b/gcc/collect2.c @@ -237,6 +237,12 @@ static const char *target_system_root = TARGET_SYSTEM_ROOT; static const char *target_system_root = ""; #endif +/* Whether we may unlink the output file, which should be set as soon as we + know we have successfully produced it. This is typically useful to prevent + blindly attempting to unlink a read-only output that the target linker + would leave untouched. */ +bool may_unlink_output_file = false; + /* Structure to hold all the directories in which to search for files to execute. */ @@ -2095,15 +2101,22 @@ fork_execute (const char *prog, char **argv) do_wait (prog, pex); } -/* Unlink a file unless we are debugging. */ +/* Unlink FILE unless we are debugging or this is the output_file + and we may not unlink it. */ static void maybe_unlink (const char *file) { - if (!debug) - unlink_if_ordinary (file); - else - notice ("[Leaving %s]\n", file); + if (debug) + { + notice ("[Leaving %s]\n", file); + return; + } + + if (file == output_file && !may_unlink_output_file) + return; + + unlink_if_ordinary (file); } /* Call maybe_unlink on the NULL-terminated list, FILE_LIST. */ diff --git a/gcc/collect2.h b/gcc/collect2.h index e18892d..d55198d 100644 --- a/gcc/collect2.h +++ b/gcc/collect2.h @@ -40,6 +40,7 @@ extern const char *c_file_name; extern struct obstack temporary_obstack; extern char *temporary_firstobj; extern bool vflag, debug; +extern bool may_unlink_output_file; extern void notice_translated (const char *, ...) ATTRIBUTE_PRINTF_1; extern void notice (const char *, ...) ATTRIBUTE_PRINTF_1; diff --git a/gcc/tlink.c b/gcc/tlink.c index 67c7086..c4c6afc 100644 --- a/gcc/tlink.c +++ b/gcc/tlink.c @@ -859,4 +859,10 @@ do_tlink (char **ld_argv, char **object_lst ATTRIBUTE_UNUSED) error ("ld returned %d exit status", exit); collect_exit (exit); } + else + { + /* We have just successfully produced an output file, so assume that we + may unlink it if need be for now on. */ + may_unlink_output_file = true; + } } -- 2.7.4