1*48095Sbostic /*- 2*48095Sbostic * Copyright (c) 1980 The Regents of the University of California. 3*48095Sbostic * All rights reserved. 4*48095Sbostic * 5*48095Sbostic * %sccs.include.redist.c% 622519Sdist */ 75517Slinton 822519Sdist #ifndef lint 9*48095Sbostic static char sccsid[] = "@(#)frame.c 5.3 (Berkeley) 04/16/91"; 10*48095Sbostic #endif /* not lint */ 115517Slinton 125517Slinton /* 135517Slinton * Activation record handling. 145517Slinton * 155517Slinton * The routines curframe and nextframe cheat by using a global copy 165517Slinton * of the display. This means there can't be multiple instances of 175517Slinton * them active at the same time and nextframe won't work in arbitrary cases. 185517Slinton * 195517Slinton * This could be solved by putting the display copy into the FRAME structure, 205517Slinton * but I didn't feel like doing this. The idea is that they be used 215517Slinton * in looping through all frames, if I had generators I would use them. 225517Slinton */ 235517Slinton 245517Slinton #include "defs.h" 255517Slinton #include "runtime.h" 265517Slinton #include "machine.h" 275517Slinton #include "process.h" 285517Slinton #include "sym.h" 295517Slinton #include "object.h" 305517Slinton #include "mappings.h" 315517Slinton #include "process/pxinfo.h" 325517Slinton #include "frame.rep" 3330849Smckusick #include "process/process.rep" 345517Slinton 355517Slinton /* 365517Slinton * Return a pointer to the current activation record. 375517Slinton * Return NIL if currently in the main program. 385517Slinton * The storage is static. 395517Slinton */ 405517Slinton 415517Slinton #define MAXDEPTH 7 425517Slinton #define dispblk(dp) ((dp - DISPLAY) / 2) 435517Slinton 445517Slinton LOCAL ADDRESS *display[MAXDEPTH]; 455517Slinton LOCAL int dispindex; 465517Slinton 475517Slinton FRAME *curframe() 485517Slinton { 495517Slinton static FRAME frame; 505517Slinton FRAME *frp; 515517Slinton ADDRESS *dp, *disp; 525517Slinton int i; 535517Slinton 545517Slinton frp = &frame; 555517Slinton dp = curdp(); 565517Slinton disp = contents(dp); 575517Slinton if (dispblk(dp) <= MAINBLK) { 585517Slinton return NIL; 595517Slinton } else { 605517Slinton getframe(frp, disp); 615517Slinton for (i = 1; i < MAXDEPTH; i++) { 625517Slinton display[i] = dispval(i); 635517Slinton } 645517Slinton dispindex = dispblk(dp); 655517Slinton return frp; 665517Slinton } 675517Slinton } 685517Slinton 695517Slinton /* 705517Slinton * Return a pointer to the next activation record up the stack. 715517Slinton * Return NIL if there is none. 725517Slinton * Writes over space pointed to by given argument. 735517Slinton */ 745517Slinton 755517Slinton FRAME *nextframe(frp) 765517Slinton FRAME *frp; 775517Slinton { 785517Slinton ADDRESS *fp; 795517Slinton 805517Slinton if (dispblk(frp->save_dp) <= MAINBLK) { 815517Slinton return(NIL); 825517Slinton } else { 835517Slinton display[dispindex] = frp->save_disp; 845517Slinton dispindex = dispblk(frp->save_dp); 855517Slinton fp = display[dispindex]; 865517Slinton getframe(frp, fp); 875517Slinton return(frp); 885517Slinton } 895517Slinton } 905517Slinton 915517Slinton /* 925517Slinton * Return the frame associated with the given function. 935517Slinton */ 945517Slinton 955517Slinton FRAME *findframe(f) 965517Slinton SYM *f; 975517Slinton { 985517Slinton static FRAME frame; 995517Slinton FRAME *frp, *prevfrp; 1005517Slinton 1015517Slinton frame.save_dp = curdp(); 1025517Slinton frame.save_disp = contents(frame.save_dp); 1035517Slinton prevfrp = &frame; 1045517Slinton for (frp = curframe(); frp != NIL; frp = nextframe(frp)) { 1055517Slinton if (whatblock(entry(frp)) == f) { 1065517Slinton return frp; 1075517Slinton } 1085517Slinton *prevfrp = *frp; 1095517Slinton } 1105517Slinton if (f == program) { 1115517Slinton return prevfrp; 1125517Slinton } else { 1135517Slinton return NIL; 1145517Slinton } 1155517Slinton } 1165517Slinton 1175517Slinton /* 1185517Slinton * Get the activation record associated with the given display pointer. 1195517Slinton */ 1205517Slinton 1215517Slinton LOCAL getframe(frp, disp) 1225517Slinton FRAME *frp; 1235517Slinton ADDRESS *disp; 1245517Slinton { 1255517Slinton if (disp == NIL) { 1265517Slinton panic("bad disp in getframe"); 1275517Slinton } 1285517Slinton dread(frp, disp, sizeof(FRAME)); 1295517Slinton frp->save_pc -= ENDOFF; 1305517Slinton } 1315517Slinton 1325517Slinton /* 1335517Slinton * Return the address of the display in the px process for the given block. 1345517Slinton */ 1355517Slinton 1365517Slinton ADDRESS *dispval(b) 1375517Slinton int b; 1385517Slinton { 1395517Slinton ADDRESS *r; 1405517Slinton 1415517Slinton dread(&r, (ADDRESS) (DISPLAY + 2*b), sizeof(r)); 1425517Slinton return r; 1435517Slinton } 1445517Slinton 1455517Slinton /* 1465517Slinton * Return the current display pointer. 1475517Slinton */ 1485517Slinton 1495517Slinton ADDRESS *curdp() 1505517Slinton { 1515517Slinton ADDRESS *r; 1525517Slinton 1535517Slinton dread(&r, (ADDRESS) DP, sizeof(r)); 1545517Slinton return r; 1555517Slinton } 1565517Slinton 1575517Slinton /* 1585517Slinton * Return the contents of the given display pointer. 1595517Slinton */ 1605517Slinton 1615517Slinton ADDRESS *contents(dp) 1625517Slinton ADDRESS *dp; 1635517Slinton { 1645517Slinton ADDRESS *r; 1655517Slinton 1665517Slinton dread(&r, (ADDRESS) dp, sizeof(r)); 1675517Slinton return r; 1685517Slinton } 1695517Slinton 1705517Slinton /* 1715517Slinton * Return the px stack address associated with a given frame pointer. 1725517Slinton * Actually, to confuse the issue we want the stack address of the 1735517Slinton * frame one up from the given one. 1745517Slinton */ 1755517Slinton 1765517Slinton ADDRESS stkaddr(frp, b) 1775517Slinton FRAME *frp; 1785517Slinton int b; 1795517Slinton { 1805517Slinton return (ADDRESS) display[b]; 1815517Slinton } 182