(root)/
gcc-13.2.0/
libgcc/
config/
i386/
gnu-unwind.h
       1  /* DWARF2 EH unwinding support for GNU Hurd: x86.
       2     Copyright (C) 2020-2023 Free Software Foundation, Inc.
       3     Contributed by Samuel Thibault <samuel.thibault@gnu.org>
       4  
       5  This file is part of GCC.
       6  
       7  GCC is free software; you can redistribute it and/or modify
       8  it under the terms of the GNU General Public License as published by
       9  the Free Software Foundation; either version 3, or (at your option)
      10  any later version.
      11  
      12  GCC is distributed in the hope that it will be useful,
      13  but WITHOUT ANY WARRANTY; without even the implied warranty of
      14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15  GNU General Public License for more details.
      16  
      17  Under Section 7 of GPL version 3, you are granted additional
      18  permissions described in the GCC Runtime Library Exception, version
      19  3.1, as published by the Free Software Foundation.
      20  
      21  You should have received a copy of the GNU General Public License and
      22  a copy of the GCC Runtime Library Exception along with this program;
      23  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      24  <http://www.gnu.org/licenses/>.  */
      25  
      26  /* Do code reading to identify a signal frame, and set the frame
      27     state data appropriately.  See unwind-dw2.c for the structs. */
      28  
      29  #ifndef inhibit_libc
      30  
      31  #include <signal.h>
      32  
      33  #ifdef __x86_64__
      34  
      35  /*
      36   * TODO: support for 64 bits needs to be implemented.
      37   */
      38  
      39  #else /* ifdef __x86_64__  */
      40  
      41  #define MD_FALLBACK_FRAME_STATE_FOR x86_gnu_fallback_frame_state
      42  
      43  static _Unwind_Reason_Code
      44  x86_gnu_fallback_frame_state
      45  (struct _Unwind_Context *context, _Unwind_FrameState *fs)
      46  {
      47    struct handler_args {
      48      int signo;
      49      union
      50        {
      51  	struct
      52  	  {
      53  	    long int sigcode;
      54  	    struct sigcontext *scp;
      55  	  } legacy;
      56  	struct
      57  	  {
      58  	    siginfo_t *siginfop;
      59  	    ucontext_t *uctxp;
      60  	  } posix;
      61        };
      62    } *handler_args;
      63    long int sigcode;
      64    unsigned long usp;
      65  
      66  /*
      67   * i386 sigtramp frame we are looking for follows.
      68   * (see glibc/sysdeps/mach/hurd/i386/trampoline.c assembly)
      69   *
      70   * rpc_wait_trampoline:
      71   *   0:	b8 e7 ff ff ff       	mov    $-25,%eax       mach_msg_trap
      72   *   5:	9a 00 00 00 00 07 00 	lcall  $7,$0
      73   *  12:	89 01                	movl   %eax, (%ecx)
      74   *  14:	89 dc                	movl   %ebx, %esp      switch to signal stack
      75   *
      76   * trampoline:
      77   *  16:	ff d2                	call   *%edx           call the handler function
      78   * RA HERE
      79   *  18:	83 c4 0c             	addl   $12, %esp       pop its args
      80   *  21:	c3                   	ret                    return to sigreturn
      81   *
      82   * firewall:
      83   *  22:	f4                   	hlt
      84   */
      85  
      86    if (!(   *(unsigned int   *)(context->ra     ) == 0xc30cc483
      87          && *(unsigned char  *)(context->ra +  4) ==       0xf4
      88  
      89          && *(unsigned int   *)(context->ra -  4) == 0xd2ffdc89
      90          && *(unsigned int   *)(context->ra -  8) == 0x01890007
      91          && *(unsigned int   *)(context->ra - 12) == 0x00000000
      92          && *(unsigned int   *)(context->ra - 16) == 0x9affffff
      93          && *(unsigned short *)(context->ra - 18) ==     0xe7b8))
      94      return _URC_END_OF_STACK;
      95  
      96    handler_args = context->cfa;
      97    sigcode = handler_args->legacy.sigcode;
      98    if (sigcode >= -16 && sigcode < 4096)
      99      {
     100        /* This cannot be a SIGINFO pointer, assume legacy.  */
     101        struct sigcontext *scp = handler_args->legacy.scp;
     102        usp = scp->sc_uesp;
     103  
     104        fs->regs.reg[0].loc.offset = (unsigned long)&scp->sc_eax - usp;
     105        fs->regs.reg[1].loc.offset = (unsigned long)&scp->sc_ecx - usp;
     106        fs->regs.reg[2].loc.offset = (unsigned long)&scp->sc_edx - usp;
     107        fs->regs.reg[3].loc.offset = (unsigned long)&scp->sc_ebx - usp;
     108        fs->regs.reg[5].loc.offset = (unsigned long)&scp->sc_ebp - usp;
     109        fs->regs.reg[6].loc.offset = (unsigned long)&scp->sc_esi - usp;
     110        fs->regs.reg[7].loc.offset = (unsigned long)&scp->sc_edi - usp;
     111        fs->regs.reg[8].loc.offset = (unsigned long)&scp->sc_eip - usp;
     112      }
     113    else
     114      {
     115        /* This is not a valid sigcode, assume SIGINFO.  */
     116        ucontext_t *uctxp = handler_args->posix.uctxp;
     117        gregset_t *gregset = &uctxp->uc_mcontext.gregs;
     118        usp = (*gregset)[REG_UESP];
     119  
     120        fs->regs.reg[0].loc.offset = (unsigned long)&(*gregset)[REG_EAX] - usp;
     121        fs->regs.reg[1].loc.offset = (unsigned long)&(*gregset)[REG_ECX] - usp;
     122        fs->regs.reg[2].loc.offset = (unsigned long)&(*gregset)[REG_EDX] - usp;
     123        fs->regs.reg[3].loc.offset = (unsigned long)&(*gregset)[REG_EBX] - usp;
     124        fs->regs.reg[5].loc.offset = (unsigned long)&(*gregset)[REG_EBP] - usp;
     125        fs->regs.reg[6].loc.offset = (unsigned long)&(*gregset)[REG_ESI] - usp;
     126        fs->regs.reg[7].loc.offset = (unsigned long)&(*gregset)[REG_EDI] - usp;
     127        fs->regs.reg[8].loc.offset = (unsigned long)&(*gregset)[REG_EIP] - usp;
     128      }
     129  
     130    fs->regs.cfa_how = CFA_REG_OFFSET;
     131    fs->regs.cfa_reg = 4;
     132    fs->regs.cfa_offset = usp - (unsigned long) context->cfa;
     133  
     134    fs->regs.how[0] = REG_SAVED_OFFSET;
     135    fs->regs.how[1] = REG_SAVED_OFFSET;
     136    fs->regs.how[2] = REG_SAVED_OFFSET;
     137    fs->regs.how[3] = REG_SAVED_OFFSET;
     138    fs->regs.how[5] = REG_SAVED_OFFSET;
     139    fs->regs.how[6] = REG_SAVED_OFFSET;
     140    fs->regs.how[7] = REG_SAVED_OFFSET;
     141    fs->regs.how[8] = REG_SAVED_OFFSET;
     142  
     143    fs->retaddr_column = 8;
     144    fs->signal_frame = 1;
     145  
     146    return _URC_NO_REASON;
     147  }
     148  
     149  #endif /* ifdef __x86_64__  */
     150  
     151  #endif /* ifndef inhibit_libc */