aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/darwin.c
diff options
context:
space:
mode:
authorSteven Bosscher <steven@gcc.gnu.org>2010-05-07 21:37:43 +0000
committerSteven Bosscher <steven@gcc.gnu.org>2010-05-07 21:37:43 +0000
commit57e8813a43d115f367b8fd0cef6b08c3403010ea (patch)
treeb036b0c810fc469ae0e5ec3f6d1436e32e0ef493 /gcc/config/darwin.c
parent0535743bf0ac81fe0bffe01c04c3682cc053a6c6 (diff)
ChangeLog:
* configure.ac (--enable-lto): Add x86_64-apple-darwin* as a platform that supports LTO. * configure: Regenerate. gcc/ChangeLog: * config.gcc (i[34567]86-*-darwin*, x86_64-*-darwin*): Add lto-macho as lto_binary_reader. * target.h (struct gcc_target): New hooks lto_start and lto_end. * target-def.h (TARGET_ASM_LTO_START, TARGET_ASM_LTO_END): Define. * cgraphunit.c (ipa_passes): Wrap LTO assembler output generation in lto_start and lto_end calls. (is_elf_or_coff): Rename to maybe_lto_object_file. Add Mach-O magic numbers. (scan_prog_file): Update is_elf_or_coff call. * doc/tm.text (TARGET_ASM_LTO_START, TARGET_ASM_LTO_END): Document. * collect2.c (main): Fix enum comparison. * config/darwin-protos.h (darwin_asm_lto_start, darwin_asm_lto_end): Add prototypes. * darwin9.h (LINK_COMMAND_SPEC): Pass -flto and -fwhopr to the linker. * darwin.h (LINK_COMMAND_SPEC): Likewise. Define TARGET_ASM_LTO_START and TARGET_ASM_LTO_END. * darwin.c: Include obstack.h and lto-streamer.h. (lto_section_names_offset, lto_section_names_obstack, lto_asm_out_file, lto_asm_out_name, saved_asm_out_file): New static global variables. (LTO_SEGMENT_NAME, LTO_NAMES_SECTION): New defines. (darwin_asm_lto_start): New function. Redirect output to asm_out_file to a temporary file. (darwin_asm_lto_end): New function. Restore asm_out_file. (darwin_asm_named_section): For LTO sections, replace the name with the offset of the section name in a string table, and build this table. (darwin_file_start): Initialize global vars for LTO support. (darwin_file_end): If output to asm_out_file was redirected, append it to the proper asm_out_file here. Add the section names section. lto/ChangeLog: * lto.h (struct lto_file_struct): Document offset member. * lto-endian.h: New file. * lto-macho.h: New file. * lto-macho.c: New file. * Make-lang.in: Add rule for lto-macho.o. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@159173 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/darwin.c')
-rw-r--r--gcc/config/darwin.c138
1 files changed, 135 insertions, 3 deletions
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index 9d8f3bc7375..93f7babbd6f 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -46,6 +46,8 @@ along with GCC; see the file COPYING3. If not see
#include "hashtab.h"
#include "df.h"
#include "debug.h"
+#include "obstack.h"
+#include "lto-streamer.h"
/* Darwin supports a feature called fix-and-continue, which is used
for rapid turn around debugging. When code is compiled with the
@@ -1387,12 +1389,88 @@ darwin_label_is_anonymous_local_objc_name (const char *name)
return (!strncmp ((const char *)p, "_OBJC_", 6));
}
+/* LTO support for Mach-O. */
+
+/* Section names for LTO sections. */
+static unsigned int lto_section_names_offset = 0;
+
+/* This is the obstack which we use to allocate the many strings. */
+static struct obstack lto_section_names_obstack;
+
+/* Segment name for LTO sections. */
+#define LTO_SEGMENT_NAME "__GNU_LTO"
+
+/* Section name for LTO section names section. */
+#define LTO_NAMES_SECTION "__section_names"
+
+/* File to temporarily store LTO data. This is appended to asm_out_file
+ in darwin_end_file. */
+static FILE *lto_asm_out_file, *saved_asm_out_file;
+static char *lto_asm_out_name;
+
+/* Prepare asm_out_file for LTO output. For darwin, this means hiding
+ asm_out_file and switching to an alternative output file. */
+void
+darwin_asm_lto_start (void)
+{
+ gcc_assert (! saved_asm_out_file);
+ saved_asm_out_file = asm_out_file;
+ if (! lto_asm_out_name)
+ lto_asm_out_name = make_temp_file (".lto.s");
+ lto_asm_out_file = fopen (lto_asm_out_name, "a");
+ if (lto_asm_out_file == NULL)
+ fatal_error ("failed to open temporary file %s for LTO output",
+ lto_asm_out_name);
+ asm_out_file = lto_asm_out_file;
+}
+
+/* Restore asm_out_file. */
+void
+darwin_asm_lto_end (void)
+{
+ gcc_assert (saved_asm_out_file);
+ fclose (lto_asm_out_file);
+ asm_out_file = saved_asm_out_file;
+ saved_asm_out_file = NULL;
+}
+
void
darwin_asm_named_section (const char *name,
- unsigned int flags ATTRIBUTE_UNUSED,
+ unsigned int flags,
tree decl ATTRIBUTE_UNUSED)
{
- fprintf (asm_out_file, "\t.section %s\n", name);
+ /* LTO sections go in a special segment __GNU_LTO. We want to replace the
+ section name with something we can use to represent arbitrary-length
+ names (section names in Mach-O are at most 16 characters long). */
+ if (strncmp (name, LTO_SECTION_NAME_PREFIX,
+ strlen (LTO_SECTION_NAME_PREFIX)) == 0)
+ {
+ /* We expect certain flags to be set... */
+ gcc_assert ((flags & (SECTION_DEBUG | SECTION_NAMED))
+ == (SECTION_DEBUG | SECTION_NAMED));
+
+ /* Add the section name to the things to output when we end the
+ current assembler output file.
+ This is all not very efficient, but that doesn't matter -- this
+ shouldn't be a hot path in the compiler... */
+ obstack_1grow (&lto_section_names_obstack, '\t');
+ obstack_grow (&lto_section_names_obstack, ".ascii ", 7);
+ obstack_1grow (&lto_section_names_obstack, '"');
+ obstack_grow (&lto_section_names_obstack, name, strlen (name));
+ obstack_grow (&lto_section_names_obstack, "\\0\"\n", 4);
+
+ /* Output the dummy section name. */
+ fprintf (asm_out_file, "\t.section %s,__%08X,regular,debug\t# %s\n",
+ LTO_SEGMENT_NAME, lto_section_names_offset, name);
+
+ /* Update the offset for the next section name. Make sure we stay
+ within reasonable length. */
+ lto_section_names_offset += strlen (name) + 1;
+ gcc_assert (lto_section_names_offset > 0
+ && lto_section_names_offset < ((unsigned) 1 << 31));
+ }
+ else
+ fprintf (asm_out_file, "\t.section %s\n", name);
}
void
@@ -1585,7 +1663,8 @@ darwin_asm_output_dwarf_delta (FILE *file, int size,
fprintf (file, "\n\t%s L$set$%d", directive, darwin_dwarf_label_counter++);
}
-/* Output labels for the start of the DWARF sections if necessary. */
+/* Output labels for the start of the DWARF sections if necessary.
+ Initialize the stuff we need for LTO long section names support. */
void
darwin_file_start (void)
{
@@ -1620,6 +1699,11 @@ darwin_file_start (void)
fprintf (asm_out_file, "Lsection%.*s:\n", namelen, debugnames[i] + 8);
}
}
+
+ /* We fill this obstack with the complete section text for the lto section
+ names to write in darwin_file_end. */
+ obstack_init (&lto_section_names_obstack);
+ lto_section_names_offset = 0;
}
/* Output an offset in a DWARF section on Darwin. On Darwin, DWARF section
@@ -1646,6 +1730,8 @@ darwin_asm_output_dwarf_offset (FILE *file, int size, const char * lab,
void
darwin_file_end (void)
{
+ const char *lto_section_names;
+
machopic_finish (asm_out_file);
if (strcmp (lang_hooks.name, "GNU C++") == 0)
{
@@ -1653,6 +1739,52 @@ darwin_file_end (void)
switch_to_section (darwin_sections[destructor_section]);
ASM_OUTPUT_ALIGN (asm_out_file, 1);
}
+
+ /* If there was LTO assembler output, append it to asm_out_file. */
+ if (lto_asm_out_name)
+ {
+ int n;
+ char *buf, *lto_asm_txt;
+
+ /* Shouldn't be here if we failed to switch back. */
+ gcc_assert (! saved_asm_out_file);
+
+ lto_asm_out_file = fopen (lto_asm_out_name, "r");
+ if (lto_asm_out_file == NULL)
+ fatal_error ("failed to open temporary file %s with LTO output",
+ lto_asm_out_name);
+ fseek (lto_asm_out_file, 0, SEEK_END);
+ n = ftell (lto_asm_out_file);
+ if (n > 0)
+ {
+ fseek (lto_asm_out_file, 0, SEEK_SET);
+ lto_asm_txt = buf = (char *) xmalloc (n + 1);
+ while (fgets (lto_asm_txt, n, lto_asm_out_file))
+ fputs (lto_asm_txt, asm_out_file);
+ }
+
+ /* Remove the temporary file. */
+ fclose (lto_asm_out_file);
+ unlink_if_ordinary (lto_asm_out_name);
+ free (lto_asm_out_name);
+ }
+
+ /* Finish the LTO section names obstack. Don't output anything if
+ there are no recorded section names. */
+ obstack_1grow (&lto_section_names_obstack, '\0');
+ lto_section_names = XOBFINISH (&lto_section_names_obstack, const char *);
+ if (strlen (lto_section_names) > 0)
+ {
+ fprintf (asm_out_file,
+ "\t.section %s,%s,regular,debug\n",
+ LTO_SEGMENT_NAME, LTO_NAMES_SECTION);
+ fprintf (asm_out_file,
+ "\t# Section names in %s are offsets into this table\n",
+ LTO_SEGMENT_NAME);
+ fprintf (asm_out_file, "%s\n", lto_section_names);
+ }
+ obstack_free (&lto_section_names_obstack, NULL);
+
fprintf (asm_out_file, "\t.subsections_via_symbols\n");
}