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.

Reply via email to