unwind-ia64.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 1,109 行 · 第 1/2 页
C
1,109 行
/* unwind-ia64.c -- utility routines to dump IA-64 unwind info for readelf. Copyright 2000, 2001 Free Software Foundation, Inc. Contributed by David Mosberger-Tang <davidm@hpl.hp.com>This file is part of GNU Binutils.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "unwind-ia64.h"#include <stdio.h>#include <string.h>#if __GNUC__ >= 2/* Define BFD64 here, even if our default architecture is 32 bit ELF as this will allow us to read in and parse 64bit and 32bit ELF files. Only do this if we belive that the compiler can support a 64 bit data type. For now we only rely on GCC being able to do this. */#define BFD64#endif#include "bfd.h"static bfd_vma unw_rlen = 0;static voidunw_print_brmask (cp, mask) char * cp; unsigned char mask;{ char *sep = ""; int i; for (i = 0; mask && (i < 5); ++i) { if (mask & 1) { cp += sprintf (cp, "%sb%u", sep, i + 1); sep = ","; } mask >>= 1; } *cp = '\0';}static voidunw_print_grmask (cp, mask) char * cp; unsigned char mask;{ char *sep = ""; int i; *cp = '\0'; for (i = 0; i < 4; ++i) { if (mask & 1) { cp += sprintf (cp, "%sr%u", sep, i + 4); sep = ","; } mask >>= 1; }}static voidunw_print_frmask (cp, mask) char * cp; unsigned long mask;{ char *sep = ""; int i; *cp = '\0'; for (i = 0; i < 20; ++i) { if (mask & 1) { cp += sprintf (cp, "%sf%u", sep, (i < 4) ? (i + 2) : (i + 12)); sep = ","; } mask >>= 1; }}static voidunw_print_abreg (cp, abreg) char * cp; unsigned char abreg;{ static const char *special_reg[16] = { "pr", "psp", "@priunat", "rp", "ar.bsp", "ar.bspstore", "ar.rnat", "ar.unat", "ar.fpsr", "ar.pfs", "ar.lc", "Unknown11", "Unknown12", "Unknown13", "Unknown14", "Unknown15" }; switch ((abreg >> 5) & 0x3) { case 0: /* gr */ sprintf (cp, "r%u", (abreg & 0x1f)); break; case 1: /* fr */ sprintf (cp, "f%u", (abreg & 0x1f)); break; case 2: /* br */ sprintf (cp, "b%u", (abreg & 0x1f)); break; case 3: /* special */ strcpy (cp, special_reg[abreg & 0xf]); break; }}static voidunw_print_xyreg (cp, x, ytreg) char * cp; unsigned char x; unsigned char ytreg;{ switch ((x << 1) | ((ytreg >> 7) & 1)) { case 0: /* gr */ sprintf (cp, "r%u", (ytreg & 0x1f)); break; case 1: /* fr */ sprintf (cp, "f%u", (ytreg & 0x1f)); break; case 2: /* br */ sprintf (cp, "b%u", (ytreg & 0x1f)); break; }}#define UNW_REG_BSP "bsp"#define UNW_REG_BSPSTORE "bspstore"#define UNW_REG_FPSR "fpsr"#define UNW_REG_LC "lc"#define UNW_REG_PFS "pfs"#define UNW_REG_PR "pr"#define UNW_REG_PSP "psp"#define UNW_REG_RNAT "rnat"#define UNW_REG_RP "rp"#define UNW_REG_UNAT "unat"typedef bfd_vma unw_word;#define UNW_DEC_BAD_CODE(code) \ printf ("Unknown code 0x%02x\n", code)#define UNW_DEC_PROLOGUE(fmt, body, rlen, arg) \ do \ { \ unw_rlen = rlen; \ *(int *)arg = body; \ printf (" %s:%s(rlen=%lu)\n", \ fmt, body ? "body" : "prologue", (unsigned long) rlen); \ } \ while (0)#define UNW_DEC_PROLOGUE_GR(fmt, rlen, mask, grsave, arg) \ do \ { \ char regname[16], maskstr[64], *sep; \ \ unw_rlen = rlen; \ *(int *)arg = 0; \ \ maskstr[0] = '\0'; \ sep = ""; \ if (mask & 0x8) \ { \ strcat (maskstr, "rp"); \ sep = ","; \ } \ if (mask & 0x4) \ { \ strcat (maskstr, sep); \ strcat (maskstr, "ar.pfs"); \ sep = ","; \ } \ if (mask & 0x2) \ { \ strcat (maskstr, sep); \ strcat (maskstr, "psp"); \ sep = ","; \ } \ if (mask & 0x1) \ { \ strcat (maskstr, sep); \ strcat (maskstr, "pr"); \ } \ sprintf (regname, "r%u", grsave); \ printf (" %s:prologue_gr(mask=[%s],grsave=%s,rlen=%lu)\n", \ fmt, maskstr, regname, (unsigned long) rlen); \ } \ while (0)#define UNW_DEC_FR_MEM(fmt, frmask, arg) \ do \ { \ char frstr[200]; \ \ unw_print_frmask (frstr, frmask); \ printf ("\t%s:fr_mem(frmask=[%s])\n", fmt, frstr); \ } \ while (0)#define UNW_DEC_GR_MEM(fmt, grmask, arg) \ do \ { \ char grstr[200]; \ \ unw_print_grmask (grstr, grmask); \ printf ("\t%s:gr_mem(grmask=[%s])\n", fmt, grstr); \ } \ while (0)#define UNW_DEC_FRGR_MEM(fmt, grmask, frmask, arg) \ do \ { \ char frstr[200], grstr[20]; \ \ unw_print_grmask (grstr, grmask); \ unw_print_frmask (frstr, frmask); \ printf ("\t%s:frgr_mem(grmask=[%s],frmask=[%s])\n", fmt, grstr, frstr); \ } \ while (0)#define UNW_DEC_BR_MEM(fmt, brmask, arg) \ do \ { \ char brstr[20]; \ \ unw_print_brmask (brstr, brmask); \ printf ("\t%s:br_mem(brmask=[%s])\n", fmt, brstr); \ } \ while (0)#define UNW_DEC_BR_GR(fmt, brmask, gr, arg) \ do \ { \ char brstr[20]; \ \ unw_print_brmask (brstr, brmask); \ printf ("\t%s:br_gr(brmask=[%s],gr=r%u)\n", fmt, brstr, gr); \ } \ while (0)#define UNW_DEC_REG_GR(fmt, src, dst, arg) \ printf ("\t%s:%s_gr(reg=r%u)\n", fmt, src, dst)#define UNW_DEC_RP_BR(fmt, dst, arg) \ printf ("\t%s:rp_br(reg=b%u)\n", fmt, dst)#define UNW_DEC_REG_WHEN(fmt, reg, t, arg) \ printf ("\t%s:%s_when(t=%lu)\n", fmt, reg, (unsigned long) t)#define UNW_DEC_REG_SPREL(fmt, reg, spoff, arg) \ printf ("\t%s:%s_sprel(spoff=0x%lx)\n", \ fmt, reg, 4*(unsigned long)spoff)#define UNW_DEC_REG_PSPREL(fmt, reg, pspoff, arg) \ printf ("\t%s:%s_psprel(pspoff=0x10-0x%lx)\n", \ fmt, reg, 4*(unsigned long)pspoff)#define UNW_DEC_GR_GR(fmt, grmask, gr, arg) \ do \ { \ char grstr[20]; \ \ unw_print_grmask (grstr, grmask); \ printf ("\t%s:gr_gr(grmask=[%s],r%u)\n", fmt, grstr, gr); \ } \ while (0)#define UNW_DEC_ABI(fmt, abi, context, arg) \ do \ { \ static const char *abiname[] = \ { \ "@svr4", "@hpux", "@nt" \ }; \ char buf[20]; \ const char *abistr = buf; \ \ if (abi < 3) \ abistr = abiname[abi]; \ else \ sprintf (buf, "0x%x", abi); \ printf ("\t%s:unwabi(abi=%s,context=0x%02x)\n", \ fmt, abistr, context); \ } \ while (0)#define UNW_DEC_PRIUNAT_GR(fmt, r, arg) \ printf ("\t%s:priunat_gr(reg=r%u)\n", fmt, r)#define UNW_DEC_PRIUNAT_WHEN_GR(fmt, t, arg) \ printf ("\t%s:priunat_when_gr(t=%lu)\n", fmt, (unsigned long) t)#define UNW_DEC_PRIUNAT_WHEN_MEM(fmt, t, arg) \ printf ("\t%s:priunat_when_mem(t=%lu)\n", fmt, (unsigned long) t)#define UNW_DEC_PRIUNAT_PSPREL(fmt, pspoff, arg) \ printf ("\t%s:priunat_psprel(pspoff=0x10-0x%lx)\n", \ fmt, 4*(unsigned long)pspoff)#define UNW_DEC_PRIUNAT_SPREL(fmt, spoff, arg) \ printf ("\t%s:priunat_sprel(spoff=0x%lx)\n", \ fmt, 4*(unsigned long)spoff)#define UNW_DEC_MEM_STACK_F(fmt, t, size, arg) \ printf ("\t%s:mem_stack_f(t=%lu,size=%lu)\n", \ fmt, (unsigned long) t, 16*(unsigned long)size)#define UNW_DEC_MEM_STACK_V(fmt, t, arg) \ printf ("\t%s:mem_stack_v(t=%lu)\n", fmt, (unsigned long) t)#define UNW_DEC_SPILL_BASE(fmt, pspoff, arg) \ printf ("\t%s:spill_base(pspoff=0x10-0x%lx)\n", \ fmt, 4*(unsigned long)pspoff)#define UNW_DEC_SPILL_MASK(fmt, dp, arg) \ do \ { \ static const char * spill_type = "-frb"; \ unsigned const char * imaskp = dp; \ unsigned char mask = 0; \ bfd_vma insn = 0; \ \ printf ("\t%s:spill_mask(imask=[", fmt); \ for (insn = 0; insn < unw_rlen; ++insn) \ { \ if ((insn % 4) == 0) \ mask = *imaskp++; \ if (insn > 0 && (insn % 3) == 0) \ putchar (','); \ putchar (spill_type[(mask >> (2 * (3 - (insn & 0x3)))) & 0x3]); \ } \ printf ("])\n"); \ dp = imaskp; \ } \ while (0)#define UNW_DEC_SPILL_SPREL(fmt, t, abreg, spoff, arg) \ do \ { \ char regname[10]; \ \ unw_print_abreg (regname, abreg); \ printf ("\t%s:spill_sprel(reg=%s,t=%lu,spoff=0x%lx)\n", \ fmt, regname, (unsigned long) t, 4*(unsigned long)off); \ } \ while (0)#define UNW_DEC_SPILL_PSPREL(fmt, t, abreg, pspoff, arg) \ do \ { \ char regname[10]; \ \ unw_print_abreg (regname, abreg); \ printf ("\t%s:spill_psprel(reg=%s,t=%lu,pspoff=0x10-0x%lx)\n", \ fmt, regname, (unsigned long) t, 4*(unsigned long)pspoff); \ } \ while (0)#define UNW_DEC_RESTORE(fmt, t, abreg, arg) \ do \ { \ char regname[10]; \ \ unw_print_abreg (regname, abreg); \ printf ("\t%s:restore(t=%lu,reg=%s)\n", \ fmt, (unsigned long) t, regname); \ } \ while (0)#define UNW_DEC_SPILL_REG(fmt, t, abreg, x, ytreg, arg) \ do \ { \ char abregname[10], tregname[10]; \ \ unw_print_abreg (abregname, abreg); \ unw_print_xyreg (tregname, x, ytreg); \ printf ("\t%s:spill_reg(t=%lu,reg=%s,treg=%s)\n", \ fmt, (unsigned long) t, abregname, tregname); \ } \ while (0)#define UNW_DEC_SPILL_SPREL_P(fmt, qp, t, abreg, spoff, arg) \ do \ { \ char regname[20]; \ \ unw_print_abreg (regname, abreg); \ printf ("\t%s:spill_sprel_p(qp=p%u,t=%lu,reg=%s,spoff=0x%lx)\n", \ fmt, qp, (unsigned long) t, regname, 4 * (unsigned long)spoff); \ } \ while (0)#define UNW_DEC_SPILL_PSPREL_P(fmt, qp, t, abreg, pspoff, arg) \ do \ { \ char regname[20]; \ \ unw_print_abreg (regname, abreg); \ printf ("\t%s:spill_psprel_p(qp=p%u,t=%lu,reg=%s,pspoff=0x10-0x%lx)\n",\ fmt, qp, (unsigned long) t, regname, 4*(unsigned long)pspoff);\ } \ while (0)#define UNW_DEC_RESTORE_P(fmt, qp, t, abreg, arg) \ do \ { \ char regname[20]; \ \ unw_print_abreg (regname, abreg); \ printf ("\t%s:restore_p(qp=p%u,t=%lu,reg=%s)\n", \ fmt, qp, (unsigned long) t, regname); \ } \ while (0)#define UNW_DEC_SPILL_REG_P(fmt, qp, t, abreg, x, ytreg, arg) \ do \ { \ char regname[20], tregname[20]; \ \ unw_print_abreg (regname, abreg); \ unw_print_xyreg (tregname, x, ytreg); \ printf ("\t%s:spill_reg_p(qp=p%u,t=%lu,reg=%s,treg=%s)\n", \ fmt, qp, (unsigned long) t, regname, tregname); \ } \ while (0)#define UNW_DEC_LABEL_STATE(fmt, label, arg) \ printf ("\t%s:label_state(label=%lu)\n", fmt, (unsigned long) label)#define UNW_DEC_COPY_STATE(fmt, label, arg) \ printf ("\t%s:copy_state(label=%lu)\n", fmt, (unsigned long) label)#define UNW_DEC_EPILOGUE(fmt, t, ecount, arg) \ printf ("\t%s:epilogue(t=%lu,ecount=%lu)\n", \ fmt, (unsigned long) t, (unsigned long) ecount)/* * Generic IA-64 unwind info decoder. * * This file is used both by the Linux kernel and objdump. Please * keep the two copies of this file in sync (modulo differences in the * prototypes...). * * You need to customize the decoder by defining the following * macros/constants before including this file: * * Types: * unw_word Unsigned integer type with at least 64 bits * * Register names: * UNW_REG_BSP * UNW_REG_BSPSTORE * UNW_REG_FPSR * UNW_REG_LC * UNW_REG_PFS * UNW_REG_PR * UNW_REG_RNAT * UNW_REG_PSP * UNW_REG_RP * UNW_REG_UNAT * * Decoder action macros: * UNW_DEC_BAD_CODE(code) * UNW_DEC_ABI(fmt,abi,context,arg) * UNW_DEC_BR_GR(fmt,brmask,gr,arg) * UNW_DEC_BR_MEM(fmt,brmask,arg) * UNW_DEC_COPY_STATE(fmt,label,arg) * UNW_DEC_EPILOGUE(fmt,t,ecount,arg) * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg) * UNW_DEC_FR_MEM(fmt,frmask,arg) * UNW_DEC_GR_GR(fmt,grmask,gr,arg) * UNW_DEC_GR_MEM(fmt,grmask,arg) * UNW_DEC_LABEL_STATE(fmt,label,arg) * UNW_DEC_MEM_STACK_F(fmt,t,size,arg) * UNW_DEC_MEM_STACK_V(fmt,t,arg) * UNW_DEC_PRIUNAT_GR(fmt,r,arg) * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg) * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg) * UNW_DEC_PROLOGUE(fmt,body,rlen,arg) * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg) * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg) * UNW_DEC_REG_REG(fmt,src,dst,arg) * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg) * UNW_DEC_REG_WHEN(fmt,reg,t,arg) * UNW_DEC_RESTORE(fmt,t,abreg,arg) * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg) * UNW_DEC_SPILL_BASE(fmt,pspoff,arg) * UNW_DEC_SPILL_MASK(fmt,imaskp,arg) * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg) * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg) * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg) * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg) * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg) * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg) */static unw_word unw_decode_uleb128 PARAMS ((const unsigned char **));static const unsigned char *unw_decode_x1 PARAMS ((const unsigned char *, unsigned char, void *));static const unsigned char *unw_decode_x2 PARAMS ((const unsigned char *, unsigned char, void *));static const unsigned char *unw_decode_x3 PARAMS ((const unsigned char *, unsigned char, void *));static const unsigned char *unw_decode_x4 PARAMS ((const unsigned char *, unsigned char, void *));static const unsigned char *unw_decode_r1 PARAMS ((const unsigned char *, unsigned char, void *));static const unsigned char *unw_decode_r2 PARAMS ((const unsigned char *, unsigned char, void *));static const unsigned char *unw_decode_r3 PARAMS ((const unsigned char *, unsigned char, void *));static const unsigned char *unw_decode_p1 PARAMS ((const unsigned char *, unsigned char, void *));static const unsigned char *unw_decode_p2_p5 PARAMS ((const unsigned char *, unsigned char, void *));static const unsigned char *unw_decode_p6 PARAMS ((const unsigned char *, unsigned char, void *));static const unsigned char *unw_decode_p7_p10 PARAMS ((const unsigned char *, unsigned char, void *));static const unsigned char *unw_decode_b1 PARAMS ((const unsigned char *, unsigned char, void *));static const unsigned char *unw_decode_b2 PARAMS ((const unsigned char *, unsigned char, void *));static const unsigned char *unw_decode_b3_x4 PARAMS ((const unsigned char *, unsigned char, void *));static unw_wordunw_decode_uleb128 (dpp) const unsigned char **dpp;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?