home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3540 < prev    next >
Encoding:
Text File  |  1991-06-26  |  17.0 KB  |  722 lines

  1. Newsgroups: alt.sources
  2. From: jtkohl@MIT.EDU (John T Kohl)
  3. Subject: mprof: DEC MIPS patches
  4. Message-ID: <JTKOHL.91Jun25103047@soup.MIT.EDU>
  5. Date: Tue, 25 Jun 91 14:30:57 GMT
  6.  
  7. I've gotten a few requests for these patches, so here they are: The
  8. MIPS-specific enhancements and GNU_C frame pointer frobbery are mine
  9. (including the null-pointer avoidance code), the other stuff is from
  10. Marc Horowitz <marc@mit.edu>.
  11.  
  12. shar & enjoy
  13.  
  14. diffs are vs. standard mprof 3.0 distributions.
  15.  
  16. RCS file: RCS/Makefile.mips,v
  17. retrieving revision 1.1
  18. diff -c -r1.1 Makefile.mips
  19. *** /tmp/,RCSt1019637    Tue Jun 25 10:20:37 1991
  20. --- Makefile.mips    Wed Feb 20 13:07:19 1991
  21. ***************
  22. *** 113,119 ****
  23.       $(BIN)/mprof -normal test1 test1.data > test1.mprof
  24.   
  25.   test1.data: test1
  26. !     test1
  27.       cp mprof.data test1.data
  28.   
  29.   test1: test1.o $(MPLIB)
  30. --- 113,119 ----
  31.       $(BIN)/mprof -normal test1 test1.data > test1.mprof
  32.   
  33.   test1.data: test1
  34. !     ./test1
  35.       cp mprof.data test1.data
  36.   
  37.   test1: test1.o $(MPLIB)
  38. ***************
  39. *** 131,137 ****
  40.       $(BIN)/mprof -normal test2 test2.data > test2.mprof
  41.   
  42.   test2.data: test2
  43. !     test2
  44.       cp mprof.data test2.data
  45.   
  46.   test2: test2.o $(MPLIB)
  47. --- 131,137 ----
  48.       $(BIN)/mprof -normal test2 test2.data > test2.mprof
  49.   
  50.   test2.data: test2
  51. !     ./test2
  52.       cp mprof.data test2.data
  53.   
  54.   test2: test2.o $(MPLIB)
  55. ===================================================================
  56. RCS file: RCS/Makefile.vax,v
  57. retrieving revision 1.1
  58. diff -c -r1.1 Makefile.vax
  59. *** /tmp/,RCSt1019637    Tue Jun 25 10:20:39 1991
  60. --- Makefile.vax    Wed Feb 20 13:25:23 1991
  61. ***************
  62. *** 15,20 ****
  63. --- 15,21 ----
  64.   
  65.   CFLAGS = -I. -g
  66.   ASFLAGS =
  67. + CPP = /lib/cpp
  68.   BIN = /mit/watchmaker/vaxbin
  69.   LIB = /mit/watchmaker/vaxlib
  70.   INCLUDE = /mit/watchmaker/include
  71. ***************
  72. *** 21,33 ****
  73.   MPLIB = libc_mp.a
  74.   LINTFLAGS = -bhx
  75.   
  76. ! # sun4,mips         ASM_SRC = md.s
  77. ! # sun4,mips         ASM_OBJ = md.o
  78. ! # vax,sun3         ASM_SRC =
  79. ! # vax,sun3         ASM_SRC =
  80.   
  81. ! ASM_SRC =
  82. ! ASM_OBJ =
  83.   
  84.   MPROF_MON_SRCS = leak.c malloc.c mpattach.c mprof_mon.c mpstruct.c $(ASM_SRC)
  85.   MPROF_MON_OBJS = leak.o malloc.o mpattach.o mprof_mon.o mpstruct.o $(ASM_OBJ)
  86. --- 22,34 ----
  87.   MPLIB = libc_mp.a
  88.   LINTFLAGS = -bhx
  89.   
  90. ! # sun4,mips,vax     ASM_SRC = md.s
  91. ! # sun4,mips,vax        ASM_OBJ = md.o
  92. ! # sun3             ASM_SRC =
  93. ! # sun3             ASM_OBJ =
  94.   
  95. ! ASM_SRC = md.s
  96. ! ASM_OBJ = md.o
  97.   
  98.   MPROF_MON_SRCS = leak.c malloc.c mpattach.c mprof_mon.c mpstruct.c $(ASM_SRC)
  99.   MPROF_MON_OBJS = leak.o malloc.o mpattach.o mprof_mon.o mpstruct.o $(ASM_OBJ)
  100. ***************
  101. *** 62,69 ****
  102.   
  103.   $(MPLIB): $(MPROF_MON_OBJS)
  104.       cp /lib/libc.a $(MPLIB)
  105. !     ar d $(MPLIB) malloc.o valloc.o $(LIB_REPLACE)
  106. !     ar r $(MPLIB) $(MPROF_MON_OBJS)
  107.       ranlib $(MPLIB)
  108.   
  109.   test: $(TEST_OBJS) test1-demo test2-demo
  110. --- 63,70 ----
  111.   
  112.   $(MPLIB): $(MPROF_MON_OBJS)
  113.       cp /lib/libc.a $(MPLIB)
  114. !     ar dv $(MPLIB) malloc.o valloc.o $(LIB_REPLACE)
  115. !     ar rv $(MPLIB) $(MPROF_MON_OBJS)
  116.       ranlib $(MPLIB)
  117.   
  118.   test: $(TEST_OBJS) test1-demo test2-demo
  119. ***************
  120. *** 88,94 ****
  121.   mpgraph.o: mpgraph.c
  122.   mprof.o: mprof.c
  123.   md.o: md.s
  124. !     $(AS) $(ASFLAGS) -o md.o md.s
  125.   
  126.   malloc.o: malloc.c
  127.       $(CC) $(CFLAGS) -Dmalloc=__malloc__ -Dfree=__free__ -Drealloc=__realloc__ malloc.c -c
  128. --- 89,95 ----
  129.   mpgraph.o: mpgraph.c
  130.   mprof.o: mprof.c
  131.   md.o: md.s
  132. !     $(CPP) md.s | $(AS) $(ASFLAGS) -o md.o
  133.   
  134.   malloc.o: malloc.c
  135.       $(CC) $(CFLAGS) -Dmalloc=__malloc__ -Dfree=__free__ -Drealloc=__realloc__ malloc.c -c
  136. ***************
  137. *** 116,122 ****
  138.       $(BIN)/mprof -normal test1 test1.data > test1.mprof
  139.   
  140.   test1.data: test1
  141. !     test1
  142.       cp mprof.data test1.data
  143.   
  144.   test1: test1.o $(MPLIB)
  145. --- 117,123 ----
  146.       $(BIN)/mprof -normal test1 test1.data > test1.mprof
  147.   
  148.   test1.data: test1
  149. !     ./test1
  150.       cp mprof.data test1.data
  151.   
  152.   test1: test1.o $(MPLIB)
  153. ***************
  154. *** 134,140 ****
  155.       $(BIN)/mprof -normal test2 test2.data > test2.mprof
  156.   
  157.   test2.data: test2
  158. !     test2
  159.       cp mprof.data test2.data
  160.   
  161.   test2: test2.o $(MPLIB)
  162. --- 135,141 ----
  163.       $(BIN)/mprof -normal test2 test2.data > test2.mprof
  164.   
  165.   test2.data: test2
  166. !     ./test2
  167.       cp mprof.data test2.data
  168.   
  169.   test2: test2.o $(MPLIB)
  170. ===================================================================
  171. RCS file: RCS/md.s,v
  172. retrieving revision 1.1
  173. diff -c -r1.1 md.s
  174. *** /tmp/,RCSt1019637    Tue Jun 25 10:20:40 1991
  175. --- md.s    Wed Feb 20 13:21:33 1991
  176. ***************
  177. *** 51,53 ****
  178. --- 51,59 ----
  179.       j    $31
  180.       .end    getsp
  181.   #endif
  182. + #ifdef vax
  183. + .globl _startaddr
  184. + .globl start
  185. + _startaddr:
  186. +     .long start
  187. + #endif
  188. ===================================================================
  189. RCS file: RCS/mpgraph.c,v
  190. retrieving revision 1.1
  191. diff -c -r1.1 mpgraph.c
  192. *** /tmp/,RCSt1019637    Tue Jun 25 10:20:41 1991
  193. --- mpgraph.c    Wed Feb 20 15:01:43 1991
  194. ***************
  195. *** 90,95 ****
  196. --- 90,97 ----
  197.   int    *scratch;
  198.   {
  199.       vertex result = (vertex) malloc(sizeof(vertex_item));
  200. +     if (!name)
  201. +     name = "(anonymous)";
  202.       result->name = name;
  203.       result->number = number;
  204.       result->srefs = 0;
  205. ***************
  206. *** 491,497 ****
  207.   char    *key;
  208.   {
  209.       ENTRY    e, *result;
  210. !     e.key = key;
  211.       
  212.       result = hsearch(e, FIND);
  213.       return (vertex) result->data;
  214. --- 493,502 ----
  215.   char    *key;
  216.   {
  217.       ENTRY    e, *result;
  218. !     if (key)
  219. !     e.key = key;
  220. !     else
  221. !     e.key = "(anonymous)";
  222.       
  223.       result = hsearch(e, FIND);
  224.       return (vertex) result->data;
  225. ===================================================================
  226. RCS file: RCS/mprof.h,v
  227. retrieving revision 1.1
  228. diff -c -r1.1 mprof.h
  229. *** /tmp/,RCSt1019637    Tue Jun 25 10:20:43 1991
  230. --- mprof.h    Wed Feb 20 18:11:48 1991
  231. ***************
  232. *** 1,8 ****
  233.   /*    mprof.h 2.5 9/14/90 16:01:19    */
  234.   /*    Copyright (c) 1987, Benjamin G. Zorn */
  235.   
  236. ! /* $Id: mprof.h,v 1.1 90/11/17 02:14:48 marc Exp $ */
  237.   
  238.   typedef    int    bool;
  239.   #define    TRUE    1
  240.   #define    FALSE    0
  241. --- 1,24 ----
  242.   /*    mprof.h 2.5 9/14/90 16:01:19    */
  243.   /*    Copyright (c) 1987, Benjamin G. Zorn */
  244.   
  245. ! /* $Id: mprof.h,v 1.3 91/02/20 10:04:42 jtkohl Exp $ */
  246.   
  247. + /* definitions for programs which modify mprof's default behavior */
  248. + #ifdef __STDC__
  249. + #define ARG(x) x
  250. + #else
  251. + #define ARG(x) ()
  252. + #endif
  253. + void set_mprof_autosave ARG((int));
  254. + void set_mprof_keep_file_open ARG((int));
  255. + void set_mprof_append_pid ARG((int));
  256. + void mprof_stop ARG((void));
  257. + void mprof_restart ARG((char *));
  258. + #undef ARG
  259.   typedef    int    bool;
  260.   #define    TRUE    1
  261.   #define    FALSE    0
  262. ***************
  263. *** 111,119 ****
  264.   
  265.   extern    char    *strdup();
  266.   
  267. ! #if (defined(vax) || (defined(sun) && !defined(sun4)))
  268. ! #define get_current_fp(first_local) ((unsigned)&(first_local) + 4)
  269.   #endif
  270.   
  271.   #if (defined(vax) || defined(sun))
  272.   #include <sys/types.h>
  273. --- 127,143 ----
  274.   
  275.   extern    char    *strdup();
  276.   
  277. ! #if defined(vax) || defined(__vax__)
  278. ! #ifdef __GNUC__
  279. ! #define get_current_fp(fp, first_local) asm("movl fp,%0" : "=g" (fp));
  280. ! #else
  281. ! #define get_current_fp(fp, first_local) fp = ((unsigned)&(first_local) + 4)
  282.   #endif
  283. + #else /* not vax */
  284. + #if (defined(sun) && !defined(sun4))
  285. + #define get_current_fp(fp, first_local) fp = ((unsigned)&(first_local) + 4)
  286. + #endif /* sun */
  287. + #endif /* vax */
  288.   
  289.   #if (defined(vax) || defined(sun))
  290.   #include <sys/types.h>
  291. ===================================================================
  292. RCS file: RCS/mprof_mon.c,v
  293. retrieving revision 1.1
  294. diff -c -r1.1 mprof_mon.c
  295. *** /tmp/,RCSt1019637    Tue Jun 25 10:20:45 1991
  296. --- mprof_mon.c    Thu Feb 21 11:51:53 1991
  297. ***************
  298. *** 1,7 ****
  299.   /*    mprof_mon.c 1.1 9/14/90 11:59:04    */
  300.   /*    Copyright (c) 1987, Benjamin G. Zorn */
  301.   
  302. ! /* $Id: mprof_mon.c,v 1.1 90/11/17 00:34:16 marc Exp $ */
  303.   
  304.   /* mprof_mon -- code that is attached to executing programs.
  305.    */
  306. --- 1,7 ----
  307.   /*    mprof_mon.c 1.1 9/14/90 11:59:04    */
  308.   /*    Copyright (c) 1987, Benjamin G. Zorn */
  309.   
  310. ! /* $Id: mprof_mon.c,v 1.5 91/02/21 11:51:16 jtkohl Exp $ */
  311.   
  312.   /* mprof_mon -- code that is attached to executing programs.
  313.    */
  314. ***************
  315. *** 8,13 ****
  316. --- 8,14 ----
  317.   
  318.   #include    <stdio.h>
  319.   #include    <sys/file.h>
  320. + #include    <sys/param.h>
  321.   #include    "mprof.h"
  322.   
  323.   #ifdef mips
  324. ***************
  325. *** 38,44 ****
  326. --- 39,48 ----
  327.   /* local variables */
  328.     
  329.   char    *mprof_filename = "mprof.data";
  330. + char    mprof_filename_buf[MAXPATHLEN];
  331.   int    mprof_autosave = 0;
  332. + int    mprof_keep_file_open = 1;
  333. + int    mprof_append_pid = 0;
  334.   int    mprof_file;
  335.   bool    mprof_initialized = FALSE;
  336.   bool    mprofing = TRUE;
  337. ***************
  338. *** 249,254 ****
  339. --- 253,259 ----
  340.   
  341.   #ifdef mips
  342.       pPDR pdr;
  343. +     unsigned getretaddr();
  344.   #endif
  345.   
  346.       if (!mprof_initialized) {
  347. ***************
  348. *** 269,275 ****
  349.       /* gather return addresses from the callstack
  350.        */
  351.   #ifndef mips
  352. !     fp = get_current_fp(first_local);
  353.       ret_addr = ret_addr_from_fp(fp);
  354.       
  355.       /* Step back 1 frame (to the caller of malloc)
  356. --- 274,280 ----
  357.       /* gather return addresses from the callstack
  358.        */
  359.   #ifndef mips
  360. !     get_current_fp(fp, first_local);
  361.       ret_addr = ret_addr_from_fp(fp);
  362.       
  363.       /* Step back 1 frame (to the caller of malloc)
  364. ***************
  365. *** 277,282 ****
  366. --- 282,288 ----
  367.       fp = prev_fp_from_fp(fp);
  368.       ret_addr = ret_addr_from_fp(fp);
  369.       
  370.       while (ret_addr > mp_root_address) {
  371.       if (no_call_graph && (fstk_i > SHORT_CALLSTACK_SIZE))
  372.         break;
  373. ***************
  374. *** 408,425 ****
  375.   }
  376.   
  377.   void
  378. ! mprof_startup()
  379.   {
  380. - #ifdef sun
  381. -     on_exit(mprof_exit, NULL);
  382. - #endif    
  383.       if (strcmp(mprof_filename, "") == 0) {
  384.       mprof_file = 1;
  385.       } else {
  386. !     mprof_file = open(mprof_filename,
  387.                 (O_WRONLY | O_CREAT | O_TRUNC),
  388.                 mprof_create_mask);
  389.       }
  390.       mpstruct_init();
  391.       mp_zero_bins();
  392.       mpleak_init();
  393. --- 414,453 ----
  394.   }
  395.   
  396.   void
  397. ! mprof_open_file()
  398.   {
  399.       if (strcmp(mprof_filename, "") == 0) {
  400.       mprof_file = 1;
  401.       } else {
  402. !     char fname[MAXPATHLEN];
  403. !     if (mprof_append_pid)
  404. !         sprintf(fname,"%s%d",mprof_filename,getpid());
  405. !     else
  406. !         sprintf(fname,"%s",  mprof_filename);
  407. !     mprof_file = open(fname,
  408.                 (O_WRONLY | O_CREAT | O_TRUNC),
  409.                 mprof_create_mask);
  410.       }
  411. + }
  412. + void
  413. + mprof_startup()
  414. + {
  415. + #if defined(vax) || defined(__vax__)
  416. +     /* if using P0INVALID code, we need to make sure we know the real
  417. +        address of start().  start+CRT0_ADDRESS is the return address
  418. +        of the active start(). see sa_vax.s */
  419. +     extern unsigned long startaddr;
  420. +     mp_root_address += startaddr;
  421. + #endif
  422. + #ifdef sun
  423. +     on_exit(mprof_exit, NULL);
  424. + #endif
  425. +     if (mprof_keep_file_open)
  426. +     mprof_open_file();
  427.       mpstruct_init();
  428.       mp_zero_bins();
  429.       mpleak_init();
  430. ***************
  431. *** 447,452 ****
  432. --- 475,483 ----
  433.       char    stats[256];
  434.       extern    int mprof_fmemC, mprof_dmemC, mprof_lmemC, mprof_smemC;
  435.   
  436. +     if (!mprof_keep_file_open)
  437. +     mprof_open_file();
  438.       ftruncate(mprof_file, 0);
  439.       lseek(mprof_file, 0L, 0);
  440.       
  441. ***************
  442. *** 471,476 ****
  443. --- 502,510 ----
  444.       mp_print_leak_table(mprof_file);
  445.       
  446.       mprof_print(mprof_file);
  447. +     if (!mprof_keep_file_open)
  448. +     close(mprof_file);
  449.   }
  450.   
  451.   void
  452. ***************
  453. *** 478,484 ****
  454.   {
  455.       if (mprof_initialized) {
  456.           mprof_writefile();
  457. !         close(mprof_file);
  458.       }
  459.   }
  460.   
  461. --- 512,519 ----
  462.   {
  463.       if (mprof_initialized) {
  464.           mprof_writefile();
  465. !     if (mprof_keep_file_open)
  466. !         close(mprof_file);
  467.       }
  468.   }
  469.   
  470. ***************
  471. *** 490,499 ****
  472.      int count;               count = 0 (default)  implies no autosave
  473.   
  474.      void
  475.      mprof_stop()            -- stop the memory profile in progress
  476.   
  477.      void
  478. !    mprof_restart(datafile)    -- restart memory profiling
  479.   
  480.   */
  481.      
  482. --- 525,546 ----
  483.      int count;               count = 0 (default)  implies no autosave
  484.   
  485.      void
  486. +    set_mprof_keep_file_open(onoff)
  487. +    int onoff            -- if onoff != 0 (default) keeps the file
  488. +                       open between writes.  Otherwise, closes
  489. +                    and opens each time.  
  490. +    void
  491. +    set_mprof_append_pid(onoff) 
  492. +    int onoff            -- appends pid to datafile name before
  493. +                    reopening it the next time.
  494. +    void
  495.      mprof_stop()            -- stop the memory profile in progress
  496.   
  497.      void
  498. !    mprof_restart(datafile)    -- restart memory profiling.   If datafile ==
  499. !                    NULL, opens old file.
  500.   
  501.   */
  502.      
  503. ***************
  504. *** 504,521 ****
  505.       mprof_autosave = count;
  506.   }
  507.         
  508.   
  509.   void
  510.   mprof_restart(datafile)
  511.   char    *datafile;
  512.   {
  513.       if (mprofing)
  514.       fprintf(stderr,
  515. !     "mprof_restart -- restart ingnored; memory profiling in progress\n");
  516.       else {
  517.       mprof_initialized = FALSE;
  518.       mprofing = TRUE;
  519. !     mprof_filename = datafile;
  520.       }
  521.   }
  522.   
  523. --- 551,582 ----
  524.       mprof_autosave = count;
  525.   }
  526.         
  527. + void
  528. + set_mprof_keep_file_open(onoff)
  529. + int    onoff;
  530. + {
  531. +     mprof_keep_file_open = onoff;
  532. + }
  533.   
  534.   void
  535. + set_mprof_append_pid(onoff)
  536. + int    onoff;
  537. + {
  538. +     mprof_append_pid = onoff;
  539. + }
  540. + void
  541.   mprof_restart(datafile)
  542.   char    *datafile;
  543.   {
  544.       if (mprofing)
  545.       fprintf(stderr,
  546. !     "mprof_restart -- restart ignored; memory profiling in progress\n");
  547.       else {
  548.       mprof_initialized = FALSE;
  549.       mprofing = TRUE;
  550. !     if (datafile)
  551. !        mprof_filename = datafile;
  552.       }
  553.   }
  554.   
  555. ***************
  556. *** 524,530 ****
  557.   {
  558.       if (!mprofing) 
  559.       fprintf(stderr,
  560. !     "mprof_stop -- stop ingnored; memory profiling not in progress\n");
  561.       else {
  562.       mprof_cleanup();
  563.       mprofing = FALSE;
  564. --- 585,591 ----
  565.   {
  566.       if (!mprofing) 
  567.       fprintf(stderr,
  568. !     "mprof_stop -- stop ignored; memory profiling not in progress\n");
  569.       else {
  570.       mprof_cleanup();
  571.       mprofing = FALSE;
  572. ***************
  573. *** 538,544 ****
  574.   
  575.   pdrinit()
  576.   {
  577. !     int i;
  578.       SYMR asym;
  579.       extern char **__Argv;    /* hack */
  580.       pFDR pfd;
  581. --- 599,605 ----
  582.   
  583.   pdrinit()
  584.   {
  585. !     register int i, j;
  586.       SYMR asym;
  587.       extern char **__Argv;    /* hack */
  588.       pFDR pfd;
  589. ***************
  590. *** 576,582 ****
  591. --- 637,702 ----
  592.           }
  593.         }
  594.       }
  595. +     for (i = 0; i < SYMHEADER(ldptr).ipdMax - 1; i++) {
  596. +         if (!pdrarray[i].adr) {
  597. +         /* jtkohl@mit.edu: this (apparently)
  598. +            happens when the symbol name for the referenced function
  599. +            has been stripped out, such as when it's a static function
  600. +            and the .o file had ld -x -r run over it.
  601. +            What we really ought to do is determine where the
  602. +            procedure really starts.
  603. +           
  604. +            we attempt to do so, by starting with the previous address,
  605. +            looking for the SECOND addiu   sp,sp,{neg_size}.
  606.   
  607. +            since the MIPS and GCC compilers only generate one such
  608. +            instruction per C function, the second one should be
  609. +            in the prologue of the desired function.
  610. +            HOWEVER, if we have a static function which is a LEAF (no
  611. +            locals, no function calls) we will actually miss the
  612. +            function and find the next one.  Luckily, such a function
  613. +            can never appear on the call graph leading to a malloc, so
  614. +            if we assign it an address just before the address of the
  615. +            next function, then we should never mistakenly "find"
  616. +            it when doing a binary search for a return address.
  617. +            If we have two or more functions with no args before
  618. +            the next known function, it gets hairier...
  619. +            ADDIU sp,sp, {size} is:
  620. +            0x27bd.... (16-bit offset size)
  621. +          */
  622. +         unsigned long *search;
  623. +         if (i == 0 || i == SYMHEADER(ldptr).ipdMax - 2)
  624. +             punt("can't fix up first/last address in table");
  625. +         search = (unsigned long *)pdrarray[i-1].adr;
  626. +         search++;        /* skip over the adjustment
  627. +                        in the previous procedure */
  628. +         while ((*search & 0xffff8000) != 0x27bd8000)
  629. +             search++;
  630. +         if (pdrarray[i+1].adr) {
  631. +             if (search == (unsigned long *)pdrarray[i+1].adr) {
  632. +             /* found next function...back up */
  633. +             search--;
  634. +             }
  635. +         } else {
  636. +             for (j = i+2; j < SYMHEADER(ldptr).ipdMax - 2; j++) {
  637. +             if (pdrarray[j].adr) {
  638. +                 if (search == (unsigned long *)pdrarray[j].adr) {
  639. +                 search -= (j-1);
  640. +                 }
  641. +                 break;
  642. +             }
  643. +             }
  644. +             if (j == SYMHEADER(ldptr).ipdMax - 2)
  645. +             punt("can't find a new anchor address");
  646. +         }
  647. +         pdrarray[i].adr = (unsigned long) search;
  648. +         }
  649. +     }
  650.       /* This is guaranteed to be between __start and main. */
  651.       mp_root_address = pdrarray[1].adr - 1;
  652.   }
  653. ***************
  654. *** 585,591 ****
  655.   getpdr(loc)
  656.   int loc;
  657.   {
  658. !     int low = 0, high = SYMHEADER(ldptr).ipdMax - 1, mid;
  659.   
  660.       /* do binary search on address */
  661.       while (low <= high) {
  662. --- 705,711 ----
  663.   getpdr(loc)
  664.   int loc;
  665.   {
  666. !     register int low = 0, high = SYMHEADER(ldptr).ipdMax - 1, mid;
  667.   
  668.       /* do binary search on address */
  669.       while (low <= high) {
  670. ***************
  671. *** 603,608 ****
  672. --- 723,729 ----
  673.   
  674.   }
  675.   
  676. + unsigned
  677.   getretaddr(pfp, pdr)
  678.   int *pfp;
  679.   pPDR pdr;
  680. ***************
  681. *** 626,632 ****
  682. --- 747,761 ----
  683.   
  684.       if (!(pdr->regmask & (1 << pdr->pcreg))) {
  685.         /* in a register and register is not saved */
  686. +       /* jtkohl@mit.edu: this probably is indicative of using
  687. +          the wrong pdr somewhere in the stack trace.  see above comments
  688. +          about static functions and ld -x -r. */
  689. +       /* just lie and terminate the search, rather than aborting
  690. +          the program. */
  691. +         return mp_root_address;
  692. + #if 0        
  693.         punt("don't know how to get register");
  694. + #endif
  695.       }
  696.   
  697.       if (pdr->framereg != 29) punt("framereg != 29");
  698. --
  699. John Kohl <jtkohl@MIT.EDU>
  700. Digital Equipment Corporation/Project Athena
  701. (The above opinions are MINE.  Don't put my words in somebody else's mouth!)
  702. ___This signature printed on recycled bits___ [not original; heard 2nd hand]
  703.