aboutsummaryrefslogtreecommitdiff
path: root/libiberty
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2018-08-23 10:21:21 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2018-08-23 10:21:21 +0000
commit832c74d935917263bb7f9852230bb39fd47584cc (patch)
treebedb8d11024b94f9e213dd63f64b4b7bafcb7ca5 /libiberty
parentebdb6f237772df251378d2c08350d345135bcb9e (diff)
downloadgcc-832c74d935917263bb7f9852230bb39fd47584cc.zip
gcc-832c74d935917263bb7f9852230bb39fd47584cc.tar.gz
gcc-832c74d935917263bb7f9852230bb39fd47584cc.tar.bz2
[libiberty patch] Fix PGO bootstrap
https://gcc.gnu.org/ml/gcc-patches/2018-08/msg01386.html PR driver/87056 * pex-unix.c (pex_unix_exec_child): Duplicate bad_fn into local scopes to avoid potential clobber. Co-Authored-By: Martin Liska <mliska@suse.cz> From-SVN: r263807
Diffstat (limited to 'libiberty')
-rw-r--r--libiberty/ChangeLog7
-rw-r--r--libiberty/pex-unix.c163
2 files changed, 90 insertions, 80 deletions
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index 22d995f..ed07acf 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,10 @@
+2018-08-23 Nathan Sidwell <nathan@acm.org>
+ Martin Liska <mliska@suse.cz>
+
+ PR driver/87056
+ * pex-unix.c (pex_unix_exec_child): Duplicate bad_fn into local
+ scopes to avoid potential clobber.
+
2018-08-20 Nathan Sidwell <nathan@acm.org>
* pex-unix.c (pex_child_error): Delete.
diff --git a/libiberty/pex-unix.c b/libiberty/pex-unix.c
index ea5ee4c..703010b 100644
--- a/libiberty/pex-unix.c
+++ b/libiberty/pex-unix.c
@@ -582,8 +582,6 @@ pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable,
issues. */
char **save_environ = environ;
- const char *bad_fn = NULL;
-
for (retries = 0; retries < 4; ++retries)
{
pid = vfork ();
@@ -602,62 +600,64 @@ pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable,
case 0:
/* Child process. */
- if (!bad_fn && in != STDIN_FILE_NO)
- {
- if (dup2 (in, STDIN_FILE_NO) < 0)
- bad_fn = "dup2";
- else if (close (in) < 0)
- bad_fn = "close";
- }
- if (!bad_fn && out != STDOUT_FILE_NO)
- {
- if (dup2 (out, STDOUT_FILE_NO) < 0)
- bad_fn = "dup2";
- else if (close (out) < 0)
- bad_fn = "close";
- }
- if (!bad_fn && errdes != STDERR_FILE_NO)
- {
- if (dup2 (errdes, STDERR_FILE_NO) < 0)
- bad_fn = "dup2";
- else if (close (errdes) < 0)
- bad_fn = "close";
- }
- if (!bad_fn && toclose >= 0)
- {
- if (close (toclose) < 0)
- bad_fn = "close";
- }
- if (!bad_fn && (flags & PEX_STDERR_TO_STDOUT) != 0)
- {
- if (dup2 (STDOUT_FILE_NO, STDERR_FILE_NO) < 0)
- bad_fn = "dup2";
- }
- if (!bad_fn)
- {
- if (env)
- /* NOTE: In a standard vfork implementation this clobbers
- the parent's copy of environ "too" (in reality there's
- only one copy). This is ok as we restore it below. */
- environ = (char**) env;
- if ((flags & PEX_SEARCH) != 0)
- {
- execvp (executable, to_ptr32 (argv));
- bad_fn = "execvp";
- }
- else
- {
- execv (executable, to_ptr32 (argv));
- bad_fn = "execv";
- }
- }
-
- /* Something failed, report an error. We don't use stdio
- routines, because we might be here due to a vfork call. */
{
+ const char *bad_fn = NULL;
+
+ if (!bad_fn && in != STDIN_FILE_NO)
+ {
+ if (dup2 (in, STDIN_FILE_NO) < 0)
+ bad_fn = "dup2";
+ else if (close (in) < 0)
+ bad_fn = "close";
+ }
+ if (!bad_fn && out != STDOUT_FILE_NO)
+ {
+ if (dup2 (out, STDOUT_FILE_NO) < 0)
+ bad_fn = "dup2";
+ else if (close (out) < 0)
+ bad_fn = "close";
+ }
+ if (!bad_fn && errdes != STDERR_FILE_NO)
+ {
+ if (dup2 (errdes, STDERR_FILE_NO) < 0)
+ bad_fn = "dup2";
+ else if (close (errdes) < 0)
+ bad_fn = "close";
+ }
+ if (!bad_fn && toclose >= 0)
+ {
+ if (close (toclose) < 0)
+ bad_fn = "close";
+ }
+ if (!bad_fn && (flags & PEX_STDERR_TO_STDOUT) != 0)
+ {
+ if (dup2 (STDOUT_FILE_NO, STDERR_FILE_NO) < 0)
+ bad_fn = "dup2";
+ }
+ if (!bad_fn)
+ {
+ if (env)
+ /* NOTE: In a standard vfork implementation this clobbers
+ the parent's copy of environ "too" (in reality there's
+ only one copy). This is ok as we restore it below. */
+ environ = (char**) env;
+ if ((flags & PEX_SEARCH) != 0)
+ {
+ execvp (executable, to_ptr32 (argv));
+ bad_fn = "execvp";
+ }
+ else
+ {
+ execv (executable, to_ptr32 (argv));
+ bad_fn = "execv";
+ }
+ }
+
+ /* Something failed, report an error. We don't use stdio
+ routines, because we might be here due to a vfork call. */
ssize_t retval = 0;
- int err = errno;
-
+ int eno = errno;
+
#define writeerr(s) (retval |= write (STDERR_FILE_NO, s, strlen (s)))
writeerr (obj->pname);
writeerr (": error trying to exec '");
@@ -665,7 +665,7 @@ pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable,
writeerr ("': ");
writeerr (bad_fn);
writeerr (": ");
- writeerr (xstrerror (err));
+ writeerr (xstrerror (eno));
writeerr ("\n");
#undef writeerr
@@ -677,30 +677,33 @@ pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable,
default:
/* Parent process. */
+ {
+ const char *bad_fn = NULL;
+
+ /* Restore environ. Note that the parent either doesn't run
+ until the child execs/exits (standard vfork behaviour), or
+ if it does run then vfork is behaving more like fork. In
+ either case we needn't worry about clobbering the child's
+ copy of environ. */
+ environ = save_environ;
+
+ if (!bad_fn && in != STDIN_FILE_NO)
+ if (close (in) < 0)
+ bad_fn = "close";
+ if (!bad_fn && out != STDOUT_FILE_NO)
+ if (close (out) < 0)
+ bad_fn = "close";
+ if (!bad_fn && errdes != STDERR_FILE_NO)
+ if (close (errdes) < 0)
+ bad_fn = "close";
- /* Restore environ.
- Note that the parent either doesn't run until the child execs/exits
- (standard vfork behaviour), or if it does run then vfork is behaving
- more like fork. In either case we needn't worry about clobbering
- the child's copy of environ. */
- environ = save_environ;
-
- if (!bad_fn && in != STDIN_FILE_NO)
- if (close (in) < 0)
- bad_fn = "close";
- if (!bad_fn && out != STDOUT_FILE_NO)
- if (close (out) < 0)
- bad_fn = "close";
- if (!bad_fn && errdes != STDERR_FILE_NO)
- if (close (errdes) < 0)
- bad_fn = "close";
-
- if (bad_fn)
- {
- *err = errno;
- *errmsg = bad_fn;
- return (pid_t) -1;
- }
+ if (bad_fn)
+ {
+ *err = errno;
+ *errmsg = bad_fn;
+ return (pid_t) -1;
+ }
+ }
return pid;
}