⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hipe_ppc_stack.c

📁 OTP是开放电信平台的简称
💻 C
字号:
/* $Id$ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "global.h"#include "bif.h"#include "hipe_stack.h"#include "hipe_ppc_asm.h"	/* for NR_ARG_REGS */AEXTERN(void,nbif_fail,(void));AEXTERN(void,nbif_stack_trap_ra,(void));/* * hipe_print_nstack() is called from hipe_bifs:show_nstack/1. */static void print_slot(Eterm *sp, unsigned int live){    Eterm val = *sp;    printf(" | 0x%0*lx | 0x%0*lx | ",	   2*(int)sizeof(long), (unsigned long)sp,	   2*(int)sizeof(long), val);    if( live )	erts_printf("%.30T", val);    printf("\r\n");}void hipe_print_nstack(Process *p){    Eterm *nsp;    Eterm *nsp_end;    const struct sdesc *sdesc1;    const struct sdesc *sdesc;    unsigned long ra;    unsigned long exnra;    unsigned int mask;    unsigned int sdesc_size;    unsigned int i;    unsigned int nstkarity;    static const char dashes[2*sizeof(long)+5] = {	[0 ... 2*sizeof(long)+3] = '-'    };    printf(" |      NATIVE  STACK      |\r\n");    printf(" |%s|%s|\r\n", dashes, dashes);    printf(" | %*s | 0x%0*lx |\r\n",	   2+2*(int)sizeof(long), "heap",	   2*(int)sizeof(long), (unsigned long)p->heap);    printf(" | %*s | 0x%0*lx |\r\n",	   2+2*(int)sizeof(long), "high_water",	   2*(int)sizeof(long), (unsigned long)p->high_water);    printf(" | %*s | 0x%0*lx |\r\n",	   2+2*(int)sizeof(long), "hend",	   2*(int)sizeof(long), (unsigned long)p->htop);    printf(" | %*s | 0x%0*lx |\r\n",	   2+2*(int)sizeof(long), "old_heap",	   2*(int)sizeof(long), (unsigned long)p->old_heap);    printf(" | %*s | 0x%0*lx |\r\n",	   2+2*(int)sizeof(long), "old_hend",	   2*(int)sizeof(long), (unsigned long)p->old_hend);    printf(" | %*s | 0x%0*lx |\r\n",	   2+2*(int)sizeof(long), "nsp",	   2*(int)sizeof(long), (unsigned long)p->hipe.nsp);    printf(" | %*s | 0x%0*lx |\r\n",	   2+2*(int)sizeof(long), "nstend",	   2*(int)sizeof(long), (unsigned long)p->hipe.nstend);    printf(" | %*s| 0x%0*lx |\r\n",	   2+2*(int)sizeof(long)+1, "nstblacklim",	   2*(int)sizeof(long), (unsigned long)p->hipe.nstblacklim);    printf(" | %*s | 0x%0*lx |\r\n",	   2+2*(int)sizeof(long), "nstgraylim",	   2*(int)sizeof(long), (unsigned long)p->hipe.nstgraylim);    printf(" | %*s | 0x%0*lx |\r\n",	   2+2*(int)sizeof(long), "nra",	   2*(int)sizeof(long), (unsigned long)p->hipe.nra);    printf(" | %*s | 0x%0*x |\r\n",	   2+2*(int)sizeof(long), "narity",	   2*(int)sizeof(long), p->hipe.narity);    printf(" |%s|%s|\r\n", dashes, dashes);    printf(" | %*s | %*s |\r\n",	   2+2*(int)sizeof(long), "Address",	   2+2*(int)sizeof(long), "Contents");    ra = (unsigned long)p->hipe.nra;    if( !ra )	return;    nsp = p->hipe.nsp;    nsp_end = p->hipe.nstend - 1;    nstkarity = p->hipe.narity - NR_ARG_REGS;    if( (int)nstkarity < 0 )	nstkarity = 0;    /* First RA not on stack. Dump current args first. */    printf(" |%s|%s|\r\n", dashes, dashes);    for(i = 0; i < nstkarity; ++i)	print_slot(&nsp[i], 1);    nsp += nstkarity;    if( ra == (unsigned long)&nbif_stack_trap_ra )	ra = (unsigned long)p->hipe.ngra;    sdesc = hipe_find_sdesc(ra);    for(;;) {	/* INV: nsp at bottom of frame described by sdesc */	printf(" |%s|%s|\r\n", dashes, dashes);	if( nsp >= nsp_end ) {	    if( nsp == nsp_end )		return;	    fprintf(stderr, "%s: passed end of stack\r\n", __FUNCTION__);	    break;	}	ra = nsp[sdesc_fsize(sdesc)];	if( ra == (unsigned long)&nbif_stack_trap_ra )	    sdesc1 = hipe_find_sdesc((unsigned long)p->hipe.ngra);	else	    sdesc1 = hipe_find_sdesc(ra);	sdesc_size = sdesc_fsize(sdesc) + 1 + sdesc_arity(sdesc);	i = 0;	mask = sdesc->livebits[0];	for(;;) {	    if( i == sdesc_fsize(sdesc) ) {		printf(" | 0x%0*lx | 0x%0*lx | ",		       2*(int)sizeof(long), (unsigned long)&nsp[i],		       2*(int)sizeof(long), ra);		if( ra == (unsigned long)&nbif_stack_trap_ra )		    printf("STACK TRAP, ORIG RA 0x%lx", (unsigned long)p->hipe.ngra);		else		    printf("NATIVE RA");		if( (exnra = sdesc_exnra(sdesc1)) != 0 )		    printf(", EXNRA 0x%lx", exnra);		printf("\r\n");	    } else {		print_slot(&nsp[i], (mask & 1));	    }	    if( ++i >= sdesc_size )		break;	    if( i & 31 )		mask >>= 1;	    else		mask = sdesc->livebits[i >> 5];	}	nsp += sdesc_size;	sdesc = sdesc1;    }    abort();}/* XXX: x86's values, not yet tuned for ppc */#define MINSTACK	128#define NSKIPFRAMES	4void hipe_update_stack_trap(Process *p, const struct sdesc *sdesc){    Eterm *nsp;    Eterm *nsp_end;    unsigned long ra;    int n;    nsp = p->hipe.nsp;    nsp_end = p->hipe.nstend - 1;    if( (unsigned long)((char*)nsp_end - (char*)nsp) < MINSTACK*sizeof(Eterm*) ) {	p->hipe.nstgraylim = NULL;	return;    }    n = NSKIPFRAMES;    for(;;) {	nsp += sdesc_fsize(sdesc);	if( nsp >= nsp_end ) {	    p->hipe.nstgraylim = NULL;	    return;	}	ra = nsp[0];	if( --n <= 0 )	    break;	nsp += 1 + sdesc_arity(sdesc);	sdesc = hipe_find_sdesc(ra);    }    p->hipe.nstgraylim = nsp + 1 + sdesc_arity(sdesc);    p->hipe.ngra = (void(*)(void))ra;    nsp[0] = (unsigned long)&nbif_stack_trap_ra;}/* * hipe_handle_stack_trap() is called when the mutator returns to * nbif_stack_trap_ra, which marks the gray/white stack boundary frame. * The gray/white boundary is moved back one or more frames. * * The function head below is "interesting". */void (*hipe_handle_stack_trap(Process *p))(void){    void (*ngra)(void) = p->hipe.ngra;    const struct sdesc *sdesc = hipe_find_sdesc((unsigned long)ngra);    hipe_update_stack_trap(p, sdesc);    return ngra;}/* * hipe_find_handler() is called from hipe_handle_exception() to locate * the current exception handler's PC and SP. * The native stack MUST contain a stack frame as it appears on * entry to a function (actuals, caller's frame, caller's return address). * p->hipe.narity MUST contain the arity (number of actuals). * On exit, p->hipe.ncallee is set to the handler's PC and p->hipe.nsp * is set to its SP (low address of its stack frame). */void hipe_find_handler(Process *p){    Eterm *nsp;    Eterm *nsp_end;    unsigned long ra;    unsigned long exnra;    unsigned int arity;    const struct sdesc *sdesc;    nsp = p->hipe.nsp;    nsp_end = p->hipe.nstend;    arity = p->hipe.narity - NR_ARG_REGS;    if( (int)arity < 0 )	arity = 0;    ra = (unsigned long)p->hipe.nra;    while( nsp < nsp_end ) {	nsp += arity;		/* skip actuals */	if( ra == (unsigned long)&nbif_stack_trap_ra )	    ra = (unsigned long)p->hipe.ngra;	sdesc = hipe_find_sdesc(ra);	if( (exnra = sdesc_exnra(sdesc)) != 0 &&	    (p->catches >= 0 ||	     exnra == (unsigned long)&nbif_fail) ) {	    p->hipe.ncallee = (void(*)(void)) exnra;	    p->hipe.nsp = nsp;	    p->hipe.narity = 0;	    /* update the gray/white boundary if we threw past it */	    if( p->hipe.nstgraylim && nsp >= p->hipe.nstgraylim )		hipe_update_stack_trap(p, sdesc);	    return;	}	nsp += sdesc_fsize(sdesc);	/* skip locals */	arity = sdesc_arity(sdesc);	ra = *nsp++;			/* fetch & skip saved ra */    }    fprintf(stderr, "%s: no native CATCH found!\r\n", __FUNCTION__);    abort();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -