head 1.6; access; symbols pkgsrc-2026Q2:1.1.0.2 pkgsrc-2026Q2-base:1.1; locks; strict; comment @# @; 1.6 date 2026.08.05.22.50.43; author js; state Exp; branches; next 1.5; commitid 06JWfOf8WvZZavQG; 1.5 date 2026.08.05.20.51.31; author js; state Exp; branches; next 1.4; commitid ciiL5Uz8l8F6wuQG; 1.4 date 2026.08.03.21.43.46; author js; state Exp; branches; next 1.3; commitid IVEh0DzZ2bv1SeQG; 1.3 date 2026.08.01.15.45.19; author js; state Exp; branches; next 1.2; commitid 1ZKOPORen7e2XWPG; 1.2 date 2026.07.13.22.04.11; author js; state Exp; branches; next 1.1; commitid gt4bLFwygItSExNG; 1.1 date 2026.06.13.15.58.32; author js; state Exp; branches; next ; commitid 6mKpx9Vn1opdBEJG; desc @@ 1.6 log @cross/ppc-morphos-gcc: Exclude function pointers and C++ metadata from baserel @ text @Also use baserel for const pointers - after all, something in a const pointer might refer to something that gets relocated, so needs to be accessed baserel as well. --- gcc/config/rs6000/rs6000.cc.orig 2026-08-05 21:32:54.304949687 +0000 +++ gcc/config/rs6000/rs6000.cc @@@@ -20952,6 +20952,106 @@@@ rs6000_elf_select_rtx_section (machine_m static int rs6000_elf_reloc_rw_mask (void); +/* Copied from varasm.cc, but modified to ignore function pointers */ +static bool +contains_data_pointers_p (tree type) +{ + switch (TREE_CODE (type)) + { + case POINTER_TYPE: + case REFERENCE_TYPE: + return !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (type)); + /* I'm not sure whether OFFSET_TYPE needs this treatment, + so I'll play safe and return 1. */ + case OFFSET_TYPE: + return true; + + case RECORD_TYPE: + case UNION_TYPE: + case QUAL_UNION_TYPE: + { + tree fields; + /* For a type that has fields, see if the fields have pointers. */ + for (fields = TYPE_FIELDS (type); fields; fields = DECL_CHAIN (fields)) + if (TREE_CODE (fields) == FIELD_DECL + && contains_data_pointers_p (TREE_TYPE (fields))) + return true; + return false; + } + + case ARRAY_TYPE: + /* An array type contains pointers if its element type does. */ + return contains_data_pointers_p (TREE_TYPE (type)); + + default: + return false; + } +} + +static bool +is_cxx_metadata_name_p (const char *name) +{ + if (strncmp(name, "_ZT", 3) != 0) + return false; + + switch (name[3]) + { + case 'I': + case 'S': + case 'V': + case 'T': + case 'C': + return true; + default: + return false; + } +} + +/* Copied from varasm.cc */ +static inline tree +ultimate_transparent_alias_target (tree *alias) +{ + tree target = *alias; + + if (IDENTIFIER_TRANSPARENT_ALIAS (target)) + { + gcc_assert (TREE_CHAIN (target)); + target = ultimate_transparent_alias_target (&TREE_CHAIN (target)); + gcc_assert (! IDENTIFIER_TRANSPARENT_ALIAS (target) + && ! TREE_CHAIN (target)); + *alias = target; + } + + return target; +} + +static bool +rs6000_decl_needs_baserel_p (tree decl) +{ + if (TREE_CODE (decl) != VAR_DECL) + return false; + + const char *section = DECL_SECTION_NAME (decl); + if (section) + { + if (strncmp (section, ".data", 5) == 0 + || strncmp (section, ".bss", 4) == 0 + || strncmp (section, ".sdata", 6) == 0 + || strncmp (section, ".sbss", 5) == 0) + return true; + else + return false; + } + + if (!TREE_READONLY (decl)) + return true; + + if (is_cxx_metadata_name_p (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)))) + return false; + + return contains_data_pointers_p (TREE_TYPE (decl)); +} + /* For a SYMBOL_REF, set generic flags and then perform some target-specific processing. @@@@ -20984,32 +21084,49 @@@@ rs6000_elf_encode_section_info (tree dec { rtx symbol = XEXP (rtl, 0); - if(TREE_CODE (decl) == VAR_DECL && - !TREE_READONLY(decl) && - GET_CODE (symbol) == SYMBOL_REF) - { - const char *name = DECL_SECTION_NAME (decl); - if (name == NULL || (strncmp(name, ".ctors", 6) != 0 && strncmp(name, ".dtors", 6) != 0)) - { - switch (categorize_decl_for_section (decl, rs6000_elf_reloc_rw_mask())) - { - case SECCAT_DATA: - case SECCAT_SDATA: - case SECCAT_TDATA: - case SECCAT_BSS: - case SECCAT_SBSS: - case SECCAT_TBSS: - SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_MORPHOS_BASEREL; - break; - default: - break; - } - } - } + if (rs6000_decl_needs_baserel_p (decl) && GET_CODE (symbol) == SYMBOL_REF) + SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_MORPHOS_BASEREL; } #endif } +static section * +rs6000_morphos_select_section (tree decl, int reloc, + unsigned HOST_WIDE_INT align) +{ + if (TARGET_BASEREL && rs6000_decl_needs_baserel_p (decl)) + return data_section; + + return default_elf_select_section (decl, reloc, align); +} + +static void +rs6000_morphos_unique_section (tree decl, int reloc) +{ + if (TARGET_BASEREL && rs6000_decl_needs_baserel_p (decl)) + { + bool one_only = DECL_ONE_ONLY (decl) && !HAVE_COMDAT_GROUP; + tree id; + const char *name, *linkonce; + char *string; + + id = DECL_ASSEMBLER_NAME (decl); + ultimate_transparent_alias_target (&id); + name = IDENTIFIER_POINTER (id); + name = targetm.strip_name_encoding (name); + + /* If we're using one_only, then there needs to be a .gnu.linkonce + prefix to the section name. */ + linkonce = one_only ? ".gnu.linkonce" : ""; + + string = ACONCAT ((linkonce, ".sdata.", name, NULL)); + + set_decl_section_name (decl, string); + } + else + default_unique_section (decl, reloc); +} + static inline bool compare_section_name (const char *section, const char *templ) { @@@@ -21034,6 +21151,15 @@@@ rs6000_elf_in_small_data_p (const_tree d if (TREE_CODE (decl) == FUNCTION_DECL) return false; +#ifdef TARGET_BASEREL + /* We can never access .rodata via r13 on baserel. We move out pointers of + .rodata into .sdata so that that relocating per opener works. However, we + never move out non-pointers and those stay in .rodata - and are never + copied, so not reachable via r13. */ + if (TARGET_BASEREL && TREE_READONLY (decl)) + return false; +#endif + if (VAR_P (decl) && DECL_SECTION_NAME (decl)) { const char *section = DECL_SECTION_NAME (decl); --- gcc/config/rs6000/morphos.h.orig 2026-07-08 22:28:52.717136366 +0000 +++ gcc/config/rs6000/morphos.h @@@@ -320,3 +320,9 @@@@ mclib=default|!mclib=*: %(endfile_morpho /* Use morphos.opt */ extern const char *morphos_mclib_name; #define TARGET_USES_MORPHOS_OPT 1 + +#undef TARGET_ASM_SELECT_SECTION +#define TARGET_ASM_SELECT_SECTION rs6000_morphos_select_section + +#undef TARGET_ASM_UNIQUE_SECTION +#define TARGET_ASM_UNIQUE_SECTION rs6000_morphos_unique_section --- libgcc/crtstuff.c.orig 2026-07-12 23:00:42.504285022 +0000 +++ libgcc/crtstuff.c @@@@ -377,6 +377,18 @@@@ extern void __cxa_finalize (void *) TARG This routine does not need to be run if none of the following clauses are true, as it will not do anything, so can be removed. */ + +#if defined(__MORPHOS__) && !defined(DTOR_LIST_END) \ + && defined(HIDDEN_DTOR_LIST_END) +func_ptr __DTOR_END__[] __attribute__ ((used, +#ifndef __LIBGCC_DTORS_SECTION_ASM_OP__ + section (".dtors"), +#endif + aligned (sizeof (func_ptr)), + visibility ("hidden"))) + = { (func_ptr) 0 }; +#endif + #if defined(CRTSTUFFS_O) || !defined(FINI_ARRAY_SECTION_ASM_OP) \ || USE_TM_CLONE_REGISTRY || defined(USE_EH_FRAME_REGISTRY) static void __attribute__((used)) @@@@ -401,7 +413,9 @@@@ __do_global_dtors_aux (void) { /* Safer version that makes sure only .dtors function pointers are called even if the static variable is maliciously changed. */ - extern const func_ptr __DTOR_END__[] __attribute__((visibility ("hidden"))); +#ifndef __MORPHOS__ + extern func_ptr __DTOR_END__[] __attribute__((visibility ("hidden"))); +#endif static size_t dtor_idx; const size_t max_idx = __DTOR_END__ - __DTOR_LIST__ - 1; func_ptr *dtor_list; @@@@ -640,6 +654,7 @@@@ DTOR_LIST_END; #ifdef __LIBGCC_DTORS_SECTION_ASM_OP__ asm (__LIBGCC_DTORS_SECTION_ASM_OP__); #endif +#ifndef __MORPHOS__ func_ptr __DTOR_END__[1] __attribute__ ((used, #ifndef __LIBGCC_DTORS_SECTION_ASM_OP__ @@@@ -647,6 +662,7 @@@@ func_ptr __DTOR_END__[1] #endif aligned(__alignof__(func_ptr)), visibility ("hidden"))) = { (func_ptr) 0 }; +#endif #elif defined(__LIBGCC_DTORS_SECTION_ASM_OP__) asm (__LIBGCC_DTORS_SECTION_ASM_OP__); STATIC func_ptr __DTOR_END__[1] @ 1.5 log @cross/ppc-morphos-gcc: Move COMDATs to sdata too for baserel and always honor explicit section @ text @d5 1 a5 1 --- gcc/config/rs6000/rs6000.cc.orig 2026-08-05 20:11:06.081111229 +0000 d7 1 a7 1 @@@@ -20952,6 +20952,82 @@@@ rs6000_elf_select_rtx_section (machine_m d11 1 a11 1 +/* Copied from varasm.cc */ d13 1 a13 1 +contains_pointers_p (tree type) d19 1 d33 1 a33 1 + && contains_pointers_p (TREE_TYPE (fields))) d40 1 a40 1 + return contains_pointers_p (TREE_TYPE (type)); d47 19 d85 1 a85 1 +rs6000_decl_needs_baserel_p (const_tree decl) d101 2 a102 1 + else if (contains_pointers_p (TREE_TYPE (decl))) d105 4 a108 1 + return !TREE_READONLY (decl); d114 1 a114 1 @@@@ -20984,32 +21060,49 @@@@ rs6000_elf_encode_section_info (tree dec d186 1 a186 1 @@@@ -21034,6 +21127,15 @@@@ rs6000_elf_in_small_data_p (const_tree d @ 1.4 log @cross/ppc-morphos-gcc: Exclude DECL_ARTIFICIAL from .rodata -> .sdata move @ text @d5 1 a5 1 --- gcc/config/rs6000/rs6000.cc.orig 2026-08-01 15:24:38.007091067 +0000 d7 1 a7 1 @@@@ -20940,6 +20940,67 @@@@ rs6000_elf_select_rtx_section (machine_m d46 18 d78 1 a78 4 + if (strncmp (section, ".ctdt", 5) == 0 + || strncmp (section, ".ctors", 6) == 0 + || strncmp (section, ".dtors", 6) == 0 + || strncmp (section, ".eh_frame", 9) == 0) d81 1 a81 1 + else if (!DECL_ARTIFICIAL (decl) && contains_pointers_p (TREE_TYPE (decl))) d90 1 a90 1 @@@@ -20972,32 +21033,22 @@@@ rs6000_elf_encode_section_info (tree dec d132 27 d162 1 a162 1 @@@@ -21022,6 +21073,15 @@@@ rs6000_elf_in_small_data_p (const_tree d d180 1 a180 1 @@@@ -320,3 +320,6 @@@@ mclib=default|!mclib=*: %(endfile_morpho d187 3 @ 1.3 log @cross/ppc-morphos-gcc: Updated const-baserel.diff - Fix inconsistent categorization for section - Never reference rodata via r13 @ text @d66 1 a66 1 + else if (contains_pointers_p (TREE_TYPE (decl))) @ 1.2 log @cross/ppc-morphos-gcc: Fix const baserel @ text @d5 1 a5 1 --- gcc/config/rs6000/rs6000.cc.orig 2026-07-08 22:28:47.622168096 +0000 d75 1 a75 1 @@@@ -20972,32 +21032,36 @@@@ rs6000_elf_encode_section_info (tree dec d82 1 a82 2 + if (rs6000_decl_needs_baserel_p (decl) && GET_CODE (symbol) == SYMBOL_REF) { d85 1 a85 2 + switch (categorize_decl_for_section (decl, rs6000_elf_reloc_rw_mask())) { d99 4 a102 12 + case SECCAT_DATA: + case SECCAT_SDATA: + case SECCAT_TDATA: + case SECCAT_BSS: + case SECCAT_SBSS: + case SECCAT_TBSS: + SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_MORPHOS_BASEREL; + break; + default: + break; } } d120 16 @ 1.1 log @Update cross/ppc-morphos-gcc to 15.2.0 This updates to the version from the MorphOS 3.20 SDK. @ text @d1 3 a3 2 Also use baserel for const - after all, something in a const might refer to something that gets relocated, so needs to be accessed baserel as well. d5 1 a5 1 --- gcc/config/rs6000/rs6000.cc.orig 2026-04-04 01:09:46.269295661 +0000 d7 70 a76 1 @@@@ -20973,7 +20973,6 @@@@ rs6000_elf_encode_section_info (tree dec d79 1 a79 1 if(TREE_CODE (decl) == VAR_DECL && d81 2 a82 1 GET_CODE (symbol) == SYMBOL_REF) d84 103 a186 1 const char *name = DECL_SECTION_NAME (decl); @