+2016-11-27 Iain Sandoe <iain@codesourcery.com>
+
+ PR target/71767
+ * config/darwin.c (imachopic_indirection_name): Make data
+ section indirections linker-visible.
+ * config/darwin.h (ASM_GENERATE_INTERNAL_LABEL): Make local
+ constant labels linker-visible.
+
2016-11-26 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
* tree.c (build_common_tree_nodes): Initialize ptrdiff_type_node.
}
/* Return the name of the non-lazy pointer (if STUB_P is false) or
- stub (if STUB_B is true) corresponding to the given name. */
+ stub (if STUB_B is true) corresponding to the given name.
+
+ If we have a situation like:
+
+global_weak_symbol:
+ ....
+Lnon_weak_local:
+ ....
+
+ ld64 will be unable to split this into two atoms (because the "L" makes
+ the second symbol 'invisible'). This means that legitimate direct accesses
+ to the second symbol will appear to be non-allowed direct accesses to an
+ atom of type weak, global which are not allowed.
+
+ To avoid this, we make the indirections have a leading 'l' (lower-case L)
+ which has a special meaning: linker can see this and use it to determine
+ atoms, but it is not placed into the final symbol table.
+
+ The implementation here is somewhat heavy-handed in that it will also mark
+ indirections to the __IMPORT,__pointers section the same way which is
+ really unnecessary, since ld64 _can_ split those into atoms as they are
+ fixed size. FIXME: determine if this is a penalty worth extra code to
+ fix.
+
+*/
const char *
machopic_indirection_name (rtx sym_ref, bool stub_p)
machopic_indirection *p;
bool needs_quotes;
const char *suffix;
+ char L_or_l = 'L';
const char *prefix = user_label_prefix;
const char *quote = "";
tree id;
if (stub_p)
suffix = STUB_SUFFIX;
else
- suffix = NON_LAZY_POINTER_SUFFIX;
+ {
+ suffix = NON_LAZY_POINTER_SUFFIX;
+ /* Let the linker see this. */
+ L_or_l = 'l';
+ }
- buffer = XALLOCAVEC (char, strlen ("&L")
+ buffer = XALLOCAVEC (char, 2 /* strlen ("&L") or ("&l") */
+ strlen (prefix)
+ namelen
+ strlen (suffix)
+ 1 /* '\0' */);
/* Construct the name of the non-lazy pointer or stub. */
- sprintf (buffer, "&%sL%s%s%s%s", quote, prefix, name, suffix, quote);
+ sprintf (buffer, "&%s%c%s%s%s%s", quote, L_or_l, prefix, name, suffix, quote);
if (!machopic_indirections)
machopic_indirections = hash_table<indirection_hasher>::create_ggc (37);
{ "weak_import", 0, 0, true, false, false, \
darwin_handle_weak_import_attribute, false }
+/* Make local constant labels linker-visible, so that if one follows a
+ weak_global constant, ld64 will be able to separate the atoms. */
#undef ASM_GENERATE_INTERNAL_LABEL
#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
- sprintf (LABEL, "*%s%ld", PREFIX, (long)(NUM))
+ do { \
+ if (strcmp ("LC", PREFIX) == 0) \
+ sprintf (LABEL, "*%s%ld", "lC", (long)(NUM)); \
+ else \
+ sprintf (LABEL, "*%s%ld", PREFIX, (long)(NUM)); \
+ } while (0)
#undef TARGET_ASM_MARK_DECL_PRESERVED
#define TARGET_ASM_MARK_DECL_PRESERVED darwin_mark_decl_preserved