#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
/* 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);
/* 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. */
}
\f
/* Main program. */
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;
}
#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);
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
/* 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;
}
int err;
char *p, buf[1024];
FILE *inf;
- int found_lto = 0;
if (which_pass == PASS_SECOND)
return;
/* 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 (<o_objects, prog_name);
+ }
+ return;
+ }
/* If we do not have an `nm', complain. */
if (nm_file_name == 0)
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)
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 (<o_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. */