1

When trying to terminate (SIGINT) our cross-compiled application running on a dual ARM Cortex-A9, we segfault on an illegal instruction in the stack unwinding.

In file ../libgcc/config/arm/unwind-arm.c:

/* ABI defined function to pop registers off the stack.  */

_Unwind_VRS_Result _Unwind_VRS_Pop (_Unwind_Context *context,
                    _Unwind_VRS_RegClass regclass,
                    _uw discriminator,
                    _Unwind_VRS_DataRepresentation representation)
{
  phase1_vrs *vrs = (phase1_vrs *) context;

  switch (regclass)
    {
    case _UVRSC_CORE:
      {
    _uw *ptr;
    _uw mask;
    int i;

    if (representation != _UVRSD_UINT32)
      return _UVRSR_FAILED;

    mask = discriminator & 0xffff;
    ptr = (_uw *) vrs->core.r[R_SP];
    /* Pop the requested registers.  */
    for (i = 0; i < 16; i++)
      {
        if (mask & (1 << i))
          vrs->core.r[i] = *(ptr++);
      }

    (...)
}

A short excerpt from the disassembler for _Unwind_VRS_Pop shows:

        224 [1]   switch (regclass)
0xb660202c                  2d e9 f0 41  stmdb  sp!, {r4, r5, r6, r7, r8, lr}
0xb6602030  <+    4>        06 46        mov    r6, r0
0xb6602032  <+    6>        c2 b0        sub    sp, #264    ; 0x108
        221 [1] {
0xb6602034  <+    8>        14 46        mov    r4, r2
0xb6602036  <+   10>        1d 46        mov    r5, r3
0xb6602038  <+   12>        04 29        cmp    r1, #4
0xb660203a  <+   14>        00 f2 b8 80  bhi.w  0xb66021ae <_Unwind_VRS_Pop+386>
0xb660203e  <+   18>        df e8 01 f0  tbb    [pc, r1]
0xb6602042  <+   22>        03 20 b6 ae  cdpge  0, 11, cr2, cr6, cr3, {0}
0xb6602046  <+   26>        db 00 00 2d  stccs  0, cr0, [r0, #-876] ; 0xfffffc94
        232 [1]     if (representation != _UVRSD_UINT32)
0xb660204a  <+   30>        40 f0 b0 80  bne.w  0xb66021ae <_Unwind_VRS_Pop+386>
        235 [1]     mask = discriminator & 0xffff;
0xb660204e  <+   34>        a1 b2        uxth   r1, r4
        236 [1]     ptr = (_uw *) vrs->core.r[R_SP];
0xb6602050  <+   36>        83 6b        ldr    r3, [r0, #56]   ; 0x38
        238 [1]     for (i = 0; i < 16; i++)
0xb6602052  <+   38>        2a 46        mov    r2, r5
        240 [1]         if (mask & (1 << i))
0xb6602054  <+   40>        01 20        movs   r0, #1
        241 [1]           vrs->core.r[i] = *(ptr++);
0xb6602056  <+   42>        37 1d        adds   r7, r6, #4
        240 [1]         if (mask & (1 << i))
0xb6602058  <+   44>        00 fa 02 fc  lsl.w  r12, r0, r2
0xb660205c  <+   48>        1c ea 01 0f  tst.w  r12, r1
        241 [1]           vrs->core.r[i] = *(ptr++);
0xb6602060  <+   52>        1c bf        itt    ne
0xb6602062  <+   54>        53 f8 04 cb  ldrne.w    r12, [r3], #4
0xb6602066  <+   58>        47 f8 22 c0  strne.w    r12, [r7, r2, lsl #2]
        238 [1]     for (i = 0; i < 16; i++)
0xb660206a  <+   62>        01 32        adds   r2, #1
0xb660206c  <+   64>        10 2a        cmp    r2, #16
0xb660206e  <+   66>        f3 d1        bne.n  0xb6602058 <_Unwind_VRS_Pop+44>
        244 [1]     if ((mask & (1 << R_SP)) == 0)
0xb6602070  <+   68>        14 f4 00 54  ands.w r4, r4, #8192   ; 0x2000
0xb6602074  <+   72>        01 d1        bne.n  0xb660207a <_Unwind_VRS_Pop+78>
        245 [1]       vrs->core.r[R_SP] = (_uw) ptr;
0xb6602076  <+   74>        b3 63        str    r3, [r6, #56]   ; 0x38
        408 [1]       return _UVRSR_OK;

It stops on this line:

0xb6602062 <+ 54> 53 f8 04 cb ldrne.w r12, [r3], #4

The toolchain is using GCC 9; sysroot generated from Buildroot.

Could this be a mismatch in toolchain or with which instruction set is used? I assume STR/LDR instructions are pretty basic operations that shouldn't result in a SIGILL?

I tried to compile with -march=armv7-a without any change.

Lasse A Karlsen
  • 801
  • 5
  • 14
  • 23
  • `ldrne.w r12, [r3], #4` means "if the zero flag is not set, load from memory location specified by register `r3`, plus 4, and store it in r12. It could be that you're reading from memory that you're "not supposed to" (which is what my understanding of a segfault is) – puppydrum64 Dec 02 '22 at 18:21

0 Answers0