aboutsummaryrefslogtreecommitdiff
path: root/gcc/collect2.c
diff options
context:
space:
mode:
authorIain Sandoe <iain@sandoe.co.uk>2018-12-23 10:43:59 +0000
committerIain Sandoe <iains@gcc.gnu.org>2018-12-23 10:43:59 +0000
commit4098a6d4368119ad098028bf0888e17a16b9f022 (patch)
treeffa042a1864822a16b8307e99a6930b3ff94855f /gcc/collect2.c
parent513825f06b561ceb7040f04fbf138a9e9c23a813 (diff)
downloadgcc-4098a6d4368119ad098028bf0888e17a16b9f022.zip
gcc-4098a6d4368119ad098028bf0888e17a16b9f022.tar.gz
gcc-4098a6d4368119ad098028bf0888e17a16b9f022.tar.bz2
use simple-object instead of nm to determine if files contain LTO.
This replaces the use of nm to search for the LTO common symbol marker and uses simple object to see if there's a section starting with ".gnu.lto_." or ".gnu.offload_lto_" 2018-12-23 Iain Sandoe <iain@sandoe.co.uk> * collect2.c (maybe_run_lto_and_relink): Don’t say we have a temp file unless we actually did some LTO. (has_lto_section, is_lto_object_file): New. (maybe_lto_object_file): Remove. (scan_prog_file): Use is_lto_object_file() instead of scanning the output of nm. From-SVN: r267371
Diffstat (limited to 'gcc/collect2.c')
-rw-r--r--gcc/collect2.c120
1 files changed, 57 insertions, 63 deletions
diff --git a/gcc/collect2.c b/gcc/collect2.c
index 6026968..dcbd3e1 100644
--- a/gcc/collect2.c
+++ b/gcc/collect2.c
@@ -30,6 +30,8 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "filenames.h"
#include "file-find.h"
+#include "simple-object.h"
+#include "lto-section-names.h"
/* TARGET_64BIT may be defined to use driver specific functionality. */
#undef TARGET_64BIT
@@ -804,7 +806,9 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
/* Run the linker again, this time replacing the object files
optimized by the LTO with the temporary file generated by the LTO. */
fork_execute ("ld", out_lto_ld_argv, HAVE_GNU_LD && at_file_supplied);
- post_ld_pass (true);
+ /* We assume that temp files were created, and therefore we need to take
+ that into account (maybe run dsymutil). */
+ post_ld_pass (/*temp_file*/true);
free (lto_ld_argv);
maybe_unlink_list (lto_o_files);
@@ -814,10 +818,11 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
/* Our caller is relying on us to do the link
even though there is no LTO back end work to be done. */
fork_execute ("ld", lto_ld_argv, HAVE_GNU_LD && at_file_supplied);
- post_ld_pass (false);
+ /* No LTO objects were found, so no new temp file. */
+ post_ld_pass (/*temp_file*/false);
}
else
- post_ld_pass (true);
+ post_ld_pass (false); /* No LTO objects were found, no temp file. */
}
/* Main program. */
@@ -1710,7 +1715,7 @@ main (int argc, char **argv)
if (lto_mode != LTO_MODE_NONE)
maybe_run_lto_and_relink (ld1_argv, object_lst, object, false);
else
- post_ld_pass (false);
+ post_ld_pass (/*temp_file*/false);
return 0;
}
@@ -1780,7 +1785,7 @@ main (int argc, char **argv)
#ifdef COLLECT_EXPORT_LIST
maybe_unlink (export_file);
#endif
- post_ld_pass (false);
+ post_ld_pass (/*temp_file*/false);
maybe_unlink (c_file);
maybe_unlink (o_file);
@@ -1874,7 +1879,7 @@ main (int argc, char **argv)
else
{
fork_execute ("ld", ld2_argv, HAVE_GNU_LD && at_file_supplied);
- post_ld_pass (false);
+ post_ld_pass (/*temp_file*/false);
}
/* Let scan_prog_file do any final mods (OSF/rose needs this for
@@ -2332,38 +2337,52 @@ write_aix_file (FILE *stream, struct id *list)
/* Check to make sure the file is an LTO object file. */
+static int
+has_lto_section (void *data, const char *name ATTRIBUTE_UNUSED,
+ off_t offset ATTRIBUTE_UNUSED,
+ off_t length ATTRIBUTE_UNUSED)
+{
+ int *found = (int *) data;
+
+ if (strncmp (name, LTO_SECTION_NAME_PREFIX,
+ sizeof (LTO_SECTION_NAME_PREFIX) - 1) != 0)
+ {
+ if (strncmp (name, OFFLOAD_SECTION_NAME_PREFIX,
+ sizeof (OFFLOAD_SECTION_NAME_PREFIX) - 1) != 0)
+ return 1;
+ }
+
+ *found = 1;
+
+ /* Stop iteration. */
+ return 0;
+}
+
static bool
-maybe_lto_object_file (const char *prog_name)
+is_lto_object_file (const char *prog_name)
{
- FILE *f;
- unsigned char buf[4];
- int i;
+ const char *errmsg;
+ int err;
+ int found = 0;
+ off_t inoff = 0;
+ int infd = open (prog_name, O_RDONLY | O_BINARY);
- static unsigned char elfmagic[4] = { 0x7f, 'E', 'L', 'F' };
- static unsigned char coffmagic[2] = { 0x4c, 0x01 };
- static unsigned char coffmagic_x64[2] = { 0x64, 0x86 };
- static unsigned char machomagic[4][4] = {
- { 0xcf, 0xfa, 0xed, 0xfe },
- { 0xce, 0xfa, 0xed, 0xfe },
- { 0xfe, 0xed, 0xfa, 0xcf },
- { 0xfe, 0xed, 0xfa, 0xce }
- };
+ if (infd == -1)
+ return false;
- f = fopen (prog_name, "rb");
- if (f == NULL)
+ simple_object_read *inobj = simple_object_start_read (infd, inoff,
+ LTO_SEGMENT_NAME,
+ &errmsg, &err);
+ if (!inobj)
return false;
- if (fread (buf, sizeof (buf), 1, f) != 1)
- buf[0] = 0;
- fclose (f);
- if (memcmp (buf, elfmagic, sizeof (elfmagic)) == 0
- || memcmp (buf, coffmagic, sizeof (coffmagic)) == 0
- || memcmp (buf, coffmagic_x64, sizeof (coffmagic_x64)) == 0)
+ errmsg = simple_object_find_sections (inobj, has_lto_section,
+ (void *) &found, &err);
+ if (! errmsg && found)
return true;
- for (i = 0; i < 4; i++)
- if (memcmp (buf, machomagic[i], sizeof (machomagic[i])) == 0)
- return true;
+ if (errmsg)
+ fatal_error (0, "%s: %s\n", errmsg, xstrerror (err));
return false;
}
@@ -2386,7 +2405,6 @@ scan_prog_file (const char *prog_name, scanpass which_pass,
int err;
char *p, buf[1024];
FILE *inf;
- int found_lto = 0;
if (which_pass == PASS_SECOND)
return;
@@ -2394,8 +2412,13 @@ scan_prog_file (const char *prog_name, scanpass which_pass,
/* LTO objects must be in a known format. This check prevents
us from accepting an archive containing LTO objects, which
gcc cannot currently handle. */
- if (which_pass == PASS_LTOINFO && !maybe_lto_object_file (prog_name))
- return;
+ if (which_pass == PASS_LTOINFO)
+ {
+ if(is_lto_object_file (prog_name)) {
+ add_lto_object (&lto_objects, prog_name);
+ }
+ return;
+ }
/* If we do not have an `nm', complain. */
if (nm_file_name == 0)
@@ -2450,12 +2473,7 @@ scan_prog_file (const char *prog_name, scanpass which_pass,
fatal_error (input_location, "can't open nm output: %m");
if (debug)
- {
- if (which_pass == PASS_LTOINFO)
- fprintf (stderr, "\nnm output with LTO info marker symbol.\n");
- else
- fprintf (stderr, "\nnm output with constructors/destructors.\n");
- }
+ fprintf (stderr, "\nnm output with constructors/destructors.\n");
/* Read each line of nm output. */
while (fgets (buf, sizeof buf, inf) != (char *) 0)
@@ -2466,30 +2484,6 @@ scan_prog_file (const char *prog_name, scanpass which_pass,
if (debug)
fprintf (stderr, "\t%s\n", buf);
- if (which_pass == PASS_LTOINFO)
- {
- if (found_lto)
- continue;
-
- /* Look for the LTO info marker symbol, and add filename to
- the LTO objects list if found. */
- for (p = buf; (ch = *p) != '\0' && ch != '\n'; p++)
- if (ch == ' ' && p[1] == '_' && p[2] == '_'
- && (strncmp (p + (p[3] == '_' ? 2 : 1), "__gnu_lto_v1", 12) == 0)
- && ISSPACE (p[p[3] == '_' ? 14 : 13]))
- {
- add_lto_object (&lto_objects, prog_name);
-
- /* We need to read all the input, so we can't just
- return here. But we can avoid useless work. */
- found_lto = 1;
-
- break;
- }
-
- continue;
- }
-
/* If it contains a constructor or destructor name, add the name
to the appropriate list unless this is a kind of symbol we're
not supposed to even consider. */