Initialize barrier_cache for ARM EH ABI compliance
authorAlexandre Oliva <oliva@adacore.com>
Thu, 6 Feb 2020 06:59:45 +0000 (03:59 -0300)
committerAlexandre Oliva <oliva@gnu.org>
Thu, 6 Feb 2020 06:59:45 +0000 (03:59 -0300)
The ARM Exception Handling ABI requires personality functions in
phase1 to initialize barrier_cache before returning
_URC_HANDLER_FOUND, and we don't.

Although our own ARM personality function does not use barrier_cache
at all, other languages' ARM personality functions, during phase2, are
allowed and expected to test barrier_cache.sp to check whether the
handler frame was reached, which implies that personality functions is
in charge of the frame, and the remaining fields of barrier_cache hold
whatever values it put there in phase1.

Since we did not set barrier_cache.sp, an earlier exception, already
handled by a non-Ada handler and then released, may have its storage
reused for a new exception, that phase1 matches to an Ada frame, but
if that leaves barrier_cache.sp alone, the phase2 personality function
that handled the earlier exception, upon reaching the frame that
handled the earlier exception, may believe the information in
barrier_cache applies to the current exception.  The C++ personality
function, for example, would take the information in the barrier_cache
and end up activating the handler that handled the earlier exception:

  try {
    throw 1;
  } catch (int i) {
    std::cout << "caught " << i << " by c++" << std::endl;
  }
  raise_ada_exception (); // might loop back to the handler above

for  gcc/ada/ChangeLog

* raise-gcc.c (personality_body) [__ARM_EABI_UNWINDER__]:
Initialize barrier_cache.sp when ending phase1.

gcc/ada/ChangeLog
gcc/ada/raise-gcc.c

index 7601fe2..64b2572 100644 (file)
@@ -1,3 +1,8 @@
+2020-02-06  Alexandre Oliva <oliva@adacore.com>
+
+       * raise-gcc.c (personality_body) [__ARM_EABI_UNWINDER__]:
+       Initialize barrier_cache.sp when ending phase1.
+
 2020-01-04  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gnatvsn.ads: Bump copyright year.
index 1ba8af1..3b6c21f 100644 (file)
@@ -1211,6 +1211,16 @@ personality_body (_Unwind_Action uw_phases,
        }
       else
        {
+#ifdef __ARM_EABI_UNWINDER__
+         /* Though we do not use this field ourselves, initializing
+            it is required by the ARM EH ABI before a personality
+            function in phase1 returns _URC_HANDLER_FOUND, so that
+            any personality function can use it in phase2 to test
+            whether the handler frame was reached.  */
+         uw_exception->barrier_cache.sp
+           = _Unwind_GetGR (uw_context, UNWIND_STACK_REG);
+#endif
+
 #ifndef CERT
          /* Trigger the appropriate notification routines before the second
             phase starts, when the stack is still intact.  First install what