Home | History | Annotate | Line # | Download | only in unwind
stackframe.c revision 1.5.6.1
      1  1.5.6.1    skrll /*	$NetBSD: stackframe.c,v 1.5.6.1 2016/10/05 20:55:30 skrll Exp $	*/
      2      1.1   cherry 
      3      1.1   cherry /* Contributed to the NetBSD foundation by Cherry G. Mathew <cherry (at) mahiti.org>
      4      1.1   cherry  * This file contains routines to use decoded unwind descriptor entries
      5      1.1   cherry  * to build a stack configuration. The unwinder consults the stack
      6      1.1   cherry  * configuration to fetch registers used to unwind the frame.
      7      1.1   cherry  * References:
      8      1.1   cherry  *	[1] section. 11.4.2.6., Itanium Software Conventions and
      9      1.1   cherry  *			Runtime Architecture Guide.
     10      1.1   cherry  */
     11      1.1   cherry 
     12      1.1   cherry #include <sys/cdefs.h>
     13      1.1   cherry #include <sys/param.h>
     14      1.1   cherry #include <sys/systm.h>
     15      1.1   cherry 
     16      1.1   cherry 
     17      1.1   cherry #include <ia64/unwind/decode.h>
     18      1.1   cherry #include <ia64/unwind/stackframe.h>
     19      1.1   cherry 
     20      1.1   cherry //#define UNWIND_DIAGNOSTIC
     21      1.1   cherry 
     22  1.5.6.1    skrll /*
     23  1.5.6.1    skrll  * Global variables:
     24  1.5.6.1    skrll  * array of struct recordchain
     25  1.5.6.1    skrll  * size of record chain array.
     26  1.5.6.1    skrll  */
     27      1.1   cherry struct recordchain strc[MAXSTATERECS];
     28      1.1   cherry int rec_cnt = 0;
     29      1.1   cherry 
     30  1.5.6.1    skrll /*
     31  1.5.6.1    skrll  * Build a recordchain of a region, given the pointer to unwind table
     32      1.1   cherry  * entry, and the number of entries to decode.
     33      1.1   cherry  */
     34  1.5.6.1    skrll void
     35  1.5.6.1    skrll buildrecordchain(uint64_t unwind_infop, struct recordchain *xxx)
     36      1.1   cherry {
     37      1.1   cherry 	uint64_t unwindstart, unwindend;
     38      1.1   cherry 	uint64_t unwindlen;
     39      1.1   cherry 	uint64_t region_len = 0;
     40      1.3  thorpej 	bool region_type = false; /* Prologue */
     41      1.1   cherry 
     42      1.1   cherry 	struct unwind_hdr_t {
     43      1.1   cherry 		uint64_t uwh;
     44      1.1   cherry 	} *uwhp = (void *) unwind_infop;
     45      1.1   cherry 
     46      1.1   cherry 	char *nextrecp, *recptr = (char *) unwind_infop + sizeof(uint64_t);
     47      1.1   cherry 
     48      1.1   cherry 	unwindstart = (uint64_t) recptr;
     49      1.1   cherry 
     50      1.1   cherry 	if (UNW_VER(uwhp->uwh) != 1) {
     51      1.1   cherry 		printf("Wrong unwind version! \n");
     52      1.1   cherry 		return;
     53      1.1   cherry 	}
     54      1.1   cherry 
     55      1.1   cherry 	unwindlen = UNW_LENGTH(uwhp->uwh) * sizeof(uint64_t);
     56      1.1   cherry 	unwindend = unwindstart + unwindlen;
     57      1.1   cherry 
     58      1.1   cherry #ifdef UNWIND_DIAGNOSTIC
     59      1.1   cherry 	printf("recptr = %p \n", recptr);
     60      1.1   cherry 	printf("unwindlen = %lx \n", unwindlen);
     61      1.1   cherry 	printf("unwindend = %lx \n", unwindend);
     62      1.1   cherry #endif
     63      1.1   cherry 
     64      1.1   cherry 	/* XXX: Ignore zero length records. */
     65      1.1   cherry 
     66      1.1   cherry 
     67  1.5.6.1    skrll 	for (rec_cnt = 0;
     68  1.5.6.1    skrll 	    rec_cnt < MAXSTATERECS && (uint64_t)recptr < unwindend;
     69      1.1   cherry 	    rec_cnt++) {
     70  1.5.6.1    skrll 		nextrecp = unwind_decode_R1(recptr, &strc[rec_cnt].udesc);
     71  1.5.6.1    skrll 		if (nextrecp) {
     72      1.1   cherry 			region_len = strc[rec_cnt].udesc.R1.rlen;
     73      1.1   cherry 			region_type = strc[rec_cnt].udesc.R1.r;
     74      1.1   cherry 			strc[rec_cnt].type = R1;
     75      1.1   cherry 			recptr = nextrecp;
     76      1.1   cherry 			continue;
     77      1.1   cherry 		}
     78      1.1   cherry 
     79  1.5.6.1    skrll 		nextrecp = unwind_decode_R2(recptr, &strc[rec_cnt].udesc);
     80  1.5.6.1    skrll 		if (nextrecp) {
     81      1.1   cherry 			region_len = strc[rec_cnt].udesc.R2.rlen;
     82  1.5.6.1    skrll 			/* R2 regions are prologue regions */
     83  1.5.6.1    skrll 			region_type = false;
     84      1.1   cherry 			strc[rec_cnt].type = R2;
     85      1.1   cherry 			recptr = nextrecp;
     86      1.1   cherry 			continue;
     87      1.1   cherry 		}
     88      1.1   cherry 
     89  1.5.6.1    skrll 		nextrecp = unwind_decode_R3(recptr, &strc[rec_cnt].udesc);
     90  1.5.6.1    skrll 		if (nextrecp) {
     91      1.1   cherry 			region_len = strc[rec_cnt].udesc.R3.rlen;
     92      1.1   cherry 			region_type = strc[rec_cnt].udesc.R3.r;
     93      1.1   cherry 			strc[rec_cnt].type = R3;
     94      1.1   cherry 			recptr = nextrecp;
     95      1.1   cherry 			continue;
     96      1.1   cherry 		}
     97      1.1   cherry 
     98  1.5.6.1    skrll 		if (region_type == false) {
     99  1.5.6.1    skrll 			/* Prologue Region */
    100  1.5.6.1    skrll 			nextrecp = unwind_decode_P1(recptr,
    101  1.5.6.1    skrll 						    &strc[rec_cnt].udesc);
    102  1.5.6.1    skrll 			if (nextrecp) {
    103      1.1   cherry 				strc[rec_cnt].type = P1;
    104      1.1   cherry 				recptr = nextrecp;
    105      1.1   cherry 				continue;
    106      1.1   cherry 			}
    107      1.1   cherry 
    108  1.5.6.1    skrll 			nextrecp = unwind_decode_P2(recptr,
    109  1.5.6.1    skrll 						    &strc[rec_cnt].udesc);
    110  1.5.6.1    skrll 			if (nextrecp) {
    111      1.1   cherry 				strc[rec_cnt].type = P2;
    112      1.1   cherry 				recptr = nextrecp;
    113      1.1   cherry 				continue;
    114      1.1   cherry 			}
    115      1.1   cherry 
    116  1.5.6.1    skrll 			nextrecp = unwind_decode_P3(recptr,
    117  1.5.6.1    skrll 						    &strc[rec_cnt].udesc);
    118  1.5.6.1    skrll 			if (nextrecp) {
    119      1.1   cherry 				strc[rec_cnt].type = P3;
    120      1.1   cherry 				recptr = nextrecp;
    121      1.1   cherry 				continue;
    122      1.1   cherry 			}
    123      1.1   cherry 
    124  1.5.6.1    skrll 			nextrecp = unwind_decode_P4(recptr,
    125  1.5.6.1    skrll 						    &strc[rec_cnt].udesc,
    126  1.5.6.1    skrll 						    region_len);
    127  1.5.6.1    skrll 			if (nextrecp) {
    128      1.1   cherry 				strc[rec_cnt].type = P4;
    129      1.1   cherry 				recptr = nextrecp;
    130      1.1   cherry 				break;
    131      1.1   cherry 			}
    132      1.1   cherry 
    133  1.5.6.1    skrll 			nextrecp = unwind_decode_P5(recptr,
    134  1.5.6.1    skrll 						    &strc[rec_cnt].udesc);
    135  1.5.6.1    skrll 			if (nextrecp) {
    136      1.1   cherry 				strc[rec_cnt].type = P5;
    137      1.1   cherry 				recptr = nextrecp;
    138      1.1   cherry 				continue;
    139      1.1   cherry 			}
    140      1.1   cherry 
    141  1.5.6.1    skrll 			nextrecp = unwind_decode_P6(recptr,
    142  1.5.6.1    skrll 						    &strc[rec_cnt].udesc);
    143  1.5.6.1    skrll 			if (nextrecp) {
    144      1.1   cherry 				strc[rec_cnt].type = P6;
    145      1.1   cherry 				recptr = nextrecp;
    146      1.1   cherry 				continue;
    147      1.1   cherry 			}
    148      1.1   cherry 
    149  1.5.6.1    skrll 			nextrecp = unwind_decode_P7(recptr,
    150  1.5.6.1    skrll 						    &strc[rec_cnt].udesc);
    151  1.5.6.1    skrll 			if (nextrecp) {
    152      1.1   cherry 				strc[rec_cnt].type = P7;
    153      1.1   cherry 				recptr = nextrecp;
    154      1.1   cherry 				continue;
    155      1.1   cherry 			}
    156      1.1   cherry 
    157  1.5.6.1    skrll 			nextrecp = unwind_decode_P8(recptr,
    158  1.5.6.1    skrll 						    &strc[rec_cnt].udesc);
    159  1.5.6.1    skrll 			if (nextrecp) {
    160      1.1   cherry 				strc[rec_cnt].type = P8;
    161      1.1   cherry 				recptr = nextrecp;
    162      1.1   cherry 				continue;
    163      1.1   cherry 			}
    164      1.1   cherry 
    165  1.5.6.1    skrll 			nextrecp = unwind_decode_P9(recptr,
    166  1.5.6.1    skrll 						    &strc[rec_cnt].udesc);
    167  1.5.6.1    skrll 			if (nextrecp) {
    168      1.1   cherry 				strc[rec_cnt].type = P9;
    169      1.1   cherry 				recptr = nextrecp;
    170      1.1   cherry 				continue;
    171      1.1   cherry 			}
    172      1.1   cherry 
    173  1.5.6.1    skrll 			nextrecp = unwind_decode_P10(recptr,
    174  1.5.6.1    skrll 						     &strc[rec_cnt].udesc);
    175  1.5.6.1    skrll 			if (nextrecp) {
    176      1.1   cherry 				strc[rec_cnt].type = P10;
    177      1.1   cherry 				recptr = nextrecp;
    178      1.1   cherry 				continue;
    179      1.1   cherry 			}
    180      1.1   cherry 
    181      1.1   cherry 			printf("Skipping prologue desc slot :: %d \n", rec_cnt);
    182  1.5.6.1    skrll 		} else {
    183      1.1   cherry 
    184  1.5.6.1    skrll 			nextrecp = unwind_decode_B1(recptr,
    185  1.5.6.1    skrll 						    &strc[rec_cnt].udesc);
    186  1.5.6.1    skrll 			if (nextrecp) {
    187      1.1   cherry 				strc[rec_cnt].type = B1;
    188      1.1   cherry 				recptr = nextrecp;
    189      1.1   cherry 				continue;
    190      1.1   cherry 			}
    191      1.1   cherry 
    192  1.5.6.1    skrll 			nextrecp = unwind_decode_B2(recptr,
    193  1.5.6.1    skrll 						    &strc[rec_cnt].udesc);
    194  1.5.6.1    skrll 			if (nextrecp) {
    195      1.1   cherry 				strc[rec_cnt].type = B2;
    196      1.1   cherry 				recptr = nextrecp;
    197      1.1   cherry 				continue;
    198      1.1   cherry 			}
    199      1.1   cherry 
    200  1.5.6.1    skrll 			nextrecp = unwind_decode_B3(recptr,
    201  1.5.6.1    skrll 						    &strc[rec_cnt].udesc);
    202  1.5.6.1    skrll 			if (nextrecp) {
    203      1.1   cherry 				strc[rec_cnt].type = B3;
    204      1.1   cherry 				recptr = nextrecp;
    205      1.1   cherry 				continue;
    206      1.1   cherry 			}
    207      1.1   cherry 
    208  1.5.6.1    skrll 			nextrecp = unwind_decode_B4(recptr,
    209  1.5.6.1    skrll 						    &strc[rec_cnt].udesc);
    210  1.5.6.1    skrll 			if (nextrecp) {
    211      1.1   cherry 				strc[rec_cnt].type = B4;
    212      1.1   cherry 				recptr = nextrecp;
    213      1.1   cherry 				continue;
    214      1.1   cherry 			}
    215      1.1   cherry 
    216  1.5.6.1    skrll 			nextrecp = unwind_decode_X1(recptr,
    217  1.5.6.1    skrll 						    &strc[rec_cnt].udesc);
    218  1.5.6.1    skrll 			if (nextrecp) {
    219      1.1   cherry 				strc[rec_cnt].type = X1;
    220      1.1   cherry 				recptr = nextrecp;
    221      1.1   cherry 				continue;
    222      1.1   cherry 			}
    223      1.1   cherry 
    224  1.5.6.1    skrll 			nextrecp = unwind_decode_X2(recptr,
    225  1.5.6.1    skrll 						    &strc[rec_cnt].udesc);
    226  1.5.6.1    skrll 			if (nextrecp) {
    227      1.1   cherry 				strc[rec_cnt].type = X2;
    228      1.1   cherry 				recptr = nextrecp;
    229      1.1   cherry 				continue;
    230      1.1   cherry 			}
    231      1.1   cherry 
    232      1.1   cherry 
    233  1.5.6.1    skrll 			nextrecp = unwind_decode_X3(recptr,
    234  1.5.6.1    skrll 						    &strc[rec_cnt].udesc);
    235  1.5.6.1    skrll 			if (nextrecp) {
    236      1.1   cherry 				strc[rec_cnt].type = X3;
    237      1.1   cherry 				recptr = nextrecp;
    238      1.1   cherry 				continue;
    239      1.1   cherry 			}
    240      1.1   cherry 
    241  1.5.6.1    skrll 			nextrecp = unwind_decode_X4(recptr,
    242  1.5.6.1    skrll 						    &strc[rec_cnt].udesc);
    243  1.5.6.1    skrll 			if (nextrecp) {
    244      1.1   cherry 				strc[rec_cnt].type = X4;
    245      1.1   cherry 				recptr = nextrecp;
    246      1.1   cherry 				continue;
    247      1.1   cherry 			}
    248      1.1   cherry 
    249      1.1   cherry 			printf("Skipping body desc slot :: %d \n", rec_cnt);
    250      1.1   cherry 		}
    251      1.1   cherry 	}
    252      1.1   cherry 
    253      1.1   cherry #ifdef UNWIND_DIAGNOSTIC
    254      1.1   cherry 	int i;
    255      1.1   cherry 	for(i = 0;i < rec_cnt;i++) {
    256      1.1   cherry 		dump_recordchain(&strc[i]);
    257      1.1   cherry 	}
    258      1.1   cherry 
    259      1.1   cherry #endif /* UNWIND_DIAGNOSTIC */
    260      1.1   cherry }
    261      1.1   cherry 
    262      1.1   cherry 
    263      1.1   cherry 
    264      1.1   cherry 
    265  1.5.6.1    skrll /*
    266  1.5.6.1    skrll  * Debug support: dump a record chain entry
    267  1.5.6.1    skrll  */
    268  1.5.6.1    skrll void
    269  1.5.6.1    skrll dump_recordchain(struct recordchain *rchain)
    270      1.1   cherry {
    271      1.1   cherry 
    272      1.1   cherry 	switch(rchain->type) {
    273      1.1   cherry 	case R1:
    274      1.1   cherry 		printf("\t R1:");
    275      1.1   cherry 		if(rchain->udesc.R1.r)
    276      1.1   cherry 			printf("body (");
    277      1.1   cherry 		else
    278      1.1   cherry 			printf("prologue (");
    279      1.1   cherry 		printf("rlen = %ld) \n", rchain->udesc.R1.rlen);
    280      1.1   cherry 		break;
    281      1.1   cherry 
    282      1.1   cherry 	case R2:
    283      1.1   cherry 		printf("\t R2:");
    284      1.1   cherry 		printf("prologue_gr (");
    285      1.1   cherry 		printf("mask = %x, ", rchain->udesc.R2.mask);
    286      1.1   cherry 		printf("grsave = %d, ", rchain->udesc.R2.grsave);
    287      1.1   cherry 		printf("rlen = %ld )\n", rchain->udesc.R2.rlen);
    288      1.1   cherry 		break;
    289      1.1   cherry 
    290      1.1   cherry 	case R3:
    291      1.1   cherry 		printf("\t R3:");
    292      1.1   cherry 		if(rchain->udesc.R3.r)
    293      1.1   cherry 			printf("body (");
    294      1.1   cherry 		else
    295      1.1   cherry 			printf("prologue (");
    296      1.1   cherry 		printf("rlen = %ld )\n", rchain->udesc.R3.rlen);
    297      1.1   cherry 		break;
    298      1.1   cherry 
    299      1.1   cherry 	case P1:
    300      1.1   cherry 		printf("\t\tP1:");
    301      1.1   cherry 		printf("br_mem (brmask = %x) \n", rchain->udesc.P1.brmask);
    302      1.1   cherry 		break;
    303      1.1   cherry 
    304      1.1   cherry 	case P2:
    305      1.1   cherry 		printf("\t\tP2:");
    306      1.1   cherry 		printf("br_gr(brmask = %x, ", rchain->udesc.P2.brmask);
    307      1.1   cherry 		printf("gr = %d ) \n", rchain->udesc.P2.gr);
    308      1.1   cherry 		break;
    309      1.1   cherry 
    310      1.1   cherry 	case P3:
    311      1.1   cherry 		printf("\t\tP3:");
    312      1.1   cherry 		switch(rchain->udesc.P3.r) {
    313      1.1   cherry 		case 0:
    314      1.1   cherry 			printf("psp_gr");
    315      1.1   cherry 			break;
    316      1.1   cherry 		case 1:
    317      1.1   cherry 			printf("rp_gr");
    318      1.1   cherry 			break;
    319      1.1   cherry 		case 2:
    320      1.1   cherry 			printf("pfs_gr");
    321      1.1   cherry 			break;
    322      1.1   cherry 		case 3:
    323      1.1   cherry 			printf("preds_gr");
    324      1.1   cherry 			break;
    325      1.1   cherry 		case 4:
    326      1.1   cherry 			printf("unat_gr");
    327      1.1   cherry 			break;
    328      1.1   cherry 		case 5:
    329      1.1   cherry 			printf("lc_gr");
    330      1.1   cherry 			break;
    331      1.1   cherry 		case 6:
    332      1.1   cherry 			printf("rp_br");
    333      1.1   cherry 			break;
    334      1.1   cherry 		case 7:
    335      1.1   cherry 			printf("rnat_gr");
    336      1.1   cherry 			break;
    337      1.1   cherry 		case 8:
    338      1.1   cherry 			printf("bsp_gr");
    339      1.1   cherry 			break;
    340      1.1   cherry 		case 9:
    341      1.1   cherry 			printf("bspstore_gr");
    342      1.1   cherry 			break;
    343      1.1   cherry 		case 10:
    344      1.1   cherry 			printf("fpsr_gr");
    345      1.1   cherry 			break;
    346      1.1   cherry 		case 11:
    347      1.1   cherry 			printf("priunat_gr");
    348      1.1   cherry 			break;
    349      1.1   cherry 		default:
    350      1.1   cherry 			printf("unknown desc: %d", rchain->udesc.P3.r);
    351      1.1   cherry 
    352      1.1   cherry 		}
    353      1.1   cherry 		printf("(gr/br = %d) \n", rchain->udesc.P3.grbr);
    354      1.1   cherry 
    355      1.1   cherry 		break;
    356      1.1   cherry 
    357      1.1   cherry 	case P4:
    358      1.1   cherry 		printf("P4: (unimplemented): \n");
    359      1.1   cherry 		break;
    360      1.1   cherry 
    361      1.1   cherry 	case P5:
    362      1.1   cherry 		printf("\t\tP5:");
    363      1.1   cherry 		printf("frgr_mem(grmask = %x, frmask = %x )\n",
    364      1.1   cherry 		       rchain->udesc.P5.grmask, rchain->udesc.P5.frmask);
    365      1.1   cherry 		break;
    366      1.1   cherry 
    367      1.1   cherry 	case P6:
    368      1.1   cherry 		printf("\t\tP6: ");
    369      1.1   cherry 		if(rchain->udesc.P6.r)
    370      1.1   cherry 			printf("gr_mem( ");
    371      1.1   cherry 		else
    372      1.1   cherry 			printf("fr_mem( ");
    373      1.1   cherry 		printf("rmask = %x) \n", rchain->udesc.P6.rmask);
    374      1.1   cherry 		break;
    375      1.1   cherry 
    376      1.1   cherry 	case P7:
    377      1.1   cherry 		printf("\t\tP7:");
    378      1.1   cherry 		switch(rchain->udesc.P7.r) {
    379      1.1   cherry 		case 0:
    380      1.1   cherry 			printf("memstack_f( ");
    381      1.1   cherry 			printf("t = %ld, ", rchain->udesc.P7.t);
    382      1.1   cherry 			printf("size = %ld) \n", rchain->udesc.P7.size);
    383      1.1   cherry 			break;
    384      1.1   cherry 		case 1:
    385      1.1   cherry 			printf("memstack_v( ");
    386      1.1   cherry 			printf("t = %ld) \n", rchain->udesc.P7.t);
    387      1.1   cherry 			break;
    388      1.1   cherry 		case 2:
    389      1.1   cherry 			printf("spillbase( ");
    390      1.1   cherry 			printf("pspoff = %ld) \n", rchain->udesc.P7.t);
    391      1.1   cherry 			break;
    392      1.1   cherry 		case 3:
    393      1.1   cherry 			printf("psp_sprel( ");
    394      1.1   cherry 			printf("spoff = %ld) \n", rchain->udesc.P7.t);
    395      1.1   cherry 			break;
    396      1.1   cherry 		case 4:
    397      1.1   cherry 			printf("rp_when( ");
    398      1.1   cherry 			printf("t = %ld) \n", rchain->udesc.P7.t);
    399      1.1   cherry 			break;
    400      1.1   cherry 		case 5:
    401      1.1   cherry 			printf("rp_psprel( ");
    402      1.1   cherry 			printf("pspoff = %ld) \n", rchain->udesc.P7.t);
    403      1.1   cherry 			break;
    404      1.1   cherry 		case 6:
    405      1.1   cherry 			printf("pfs_when( ");
    406      1.1   cherry 			printf("t = %ld) \n", rchain->udesc.P7.t);
    407      1.1   cherry 			break;
    408      1.1   cherry 		case 7:
    409      1.1   cherry 			printf("pfs_psprel( ");
    410      1.1   cherry 			printf("pspoff = %ld) \n", rchain->udesc.P7.t);
    411      1.1   cherry 			break;
    412      1.1   cherry 		case 8:
    413      1.1   cherry 			printf("preds_when( ");
    414      1.1   cherry 			printf("t = %ld) \n", rchain->udesc.P7.t);
    415      1.1   cherry 			break;
    416      1.1   cherry 		case 9:
    417      1.1   cherry 			printf("preds_psprel( ");
    418      1.1   cherry 			printf("pspoff = %ld) \n", rchain->udesc.P7.t);
    419      1.1   cherry 			break;
    420      1.1   cherry 		case 10:
    421      1.1   cherry 			printf("lc_when( ");
    422      1.1   cherry 			printf("t = %ld) \n", rchain->udesc.P7.t);
    423      1.1   cherry 			break;
    424      1.1   cherry 		case 11:
    425      1.1   cherry 			printf("lc_psprel( ");
    426      1.1   cherry 			printf("pspoff = %ld) \n", rchain->udesc.P7.t);
    427      1.1   cherry 			break;
    428      1.1   cherry 		case 12:
    429      1.1   cherry 			printf("unat_when( ");
    430      1.1   cherry 			printf("t = %ld) \n", rchain->udesc.P7.t);
    431      1.1   cherry 			break;
    432      1.1   cherry 		case 13:
    433      1.1   cherry 			printf("unat_psprel( ");
    434      1.1   cherry 			printf("pspoff = %ld) \n", rchain->udesc.P7.t);
    435      1.1   cherry 			break;
    436      1.1   cherry 		case 14:
    437      1.1   cherry 			printf("fpsr_when( ");
    438      1.1   cherry 			printf("t = %ld) \n", rchain->udesc.P7.t);
    439      1.1   cherry 			break;
    440      1.1   cherry 		case 15:
    441      1.1   cherry 			printf("fpsr_psprel( ");
    442      1.1   cherry 			printf("pspoff = %ld) \n", rchain->udesc.P7.t);
    443      1.1   cherry 			break;
    444      1.1   cherry 		default:
    445      1.1   cherry 			printf("unknown \n");
    446      1.1   cherry 		}
    447      1.1   cherry 
    448      1.1   cherry 		break;
    449      1.1   cherry 
    450      1.1   cherry 	case P8:
    451      1.1   cherry 		printf("\t\tP8:");
    452      1.1   cherry 		switch(rchain->udesc.P8.r) {
    453      1.1   cherry 		case 1:
    454      1.1   cherry 			printf("rp_sprel( ");
    455      1.1   cherry 			printf("spoff = %ld) \n", rchain->udesc.P8.t);
    456      1.1   cherry 			break;
    457      1.1   cherry 		case 2:
    458      1.1   cherry 			printf("pfs_sprel( ");
    459      1.1   cherry 			printf("spoff = %ld) \n", rchain->udesc.P8.t);
    460      1.1   cherry 			break;
    461      1.1   cherry 		case 3:
    462      1.1   cherry 			printf("preds_sprel( ");
    463      1.1   cherry 			printf("spoff = %ld) \n", rchain->udesc.P8.t);
    464      1.1   cherry 			break;
    465      1.1   cherry 		case 4:
    466      1.1   cherry 			printf("lc_sprel( ");
    467      1.1   cherry 			printf("spoff = %ld) \n", rchain->udesc.P8.t);
    468      1.1   cherry 			break;
    469      1.1   cherry 		case 5:
    470      1.1   cherry 			printf("unat_sprel( ");
    471      1.1   cherry 			printf("spoff = %ld) \n", rchain->udesc.P8.t);
    472      1.1   cherry 			break;
    473      1.1   cherry 		case 6:
    474      1.1   cherry 			printf("fpsr_sprel( ");
    475      1.1   cherry 			printf("spoff = %ld) \n", rchain->udesc.P8.t);
    476      1.1   cherry 			break;
    477      1.1   cherry 		case 7:
    478      1.1   cherry 			printf("bsp_when( ");
    479      1.1   cherry 			printf("t = %ld) \n", rchain->udesc.P8.t);
    480      1.1   cherry 			break;
    481      1.1   cherry 		case 8:
    482      1.1   cherry 			printf("bsp_psprel( ");
    483      1.1   cherry 			printf("pspoff = %ld) \n", rchain->udesc.P8.t);
    484      1.1   cherry 			break;
    485      1.1   cherry 		case 9:
    486      1.1   cherry 			printf("bsp_sprel( ");
    487      1.1   cherry 			printf("spoff = %ld) \n", rchain->udesc.P8.t);
    488      1.1   cherry 			break;
    489      1.1   cherry 		case 10:
    490      1.1   cherry 			printf("bspstore_when( ");
    491      1.1   cherry 			printf("t = %ld) \n", rchain->udesc.P8.t);
    492      1.1   cherry 			break;
    493      1.1   cherry 		case 11:
    494      1.1   cherry 			printf("bspstore_psprel( ");
    495      1.1   cherry 			printf("pspoff = %ld) \n", rchain->udesc.P8.t);
    496      1.1   cherry 			break;
    497      1.1   cherry 		case 12:
    498      1.1   cherry 			printf("bspstore_sprel( ");
    499      1.1   cherry 			printf("spoff = %ld) \n", rchain->udesc.P8.t);
    500      1.1   cherry 			break;
    501      1.1   cherry 		case 13:
    502      1.1   cherry 			printf("rnat_when( ");
    503      1.1   cherry 			printf("t = %ld) \n", rchain->udesc.P8.t);
    504      1.1   cherry 			break;
    505      1.1   cherry 		case 14:
    506      1.1   cherry 			printf("rnat_psprel( ");
    507      1.1   cherry 			printf("pspoff = %ld) \n", rchain->udesc.P8.t);
    508      1.1   cherry 			break;
    509      1.1   cherry 		case 15:
    510      1.1   cherry 			printf("rnat_sprel( ");
    511      1.1   cherry 			printf("spoff = %ld) \n", rchain->udesc.P8.t);
    512      1.1   cherry 			break;
    513      1.1   cherry 		case 16:
    514      1.1   cherry 			printf("priunat_when_gr( ");
    515      1.1   cherry 			printf("t = %ld) \n", rchain->udesc.P8.t);
    516      1.1   cherry 			break;
    517      1.1   cherry 		case 17:
    518      1.1   cherry 			printf("priunat_psprel( ");
    519      1.1   cherry 			printf("pspoff = %ld) \n", rchain->udesc.P8.t);
    520      1.1   cherry 			break;
    521      1.1   cherry 		case 18:
    522      1.1   cherry 			printf("priunat_sprel( ");
    523      1.1   cherry 			printf("spoff = %ld) \n", rchain->udesc.P8.t);
    524      1.1   cherry 			break;
    525      1.1   cherry 		case 19:
    526      1.1   cherry 			printf("priunat_when_mem( ");
    527      1.1   cherry 			printf("t = %ld) \n", rchain->udesc.P8.t);
    528      1.1   cherry 			break;
    529      1.1   cherry 
    530      1.1   cherry 		default:
    531      1.1   cherry 			printf("unknown \n");
    532      1.1   cherry 		}
    533      1.1   cherry 
    534      1.1   cherry 		break;
    535      1.1   cherry 
    536      1.1   cherry 	case P9:
    537      1.1   cherry 		printf("\t\tP9:");
    538      1.1   cherry 		printf("(grmask = %x, gr = %d) \n",
    539      1.1   cherry 		       rchain->udesc.P9.grmask, rchain->udesc.P9.gr);
    540      1.1   cherry 		break;
    541      1.1   cherry 
    542      1.1   cherry 	case P10:
    543      1.1   cherry 		printf("\t\tP10:");
    544      1.1   cherry 		printf("(abi: ");
    545      1.1   cherry 		switch(rchain->udesc.P10.abi) {
    546      1.1   cherry 		case 0:
    547      1.1   cherry 			printf("Unix SVR4) \n");
    548      1.1   cherry 			break;
    549      1.1   cherry 		case 1:
    550      1.1   cherry 			printf("HP-UX) \n");
    551      1.1   cherry 			break;
    552      1.1   cherry 		default:
    553      1.1   cherry 			printf("Other) \n");
    554      1.1   cherry 		}
    555      1.1   cherry 		break;
    556      1.1   cherry 
    557      1.1   cherry 	case B1:
    558      1.1   cherry 		printf("\t\tB1:");
    559      1.1   cherry 		if(rchain->udesc.B1.r)
    560      1.1   cherry 			printf("copy_state( ");
    561      1.1   cherry 		else
    562      1.1   cherry 			printf("label_state( ");
    563      1.1   cherry 		printf("label = %d) \n", rchain->udesc.B1.label);
    564      1.1   cherry 
    565      1.1   cherry 		break;
    566      1.1   cherry 
    567      1.1   cherry 	case B2:
    568      1.1   cherry 		printf("\t\tB2:");
    569      1.1   cherry 		printf("(ecount = %d, t = %ld)\n",
    570      1.1   cherry 		       rchain->udesc.B2.ecount, rchain->udesc.B2.t);
    571      1.1   cherry 
    572      1.1   cherry 		break;
    573      1.1   cherry 
    574      1.1   cherry 	case B3:
    575      1.1   cherry 		printf("\t\tB3:");
    576      1.1   cherry 		printf("(t = %ld, ecount = %ld) \n",
    577      1.1   cherry 		       rchain->udesc.B3.t, rchain->udesc.B3.ecount);
    578      1.1   cherry 
    579      1.1   cherry 		break;
    580      1.1   cherry 
    581      1.1   cherry 	case B4:
    582      1.1   cherry 		printf("\t\tB4:");
    583      1.1   cherry 		if(rchain->udesc.B4.r)
    584      1.1   cherry 			printf("copy_state( ");
    585      1.1   cherry 		else
    586      1.1   cherry 			printf("label_state( ");
    587      1.1   cherry 
    588      1.1   cherry 		printf("label = %ld) \n", rchain->udesc.B4.label);
    589      1.1   cherry 
    590      1.1   cherry 		break;
    591      1.1   cherry 
    592      1.1   cherry 
    593      1.1   cherry 	case X1:
    594      1.1   cherry 		printf("\tX1:\n ");
    595      1.1   cherry 		break;
    596      1.1   cherry 
    597      1.1   cherry 	case X2:
    598      1.1   cherry 		printf("\tX2:\n");
    599      1.1   cherry 		break;
    600      1.1   cherry 
    601      1.1   cherry 	case X3:
    602      1.1   cherry 		printf("\tX3:\n");
    603      1.1   cherry 		break;
    604      1.1   cherry 
    605      1.1   cherry 	case X4:
    606      1.1   cherry 		printf("\tX4:\n");
    607      1.1   cherry 		break;
    608      1.1   cherry 	default:
    609      1.1   cherry 		printf("\tunknow: \n");
    610      1.1   cherry 	}
    611      1.1   cherry 
    612      1.1   cherry }
    613      1.1   cherry 
    614  1.5.6.1    skrll /*
    615  1.5.6.1    skrll  * State record stuff..... based on section 11. and Appendix A. of the
    616  1.5.6.1    skrll  * "Itanium Software Conventions and Runtime Architecture Guide"
    617      1.1   cherry  */
    618      1.1   cherry 
    619      1.1   cherry 
    620  1.5.6.1    skrll /*
    621  1.5.6.1    skrll  * Global variables:
    622      1.1   cherry  * 1. Two arrays of staterecords: recordstack[], recordstackcopy[]
    623      1.1   cherry  *	XXX:	Since we don't use malloc, we have two arbitrary sized arrays
    624      1.1   cherry  *		providing guaranteed memory from the BSS. See the TODO file
    625      1.1   cherry  *		for more details.
    626      1.1   cherry  * 2. Two head variables to hold the member index: unwind_rsp,unwind_rscp
    627      1.1   cherry  */
    628      1.1   cherry 
    629      1.1   cherry struct staterecord recordstack[MAXSTATERECS];
    630      1.1   cherry struct staterecord recordstackcopy[MAXSTATERECS];
    631      1.1   cherry struct staterecord current_state;
    632      1.1   cherry struct staterecord *unwind_rsp, *unwind_rscp;
    633      1.1   cherry 
    634      1.1   cherry 
    635  1.5.6.1    skrll /* Base of spill area in memory stack frame as a psp relative offset */
    636  1.5.6.1    skrll uint64_t spill_base = 0;
    637      1.1   cherry 
    638  1.5.6.1    skrll /*
    639  1.5.6.1    skrll  * Initialises a staterecord from a given template,
    640      1.1   cherry  * with default values as described by the Runtime Spec.
    641      1.1   cherry  */
    642      1.1   cherry void
    643      1.1   cherry initrecord(struct staterecord *target)
    644      1.1   cherry {
    645      1.1   cherry 	target->bsp.where = UNSAVED;
    646      1.1   cherry 	target->bsp.when = 0;
    647      1.1   cherry 	target->bsp.offset = INVALID;
    648      1.1   cherry 	target->psp.where = UNSAVED;
    649      1.1   cherry 	target->psp.when = 0;
    650      1.1   cherry 	target->psp.offset = INVALID;
    651      1.1   cherry 	target->rp.where = UNSAVED;
    652      1.1   cherry 	target->rp.when = 0;
    653      1.1   cherry 	target->rp.offset = INVALID;
    654      1.1   cherry 	target->pfs.where = UNSAVED;
    655      1.1   cherry 	target->pfs.when = 0;
    656      1.1   cherry 	target->pfs.offset = INVALID;
    657      1.1   cherry }
    658      1.1   cherry 
    659      1.1   cherry 
    660  1.5.6.1    skrll /*
    661  1.5.6.1    skrll  * Modifies a staterecord structure by parsing
    662      1.1   cherry  * a single record chain structure.
    663      1.1   cherry  * regionoffset is the offset within a (prologue) region
    664      1.1   cherry  * where the stack unwinding began.
    665      1.1   cherry  */
    666  1.5.6.1    skrll void
    667  1.5.6.1    skrll modifyrecord(struct staterecord *srec, struct recordchain *rchain,
    668  1.5.6.1    skrll 	uint64_t regionoffset)
    669      1.1   cherry {
    670  1.5.6.1    skrll 	/*
    671  1.5.6.1    skrll 	 * Default start save GR for prologue_save GRs.
    672  1.5.6.1    skrll 	 */
    673  1.5.6.1    skrll 	uint64_t grno = 32;
    674      1.1   cherry 
    675      1.1   cherry 
    676      1.1   cherry 	switch (rchain->type) {
    677      1.1   cherry 
    678      1.1   cherry 	case R2:
    679  1.5.6.1    skrll 		/*
    680  1.5.6.1    skrll 		 * R2, prologue_gr is the only region encoding
    681      1.1   cherry 		 * with register save info.
    682      1.1   cherry 		 */
    683      1.1   cherry 
    684      1.1   cherry 		grno = rchain->udesc.R2.grsave;
    685      1.1   cherry 
    686      1.1   cherry 		if (rchain->udesc.R2.mask & R2MASKRP) {
    687      1.1   cherry 			srec->rp.when = 0;
    688      1.1   cherry 			srec->rp.where = GRREL;
    689      1.1   cherry 			srec->rp.offset = grno++;
    690      1.1   cherry 		}
    691      1.1   cherry 
    692      1.1   cherry 		if (rchain->udesc.R2.mask & R2MASKPFS) {
    693      1.1   cherry 			srec->pfs.when = 0;
    694      1.1   cherry 			srec->pfs.where = GRREL;
    695      1.1   cherry 			srec->pfs.offset = grno++;
    696      1.1   cherry 		}
    697      1.1   cherry 
    698      1.1   cherry 		if (rchain->udesc.R2.mask & R2MASKPSP) {
    699      1.1   cherry 			srec->psp.when = 0;
    700      1.1   cherry 			srec->psp.where = GRREL;
    701      1.1   cherry 			srec->psp.offset = grno++;
    702      1.1   cherry 		}
    703      1.1   cherry 		break;
    704      1.1   cherry 
    705      1.1   cherry 	case P3:
    706      1.1   cherry 		switch (rchain->udesc.P3.r) {
    707      1.1   cherry 		case 0: /* psp_gr */
    708      1.1   cherry 			if (srec->psp.when < regionoffset) {
    709      1.1   cherry 				srec->psp.where = GRREL;
    710      1.1   cherry 				srec->psp.offset = rchain->udesc.P3.grbr;
    711      1.1   cherry 			}
    712      1.1   cherry 			break;
    713      1.1   cherry 
    714      1.1   cherry 		case 1: /* rp_gr */
    715      1.1   cherry 			if (srec->rp.when < regionoffset) {
    716      1.1   cherry 				srec->rp.where = GRREL;
    717      1.1   cherry 				srec->rp.offset = rchain->udesc.P3.grbr;
    718      1.1   cherry 			}
    719      1.1   cherry 			break;
    720      1.1   cherry 
    721      1.1   cherry 		case 2: /* pfs_gr */
    722      1.1   cherry 			if (srec->pfs.when < regionoffset) {
    723      1.1   cherry 				srec->pfs.where = GRREL;
    724      1.1   cherry 				srec->pfs.offset = rchain->udesc.P3.grbr;
    725      1.1   cherry 			}
    726      1.1   cherry 			break;
    727      1.1   cherry 
    728      1.1   cherry 		}
    729      1.1   cherry 		break;
    730      1.1   cherry 
    731      1.1   cherry 
    732  1.5.6.1    skrll 	/*
    733  1.5.6.1    skrll 	 * XXX: P4 spill_mask and P7: spill_base are for GRs, FRs, and BRs.
    734      1.1   cherry 	 * We're not particularly worried about those right now.
    735      1.1   cherry 	 */
    736      1.1   cherry 
    737      1.1   cherry 	case P7:
    738      1.1   cherry 		switch (rchain->udesc.P7.r) {
    739      1.1   cherry 
    740      1.1   cherry 		case 0: /* mem_stack_f */
    741  1.5.6.1    skrll 			if (srec->psp.offset != INVALID) {
    742  1.5.6.1    skrll 				printf("!!!saw mem_stack_f more than once. \n");
    743  1.5.6.1    skrll 			}
    744      1.1   cherry 			srec->psp.when = rchain->udesc.P7.t;
    745      1.1   cherry 			if (srec->psp.when < regionoffset) {
    746      1.1   cherry 				srec->psp.where = IMMED;
    747  1.5.6.1    skrll 				/* spsz.offset is "overloaded" */
    748  1.5.6.1    skrll 				srec->psp.offset = rchain->udesc.P7.size;
    749      1.1   cherry 			}
    750      1.1   cherry 			break;
    751      1.1   cherry 
    752      1.1   cherry 		case 1: /* mem_stack_v */
    753      1.1   cherry 			srec->psp.when = rchain->udesc.P7.t;
    754      1.1   cherry 			break;
    755      1.1   cherry 
    756      1.1   cherry 		case 2: /* spill_base */
    757      1.1   cherry 			spill_base = rchain->udesc.P7.t;
    758      1.1   cherry 			break;
    759      1.1   cherry 
    760      1.1   cherry 		case 3: /* psp_sprel */
    761      1.1   cherry 			if (srec->psp.when < regionoffset) {
    762      1.1   cherry 				srec->psp.where = SPREL;
    763      1.1   cherry 				srec->psp.offset = rchain->udesc.P7.t;
    764      1.1   cherry 			}
    765      1.1   cherry 			break;
    766      1.1   cherry 
    767      1.1   cherry 		case 4: /* rp_when */
    768      1.1   cherry 			srec->rp.when = rchain->udesc.P7.t;
    769  1.5.6.1    skrll 			/*
    770  1.5.6.1    skrll 			 * XXX: Need to set to prologue_gr(grno) for
    771  1.5.6.1    skrll 			 *	the orphan case ie; _gr/_psprel/_sprel
    772  1.5.6.1    skrll 			 *	not set and therefore default to begin
    773  1.5.6.1    skrll 			 *	from the gr specified in prologue_gr.
    774      1.1   cherry 			 */
    775      1.1   cherry 			break;
    776      1.1   cherry 
    777      1.1   cherry 		case 5: /* rp_psprel */
    778      1.1   cherry 			if (srec->rp.when < regionoffset) {
    779      1.1   cherry 				srec->rp.where = PSPREL;
    780      1.1   cherry 				srec->rp.offset = rchain->udesc.P7.t;
    781      1.1   cherry 			}
    782      1.1   cherry 			break;
    783      1.1   cherry 
    784      1.1   cherry 		case 6: /* pfs_when */
    785      1.1   cherry 			srec->pfs.when = rchain->udesc.P7.t;
    786  1.5.6.1    skrll 			/*
    787  1.5.6.1    skrll 			 * XXX: Need to set to prologue_gr(grno) for
    788  1.5.6.1    skrll 			 *	the orphan case ie; _gr/_psprel/_sprel
    789  1.5.6.1    skrll 			 *	not set and therefore default to begin
    790  1.5.6.1    skrll 			 *	from the gr specified in prologue_gr.
    791      1.1   cherry 			 */
    792      1.1   cherry 			break;
    793      1.1   cherry 
    794      1.1   cherry 		case 7: /* pfs_psprel */
    795      1.1   cherry 			if (srec->pfs.when < regionoffset) {
    796      1.1   cherry 				srec->pfs.where = PSPREL;
    797      1.1   cherry 				srec->pfs.offset = rchain->udesc.P7.t;
    798      1.1   cherry 			}
    799      1.1   cherry 			break;
    800      1.1   cherry 
    801      1.1   cherry 		}
    802      1.1   cherry 		break;
    803      1.1   cherry 
    804      1.1   cherry 	case P8:
    805      1.1   cherry 		switch (rchain->udesc.P8.r) {
    806      1.1   cherry 		case 1: /* rp_sprel */
    807      1.1   cherry 			if (srec->rp.when < regionoffset) {
    808      1.1   cherry 				srec->rp.where = SPREL;
    809      1.1   cherry 				srec->rp.offset = rchain->udesc.P8.t;
    810      1.1   cherry 			}
    811      1.1   cherry 			break;
    812      1.1   cherry 		case 2: /* pfs_sprel */
    813      1.1   cherry 			if (srec->pfs.when < regionoffset) {
    814      1.1   cherry 				srec->pfs.where = SPREL;
    815      1.1   cherry 				srec->pfs.offset = rchain->udesc.P8.t;
    816      1.1   cherry 
    817      1.1   cherry 			}
    818      1.1   cherry 			break;
    819      1.1   cherry 		}
    820      1.1   cherry 		break;
    821      1.1   cherry 
    822      1.1   cherry 	case B1:
    823      1.1   cherry 
    824      1.1   cherry 		rchain->udesc.B1.r ? switchrecordstack(0) :
    825      1.1   cherry 			clonerecordstack(0);
    826      1.1   cherry 		break;
    827      1.1   cherry 
    828      1.1   cherry 	case B2:
    829      1.1   cherry 		if (regionoffset < rchain->udesc.B2.t) {
    830      1.1   cherry 		poprecord(&current_state, rchain->udesc.B2.ecount);
    831      1.1   cherry 		}
    832      1.1   cherry 		break;
    833      1.1   cherry 	case B3:
    834      1.1   cherry 		if (regionoffset < rchain->udesc.B3.t) {
    835      1.1   cherry 		poprecord(&current_state, rchain->udesc.B3.ecount);
    836      1.1   cherry 		}
    837      1.1   cherry 		break;
    838      1.1   cherry 	case B4:
    839      1.1   cherry 		rchain->udesc.B4.r ? switchrecordstack(0) :
    840      1.1   cherry 			clonerecordstack(0);
    841      1.1   cherry 		break;
    842      1.1   cherry 
    843      1.1   cherry 	case X1:
    844      1.1   cherry 	case X2:
    845      1.1   cherry 	case X3:
    846      1.1   cherry 		/* XXX: Todo */
    847      1.1   cherry 		break;
    848      1.1   cherry 
    849      1.1   cherry 
    850      1.1   cherry 	case R1:
    851      1.1   cherry 	case R3:
    852      1.1   cherry 	case P1:
    853      1.1   cherry 	case P2:
    854      1.1   cherry 	case P4:
    855      1.1   cherry 	case P5:
    856      1.1   cherry 	case P6:
    857      1.1   cherry 	case P9:
    858      1.1   cherry 	case P10:
    859      1.1   cherry 	default:
    860      1.1   cherry 		/* Ignore. */
    861      1.1   cherry 		printf("XXX: Ignored. \n");
    862      1.1   cherry 	}
    863      1.1   cherry 
    864      1.1   cherry 
    865      1.1   cherry }
    866      1.1   cherry 
    867  1.5.6.1    skrll void
    868  1.5.6.1    skrll dump_staterecord(struct staterecord *srec)
    869      1.1   cherry {
    870      1.1   cherry 	printf("rp.where: ");
    871      1.1   cherry 	switch(srec->rp.where) {
    872      1.1   cherry 	case UNSAVED:
    873      1.1   cherry 		printf("UNSAVED ");
    874      1.1   cherry 		break;
    875      1.1   cherry 	case BRREL:
    876      1.1   cherry 		printf("BRREL ");
    877      1.1   cherry 		break;
    878      1.1   cherry 	case GRREL:
    879      1.1   cherry 		printf("GRREL ");
    880      1.1   cherry 		break;
    881      1.1   cherry 	case SPREL:
    882      1.1   cherry 		printf("SPREL ");
    883      1.1   cherry 		break;
    884      1.1   cherry 	case PSPREL:
    885      1.1   cherry 		printf("PSPSREL ");
    886      1.1   cherry 		break;
    887      1.1   cherry 	default:
    888      1.1   cherry 		printf("unknown ");
    889      1.1   cherry 	}
    890      1.1   cherry 
    891      1.1   cherry 	printf(", rp.when = %lu, ", srec->rp.when);
    892      1.1   cherry 	printf("rp.offset = %lu \n", srec->rp.offset);
    893      1.1   cherry 
    894      1.1   cherry 
    895      1.1   cherry 	printf("pfs.where: ");
    896      1.1   cherry 	switch(srec->pfs.where) {
    897      1.1   cherry 	case UNSAVED:
    898      1.1   cherry 		printf("UNSAVED ");
    899      1.1   cherry 		break;
    900      1.1   cherry 	case BRREL:
    901      1.1   cherry 		printf("BRREL ");
    902      1.1   cherry 		break;
    903      1.1   cherry 	case GRREL:
    904      1.1   cherry 		printf("GRREL ");
    905      1.1   cherry 		break;
    906      1.1   cherry 	case SPREL:
    907      1.1   cherry 		printf("SPREL ");
    908      1.1   cherry 		break;
    909      1.1   cherry 	case PSPREL:
    910      1.1   cherry 		printf("PSPSREL ");
    911      1.1   cherry 		break;
    912      1.1   cherry 	default:
    913      1.1   cherry 		printf("unknown ");
    914      1.1   cherry 	}
    915      1.1   cherry 
    916      1.1   cherry 	printf(", pfs.when = %lu, ", srec->pfs.when);
    917      1.1   cherry 	printf("pfs.offset = %lu \n", srec->pfs.offset);
    918      1.1   cherry }
    919      1.1   cherry 
    920      1.1   cherry 
    921  1.5.6.1    skrll /*
    922  1.5.6.1    skrll  * Push a state record on the record stack.
    923  1.5.6.1    skrll  */
    924  1.5.6.1    skrll void
    925  1.5.6.1    skrll pushrecord(struct staterecord *srec)
    926      1.1   cherry {
    927      1.1   cherry 	if(unwind_rsp >= recordstack + MAXSTATERECS) {
    928      1.1   cherry 		printf("Push exceeded array size!!! \n");
    929      1.1   cherry 		return;
    930      1.1   cherry 	}
    931      1.1   cherry 
    932      1.1   cherry 	memcpy(unwind_rsp, srec, sizeof(struct staterecord));
    933      1.1   cherry 	unwind_rsp++;
    934      1.1   cherry 
    935      1.1   cherry }
    936      1.1   cherry 
    937  1.5.6.1    skrll /*
    938  1.5.6.1    skrll  * Pop n state records off the record stack.
    939  1.5.6.1    skrll  */
    940  1.5.6.1    skrll void
    941  1.5.6.1    skrll poprecord(struct staterecord *srec, int n)
    942      1.1   cherry {
    943      1.1   cherry 	if(unwind_rsp == recordstack) {
    944      1.1   cherry 		printf("Popped beyond end of Stack!!! \n");
    945      1.1   cherry 		return;
    946      1.1   cherry 	}
    947      1.1   cherry 	unwind_rsp -= n;
    948      1.1   cherry 	memcpy(srec, unwind_rsp, sizeof(struct staterecord));
    949      1.1   cherry #ifdef DEBUG
    950      1.4   cegger 	memset(unwind_rsp, 0, sizeof(struct staterecord) * n);
    951      1.1   cherry #endif
    952      1.1   cherry 
    953      1.1   cherry }
    954      1.1   cherry 
    955  1.5.6.1    skrll /*
    956  1.5.6.1    skrll  * Clone the whole record stack upto this one.
    957  1.5.6.1    skrll  */
    958  1.5.6.1    skrll void
    959  1.5.6.1    skrll clonerecordstack(u_int label)
    960      1.1   cherry {
    961      1.1   cherry 	memcpy(recordstackcopy, recordstack,
    962      1.1   cherry 	       (unwind_rsp - recordstack) * sizeof(struct staterecord));
    963      1.1   cherry 	unwind_rscp = unwind_rsp;
    964      1.1   cherry }
    965      1.1   cherry 
    966  1.5.6.1    skrll /*
    967  1.5.6.1    skrll  * Discard the current stack, and adopt a clone.
    968  1.5.6.1    skrll  */
    969  1.5.6.1    skrll void
    970  1.5.6.1    skrll switchrecordstack(u_int label)
    971      1.1   cherry {
    972      1.1   cherry 	memcpy((void *) recordstack, (void *) recordstackcopy,
    973      1.1   cherry 	       (unwind_rscp - recordstackcopy) * sizeof(struct staterecord));
    974      1.1   cherry 	unwind_rsp = unwind_rscp;
    975      1.1   cherry 
    976      1.1   cherry }
    977      1.1   cherry 
    978  1.5.6.1    skrll /*
    979  1.5.6.1    skrll  * In the context of a procedure:
    980      1.1   cherry  * Parses through a record chain, building, pushing and/or popping staterecords,
    981      1.1   cherry  * or cloning/destroying stacks of staterecords as required.
    982      1.1   cherry  * Parameters are:
    983      1.1   cherry  *	rchain: pointer to recordchain array.
    984  1.5.6.1    skrll  *	procoffset: offset of point of interest, in slots, within procedure
    985  1.5.6.1    skrll  *                  starting from slot 0
    986      1.1   cherry  * This routine obeys [1]
    987      1.1   cherry  */
    988  1.5.6.1    skrll struct staterecord *
    989  1.5.6.1    skrll buildrecordstack(struct recordchain *rchain, uint64_t procoffset)
    990      1.1   cherry {
    991  1.5.6.1    skrll 	/* Current region length, defaults to zero if not specified */
    992  1.5.6.1    skrll 	uint64_t rlen = 0;
    993  1.5.6.1    skrll 	/* Accumulated region length */
    994  1.5.6.1    skrll 	uint64_t roffset = 0;
    995  1.5.6.1    skrll 	/* Offset within current region */
    996  1.5.6.1    skrll 	uint64_t rdepth = 0;
    997      1.1   cherry 
    998      1.2  thorpej 	bool rtype;
    999  1.5.6.1    skrll 	int i;
   1000      1.1   cherry 
   1001  1.5.6.1    skrll 	/* Start with bottom of staterecord stack. */
   1002  1.5.6.1    skrll 	unwind_rsp = recordstack;
   1003      1.1   cherry 
   1004      1.1   cherry 	initrecord(&current_state);
   1005      1.1   cherry 
   1006      1.1   cherry 	for (i = 0;i < rec_cnt;i++) {
   1007      1.1   cherry 
   1008      1.1   cherry 		switch (rchain[i].type) {
   1009      1.1   cherry 		case R1:
   1010      1.1   cherry 			rlen = rchain[i].udesc.R1.rlen;
   1011  1.5.6.1    skrll 			if (procoffset < roffset) {
   1012  1.5.6.1    skrll 				/*
   1013  1.5.6.1    skrll 				 * Overshot Region containing
   1014  1.5.6.1    skrll 				 * procoffset. Bail out.
   1015  1.5.6.1    skrll 				 */
   1016  1.5.6.1    skrll 				goto out;
   1017  1.5.6.1    skrll 			}
   1018      1.1   cherry 			rdepth = procoffset - roffset;
   1019      1.1   cherry 			roffset += rlen;
   1020      1.1   cherry 			rtype = rchain[i].udesc.R1.r;
   1021      1.1   cherry 			if (!rtype) {
   1022      1.1   cherry 				pushrecord(&current_state);
   1023      1.1   cherry 			}
   1024      1.1   cherry 			break;
   1025      1.1   cherry 
   1026      1.1   cherry 		case R3:
   1027      1.1   cherry 			rlen = rchain[i].udesc.R3.rlen;
   1028  1.5.6.1    skrll 			if (procoffset < roffset) {
   1029  1.5.6.1    skrll 				/*
   1030  1.5.6.1    skrll 				 * Overshot Region containing
   1031  1.5.6.1    skrll 				 * procoffset. Bail out.
   1032  1.5.6.1    skrll 				 */
   1033  1.5.6.1    skrll 				goto out;
   1034  1.5.6.1    skrll 			}
   1035      1.1   cherry 			rdepth = procoffset - roffset;
   1036      1.1   cherry 			roffset += rlen;
   1037      1.1   cherry 			rtype = rchain[i].udesc.R3.r;
   1038      1.1   cherry 			if (!rtype) {
   1039      1.1   cherry 				pushrecord(&current_state);
   1040      1.1   cherry 			}
   1041      1.1   cherry 			break;
   1042      1.1   cherry 
   1043      1.1   cherry 		case R2:
   1044      1.1   cherry 			rlen = rchain[i].udesc.R2.rlen;
   1045  1.5.6.1    skrll 			if (procoffset < roffset) {
   1046  1.5.6.1    skrll 				/*
   1047  1.5.6.1    skrll 				 * Overshot Region containing
   1048  1.5.6.1    skrll 				 * procoffset. Bail out.
   1049  1.5.6.1    skrll 				 */
   1050  1.5.6.1    skrll 				goto out;
   1051  1.5.6.1    skrll 			}
   1052      1.1   cherry 			rdepth = procoffset - roffset;
   1053      1.1   cherry 			roffset += rlen;
   1054      1.3  thorpej 			rtype = false; /* prologue region */
   1055      1.1   cherry 			pushrecord(&current_state);
   1056      1.1   cherry 
   1057      1.1   cherry 			/* R2 has save info. Continue down. */
   1058  1.5.6.1    skrll 			/* FALLTHROUGH */
   1059      1.1   cherry 		case P1:
   1060      1.1   cherry 		case P2:
   1061      1.1   cherry 		case P3:
   1062      1.1   cherry 		case P4:
   1063      1.1   cherry 		case P5:
   1064      1.1   cherry 		case P6:
   1065      1.1   cherry 		case P7:
   1066      1.1   cherry 		case P8:
   1067      1.1   cherry 		case P9:
   1068      1.1   cherry 		case P10:
   1069      1.1   cherry 			modifyrecord(&current_state, &rchain[i], rdepth);
   1070      1.1   cherry 			break;
   1071      1.1   cherry 
   1072      1.1   cherry 		case B1:
   1073      1.1   cherry 		case B2:
   1074      1.1   cherry 		case B3:
   1075      1.1   cherry 		case B4:
   1076  1.5.6.1    skrll 			modifyrecord(&current_state, &rchain[i],
   1077  1.5.6.1    skrll 				     rlen - 1 - rdepth);
   1078      1.1   cherry 			break;
   1079      1.1   cherry 
   1080      1.1   cherry 		case X1:
   1081      1.1   cherry 		case X2:
   1082      1.1   cherry 		case X3:
   1083      1.1   cherry 		case X4:
   1084      1.1   cherry 		default:
   1085      1.1   cherry 			printf("Error: Unknown descriptor type!!! \n");
   1086      1.1   cherry 
   1087      1.1   cherry 		}
   1088      1.1   cherry 
   1089      1.1   cherry #if UNWIND_DIAGNOSTIC
   1090      1.1   cherry 		dump_staterecord(&current_state);
   1091      1.1   cherry #endif
   1092      1.1   cherry 
   1093      1.1   cherry 
   1094      1.1   cherry 	}
   1095      1.1   cherry 
   1096      1.1   cherry out:
   1097      1.1   cherry 
   1098      1.1   cherry 	return &current_state;
   1099      1.1   cherry }
   1100      1.1   cherry 
   1101  1.5.6.1    skrll void
   1102  1.5.6.1    skrll updateregs(struct unwind_frame *uwf, struct staterecord *srec,
   1103  1.5.6.1    skrll 	uint64_t procoffset)
   1104      1.1   cherry {
   1105      1.1   cherry 	/* XXX: Update uwf for regs other than rp and pfs*/
   1106      1.1   cherry 	uint64_t roffset = 0;
   1107      1.1   cherry 
   1108      1.1   cherry 	/* Uses shadow arrays to update uwf from srec in a loop. */
   1109      1.1   cherry 	/* Count of number of regstate elements in struct staterecord */
   1110      1.1   cherry 	int statecount = sizeof(struct staterecord)/sizeof(struct regstate);
   1111      1.1   cherry 	/* Pointer to current regstate. */
   1112      1.1   cherry 	struct regstate *stptr = (void *) srec;
   1113      1.1   cherry 	/* Pointer to current unwind_frame element */
   1114      1.1   cherry 	uint64_t *gr = (void *) uwf;
   1115      1.1   cherry 
   1116      1.1   cherry 	int i;
   1117      1.1   cherry 
   1118  1.5.6.1    skrll #ifdef UNWIND_DIAGNOSTIC
   1119  1.5.6.1    skrll 	printf("updateregs(): \n");
   1120  1.5.6.1    skrll 	printf("procoffset (slots) = %lu \n", procoffset);
   1121  1.5.6.1    skrll #endif
   1122  1.5.6.1    skrll 
   1123      1.1   cherry 	for(i = 0; i < statecount; i++) {
   1124      1.1   cherry 		switch (stptr[i].where) {
   1125      1.1   cherry 		case IMMED: /* currently only mem_stack_f */
   1126      1.1   cherry 			if (stptr[i].when >= procoffset) break;
   1127      1.1   cherry 			uwf->psp -= (stptr[i].offset << 4);
   1128      1.1   cherry 			break;
   1129      1.1   cherry 
   1130      1.1   cherry 		case GRREL:
   1131      1.1   cherry 			if (stptr[i].when >= procoffset) break;
   1132      1.1   cherry 
   1133      1.1   cherry 			roffset = stptr[i].offset;
   1134      1.1   cherry 			if (roffset == 0) {
   1135      1.1   cherry 				gr[i] = 0;
   1136      1.1   cherry 				break;
   1137      1.1   cherry 			}
   1138      1.1   cherry 
   1139      1.1   cherry 
   1140      1.1   cherry 			if (roffset < 32) {
   1141  1.5.6.1    skrll 				printf("GR%ld: static register save ??? \n",
   1142  1.5.6.1    skrll 				       roffset);
   1143      1.1   cherry 				break;
   1144      1.1   cherry 			}
   1145      1.1   cherry 
   1146      1.1   cherry 			/* Fetch from bsp + offset - 32 + Adjust for RNAT. */
   1147      1.1   cherry 			roffset -= 32;
   1148      1.1   cherry 			gr[i] = ia64_getrse_gr(uwf->bsp, roffset);
   1149      1.1   cherry 			break;
   1150      1.1   cherry 
   1151      1.1   cherry 		case SPREL:
   1152      1.1   cherry 			if (stptr[i].when >= procoffset) break;
   1153      1.1   cherry 
   1154      1.1   cherry 			/* Check if frame has been setup. */
   1155      1.1   cherry 			if (srec->psp.offset == INVALID) {
   1156  1.5.6.1    skrll 				printf("sprel used without setting up "
   1157  1.5.6.1    skrll 				       "stackframe!!! \n");
   1158      1.1   cherry 				break;
   1159      1.1   cherry 			}
   1160      1.1   cherry 
   1161      1.1   cherry 			roffset = stptr[i].offset;
   1162      1.1   cherry 
   1163      1.1   cherry 			/* Fetch from sp + offset */
   1164  1.5.6.1    skrll 			memcpy(&gr[i], (char *) uwf->sp + roffset * 4,
   1165  1.5.6.1    skrll 			       sizeof(uint64_t));
   1166      1.1   cherry 			break;
   1167      1.1   cherry 
   1168      1.1   cherry 
   1169      1.1   cherry 		case PSPREL:
   1170      1.1   cherry 			if (stptr[i].when >= procoffset) break;
   1171      1.1   cherry 
   1172      1.1   cherry 			/* Check if frame has been setup. */
   1173      1.1   cherry 			if (srec->psp.offset == INVALID) {
   1174  1.5.6.1    skrll 				printf("psprel used without setting up "
   1175  1.5.6.1    skrll 				       "stackframe!!! \n");
   1176      1.1   cherry 				break;
   1177      1.1   cherry 			}
   1178      1.1   cherry 
   1179      1.1   cherry 			roffset = stptr[i].offset;
   1180      1.1   cherry 
   1181      1.1   cherry 			/* Fetch from sp + offset */
   1182  1.5.6.1    skrll 			memcpy(&gr[i], (char *) uwf->psp + 16 - (roffset * 4),
   1183  1.5.6.1    skrll 			       sizeof(uint64_t));
   1184      1.1   cherry 			break;
   1185      1.1   cherry 
   1186      1.1   cherry 		case UNSAVED:
   1187      1.1   cherry 		case BRREL:
   1188      1.1   cherry 		default:
   1189      1.1   cherry #ifdef UNWIND_DIAGNOSTIC
   1190      1.1   cherry 			printf ("updateregs: reg[%d] is UNSAVED \n", i);
   1191      1.1   cherry #endif
   1192      1.1   cherry 			break;
   1193      1.1   cherry 			/* XXX: Not implemented yet. */
   1194      1.1   cherry 		}
   1195      1.1   cherry 
   1196      1.1   cherry 	}
   1197      1.1   cherry 
   1198      1.1   cherry }
   1199      1.1   cherry 
   1200      1.1   cherry 
   1201  1.5.6.1    skrll /*
   1202  1.5.6.1    skrll  * Locates unwind table entry, given unwind table entry info.
   1203      1.1   cherry  * Expects the variables ia64_unwindtab, and ia64_unwindtablen
   1204      1.1   cherry  * to be set appropriately.
   1205      1.1   cherry  */
   1206      1.1   cherry struct uwtable_ent *
   1207      1.1   cherry get_unwind_table_entry(uint64_t iprel)
   1208      1.1   cherry {
   1209      1.1   cherry 
   1210      1.1   cherry 	extern uint64_t ia64_unwindtab, ia64_unwindtablen;
   1211      1.1   cherry 
   1212      1.1   cherry 	struct uwtable_ent *uwt;
   1213      1.1   cherry 	int tabent;
   1214      1.1   cherry 
   1215  1.5.6.1    skrll 
   1216      1.1   cherry 	for(uwt = (struct uwtable_ent *) ia64_unwindtab, tabent = 0;
   1217      1.1   cherry 	    /* The Runtime spec tells me the table entries are sorted. */
   1218      1.1   cherry 	    uwt->end <= iprel && tabent < ia64_unwindtablen;
   1219      1.1   cherry 	    uwt++, tabent += sizeof(struct uwtable_ent));
   1220      1.1   cherry 
   1221      1.1   cherry 
   1222      1.1   cherry 	if (!(uwt->start <= iprel && iprel < uwt->end)) {
   1223      1.1   cherry #ifdef UNWIND_DIAGNOSTIC
   1224      1.1   cherry 		printf("Entry not found \n");
   1225      1.1   cherry 		printf("iprel = %lx \n", iprel);
   1226      1.1   cherry 		printf("uwt->start = %lx \nuwt->end = %lx \n",
   1227      1.1   cherry 		       uwt->start, uwt->end);
   1228      1.1   cherry 		printf("tabent = %d \n", tabent);
   1229      1.1   cherry 		printf("ia64_unwindtablen = %ld \n",
   1230      1.1   cherry 		       ia64_unwindtablen);
   1231      1.1   cherry #endif
   1232      1.1   cherry 		return NULL;
   1233      1.1   cherry 	}
   1234      1.1   cherry 
   1235      1.1   cherry #ifdef UNWIND_DIAGNOSTIC
   1236      1.1   cherry 	printf("uwt->start = %lx \nuwt->end = %lx \n"
   1237      1.1   cherry 	       "uwt->infoptr = %p\n", uwt->start, uwt->end, uwt->infoptr);
   1238      1.1   cherry #endif
   1239      1.1   cherry 
   1240      1.1   cherry 	return uwt;
   1241      1.1   cherry }
   1242      1.1   cherry 
   1243      1.1   cherry 
   1244      1.1   cherry /*
   1245      1.1   cherry  * Reads unwind table info and updates register values.
   1246      1.1   cherry  */
   1247      1.1   cherry void
   1248  1.5.6.1    skrll patchunwindframe(struct unwind_frame *uwf, uint64_t iprel, uint64_t relocoffset)
   1249      1.1   cherry {
   1250      1.1   cherry 
   1251      1.1   cherry 	extern struct recordchain strc[];
   1252      1.1   cherry 	struct staterecord *srec;
   1253      1.1   cherry 	struct uwtable_ent *uwt;
   1254      1.1   cherry 	uint64_t infoptr, procoffset, slotoffset;
   1255      1.1   cherry 
   1256  1.5.6.1    skrll #if 0 /* does not work - moved to assertion at the call site */
   1257      1.1   cherry 	if (iprel < 0) {
   1258      1.1   cherry 		panic("unwind ip out of range!!! \n");
   1259      1.1   cherry 		return;
   1260      1.1   cherry 	}
   1261  1.5.6.1    skrll #endif
   1262      1.1   cherry 
   1263      1.1   cherry 	uwt = get_unwind_table_entry(iprel);
   1264      1.1   cherry 
   1265      1.1   cherry 	if (uwt == NULL) return;
   1266      1.1   cherry 
   1267      1.1   cherry 	infoptr = (uint64_t) uwt->infoptr + relocoffset;
   1268      1.1   cherry 
   1269      1.1   cherry 	if (infoptr > relocoffset) {
   1270      1.1   cherry 		buildrecordchain(infoptr, NULL);
   1271  1.5.6.1    skrll 	} else {
   1272  1.5.6.1    skrll 		return;
   1273      1.1   cherry 	}
   1274      1.1   cherry 
   1275      1.1   cherry 	slotoffset = iprel & 3;
   1276      1.1   cherry 
   1277      1.1   cherry 	/* procoffset in Number of _slots_ , _not_ a byte offset. */
   1278      1.1   cherry 
   1279  1.5.6.1    skrll 	procoffset = (((iprel - slotoffset) - (uwt->start)) / 0x10 * 3)
   1280  1.5.6.1    skrll 		+ slotoffset;
   1281      1.1   cherry 	srec = buildrecordstack(strc, procoffset);
   1282      1.1   cherry 
   1283      1.1   cherry 	updateregs(uwf, srec, procoffset);
   1284      1.1   cherry }
   1285