aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/darwin.c
diff options
context:
space:
mode:
authorIain Sandoe <iain@sandoe.co.uk>2019-10-13 18:58:50 +0000
committerIain Sandoe <iains@gcc.gnu.org>2019-10-13 18:58:50 +0000
commitf922d945244558904be6868dc036c31fd05750dd (patch)
tree7383287eef15a75a68885e7e0ab27a4bc6cbd000 /gcc/config/darwin.c
parent67f192f7687d0cce6cf81e188745a48c71b4b019 (diff)
downloadgcc-f922d945244558904be6868dc036c31fd05750dd.zip
gcc-f922d945244558904be6868dc036c31fd05750dd.tar.gz
gcc-f922d945244558904be6868dc036c31fd05750dd.tar.bz2
[Darwin, machopic 8/n] Back out part of PR71767 fix.
We applied a conservative, but fairly large, hammer to fix PR71767. However, ideally, we want minimise the number of symbols visible to ld64 and to match the cases emitted by clang (since that's what ld64 is expecting). Now we've improved the handling of indirections, we can make the indirection symbols local when they are in the regular non-lazy symbol pointers section. We will continue to make any indirections in the data section visible (since right now we have no way to track if a given symbol follows a weak global). This change makes no difference to handling of labels for constants (to be revised in a future patch). There's a mechanical change to a number of tests (allowing 'l' or 'L' as the indirection symbol prefix). gcc/ChangeLog: 2019-10-13 Iain Sandoe <iain@sandoe.co.uk> * config/darwin.c (machopic_indirection_name): Rework the function to emit linker-visible symbols only for indirections in the data section. Clean up the code and update comments. gcc/testsuite/ChangeLog: 2019-10-13 Iain Sandoe <iain@sandoe.co.uk> * gcc.target/i386/indirect-thunk-1.c: Allow 'l' or 'L' in indirection label prefix, for Darwin. * gcc.target/i386/indirect-thunk-2.c: Likewise. * gcc.target/i386/indirect-thunk-3.c: Likewise. * gcc.target/i386/indirect-thunk-4.c: Likewise. * gcc.target/i386/indirect-thunk-attr-1.c: Likewise. * gcc.target/i386/indirect-thunk-attr-2.c: Likewise. * gcc.target/i386/indirect-thunk-attr-3.c: Likewise. * gcc.target/i386/indirect-thunk-attr-4.c: Likewise. * gcc.target/i386/indirect-thunk-attr-5.c: Likewise. * gcc.target/i386/indirect-thunk-attr-6.c: Likewise. * gcc.target/i386/indirect-thunk-extern-1.c: Likewise. * gcc.target/i386/indirect-thunk-extern-2.c: Likewise. * gcc.target/i386/indirect-thunk-extern-3.c: Likewise. * gcc.target/i386/indirect-thunk-extern-4.c: Likewise. * gcc.target/i386/indirect-thunk-inline-1.c: Likewise. * gcc.target/i386/indirect-thunk-inline-2.c: Likewise. * gcc.target/i386/indirect-thunk-inline-3.c: Likewise. * gcc.target/i386/indirect-thunk-inline-4.c: Likewise. * gcc.target/i386/pr32219-2.c: Likewise. * gcc.target/i386/pr32219-3.c: Likewise. * gcc.target/i386/pr32219-4.c: Likewise. * gcc.target/i386/pr32219-7.c: Likewise. * gcc.target/i386/pr32219-8.c: Likewise. * gcc.target/i386/ret-thunk-14.c: Likewise. * gcc.target/i386/ret-thunk-15.c: Likewise. * gcc.target/i386/ret-thunk-9.c: Likewise. From-SVN: r276943
Diffstat (limited to 'gcc/config/darwin.c')
-rw-r--r--gcc/config/darwin.c108
1 files changed, 43 insertions, 65 deletions
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index eefffee..8635fc2 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -495,7 +495,7 @@ indirection_hasher::equal (machopic_indirection *s, const char *k)
/* 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.
- If we have a situation like:
+ PR71767 - If we have a situation like:
global_weak_symbol:
....
@@ -504,36 +504,22 @@ 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 the second symbol will appear to be 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.
+ To avoid this, we make any data-section 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.
+ Symbols in the non-lazy symbol pointers section (or stubs) do not have this
+ problem because ld64 already knows the size of each entry.
*/
const char *
machopic_indirection_name (rtx sym_ref, bool stub_p)
{
- char *buffer;
const char *name = XSTR (sym_ref, 0);
- size_t namelen = strlen (name);
- 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;
-
- id = maybe_get_identifier (name);
+ tree id = maybe_get_identifier (name);
if (id)
{
tree id_orig = id;
@@ -541,43 +527,47 @@ machopic_indirection_name (rtx sym_ref, bool stub_p)
while (IDENTIFIER_TRANSPARENT_ALIAS (id))
id = TREE_CHAIN (id);
if (id != id_orig)
- {
- name = IDENTIFIER_POINTER (id);
- namelen = strlen (name);
- }
+ name = IDENTIFIER_POINTER (id);
}
+ const char *prefix = user_label_prefix;
+ /* If we are emitting the label 'verbatim' then omit the U_L_P and count
+ the name without the leading '*'. */
if (name[0] == '*')
{
prefix = "";
++name;
- --namelen;
}
- needs_quotes = name_needs_quotes (name);
- if (needs_quotes)
- {
- quote = "\"";
- }
-
- if (stub_p)
- suffix = STUB_SUFFIX;
- else
- {
- suffix = NON_LAZY_POINTER_SUFFIX;
- /* Let the linker see this. */
- L_or_l = 'l';
- }
-
- buffer = XALLOCAVEC (char, 2 /* strlen ("&L") or ("&l") */
- + strlen (prefix)
- + namelen
- + strlen (suffix)
- + 2 * strlen (quote)
- + 1 /* '\0' */);
+ /* Here we are undoing a number of causes that placed some indirections
+ (apparently erroneously) into the .data section. Specifically, some
+ symbols that are ABI mandated indirections and some hidden symbols
+ were being placed there - which cause difficulties with later
+ versions of ld64. Iff (after these checks) some symbol still gets an
+ indirection in the data section, we want to adjust the indirection
+ name to be linker visible to deal with PR71767 (notes above). */
+ bool nlsp_in_data_section =
+ ! MACHO_SYMBOL_MUST_INDIRECT_P (sym_ref)
+ && ! MACHO_SYMBOL_HIDDEN_VIS_P (sym_ref)
+ && (machopic_symbol_defined_p (sym_ref) || SYMBOL_REF_LOCAL_P (sym_ref))
+ && ! indirect_data (sym_ref);
+
+ const char *suffix = stub_p ? STUB_SUFFIX : NON_LAZY_POINTER_SUFFIX;
+ /* If the indirection is in the data section, let the linker see it. */
+ char L_or_l = (!stub_p && nlsp_in_data_section) ? 'l' : 'L';
+ /* We have mangled symbols with spaces and punctuation which typically
+ need surrounding in quotes for the assembler to consume them. */
+ const char *quote = name_needs_quotes (name) ? "\"" : "";
+ char *buffer = XALLOCAVEC (char, 2 /* strlen ("&L") or ("&l") */
+ + strlen (prefix)
+ + strlen (name)
+ + strlen (suffix)
+ + 2 * strlen (quote)
+ + 1 /* '\0' */);
/* Construct the name of the non-lazy pointer or stub. */
- sprintf (buffer, "&%s%c%s%s%s%s", quote, L_or_l, 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);
@@ -586,10 +576,9 @@ machopic_indirection_name (rtx sym_ref, bool stub_p)
= machopic_indirections->find_slot_with_hash (buffer,
htab_hash_string (buffer),
INSERT);
+ machopic_indirection *p;
if (*slot)
- {
- p = *slot;
- }
+ p = *slot;
else
{
p = ggc_alloc<machopic_indirection> ();
@@ -597,18 +586,7 @@ machopic_indirection_name (rtx sym_ref, bool stub_p)
p->ptr_name = xstrdup (buffer);
p->stub_p = stub_p;
p->used = false;
- /* Here we are undoing a number of causes that placed some indirections
- (apparently erroneously) into the .data section. Specifically, some
- symbols that are ABI mandated indirections and some hidden symbols
- were being placed there - which cause difficulties with later
- versions of ld64.
- */
- p->nlsp_in_data_section =
- ! MACHO_SYMBOL_MUST_INDIRECT_P (sym_ref)
- && ! MACHO_SYMBOL_HIDDEN_VIS_P (sym_ref)
- && (machopic_symbol_defined_p (sym_ref)
- || SYMBOL_REF_LOCAL_P (sym_ref))
- && ! indirect_data (sym_ref);
+ p->nlsp_in_data_section = nlsp_in_data_section;
*slot = p;
}