static void update_stubs (const char *);
static const char *machopic_non_lazy_ptr_name (const char*);
-/* Earliest operating system for which generated code is targeted, as string
- and as integer. The string form is "10.0", "10.1", etc. The corresponding
- numeric versions are 1000, 1010, etc. This number is used for feature
- tests of the form "enable_this_feature = macosx_version_min_required >= n",
- so 0 is a conservative default. */
-
-const char *darwin_macosx_version_name;
-unsigned int macosx_version_min_required = 0;
-
-/* Parse -macosx= option. */
-
-static struct darwin_macosx_vers {
- const char *vers_str;
- unsigned int vers_num;
-} darwin_macosx_vers_tbl[] = {
- { "10.0", 1000 },
- { "10.1", 1010 },
- { "10.2", 1020 },
- { "jaguar", 1020 },
- { "10.3", 1030 },
- { "panther", 1030 },
- { "10.4", 1040 },
- { "10.5", 1050 },
- { NULL, 0 }
-};
-
-void darwin_parse_macosx_version_name (void)
-{
- if (darwin_macosx_version_name)
- {
- struct darwin_macosx_vers *v = darwin_macosx_vers_tbl;
- while (v->vers_str
- && strcmp (darwin_macosx_version_name, v->vers_str) != 0)
- v++;
-
- if (v->vers_str)
- macosx_version_min_required = v->vers_num;
- else
- warning ("-macosx=%s: unrecognized version", darwin_macosx_version_name);
- }
-}
-
int
name_needs_quotes (const char *name)
{
const char *
machopic_function_base_name (void)
{
- const char *current_name;
/* if dynamic-no-pic is on, we should not get here */
if (MACHO_DYNAMIC_NO_PIC_P)
abort ();
- current_name =
- IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
if (function_base == NULL)
function_base =
if (! TREE_USED (temp))
continue;
- /* If the symbol is actually defined, we don't need a stub. */
- if (sym_name[0] == '!' && sym_name[1] == 'T')
- continue;
-
sym_name = darwin_strip_name_encoding (sym_name);
sym = alloca (strlen (sym_name) + 2);
if ((TREE_CODE (decl) == FUNCTION_DECL
|| TREE_CODE (decl) == VAR_DECL)
&& !DECL_EXTERNAL (decl)
+ && (!TREE_PUBLIC (decl) || (!DECL_ONE_ONLY (decl) && !DECL_WEAK (decl)))
&& ((TREE_STATIC (decl)
&& (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
- || (DECL_INITIAL (decl)
+ || (!DECL_COMMON (decl) && DECL_INITIAL (decl)
&& DECL_INITIAL (decl) != error_mark_node)))
defined = 1;
}
}
-/* Function NAME is being defined, and its label has just been output.
- If there's already a reference to a stub for this function, we can
- just emit the stub label now and we don't bother emitting the stub later. */
-
-void
-machopic_output_possible_stub_label (FILE *file, const char *name)
-{
- tree temp;
-
- /* Ensure we're looking at a section-encoded name. */
- if (name[0] != '!' || (name[1] != 't' && name[1] != 'T'))
- return;
-
- for (temp = machopic_stubs;
- temp != NULL_TREE;
- temp = TREE_CHAIN (temp))
- {
- const char *sym_name;
-
- sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
- if (sym_name[0] == '!' && (sym_name[1] == 'T' || sym_name[1] == 't')
- && ! strcmp (name+2, sym_name+2))
- {
- ASM_OUTPUT_LABEL (file, IDENTIFIER_POINTER (TREE_PURPOSE (temp)));
- /* Avoid generating a stub for this. */
- TREE_USED (temp) = 0;
- break;
- }
- }
-}
-
/* Scan the list of stubs and update any recorded names whose
stripped name matches the argument. */
}
void
+darwin_make_decl_one_only (tree decl)
+{
+ static const char *text_section = "__TEXT,__textcoal_nt,coalesced,no_toc";
+ static const char *data_section = "__DATA,__datacoal_nt,coalesced,no_toc";
+
+ const char *sec = TREE_CODE (decl) == FUNCTION_DECL
+ ? text_section
+ : data_section;
+ TREE_PUBLIC (decl) = 1;
+ DECL_ONE_ONLY (decl) = 1;
+ DECL_SECTION_NAME (decl) = build_string (strlen (sec), sec);
+}
+
+void
machopic_select_section (tree exp, int reloc,
unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
{
if (TREE_CODE (exp) == STRING_CST
&& ((size_t) TREE_STRING_LENGTH (exp)
- == strlen (TREE_STRING_POINTER (exp)) + 1)
- && ! flag_writable_strings)
+ == strlen (TREE_STRING_POINTER (exp)) + 1))
cstring_section ();
else if ((TREE_CODE (exp) == INTEGER_CST || TREE_CODE (exp) == REAL_CST)
&& flag_merge_constants)
default_globalize_label (stream, name);
}
+void
+darwin_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED)
+{
+ if (flag_reorder_blocks_and_partition)
+ fprintf (asm_out_file, SECTION_FORMAT_STRING, name);
+ else
+ fprintf (asm_out_file, ".section %s\n", name);
+}
+
+unsigned int
+darwin_section_type_flags (tree decl, const char *name, int reloc)
+{
+ unsigned int flags = default_section_type_flags (decl, name, reloc);
+
+ /* Weak or linkonce variables live in a writable section. */
+ if (decl != 0 && TREE_CODE (decl) != FUNCTION_DECL
+ && (DECL_WEAK (decl) || DECL_ONE_ONLY (decl)))
+ flags |= SECTION_WRITE;
+
+ return flags;
+}
+
+void
+darwin_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
+{
+ /* Darwin does not use unique sections. However, the target's
+ unique_section hook is called for linkonce symbols. We need
+ to set an appropriate section for such symbols. */
+ if (DECL_ONE_ONLY (decl) && !DECL_SECTION_NAME (decl))
+ darwin_make_decl_one_only (decl);
+}
+
+/* Emit a label for an FDE, making it global and/or weak if appropriate.
+ The third parameter is nonzero if this is just a placeholder for an
+ FDE that we are omitting. */
+void
+darwin_emit_unwind_label(FILE *file, tree decl, int empty)
+{
+ tree id = DECL_ASSEMBLER_NAME (decl)
+ ? DECL_ASSEMBLER_NAME (decl)
+ : DECL_NAME (decl);
+
+ const char *prefix = "_";
+ const int prefix_len = 1;
+
+ const char *base = IDENTIFIER_POINTER (id);
+ unsigned int base_len = IDENTIFIER_LENGTH (id);
+
+ const char *suffix = ".eh";
+ unsigned int suffix_len = 3;
+
+ int need_quotes = name_needs_quotes (base);
+ int quotes_len = need_quotes ? 2 : 0;
+
+ char *lab = xmalloc (prefix_len + base_len + suffix_len + quotes_len + 1);
+ lab[0] = '\0';
+
+ if (need_quotes)
+ strcat(lab, "\"");
+ strcat(lab, prefix);
+ strcat(lab, base);
+ strcat(lab, suffix);
+ if (need_quotes)
+ strcat(lab, "\"");
+
+ if (TREE_PUBLIC (decl))
+ fprintf (file, "%s %s\n",
+ (DECL_VISIBILITY (decl) != VISIBILITY_HIDDEN
+ ? ".globl"
+ : ".private_extern"),
+ lab);
+
+ if (DECL_ONE_ONLY (decl) && TREE_PUBLIC (decl))
+ fprintf (file, ".weak_definition %s\n", lab);
+
+ if (empty)
+ fprintf (file, "%s = 0\n", lab);
+ else
+ fprintf (file, "%s:\n", lab);
+
+ free (lab);
+}
+
+/* Generate a PC-relative reference to a Mach-O non-lazy-symbol. */
+void
+darwin_non_lazy_pcrel (FILE *file, rtx addr)
+{
+ const char *str;
+ const char *nlp_name;
+
+ if (GET_CODE (addr) != SYMBOL_REF)
+ abort ();
+
+ str = darwin_strip_name_encoding (XSTR (addr, 0));
+ nlp_name = machopic_non_lazy_ptr_name (str);
+ fputs ("\t.long\t", file);
+ ASM_OUTPUT_LABELREF (file, nlp_name);
+ fputs ("-.", file);
+}
+
/* Emit an assembler directive to set visibility for a symbol. The
only supported visibilities are VISIBILITY_DEFAULT and
VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
darwin_asm_output_dwarf_delta (FILE *file, int size ATTRIBUTE_UNUSED,
const char *lab1, const char *lab2)
{
- const char *p = lab1 + (lab1[0] == '*');
- int islocaldiff = (p[0] == 'L');
+ int islocaldiff = (lab1[0] == '*' && lab1[1] == 'L'
+ && lab2[0] == '*' && lab2[1] == 'L');
if (islocaldiff)
fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);