https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98692

--- Comment #18 from Mark Wielaard <mark at gcc dot gnu.org> ---
The current thinking (Julian did the thinking, I am just repeating) is that
this is caused by the way the _savegpr and/or restgpr functions return using
blr.

PPC has two special "lets zap the red zone" (the 288 bytes below the stack
pointer) cases:

#  define VG_STACK_REDZONE_SZB    288  // number of addressable bytes below R1
                                       // from 64-bit PowerPC ELF ABI 
                                       // Supplement 1.7

   guest_ppc_zap_RZ_at_blr
      guest is ppc64-linux                ==> True
      guest is ppc32-linux                ==> False
      guest is other                      ==> inapplicable

   guest_ppc_zap_RZ_at_bl
      guest is ppc64-linux                ==> const True
      guest is ppc32-linux                ==> const False
      guest is other                      ==> inapplicable
   guest_stack_redzone_size
      guest is ppc32-linux                ==> 0
      guest is ppc64-linux                ==> 288
      guest is amd64-linux                ==> 128
      guest is other                      ==> inapplicable

      /* PPC and AMD64 GUESTS only: how many bytes below the 
         stack pointer are validly addressible? */
      Int guest_stack_redzone_size;

      /* PPC GUESTS only: should we zap the stack red zone at a 'blr'
         (function return) ? */
      Bool guest_ppc_zap_RZ_at_blr;

      /* PPC GUESTS only: should we zap the stack red zone at a 'bl'
         (function call) ?  Is supplied with the guest address of the
         target of the call since that may be significant.  If NULL,
         is assumed equivalent to a fn which always returns False. */
      Bool (*guest_ppc_zap_RZ_at_bl)(Addr);

#  if defined(VGP_ppc32_linux)
   vex_abiinfo.guest_ppc_zap_RZ_at_blr        = False;
   vex_abiinfo.guest_ppc_zap_RZ_at_bl         = NULL;
#  endif

#  if defined(VGP_ppc64be_linux)
   vex_abiinfo.guest_ppc_zap_RZ_at_blr        = True;
   vex_abiinfo.guest_ppc_zap_RZ_at_bl         = const_True;
   vex_abiinfo.host_ppc_calls_use_fndescrs    = True;
#  endif

#  if defined(VGP_ppc64le_linux)
   vex_abiinfo.guest_ppc_zap_RZ_at_blr        = True;
   vex_abiinfo.guest_ppc_zap_RZ_at_bl         = const_True;
   vex_abiinfo.host_ppc_calls_use_fndescrs    = False;
#  endif

What happens on a blr function return is that, based on the
guest_ppc_zap_RZ_at_blr value, the redzone is marked as containing undefined
values.

And indeed, with this patch:

diff --git a/coregrind/m_translate.c b/coregrind/m_translate.c
index 332202a91..6dd01afac 100644
--- a/coregrind/m_translate.c
+++ b/coregrind/m_translate.c
@@ -1709,7 +1709,7 @@ Bool VG_(translate) ( ThreadId tid,
 #  endif

 #  if defined(VGP_ppc64le_linux)
-   vex_abiinfo.guest_ppc_zap_RZ_at_blr        = True;
+   vex_abiinfo.guest_ppc_zap_RZ_at_blr        = False;
    vex_abiinfo.guest_ppc_zap_RZ_at_bl         = const_True;
    vex_abiinfo.host_ppc_calls_use_fndescrs    = False;
 #  endif

The warning goes away.

But is that the right thing to do always? It seems to mask issues where a
function is using the red zone values set by another function.

Reply via email to