https://sourceware.org/bugzilla/show_bug.cgi?id=34102

            Bug ID: 34102
           Summary: Force __exidx_start align to 4 byte, prevent
                    __exidx_start not point to .ARM.exidx correctly.
           Product: binutils
           Version: 2.47 (HEAD)
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: ld
          Assignee: unassigned at sourceware dot org
          Reporter: hanwei62 at huawei dot com
  Target Milestone: ---

I encounter a runtime fail use gcc-arm-eabi compiler c++ code with exception
handler routine.

TL;DR
I found the `__exidx_start` symbol is not aligned to 4 byte(depend on
`.ARM.extab`'s size), but `.ARM.exidx` section is aligned to 4 byte. So in the
exception handler routine, 

```
__cxa_throw -> _Unwind_RaiseException -> __gnu_Unwind_RaiseException ->
get_eit_entry -> search_EIT_table
```

the `__EIT_entry` data is mistaken, this lead to exception handler routine
failed.

Fix it by this patch:

diff --git a/ld/emulparams/armelf.sh b/ld/emulparams/armelf.sh
index dd71fe77e6f..38e3b4701e9 100644
--- a/ld/emulparams/armelf.sh
+++ b/ld/emulparams/armelf.sh
@@ -16,6 +16,7 @@ OTHER_SECTIONS='.note.gnu.arm.ident 0 : { KEEP
(*(.note.gnu.arm.ident)) }'
 ATTRS_SECTIONS='.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP
(*(.gnu.attributes)) }'
 OTHER_READONLY_SECTIONS="
   .ARM.extab ${RELOCATING-0} : { *(.ARM.extab${RELOCATING+*
.gnu.linkonce.armextab.*}) }
+  . = ALIGN (4);
   .ARM.exidx ${RELOCATING-0} :
     {
       ${RELOCATING+PROVIDE_HIDDEN (__exidx_start = .);}

---

Detail

gcc-arm-eabi version is 14.3

Reproduction:

```
#include <string>
#include <system_error>
#include <stdio.h>

# define _VERIFY_PRINT(S, F, L, P, C) __builtin_fprintf(stderr, S, F, L, P, C)

#define VERIFY(fn)                                                      \
  do                                                                    \
  {                                                                     \
    if (! (fn))                                                         \
      {                                                                 \
        _VERIFY_PRINT("%s:%d: %s: Assertion '%s' failed.\n",            \
                      __FILE__, __LINE__, __PRETTY_FUNCTION__, #fn);    \
        __builtin_abort();                                              \
      }                                                                 \
  } while (false)

// libstdc++/2089
class fuzzy_logic : public std::system_error
{
public:
  fuzzy_logic() : std::system_error(std::error_code(), "whoa") { }
};

void test03()
{
  try
    { throw fuzzy_logic(); }
  catch(const fuzzy_logic& obj)
    { VERIFY( std::string(obj.what()).find("whoa") != std::string::npos ); }
  catch(...)
    { VERIFY( false ); }
}

int main(void)
{
  test03();
  return 0;
}
```

with compiler commands: 

```
-O2 -fno-short-enums  -std=gnu++17 
```

failed with output:

```
terminate called after throwing an instance of '__gnu_test::positioning_error'
terminate called recursively
```

$ readelf -sW fail | grep __exidx_start
  6280: 000883f2     0 NOTYPE  LOCAL  DEFAULT    5 __exidx_start

$ readelf -SW fail
...
  [ 4] .rodata           PROGBITS        000820e8 0820e8 003d38 00   A  0   0 
8
  [ 5] .ARM.extab        PROGBITS        00085e20 085e20 0025d2 00   A  0   0 
4
  [ 6] .ARM.exidx        ARM_EXIDX       000883f4 0883f4 001bb0 00  AL  2   0 
4
  [ 7] .eh_frame         PROGBITS        00089fa4 089fa4 000004 00   A  0   0 
4
...

The key is `__exidx_start` not point to `.ARM.exidx` start correctly.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Reply via email to