diff options
author | Iain Sandoe <iain@sandoe.co.uk> | 2025-08-07 17:51:14 +0100 |
---|---|---|
committer | Iain Sandoe <iain@sandoe.co.uk> | 2025-08-09 15:13:30 +0100 |
commit | e38a8582d5b490976e72b7dbcd388e6b81f338c0 (patch) | |
tree | 9b6d3c953001576d51327e6c5be519643bc78bbf /gcc | |
parent | d950ba6e51b56adf72e45c58067291be4e0b6785 (diff) | |
download | gcc-e38a8582d5b490976e72b7dbcd388e6b81f338c0.zip gcc-e38a8582d5b490976e72b7dbcd388e6b81f338c0.tar.gz gcc-e38a8582d5b490976e72b7dbcd388e6b81f338c0.tar.bz2 |
Darwin: Anchor block internal symbols must not be linker-visible.
When we are using section anchors, there's a requirement that the
sequence of the content is an unbroken block. If we allow linker-
visible symbols in that block, ld(64) would be able to break it
into sub-sections on those symbol boundaries.
Do not allow symbols that should be visible to be anchored.
Do not make anchor block internal symbols linker-visible.
gcc/ChangeLog:
* config/darwin.cc (darwin_encode_section_info): Do not
make anchored symbols linker-visible.
(darwin_use_anchors_for_symbol_p): Disallow anchoring on
symbols that must be linker-visible (or external), even
if the definitions are in this TU.
Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/darwin.cc | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/gcc/config/darwin.cc b/gcc/config/darwin.cc index be2daed..1724084 100644 --- a/gcc/config/darwin.cc +++ b/gcc/config/darwin.cc @@ -1298,6 +1298,29 @@ darwin_encode_section_info (tree decl, rtx rtl, int first) SYMBOL_FLAG_EXTERNAL. */ default_encode_section_info (decl, rtl, first); + if (CONSTANT_CLASS_P (decl)) + { + bool is_str = TREE_CODE (decl) == STRING_CST; + rtx sym_ref = XEXP (rtl, 0); + + /* If this is a string cst or not anchored we have nothing to do. */ + if (is_str || !SYMBOL_REF_HAS_BLOCK_INFO_P (sym_ref)) + return; + + tree sym_decl = SYMBOL_REF_DECL (sym_ref); + const char *name = XSTR (sym_ref, 0); + gcc_checking_assert (strncmp ("*lC", name, 3) == 0); + + char *buf; + /* Lets identify anchored constants with a different prefix, for the + sake of inspection only. */ + buf = xasprintf ("*LaC%s", &name[3]); + if (sym_decl) + DECL_NAME (sym_decl) = get_identifier (buf); + XSTR (sym_ref, 0) = ggc_strdup (buf); + free (buf); + } + if (! VAR_OR_FUNCTION_DECL_P (decl)) return; @@ -3297,11 +3320,16 @@ darwin_use_anchors_for_symbol_p (const_rtx symbol) { if (DARWIN_SECTION_ANCHORS && flag_section_anchors) { - section *sect; - /* If the section contains a zero-sized object it's ineligible. */ - sect = SYMBOL_REF_BLOCK (symbol)->sect; - /* This should have the effect of disabling anchors for vars that follow - any zero-sized one, in a given section. */ + tree decl = SYMBOL_REF_DECL (symbol); + /* If the symbol would be linker-visible, then it can split at that + so we must disallow. This is more strict than the default impl. + TODO: add other cases. */ + if (decl && DECL_P (decl) + && (TREE_PUBLIC (decl) || !DECL_ARTIFICIAL (decl))) + return false; + + /* We mark sections containing unsuitable entries. */ + section *sect = SYMBOL_REF_BLOCK (symbol)->sect; if (sect->common.flags & SECTION_NO_ANCHOR) return false; |