https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98779
Bug ID: 98779 Summary: [arm] libgcc incompatible with -mpure-code Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libgcc Assignee: unassigned at gcc dot gnu.org Reporter: clyon at gcc dot gnu.org Target Milestone: --- As discussed in https://gcc.gnu.org/pipermail/gcc-patches/2021-January/562934.html some parts of libgcc for arm are incompatible with -mpure-code. There is currently no multilib using -mpure-code, so incompatible code may be silently linked from libgcc with code compiled with -mpure-code. The parts of libgcc written in C would be OK if compiled with -mpure-code, but the parts written in assembly would need to: - avoid the offending code sequences - be placed in a section with SHF_ARM_PURECODE It's probably undesirable to rewrite the assembly parts in a -mpure-code compatible way unconditionally: it has a negative impact on both performance and code size. It's not clear yet if we'd like to introduce a multilib for this case. We also have to keep in mind that the linker puts .text and .text.noread sections in different segments, and does not emit a warning when the two types of code are linked together. I have looked at which libgcc functions contain code incompatible with -mpure-code: * assembly, use constant pool __clzsi2 __ctzsi2 * macro test_div_by_zero in bpabi-v6m.S uses a constant pool __aeabi_ldivmod __aeabi_uldivmod * code in fixed-bit.c generates a constant pool if not compiled with -mpure-code: z = ((UINT_C_TYPE) 1) << I_F_BITS; if (x >= 0) z -= (UINT_C_TYPE) 1; ldr r3, .L8 lsrs r0, r2, #31 mov ip, r3 add r0, r0, ip b .L1 .L9: .align 2 .L8: .word 2147483647 this impacts the following functions: __gnu_ssaddsq3 __gnu_ssadddq3 __gnu_ssaddsa3 __gnu_ssaddda3 __gnu_sssubsq3 __gnu_sssubdq3 __gnu_sssubsa3 __gnu_sssubda3 __gnu_ssnegsq2 __gnu_ssnegdq2 __gnu_ssnegsa2 __gnu_ssnegda2 __gnu_usaddusq3 __gnu_usaddudq3 __gnu_usaddusa3 __gnu_usadduda3 __gnu_usnegusq2 __gnu_usnegudq2 __gnu_usnegusa2 __gnu_usneguda2 __gnu_fractqiusq __gnu_fractqiudq __gnu_fracthiusq __gnu_fracthiudq __gnu_fractsiusq __gnu_fractsiudq __gnu_fractdiusq __gnu_fractdiudq __gnu_satfractqqsq2 __gnu_satfractqqsa __gnu_satfracthqsq2 __gnu_satfractsqda __gnu_satfracthasq __gnu_satfracthasa2 __gnu_satfracthausq __gnu_satfracthaudq __gnu_satfractsasq __gnu_satfractsausq __gnu_satfractsaudq __gnu_satfractdausq __gnu_satfractdaudq __gnu_satfractuhasq __gnu_satfractuhadq __gnu_satfractuhausq __gnu_satfractuhaudq __gnu_satfractusasq __gnu_satfractusadq __gnu_satfractusausq __gnu_satfractusaudq __gnu_satfractudadq __gnu_satfractudaudq __gnu_satfractqisq __gnu_satfractqisa __gnu_satfracthisq __gnu_satfracthisa __gnu_satfractsisq __gnu_satfractsisa __gnu_satfractsiusa __gnu_satfractdiusq __gnu_satfractdiusa __gnu_satfractdiuda __gnu_fractunsqiusq __gnu_fractunsqiudq __gnu_fractunshiusq __gnu_fractunshiudq __gnu_fractunssiusq __gnu_fractunssiudq __gnu_fractunsdiusq __gnu_fractunsdiudq __gnu_satfractunsqisq __gnu_satfractunsqidq __gnu_satfractunsqisa __gnu_satfractunsqida __gnu_satfractunsqiusa __gnu_satfractunsqiuda __gnu_satfractunshisq __gnu_satfractunshidq __gnu_satfractunssisq __gnu_satfractunssidq __gnu_satfractunssisa __gnu_satfractunssiusa __gnu_satfractunsdisq __gnu_satfractunsdidq __gnu_satfractunsdisa __gnu_satfractunsdida __gnu_satfractunsdiuda Other functions performing load/stores outside of the stack include: __gnu_thumb1_case_sqi __gnu_thumb1_case_uqi __gnu_thumb1_case_shi __gnu_thumb1_case_uhi __gnu_thumb1_case_si These are OK, because they are used in PIC mode, which is incompatible with -mpure-code anyway. __gcc_bcmp __gnu_saturate1qq __gnu_saturate1hq __gnu_saturate1sq __gnu_saturate1ha __gnu_saturate1sa __gnu_saturate1uqq __gnu_saturate1uhq __gnu_saturate1uha __gnu_saturate1usa __gnu_saturate2dq __gnu_saturate2da __gnu_saturate2udq __gnu_saturate2uda __aeabi_uread4 __aeabi_uread8 __gnu_float2h_internal emutls_alloc These are OK as long as their pointer parameters point to data in suitable locations. Finally all the functions related to unwinding rely to their parameters pointing to data with read access rights.