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