(root)/
gcc-13.2.0/
gcc/
testsuite/
g++.dg/
torture/
stackalign/
test-unwind.h
       1  #include "check.h"
       2  
       3  
       4  #define ASMNAME(cname)  ASMNAME2 (__USER_LABEL_PREFIX__, cname)
       5  #define ASMNAME2(prefix, cname) STRING (prefix) cname
       6  #define STRING(x)    #x
       7  
       8  #ifdef  __cplusplus
       9  extern "C" void abort (void);
      10  #else
      11  extern void abort (void);
      12  #endif
      13  
      14  extern void foo(void);
      15  
      16  #define INIT_EDI 1
      17  #define INIT_ESI 2
      18  #define INIT_EBX 3
      19  
      20  /* Set DI/SI/BX to wrong value
      21     Use following template so that RA will save/restore callee
      22     save registers in prologue/epilogue */
      23  #define ALTER_REGS() \
      24    { \
      25          int dummy;      \
      26          __asm__  __volatile__ (\
      27          "movl %1, %0" : "=D" (dummy) : "i" (-INIT_EDI)\
      28          );\
      29          __asm__  __volatile__ (\
      30          "movl %1, %0" : "=S" (dummy) : "i" (-INIT_ESI)\
      31          );\
      32          __asm__  __volatile__ (\
      33          "movl %1, %0" : "=b" (dummy) : "i" (-INIT_EBX)\
      34          );\
      35    }
      36  
      37  #if defined __PIC__ || defined __USING_SJLJ_EXCEPTIONS__
      38  int
      39  main ()
      40  {
      41    return 0;
      42  }
      43  #else
      44  void __attribute__ ((noinline))
      45  copy (char *p, int size)
      46  {
      47    __builtin_strncpy (p, "good", size);
      48  }
      49  
      50  int g_edi __attribute__((externally_visible)) =INIT_EDI;
      51  int g_esi __attribute__((externally_visible)) =INIT_ESI;
      52  int g_ebx __attribute__((externally_visible)) = INIT_EBX; 
      53  int g_ebp __attribute__((externally_visible));
      54  int g_esp __attribute__((externally_visible));
      55  int g_ebp_save __attribute__((externally_visible));
      56  int g_esp_save __attribute__((externally_visible));
      57  int n_error;
      58  
      59  int
      60  main()
      61  {
      62          int dummy;
      63  	// Init registers to correct value.
      64          // Use following template so that RA will save/restore callee
      65  	// save registers in prologue/epilogue
      66  	__asm__  __volatile__ (
      67  	"movl %1, %0"
      68  	: "=D" (dummy)
      69  	: "i" (INIT_EDI)
      70  	);
      71  	__asm__  __volatile__ (
      72  	"movl %1, %0"
      73  	: "=S" (dummy)
      74  	: "i" (INIT_ESI)
      75  	);
      76  	__asm__  __volatile__ (
      77  	"movl %1, %0"
      78  	: "=b" (dummy)
      79  	: "i" (INIT_EBX)
      80  	);
      81  	__asm__ __volatile__ (
      82  	"movl %ebp," ASMNAME("g_ebp_save")"\n\t"
      83  	"movl %esp," ASMNAME("g_esp_save")"\n\t"
      84  	);
      85  	try {
      86  		foo();
      87  	}
      88  	catch (...)
      89  	{
      90  	}
      91  
      92  	// Get DI/SI/BX register value after exception caught
      93  	__asm__ __volatile__ (
      94  	"movl %edi," ASMNAME("g_edi")"\n\t"
      95  	"movl %esi," ASMNAME("g_esi")"\n\t"
      96  	"movl %ebx," ASMNAME("g_ebx")"\n\t"
      97  	"movl %ebp," ASMNAME("g_ebp")"\n\t"
      98  	"movl %esp," ASMNAME("g_esp")"\n\t"
      99  	);
     100  
     101  	// Check if DI/SI/BX register value are the same as before calling
     102          // foo.
     103  	if (g_edi != INIT_EDI)
     104  	{
     105  		n_error++;
     106  #ifdef DEBUG
     107  		printf("edi=%d, correct value:%d\n", g_edi, INIT_EDI);
     108  #endif
     109  	}
     110  	if (g_esi != INIT_ESI)
     111  	{
     112  		n_error++;
     113  #ifdef DEBUG
     114  		printf("esi=%d, correct value:%d\n", g_esi, INIT_ESI);
     115  #endif
     116  	}
     117  	if (g_ebx != INIT_EBX)
     118  	{
     119  		n_error++;
     120  #ifdef DEBUG
     121  		printf("ebx=%d, correct value:%d\n", g_ebx, INIT_EBX);
     122  #endif
     123  	}
     124  	if (g_ebp != g_ebp_save)
     125  	{
     126  		n_error++;
     127  #ifdef DEBUG
     128  		printf("ebp=0x%x, correct value:0x%x\n", g_ebp, g_ebp_save);
     129  #endif
     130  	}
     131  	if (g_esp != g_esp_save)
     132  	{
     133  		n_error++;
     134  #ifdef DEBUG
     135  		printf("esp=0x%x, correct value:0x%x\n", g_esp, g_esp_save);
     136  #endif
     137  	}
     138  	if (n_error !=0)
     139  		abort();
     140  	return 0;
     141  }
     142  #endif