(root)/
binutils-2.41/
binutils/
unwind-ia64.c
       1  /* unwind-ia64.c -- utility routines to dump IA-64 unwind info for readelf.
       2     Copyright (C) 2000-2023 Free Software Foundation, Inc.
       3  
       4     Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
       5  
       6     This file is part of GNU Binutils.
       7  
       8     This program is free software; you can redistribute it and/or modify
       9     it under the terms of the GNU General Public License as published by
      10     the Free Software Foundation; either version 3, or (at your option)
      11     any later version.
      12  
      13     This program is distributed in the hope that it will be useful,
      14     but WITHOUT ANY WARRANTY; without even the implied warranty of
      15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16     GNU General Public License for more details.
      17  
      18     You should have received a copy of the GNU General Public License
      19     along with this program; if not, write to the Free Software
      20     Foundation, 51 Franklin Street - Fifth Floor, Boston,
      21     MA 02110-1301, USA.  */
      22  
      23  #include "config.h"
      24  #include "sysdep.h"
      25  #include "unwind-ia64.h"
      26  
      27  #if __GNUC__ >= 2
      28  /* Define BFD64 here, even if our default architecture is 32 bit ELF
      29     as this will allow us to read in and parse 64bit and 32bit ELF files.
      30     Only do this if we believe that the compiler can support a 64 bit
      31     data type.  For now we only rely on GCC being able to do this.  */
      32  #define BFD64
      33  #endif
      34  #include "bfd.h"
      35  
      36  static bfd_vma unw_rlen = 0;
      37  
      38  static void unw_print_brmask (char *, unsigned int);
      39  static void unw_print_grmask (char *, unsigned int);
      40  static void unw_print_frmask (char *, unsigned int);
      41  static void unw_print_abreg (char *, unsigned int);
      42  static void unw_print_xyreg (char *, unsigned int, unsigned int);
      43  
      44  static void
      45  unw_print_brmask (char *cp, unsigned int mask)
      46  {
      47    int sep = 0;
      48    int i;
      49  
      50    for (i = 0; mask && (i < 5); ++i)
      51      {
      52        if (mask & 1)
      53  	{
      54  	  if (sep)
      55  	    *cp++ = ',';
      56  	  *cp++ = 'b';
      57  	  *cp++ = i + 1 + '0';
      58  	  sep = 1;
      59  	}
      60        mask >>= 1;
      61      }
      62    *cp = '\0';
      63  }
      64  
      65  static void
      66  unw_print_grmask (char *cp, unsigned int mask)
      67  {
      68    int sep = 0;
      69    int i;
      70  
      71    for (i = 0; i < 4; ++i)
      72      {
      73        if (mask & 1)
      74  	{
      75  	  if (sep)
      76  	    *cp++ = ',';
      77  	  *cp++ = 'r';
      78  	  *cp++ = i + 4 + '0';
      79  	  sep = 1;
      80  	}
      81        mask >>= 1;
      82      }
      83    *cp = '\0';
      84  }
      85  
      86  static void
      87  unw_print_frmask (char *cp, unsigned int mask)
      88  {
      89    int sep = 0;
      90    int i;
      91  
      92    for (i = 0; i < 20; ++i)
      93      {
      94        if (mask & 1)
      95  	{
      96  	  if (sep)
      97  	    *cp++ = ',';
      98  	  *cp++ = 'f';
      99  	  if (i < 4)
     100  	    *cp++ = i + 2 + '0';
     101  	  else
     102  	    {
     103  	      *cp++ = (i + 2) / 10 + 1 + '0';
     104  	      *cp++ = (i + 2) % 10 + '0';
     105  	    }
     106  	  sep = 1;
     107  	}
     108        mask >>= 1;
     109      }
     110    *cp = '\0';
     111  }
     112  
     113  static void
     114  unw_print_abreg (char *cp, unsigned int abreg)
     115  {
     116    static const char * const special_reg[16] =
     117    {
     118      "pr", "psp", "@priunat", "rp", "ar.bsp", "ar.bspstore", "ar.rnat",
     119      "ar.unat", "ar.fpsr", "ar.pfs", "ar.lc",
     120      "Unknown11", "Unknown12", "Unknown13", "Unknown14", "Unknown15"
     121    };
     122  
     123    switch ((abreg >> 5) & 0x3)
     124      {
     125      case 0: /* gr */
     126        sprintf (cp, "r%u", (abreg & 0x1f));
     127        break;
     128  
     129      case 1: /* fr */
     130        sprintf (cp, "f%u", (abreg & 0x1f));
     131        break;
     132  
     133      case 2: /* br */
     134        sprintf (cp, "b%u", (abreg & 0x1f));
     135        break;
     136  
     137      case 3: /* special */
     138        strcpy (cp, special_reg[abreg & 0xf]);
     139        break;
     140      }
     141  }
     142  
     143  static void
     144  unw_print_xyreg (char *cp, unsigned int x, unsigned int ytreg)
     145  {
     146    switch ((x << 1) | ((ytreg >> 7) & 1))
     147      {
     148      case 0: /* gr */
     149        sprintf (cp, "r%u", (ytreg & 0x1f));
     150        break;
     151  
     152      case 1: /* fr */
     153        sprintf (cp, "f%u", (ytreg & 0x1f));
     154        break;
     155  
     156      case 2: /* br */
     157        sprintf (cp, "b%u", (ytreg & 0x1f));
     158        break;
     159  
     160      default:
     161        strcpy (cp, "invalid");
     162        break;
     163      }
     164  }
     165  
     166  #define UNW_REG_BSP		"bsp"
     167  #define UNW_REG_BSPSTORE	"bspstore"
     168  #define UNW_REG_FPSR		"fpsr"
     169  #define UNW_REG_LC		"lc"
     170  #define UNW_REG_PFS		"pfs"
     171  #define UNW_REG_PR		"pr"
     172  #define UNW_REG_PSP		"psp"
     173  #define UNW_REG_RNAT		"rnat"
     174  #define UNW_REG_RP		"rp"
     175  #define UNW_REG_UNAT		"unat"
     176  
     177  typedef bfd_vma unw_word;
     178  
     179  #define UNW_DEC_BAD_CODE(code)			\
     180    printf (_("Unknown code 0x%02x\n"), code)
     181  
     182  #define UNW_DEC_PROLOGUE(fmt, body, rlen, arg)					\
     183    do										\
     184      {										\
     185        unw_rlen = rlen;								\
     186        *(int *)arg = body;							\
     187        printf ("    %s:%s(rlen=%lu)\n",						\
     188  	      fmt, body ? "body" : "prologue", (unsigned long) rlen);		\
     189      }										\
     190    while (0)
     191  
     192  #define UNW_DEC_PROLOGUE_GR(fmt, rlen, mask, grsave, arg)			\
     193    do										\
     194      {										\
     195        char regname[16], maskstr[64], *sep;					\
     196  										\
     197        unw_rlen = rlen;								\
     198        *(int *)arg = 0;								\
     199  										\
     200        maskstr[0] = '\0';							\
     201        sep = "";									\
     202        if (mask & 0x8)								\
     203  	{									\
     204  	  strcat (maskstr, "rp");						\
     205  	  sep = ",";								\
     206  	}									\
     207        if (mask & 0x4)								\
     208  	{									\
     209  	  strcat (maskstr, sep);						\
     210  	  strcat (maskstr, "ar.pfs");						\
     211  	  sep = ",";								\
     212  	}									\
     213        if (mask & 0x2)								\
     214  	{									\
     215  	  strcat (maskstr, sep);						\
     216  	  strcat (maskstr, "psp");						\
     217  	  sep = ",";								\
     218  	}									\
     219        if (mask & 0x1)								\
     220  	{									\
     221  	  strcat (maskstr, sep);						\
     222  	  strcat (maskstr, "pr");						\
     223  	}									\
     224        sprintf (regname, "r%u", grsave);						\
     225        printf ("    %s:prologue_gr(mask=[%s],grsave=%s,rlen=%lu)\n",		\
     226  	      fmt, maskstr, regname, (unsigned long) rlen);			\
     227      }										\
     228    while (0)
     229  
     230  #define UNW_DEC_FR_MEM(fmt, frmask, arg)			\
     231    do								\
     232      {								\
     233        char frstr[200];						\
     234  								\
     235        unw_print_frmask (frstr, frmask);				\
     236        printf ("\t%s:fr_mem(frmask=[%s])\n", fmt, frstr);	\
     237      }								\
     238    while (0)
     239  
     240  #define UNW_DEC_GR_MEM(fmt, grmask, arg)			\
     241    do								\
     242      {								\
     243        char grstr[200];						\
     244  								\
     245        unw_print_grmask (grstr, grmask);				\
     246        printf ("\t%s:gr_mem(grmask=[%s])\n", fmt, grstr);	\
     247      }								\
     248    while (0)
     249  
     250  #define UNW_DEC_FRGR_MEM(fmt, grmask, frmask, arg)				\
     251    do										\
     252      {										\
     253        char frstr[200], grstr[20];						\
     254  										\
     255        unw_print_grmask (grstr, grmask);						\
     256        unw_print_frmask (frstr, frmask);						\
     257        printf ("\t%s:frgr_mem(grmask=[%s],frmask=[%s])\n", fmt, grstr, frstr);	\
     258      }										\
     259    while (0)
     260  
     261  #define UNW_DEC_BR_MEM(fmt, brmask, arg)				\
     262    do									\
     263      {									\
     264        char brstr[20];							\
     265  									\
     266        unw_print_brmask (brstr, brmask);					\
     267        printf ("\t%s:br_mem(brmask=[%s])\n", fmt, brstr);		\
     268      }									\
     269    while (0)
     270  
     271  #define UNW_DEC_BR_GR(fmt, brmask, gr, arg)				\
     272    do									\
     273      {									\
     274        char brstr[20];							\
     275  									\
     276        unw_print_brmask (brstr, brmask);					\
     277        printf ("\t%s:br_gr(brmask=[%s],gr=r%u)\n", fmt, brstr, gr);	\
     278      }									\
     279    while (0)
     280  
     281  #define UNW_DEC_REG_GR(fmt, src, dst, arg)		\
     282    printf ("\t%s:%s_gr(reg=r%u)\n", fmt, src, dst)
     283  
     284  #define UNW_DEC_RP_BR(fmt, dst, arg)		\
     285    printf ("\t%s:rp_br(reg=b%u)\n", fmt, dst)
     286  
     287  #define UNW_DEC_REG_WHEN(fmt, reg, t, arg)				\
     288    printf ("\t%s:%s_when(t=%lu)\n", fmt, reg, (unsigned long) t)
     289  
     290  #define UNW_DEC_REG_SPREL(fmt, reg, spoff, arg)		\
     291    printf ("\t%s:%s_sprel(spoff=0x%lx)\n",		\
     292  	  fmt, reg, 4*(unsigned long)spoff)
     293  
     294  #define UNW_DEC_REG_PSPREL(fmt, reg, pspoff, arg)		\
     295    printf ("\t%s:%s_psprel(pspoff=0x10-0x%lx)\n",		\
     296  	  fmt, reg, 4*(unsigned long)pspoff)
     297  
     298  #define UNW_DEC_GR_GR(fmt, grmask, gr, arg)				\
     299    do									\
     300      {									\
     301        char grstr[20];							\
     302  									\
     303        unw_print_grmask (grstr, grmask);					\
     304        printf ("\t%s:gr_gr(grmask=[%s],r%u)\n", fmt, grstr, gr);		\
     305      }									\
     306    while (0)
     307  
     308  #define UNW_DEC_ABI(fmt, abi, context, arg)			\
     309    do								\
     310      {								\
     311        static const char * const abiname[] =			\
     312        {								\
     313  	"@svr4", "@hpux", "@nt"					\
     314        };							\
     315        char buf[20];						\
     316        const char *abistr = buf;					\
     317  								\
     318        if (abi < 3)						\
     319  	abistr = abiname[abi];					\
     320        else							\
     321  	sprintf (buf, "0x%x", abi);				\
     322        printf ("\t%s:unwabi(abi=%s,context=0x%02x)\n",		\
     323  	      fmt, abistr, context);				\
     324      }								\
     325    while (0)
     326  
     327  #define UNW_DEC_PRIUNAT_GR(fmt, r, arg)		\
     328    printf ("\t%s:priunat_gr(reg=r%u)\n", fmt, r)
     329  
     330  #define UNW_DEC_PRIUNAT_WHEN_GR(fmt, t, arg)				\
     331    printf ("\t%s:priunat_when_gr(t=%lu)\n", fmt, (unsigned long) t)
     332  
     333  #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt, t, arg)				\
     334    printf ("\t%s:priunat_when_mem(t=%lu)\n", fmt, (unsigned long) t)
     335  
     336  #define UNW_DEC_PRIUNAT_PSPREL(fmt, pspoff, arg)		\
     337    printf ("\t%s:priunat_psprel(pspoff=0x10-0x%lx)\n",		\
     338  	  fmt, 4*(unsigned long)pspoff)
     339  
     340  #define UNW_DEC_PRIUNAT_SPREL(fmt, spoff, arg)		\
     341    printf ("\t%s:priunat_sprel(spoff=0x%lx)\n",		\
     342  	  fmt, 4*(unsigned long)spoff)
     343  
     344  #define UNW_DEC_MEM_STACK_F(fmt, t, size, arg)		\
     345    printf ("\t%s:mem_stack_f(t=%lu,size=%lu)\n",		\
     346  	  fmt, (unsigned long) t, 16*(unsigned long)size)
     347  
     348  #define UNW_DEC_MEM_STACK_V(fmt, t, arg)				\
     349    printf ("\t%s:mem_stack_v(t=%lu)\n", fmt, (unsigned long) t)
     350  
     351  #define UNW_DEC_SPILL_BASE(fmt, pspoff, arg)			\
     352    printf ("\t%s:spill_base(pspoff=0x10-0x%lx)\n",		\
     353  	  fmt, 4*(unsigned long)pspoff)
     354  
     355  #define UNW_DEC_SPILL_MASK(fmt, dp, arg, end)				\
     356    do									\
     357      {									\
     358        static const char *spill_type = "-frb";				\
     359        unsigned const char *imaskp = dp;					\
     360        unsigned char mask = 0;						\
     361        bfd_vma insn = 0;							\
     362        									\
     363        /* PR 18420.  */							\
     364        if ((dp + (unw_rlen / 4)) > end)					\
     365  	{								\
     366  	  printf (_("\nERROR: unwind length too long (0x%lx > 0x%lx)\n\n"), \
     367  		  (long) (unw_rlen / 4), (long)(end - dp));		\
     368  	  /* FIXME: Should we reset unw_rlen ?  */			\
     369  	  break;							\
     370  	}								\
     371        printf ("\t%s:spill_mask(imask=[", fmt);					\
     372        for (insn = 0; insn < unw_rlen; ++insn)					\
     373  	{									\
     374  	  if ((insn % 4) == 0)							\
     375  	    mask = *imaskp++;							\
     376  	  if (insn > 0 && (insn % 3) == 0)					\
     377  	    putchar (',');							\
     378  	  putchar (spill_type[(mask >> (2 * (3 - (insn & 0x3)))) & 0x3]);	\
     379  	}									\
     380        printf ("])\n");								\
     381        dp = imaskp;								\
     382      }										\
     383    while (0)
     384  
     385  #define UNW_DEC_SPILL_SPREL(fmt, t, abreg, spoff, arg)				\
     386    do										\
     387      {										\
     388        char regname[20];								\
     389  										\
     390        unw_print_abreg (regname, abreg);						\
     391        printf ("\t%s:spill_sprel(reg=%s,t=%lu,spoff=0x%lx)\n",			\
     392  	      fmt, regname, (unsigned long) t, 4*(unsigned long)off);		\
     393      }										\
     394    while (0)
     395  
     396  #define UNW_DEC_SPILL_PSPREL(fmt, t, abreg, pspoff, arg)			\
     397    do										\
     398      {										\
     399        char regname[20];								\
     400  										\
     401        unw_print_abreg (regname, abreg);						\
     402        printf ("\t%s:spill_psprel(reg=%s,t=%lu,pspoff=0x10-0x%lx)\n",		\
     403  	      fmt, regname, (unsigned long) t, 4*(unsigned long)pspoff);	\
     404      }										\
     405    while (0)
     406  
     407  #define UNW_DEC_RESTORE(fmt, t, abreg, arg)			\
     408    do								\
     409      {								\
     410        char regname[20];						\
     411  								\
     412        unw_print_abreg (regname, abreg);				\
     413        printf ("\t%s:restore(t=%lu,reg=%s)\n",			\
     414  	      fmt, (unsigned long) t, regname);			\
     415      }								\
     416    while (0)
     417  
     418  #define UNW_DEC_SPILL_REG(fmt, t, abreg, x, ytreg, arg)		\
     419    do								\
     420      {								\
     421        char abregname[20], tregname[20];				\
     422  								\
     423        unw_print_abreg (abregname, abreg);			\
     424        unw_print_xyreg (tregname, x, ytreg);			\
     425        printf ("\t%s:spill_reg(t=%lu,reg=%s,treg=%s)\n",		\
     426  	      fmt, (unsigned long) t, abregname, tregname);	\
     427      }								\
     428    while (0)
     429  
     430  #define UNW_DEC_SPILL_SPREL_P(fmt, qp, t, abreg, spoff, arg)			    \
     431    do										    \
     432      {										    \
     433        char regname[20];								    \
     434  										    \
     435        unw_print_abreg (regname, abreg);						    \
     436        printf ("\t%s:spill_sprel_p(qp=p%u,t=%lu,reg=%s,spoff=0x%lx)\n",		    \
     437  	      fmt, qp, (unsigned long) t, regname, 4 * (unsigned long)spoff);	    \
     438      }										    \
     439    while (0)
     440  
     441  #define UNW_DEC_SPILL_PSPREL_P(fmt, qp, t, abreg, pspoff, arg)		\
     442    do									\
     443      {									\
     444        char regname[20];							\
     445  									\
     446        unw_print_abreg (regname, abreg);					\
     447        printf ("\t%s:spill_psprel_p(qp=p%u,t=%lu,reg=%s,pspoff=0x10-0x%lx)\n",\
     448  	      fmt, qp, (unsigned long) t, regname, 4*(unsigned long)pspoff);\
     449      }									\
     450    while (0)
     451  
     452  #define UNW_DEC_RESTORE_P(fmt, qp, t, abreg, arg)			\
     453    do									\
     454      {									\
     455        char regname[20];							\
     456  									\
     457        unw_print_abreg (regname, abreg);					\
     458        printf ("\t%s:restore_p(qp=p%u,t=%lu,reg=%s)\n",			\
     459  	      fmt, qp, (unsigned long) t, regname);			\
     460      }									\
     461    while (0)
     462  
     463  #define UNW_DEC_SPILL_REG_P(fmt, qp, t, abreg, x, ytreg, arg)		\
     464    do									\
     465      {									\
     466        char regname[20], tregname[20];					\
     467  									\
     468        unw_print_abreg (regname, abreg);					\
     469        unw_print_xyreg (tregname, x, ytreg);				\
     470        printf ("\t%s:spill_reg_p(qp=p%u,t=%lu,reg=%s,treg=%s)\n",	\
     471  	      fmt, qp, (unsigned long) t, regname, tregname);		\
     472      }									\
     473    while (0)
     474  
     475  #define UNW_DEC_LABEL_STATE(fmt, label, arg)				\
     476    printf ("\t%s:label_state(label=%lu)\n", fmt, (unsigned long) label)
     477  
     478  #define UNW_DEC_COPY_STATE(fmt, label, arg)				\
     479    printf ("\t%s:copy_state(label=%lu)\n", fmt, (unsigned long) label)
     480  
     481  #define UNW_DEC_EPILOGUE(fmt, t, ecount, arg)		\
     482    printf ("\t%s:epilogue(t=%lu,ecount=%lu)\n",		\
     483  	  fmt, (unsigned long) t, (unsigned long) ecount)
     484  
     485  /*
     486   * Generic IA-64 unwind info decoder.
     487   *
     488   * This file is used both by the Linux kernel and objdump.  Please
     489   * keep the two copies of this file in sync (modulo differences in the
     490   * prototypes...).
     491   *
     492   * You need to customize the decoder by defining the following
     493   * macros/constants before including this file:
     494   *
     495   *  Types:
     496   *	unw_word	Unsigned integer type with at least 64 bits
     497   *
     498   *  Register names:
     499   *	UNW_REG_BSP
     500   *	UNW_REG_BSPSTORE
     501   *	UNW_REG_FPSR
     502   *	UNW_REG_LC
     503   *	UNW_REG_PFS
     504   *	UNW_REG_PR
     505   *	UNW_REG_RNAT
     506   *	UNW_REG_PSP
     507   *	UNW_REG_RP
     508   *	UNW_REG_UNAT
     509   *
     510   *  Decoder action macros:
     511   *	UNW_DEC_BAD_CODE(code)
     512   *	UNW_DEC_ABI(fmt,abi,context,arg)
     513   *	UNW_DEC_BR_GR(fmt,brmask,gr,arg)
     514   *	UNW_DEC_BR_MEM(fmt,brmask,arg)
     515   *	UNW_DEC_COPY_STATE(fmt,label,arg)
     516   *	UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
     517   *	UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
     518   *	UNW_DEC_FR_MEM(fmt,frmask,arg)
     519   *	UNW_DEC_GR_GR(fmt,grmask,gr,arg)
     520   *	UNW_DEC_GR_MEM(fmt,grmask,arg)
     521   *	UNW_DEC_LABEL_STATE(fmt,label,arg)
     522   *	UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
     523   *	UNW_DEC_MEM_STACK_V(fmt,t,arg)
     524   *	UNW_DEC_PRIUNAT_GR(fmt,r,arg)
     525   *	UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
     526   *	UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
     527   *	UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
     528   *	UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
     529   *	UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
     530   *	UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
     531   *	UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
     532   *	UNW_DEC_REG_REG(fmt,src,dst,arg)
     533   *	UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
     534   *	UNW_DEC_REG_WHEN(fmt,reg,t,arg)
     535   *	UNW_DEC_RESTORE(fmt,t,abreg,arg)
     536   *	UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
     537   *	UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
     538   *	UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
     539   *	UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
     540   *	UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
     541   *	UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
     542   *	UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
     543   *	UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
     544   *	UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
     545   */
     546  
     547  static unw_word
     548  unw_decode_uleb128 (const unsigned char **dpp, const unsigned char * end)
     549  {
     550    unsigned shift = 0;
     551    int status = 1;
     552    unw_word byte, result = 0;
     553    const unsigned char *bp = *dpp;
     554  
     555    while (bp < end)
     556      {
     557        byte = *bp++;
     558        if (shift < sizeof (result) * 8)
     559  	{
     560  	  result |= (byte & 0x7f) << shift;
     561  	  if ((result >> shift) != (byte & 0x7f))
     562  	    /* Overflow.  */
     563  	    status |= 2;
     564  	  shift += 7;
     565  	}
     566        else if ((byte & 0x7f) != 0)
     567  	status |= 2;
     568  
     569        if ((byte & 0x80) == 0)
     570  	{
     571  	  status &= ~1;
     572  	  break;
     573  	}
     574      }
     575  
     576    *dpp = bp;
     577    if (status != 0)
     578      printf (_("Bad uleb128\n"));
     579  
     580    return result;
     581  }
     582  
     583  static const unsigned char *
     584  unw_decode_x1 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
     585  	       void *arg ATTRIBUTE_UNUSED, const unsigned char * end)
     586  {
     587    unsigned char byte1, abreg;
     588    unw_word t, off;
     589  
     590    if ((end - dp) < 3)
     591      {
     592        printf (_("\t<corrupt X1>\n"));
     593        return end;
     594      }
     595  
     596    byte1 = *dp++;
     597    t = unw_decode_uleb128 (&dp, end);
     598    off = unw_decode_uleb128 (&dp, end);
     599    abreg = (byte1 & 0x7f);
     600    if (byte1 & 0x80)
     601      UNW_DEC_SPILL_SPREL ("X1", t, abreg, off, arg);
     602    else
     603      UNW_DEC_SPILL_PSPREL ("X1", t, abreg, off, arg);
     604    return dp;
     605  }
     606  
     607  static const unsigned char *
     608  unw_decode_x2 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
     609  	       void *arg ATTRIBUTE_UNUSED, const unsigned char * end)
     610  {
     611    unsigned char byte1, byte2, abreg, x, ytreg;
     612    unw_word t;
     613  
     614    if ((end - dp) < 3)
     615      {
     616        printf (_("\t<corrupt X2>\n"));
     617        return end;
     618      }
     619  
     620    byte1 = *dp++;
     621    byte2 = *dp++;
     622    t = unw_decode_uleb128 (&dp, end);
     623    abreg = (byte1 & 0x7f);
     624    ytreg = byte2;
     625    x = (byte1 >> 7) & 1;
     626    if ((byte1 & 0x80) == 0 && ytreg == 0)
     627      UNW_DEC_RESTORE ("X2", t, abreg, arg);
     628    else
     629      UNW_DEC_SPILL_REG ("X2", t, abreg, x, ytreg, arg);
     630    return dp;
     631  }
     632  
     633  static const unsigned char *
     634  unw_decode_x3 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
     635  	       void *arg ATTRIBUTE_UNUSED, const unsigned char * end)
     636  {
     637    unsigned char byte1, byte2, abreg, qp;
     638    unw_word t, off;
     639  
     640    if ((end - dp) < 4)
     641      {
     642        printf (_("\t<corrupt X3>\n"));
     643        return end;
     644      }
     645  
     646    byte1 = *dp++;
     647    byte2 = *dp++;
     648    t = unw_decode_uleb128 (&dp, end);
     649    off = unw_decode_uleb128 (&dp, end);
     650  
     651    qp = (byte1 & 0x3f);
     652    abreg = (byte2 & 0x7f);
     653  
     654    if (byte1 & 0x80)
     655      UNW_DEC_SPILL_SPREL_P ("X3", qp, t, abreg, off, arg);
     656    else
     657      UNW_DEC_SPILL_PSPREL_P ("X3", qp, t, abreg, off, arg);
     658    return dp;
     659  }
     660  
     661  static const unsigned char *
     662  unw_decode_x4 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
     663  	       void *arg ATTRIBUTE_UNUSED, const unsigned char * end)
     664  {
     665    unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg;
     666    unw_word t;
     667  
     668    if ((end - dp) < 4)
     669      {
     670        printf (_("\t<corrupt X4>\n"));
     671        return end;
     672      }
     673  
     674    byte1 = *dp++;
     675    byte2 = *dp++;
     676    byte3 = *dp++;
     677    t = unw_decode_uleb128 (&dp, end);
     678  
     679    qp = (byte1 & 0x3f);
     680    abreg = (byte2 & 0x7f);
     681    x = (byte2 >> 7) & 1;
     682    ytreg = byte3;
     683  
     684    if ((byte2 & 0x80) == 0 && byte3 == 0)
     685      UNW_DEC_RESTORE_P ("X4", qp, t, abreg, arg);
     686    else
     687      UNW_DEC_SPILL_REG_P ("X4", qp, t, abreg, x, ytreg, arg);
     688    return dp;
     689  }
     690  
     691  static const unsigned char *
     692  unw_decode_r1 (const unsigned char *dp, unsigned int code, void *arg,
     693  	       const unsigned char * end ATTRIBUTE_UNUSED)
     694  {
     695    int body = (code & 0x20) != 0;
     696    unw_word rlen;
     697  
     698    rlen = (code & 0x1f);
     699    UNW_DEC_PROLOGUE ("R1", body, rlen, arg);
     700    return dp;
     701  }
     702  
     703  static const unsigned char *
     704  unw_decode_r2 (const unsigned char *dp, unsigned int code, void *arg,
     705  	       const unsigned char * end)
     706  {
     707    unsigned char byte1, mask, grsave;
     708    unw_word rlen;
     709  
     710    if ((end - dp) < 2)
     711      {
     712        printf (_("\t<corrupt R2>\n"));
     713        return end;
     714      }
     715  
     716    byte1 = *dp++;
     717  
     718    mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
     719    grsave = (byte1 & 0x7f);
     720    rlen = unw_decode_uleb128 (& dp, end);
     721    UNW_DEC_PROLOGUE_GR ("R2", rlen, mask, grsave, arg);
     722    return dp;
     723  }
     724  
     725  static const unsigned char *
     726  unw_decode_r3 (const unsigned char *dp, unsigned int code, void *arg,
     727  	       const unsigned char * end)
     728  {
     729    unw_word rlen;
     730  
     731    rlen = unw_decode_uleb128 (& dp, end);
     732    UNW_DEC_PROLOGUE ("R3", ((code & 0x3) == 1), rlen, arg);
     733    return dp;
     734  }
     735  
     736  static const unsigned char *
     737  unw_decode_p1 (const unsigned char *dp, unsigned int code,
     738  	       void *arg ATTRIBUTE_UNUSED,
     739  	       const unsigned char * end ATTRIBUTE_UNUSED)
     740  {
     741    unsigned char brmask = (code & 0x1f);
     742  
     743    UNW_DEC_BR_MEM ("P1", brmask, arg);
     744    return dp;
     745  }
     746  
     747  static const unsigned char *
     748  unw_decode_p2_p5 (const unsigned char *dp, unsigned int code,
     749  		  void *arg ATTRIBUTE_UNUSED,
     750  		  const unsigned char * end)
     751  {
     752    if ((code & 0x10) == 0)
     753      {
     754        unsigned char byte1;
     755  
     756        if ((end - dp) < 1)
     757  	{
     758  	  printf (_("\t<corrupt P2>\n"));
     759  	  return end;
     760  	}
     761  
     762        byte1 = *dp++;
     763  
     764        UNW_DEC_BR_GR ("P2", ((code & 0xf) << 1) | ((byte1 >> 7) & 1),
     765  		     (byte1 & 0x7f), arg);
     766      }
     767    else if ((code & 0x08) == 0)
     768      {
     769        unsigned char byte1, r, dst;
     770  
     771        if ((end - dp) < 1)
     772  	{
     773  	  printf (_("\t<corrupt P3>\n"));
     774  	  return end;
     775  	}
     776  
     777        byte1 = *dp++;
     778  
     779        r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
     780        dst = (byte1 & 0x7f);
     781        switch (r)
     782  	{
     783  	case 0:
     784  	  UNW_DEC_REG_GR ("P3", UNW_REG_PSP, dst, arg);
     785  	  break;
     786  	case 1:
     787  	  UNW_DEC_REG_GR ("P3", UNW_REG_RP, dst, arg);
     788  	  break;
     789  	case 2:
     790  	  UNW_DEC_REG_GR ("P3", UNW_REG_PFS, dst, arg);
     791  	  break;
     792  	case 3:
     793  	  UNW_DEC_REG_GR ("P3", UNW_REG_PR, dst, arg);
     794  	  break;
     795  	case 4:
     796  	  UNW_DEC_REG_GR ("P3", UNW_REG_UNAT, dst, arg);
     797  	  break;
     798  	case 5:
     799  	  UNW_DEC_REG_GR ("P3", UNW_REG_LC, dst, arg);
     800  	  break;
     801  	case 6:
     802  	  UNW_DEC_RP_BR ("P3", dst, arg);
     803  	  break;
     804  	case 7:
     805  	  UNW_DEC_REG_GR ("P3", UNW_REG_RNAT, dst, arg);
     806  	  break;
     807  	case 8:
     808  	  UNW_DEC_REG_GR ("P3", UNW_REG_BSP, dst, arg);
     809  	  break;
     810  	case 9:
     811  	  UNW_DEC_REG_GR ("P3", UNW_REG_BSPSTORE, dst, arg);
     812  	  break;
     813  	case 10:
     814  	  UNW_DEC_REG_GR ("P3", UNW_REG_FPSR, dst, arg);
     815  	  break;
     816  	case 11:
     817  	  UNW_DEC_PRIUNAT_GR ("P3", dst, arg);
     818  	  break;
     819  	default:
     820  	  UNW_DEC_BAD_CODE (r);
     821  	  break;
     822  	}
     823      }
     824    else if ((code & 0x7) == 0)
     825      UNW_DEC_SPILL_MASK ("P4", dp, arg, end);
     826    else if ((code & 0x7) == 1)
     827      {
     828        unw_word grmask, frmask, byte1, byte2, byte3;
     829  
     830        if ((end - dp) < 3)
     831  	{
     832  	  printf (_("\t<corrupt P5>\n"));
     833  	  return end;
     834  	}
     835        byte1 = *dp++;
     836        byte2 = *dp++;
     837        byte3 = *dp++;
     838        grmask = ((byte1 >> 4) & 0xf);
     839        frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3;
     840        UNW_DEC_FRGR_MEM ("P5", grmask, frmask, arg);
     841      }
     842    else
     843      UNW_DEC_BAD_CODE (code);
     844  
     845    return dp;
     846  }
     847  
     848  static const unsigned char *
     849  unw_decode_p6 (const unsigned char *dp, unsigned int code,
     850  	       void *arg ATTRIBUTE_UNUSED,
     851  	       const unsigned char * end ATTRIBUTE_UNUSED)
     852  {
     853    int gregs = (code & 0x10) != 0;
     854    unsigned char mask = (code & 0x0f);
     855  
     856    if (gregs)
     857      UNW_DEC_GR_MEM ("P6", mask, arg);
     858    else
     859      UNW_DEC_FR_MEM ("P6", mask, arg);
     860    return dp;
     861  }
     862  
     863  static const unsigned char *
     864  unw_decode_p7_p10 (const unsigned char *dp, unsigned int code, void *arg,
     865  		   const unsigned char * end)
     866  {
     867    unsigned char r, byte1, byte2;
     868    unw_word t, size;
     869  
     870    if ((code & 0x10) == 0)
     871      {
     872        r = (code & 0xf);
     873        t = unw_decode_uleb128 (&dp, end);
     874        switch (r)
     875  	{
     876  	case 0:
     877  	  size = unw_decode_uleb128 (&dp, end);
     878  	  UNW_DEC_MEM_STACK_F ("P7", t, size, arg);
     879  	  break;
     880  
     881  	case 1:
     882  	  UNW_DEC_MEM_STACK_V ("P7", t, arg);
     883  	  break;
     884  	case 2:
     885  	  UNW_DEC_SPILL_BASE ("P7", t, arg);
     886  	  break;
     887  	case 3:
     888  	  UNW_DEC_REG_SPREL ("P7", UNW_REG_PSP, t, arg);
     889  	  break;
     890  	case 4:
     891  	  UNW_DEC_REG_WHEN ("P7", UNW_REG_RP, t, arg);
     892  	  break;
     893  	case 5:
     894  	  UNW_DEC_REG_PSPREL ("P7", UNW_REG_RP, t, arg);
     895  	  break;
     896  	case 6:
     897  	  UNW_DEC_REG_WHEN ("P7", UNW_REG_PFS, t, arg);
     898  	  break;
     899  	case 7:
     900  	  UNW_DEC_REG_PSPREL ("P7", UNW_REG_PFS, t, arg);
     901  	  break;
     902  	case 8:
     903  	  UNW_DEC_REG_WHEN ("P7", UNW_REG_PR, t, arg);
     904  	  break;
     905  	case 9:
     906  	  UNW_DEC_REG_PSPREL ("P7", UNW_REG_PR, t, arg);
     907  	  break;
     908  	case 10:
     909  	  UNW_DEC_REG_WHEN ("P7", UNW_REG_LC, t, arg);
     910  	  break;
     911  	case 11:
     912  	  UNW_DEC_REG_PSPREL ("P7", UNW_REG_LC, t, arg);
     913  	  break;
     914  	case 12:
     915  	  UNW_DEC_REG_WHEN ("P7", UNW_REG_UNAT, t, arg);
     916  	  break;
     917  	case 13:
     918  	  UNW_DEC_REG_PSPREL ("P7", UNW_REG_UNAT, t, arg);
     919  	  break;
     920  	case 14:
     921  	  UNW_DEC_REG_WHEN ("P7", UNW_REG_FPSR, t, arg);
     922  	  break;
     923  	case 15:
     924  	  UNW_DEC_REG_PSPREL ("P7", UNW_REG_FPSR, t, arg);
     925  	  break;
     926  	default:
     927  	  UNW_DEC_BAD_CODE (r);
     928  	  break;
     929  	}
     930      }
     931    else
     932      {
     933        switch (code & 0xf)
     934  	{
     935  	case 0x0:		/* p8 */
     936  	  {
     937  	    if ((end - dp) < 2)
     938  	      {
     939  		printf (_("\t<corrupt P8>\n"));
     940  		return end;
     941  	      }
     942  
     943  	    r = *dp++;
     944  	    t = unw_decode_uleb128 (&dp, end);
     945  	    switch (r)
     946  	      {
     947  	      case 1:
     948  		UNW_DEC_REG_SPREL ("P8", UNW_REG_RP, t, arg);
     949  		break;
     950  	      case 2:
     951  		UNW_DEC_REG_SPREL ("P8", UNW_REG_PFS, t, arg);
     952  		break;
     953  	      case 3:
     954  		UNW_DEC_REG_SPREL ("P8", UNW_REG_PR, t, arg);
     955  		break;
     956  	      case 4:
     957  		UNW_DEC_REG_SPREL ("P8", UNW_REG_LC, t, arg);
     958  		break;
     959  	      case 5:
     960  		UNW_DEC_REG_SPREL ("P8", UNW_REG_UNAT, t, arg);
     961  		break;
     962  	      case 6:
     963  		UNW_DEC_REG_SPREL ("P8", UNW_REG_FPSR, t, arg);
     964  		break;
     965  	      case 7:
     966  		UNW_DEC_REG_WHEN ("P8", UNW_REG_BSP, t, arg);
     967  		break;
     968  	      case 8:
     969  		UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSP, t, arg);
     970  		break;
     971  	      case 9:
     972  		UNW_DEC_REG_SPREL ("P8", UNW_REG_BSP, t, arg);
     973  		break;
     974  	      case 10:
     975  		UNW_DEC_REG_WHEN ("P8", UNW_REG_BSPSTORE, t, arg);
     976  		break;
     977  	      case 11:
     978  		UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSPSTORE, t, arg);
     979  		break;
     980  	      case 12:
     981  		UNW_DEC_REG_SPREL ("P8", UNW_REG_BSPSTORE, t, arg);
     982  		break;
     983  	      case 13:
     984  		UNW_DEC_REG_WHEN ("P8", UNW_REG_RNAT, t, arg);
     985  		break;
     986  	      case 14:
     987  		UNW_DEC_REG_PSPREL ("P8", UNW_REG_RNAT, t, arg);
     988  		break;
     989  	      case 15:
     990  		UNW_DEC_REG_SPREL ("P8", UNW_REG_RNAT, t, arg);
     991  		break;
     992  	      case 16:
     993  		UNW_DEC_PRIUNAT_WHEN_GR ("P8", t, arg);
     994  		break;
     995  	      case 17:
     996  		UNW_DEC_PRIUNAT_PSPREL ("P8", t, arg);
     997  		break;
     998  	      case 18:
     999  		UNW_DEC_PRIUNAT_SPREL ("P8", t, arg);
    1000  		break;
    1001  	      case 19:
    1002  		UNW_DEC_PRIUNAT_WHEN_MEM ("P8", t, arg);
    1003  		break;
    1004  	      default:
    1005  		UNW_DEC_BAD_CODE (r);
    1006  		break;
    1007  	      }
    1008  	  }
    1009  	  break;
    1010  
    1011  	case 0x1:
    1012  	  if ((end - dp) < 2)
    1013  	    {
    1014  	      printf (_("\t<corrupt P9>\n"));
    1015  	      return end;
    1016  	    }
    1017  
    1018  	  byte1 = *dp++;
    1019  	  byte2 = *dp++;
    1020  	  UNW_DEC_GR_GR ("P9", (byte1 & 0xf), (byte2 & 0x7f), arg);
    1021  	  break;
    1022  
    1023  	case 0xf:		/* p10 */
    1024  	  if ((end - dp) < 2)
    1025  	    {
    1026  	      printf (_("\t<corrupt P10>\n"));
    1027  	      return end;
    1028  	    }
    1029  
    1030  	  byte1 = *dp++;
    1031  	  byte2 = *dp++;
    1032  	  UNW_DEC_ABI ("P10", byte1, byte2, arg);
    1033  	  break;
    1034  
    1035  	case 0x9:
    1036  	  return unw_decode_x1 (dp, code, arg, end);
    1037  
    1038  	case 0xa:
    1039  	  return unw_decode_x2 (dp, code, arg, end);
    1040  
    1041  	case 0xb:
    1042  	  return unw_decode_x3 (dp, code, arg, end);
    1043  
    1044  	case 0xc:
    1045  	  return unw_decode_x4 (dp, code, arg, end);
    1046  
    1047  	default:
    1048  	  UNW_DEC_BAD_CODE (code);
    1049  	  break;
    1050  	}
    1051      }
    1052    return dp;
    1053  }
    1054  
    1055  static const unsigned char *
    1056  unw_decode_b1 (const unsigned char *dp, unsigned int code,
    1057  	       void *arg ATTRIBUTE_UNUSED,
    1058  	       const unsigned char * end ATTRIBUTE_UNUSED)
    1059  {
    1060    unw_word label = (code & 0x1f);
    1061  
    1062    if ((code & 0x20) != 0)
    1063      UNW_DEC_COPY_STATE ("B1", label, arg);
    1064    else
    1065      UNW_DEC_LABEL_STATE ("B1", label, arg);
    1066    return dp;
    1067  }
    1068  
    1069  static const unsigned char *
    1070  unw_decode_b2 (const unsigned char *dp, unsigned int code,
    1071  	       void *arg ATTRIBUTE_UNUSED,
    1072  	       const unsigned char * end)
    1073  {
    1074    unw_word t;
    1075  
    1076    t = unw_decode_uleb128 (& dp, end);
    1077    UNW_DEC_EPILOGUE ("B2", t, (code & 0x1f), arg);
    1078    return dp;
    1079  }
    1080  
    1081  static const unsigned char *
    1082  unw_decode_b3_x4 (const unsigned char *dp, unsigned int code, void *arg,
    1083  		  const unsigned char * end)
    1084  {
    1085    unw_word t, ecount, label;
    1086  
    1087    if ((code & 0x10) == 0)
    1088      {
    1089        t = unw_decode_uleb128 (&dp, end);
    1090        ecount = unw_decode_uleb128 (&dp, end);
    1091        UNW_DEC_EPILOGUE ("B3", t, ecount, arg);
    1092      }
    1093    else if ((code & 0x07) == 0)
    1094      {
    1095        label = unw_decode_uleb128 (&dp, end);
    1096        if ((code & 0x08) != 0)
    1097  	UNW_DEC_COPY_STATE ("B4", label, arg);
    1098        else
    1099  	UNW_DEC_LABEL_STATE ("B4", label, arg);
    1100      }
    1101    else
    1102      switch (code & 0x7)
    1103        {
    1104        case 1:
    1105  	return unw_decode_x1 (dp, code, arg, end);
    1106        case 2:
    1107  	return unw_decode_x2 (dp, code, arg, end);
    1108        case 3:
    1109  	return unw_decode_x3 (dp, code, arg, end);
    1110        case 4:
    1111  	return unw_decode_x4 (dp, code, arg, end);
    1112        default:
    1113  	UNW_DEC_BAD_CODE (code);
    1114  	break;
    1115        }
    1116    return dp;
    1117  }
    1118  
    1119  typedef const unsigned char *(*unw_decoder)
    1120    (const unsigned char *, unsigned int, void *, const unsigned char *);
    1121  
    1122  static const unw_decoder unw_decode_table[2][8] =
    1123    {
    1124      /* prologue table: */
    1125      {
    1126        unw_decode_r1,		/* 0 */
    1127        unw_decode_r1,
    1128        unw_decode_r2,
    1129        unw_decode_r3,
    1130        unw_decode_p1,		/* 4 */
    1131        unw_decode_p2_p5,
    1132        unw_decode_p6,
    1133        unw_decode_p7_p10
    1134      },
    1135      {
    1136        unw_decode_r1,		/* 0 */
    1137        unw_decode_r1,
    1138        unw_decode_r2,
    1139        unw_decode_r3,
    1140        unw_decode_b1,		/* 4 */
    1141        unw_decode_b1,
    1142        unw_decode_b2,
    1143        unw_decode_b3_x4
    1144      }
    1145    };
    1146  
    1147  /* Decode one descriptor and return address of next descriptor.  */
    1148  const unsigned char *
    1149  unw_decode (const unsigned char *dp, int inside_body,
    1150  	    void *ptr_inside_body, const unsigned char * end)
    1151  {
    1152    unw_decoder decoder;
    1153    unsigned char code;
    1154  
    1155    if ((end - dp) < 1)
    1156      {
    1157        printf (_("\t<corrupt IA64 descriptor>\n"));
    1158        return end;
    1159      }
    1160  
    1161    code = *dp++;
    1162    decoder = unw_decode_table[inside_body][code >> 5];
    1163    return (*decoder) (dp, code, ptr_inside_body, end);
    1164  }