home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3549 < prev    next >
Internet Message Format  |  1991-06-26  |  23KB

  1. From: steve@robobar.co.uk (Steve Bleazard)
  2. Newsgroups: comp.unix.xenix.sco,alt.sources
  3. Subject: mprof patches for SCO XENIX with GCC
  4. Message-ID: <1991Jun26.070843.12908@robobar.co.uk>
  5. Date: 26 Jun 91 07:08:43 GMT
  6.  
  7. Submitted-by: steve@robobar.co.uk (Steve Bleazard)
  8. Archive-name: mprof/xenix.pch01
  9. Environment: SCO XENIX GCC
  10.  
  11. Mprof is a tool for finding memory leaks, etc., which I found languishing
  12. on ucbarpa.berkeley.edu:/pub/mprof-3.0.tar.Z and I needed it, so here's
  13. the port to XENIX which I did in order to be able to use it.
  14.  
  15. This port works best if you have a reasonably up to date version of
  16. my port of GCC to SCO XENIX (any version with GDB support will do).
  17. You can find copies of my XENIX GCC binaries on unix.secs.oakland.edu
  18. for anon FTP, and on the anomaly.sbs.com anon UUCP archive which is
  19. regularly advertised here.  (GCC at version 1.37.1 which is what I
  20. still use)  Of course you need SCO's development system (I use
  21. version 2.3.1b) as well.  I have not tried mprof with any combination
  22. other than GCC with SCO 2.3.1 libraries/include files.
  23.  
  24. I'm not sure if I will be able to help anyone with problems using mprof
  25. since I haven't read the manual yet, although it has helped me plug a
  26. couple of serious leaks already, well justifying the time spent porting it,
  27. in fact.  However, mail will be welcome.
  28.  
  29. diff -c -r -N mprof.orig/Makefile mprof/Makefile
  30. *** mprof.orig/Makefile
  31. --- mprof/Makefile    Wed Jun 26 07:34:57 1991
  32. ***************
  33. *** 0 ****
  34. --- 1,102 ----
  35. + #    %M% %I% %G% %U%    
  36. + #    Copyright (c) 1987, Benjamin G. Zorn
  37. + #
  38. + # Makefile for MPROF data generation
  39. + #
  40. + CC = gcc
  41. + CFLAGS= -I. -Dxenix
  42. + BIN=    /usr/local/bin
  43. + LIB=    /lib/386
  44. + MPLIB=    Slibmp.a
  45. + MPROF_MON_SRCS = leak.c malloc.c mpattach.c mprof_mon.c mpstruct.c pagesz.c
  46. + MPROF_MON_OBJS = leak.o malloc.o mpattach.o mprof_mon.o mpstruct.o pagesz.o
  47. + MPROF_SRCS = mprof.c mpstruct.c mpgraph.c xsym.c
  48. + MPROF_OBJS = mprof.o mpstruct.o mpgraph.o xsym.o
  49. + DOC_SRC = mprof.1
  50. + DOC_OBJS = mprof.man
  51. + DISTNAME = mprof30
  52. + TEST_SRCS = test1.c test2.c
  53. + TEST_OBJS = test1.o test2.o
  54. + all: mprof $(MPROF_MON_OBJS) $(DOC_OBJS) $(MPLIB)
  55. + $(MPLIB): $(MPROF_MON_OBJS)
  56. +     rm -rf $(MPLIB)
  57. +     ar cq $(MPLIB) $(MPROF_MON_OBJS)
  58. +     ranlib $(MPLIB)
  59. + test: $(TEST_OBJS) test1-demo test2-demo
  60. +     
  61. + clean:
  62. +     rm -f *.o mprof.lint mprof-mon.lint \
  63. +     $(DOC_OBJS) \
  64. +     $(TEST_OBJS) \
  65. +     test1 test1.data test1.mprof \
  66. +     test2 test2.data test2.mprof \
  67. +     libc_mp.a mprof mprof.data
  68. + leak.o: leak.c
  69. + mprof_mon.o: mprof_mon.c
  70. + mpstruct.o: mpstruct.c
  71. + mpgraph.o: mpgraph.c
  72. + mprof.o: mprof.c
  73. + malloc.o: malloc.c
  74. +     $(CC) $(CFLAGS) -Dmalloc=__malloc__ -Dfree=__free__ -Drealloc=__realloc__ malloc.c -c
  75. + mprof: $(MPROF_OBJS)
  76. +     $(CC) $(CFLAGS) -o mprof $(MPROF_OBJS)
  77. + mprof.man: mprof.1
  78. +     nroff -man mprof.1 > mprof.man
  79. + dist: MANIFEST
  80. +     tar cvf $(DISTNAME).tar `cat MANIFEST`
  81. +     compress $(DISTNAME).tar
  82. + #
  83. + # Examples to test if MPROF is installed correctly
  84. + #
  85. + # A very simple test (tests calloc and valloc)
  86. + test1-demo: test1.data
  87. +     $(BIN)/mprof -normal test1 test1.data > test1.mprof
  88. + test1.mprof: test1.data
  89. +     $(BIN)/mprof -normal test1 test1.data > test1.mprof
  90. + test1.data: test1
  91. +     test1
  92. +     cp mprof.data test1.data
  93. + # test1: test1.o $(MPLIB)
  94. + #    $(CC) $(CFLAGS) -o test1 test1.o $(MPLIB)
  95. + test1: test1.o $(MPROF_MON_OBJS)
  96. +     $(CC) $(CFLAGS) -g -o test1 test1.o $(MPROF_MON_OBJS)
  97. + test1.o: test1.c
  98. + # test2 program (example from paper)
  99. + test2-demo: test2.data
  100. +     $(BIN)/mprof -normal test2 test2.data > test2.mprof
  101. + test2.mprof: test2.data
  102. +     $(BIN)/mprof -normal test2 test2.data > test2.mprof
  103. + test2.data: test2
  104. +     test2
  105. +     cp mprof.data test2.data
  106. + test2: test2.o $(MPLIB)
  107. +     $(CC) $(CFLAGS) -o test2 test2.o $(MPLIB)
  108. + test2.o: test2.c
  109. diff -c -r -N mprof.orig/gas-nlist.h mprof/gas-nlist.h
  110. *** mprof.orig/gas-nlist.h
  111. --- mprof/gas-nlist.h    Tue Jun 25 10:21:12 1991
  112. ***************
  113. *** 0 ****
  114. --- 1,13 ----
  115. + #define N_STAB 0340
  116. + struct gas_nlist {
  117. +     union {
  118. +         char    *n_name;
  119. +         struct gas_nlist *n_next;
  120. +         long    n_strx;
  121. +     } n_un;
  122. +     char    n_type;
  123. +     char    n_other;
  124. +     short    n_desc;
  125. +     unsigned n_value;
  126. + };
  127. diff -c -r -N mprof.orig/malloc.c mprof/malloc.c
  128. *** mprof.orig/malloc.c    Fri Sep 14 18:19:40 1990
  129. --- mprof/malloc.c    Tue Jun 25 08:08:04 1991
  130. ***************
  131. *** 20,25 ****
  132. --- 20,31 ----
  133.    */
  134.   
  135.   #include <sys/types.h>
  136. + #ifdef xenix
  137. + #include <string.h>
  138. + typedef    unsigned char u_char;
  139. + typedef    unsigned int u_int;
  140. + #define bcopy(s,d,l) memcpy(d,s,l)
  141. + #endif
  142.   
  143.   #define    NULL 0
  144.   
  145. diff -c -r -N mprof.orig/mpattach.c mprof/mpattach.c
  146. *** mprof.orig/mpattach.c    Fri Sep 14 18:19:41 1990
  147. --- mprof/mpattach.c    Tue Jun 25 15:26:16 1991
  148. ***************
  149. *** 181,186 ****
  150. --- 181,201 ----
  151.   
  152.   #endif
  153.   
  154. + #if defined(xenix) && !defined(USE_ATEXIT)
  155. + void exit(int code)
  156. + {
  157. +   void mprof_exit();
  158. +   extern void _cleanup(void);
  159. +   extern void _xcleanup(void);
  160. +   extern int _exit(int);
  161. +   mprof_exit(code, 0);
  162. +   _cleanup();
  163. +   _xcleanup();
  164. +   _exit(code);
  165. + }
  166. + #endif
  167.   void
  168.   mprof_exit(status, dummy)
  169.   int    status;
  170. diff -c -r -N mprof.orig/mpgraph.c mprof/mpgraph.c
  171. *** mprof.orig/mpgraph.c    Fri Sep 14 23:24:55 1990
  172. --- mprof/mpgraph.c    Tue Jun 25 13:04:12 1991
  173. ***************
  174. *** 104,110 ****
  175.       vertex    from, to;
  176.       mpdata    data;
  177.       int        mark;
  178. !     struct edge_struct *save
  179.   } *edge, edge_item;
  180.   
  181.   edge
  182. --- 104,110 ----
  183.       vertex    from, to;
  184.       mpdata    data;
  185.       int        mark;
  186. !     struct edge_struct *save;
  187.   } *edge, edge_item;
  188.   
  189.   edge
  190. diff -c -r -N mprof.orig/mprof.c mprof/mprof.c
  191. *** mprof.orig/mprof.c    Fri Sep 14 22:01:25 1990
  192. --- mprof/mprof.c    Tue Jun 25 13:40:31 1991
  193. ***************
  194. *** 5,15 ****
  195. --- 5,27 ----
  196.    */
  197.       
  198.   
  199. + #ifdef xenix
  200. + #include "xgasstab.h"
  201. + #include "gas-nlist.h"
  202. + #include <sys/types.h>
  203. + #include <fcntl.h>
  204. + #include <sys/relsym.h>
  205. + #include <sys/param.h>
  206. + #define index strchr
  207. + #endif
  208.   #include    <stdio.h>
  209.   #include    <sys/file.h>
  210.   #include    <ctype.h>
  211.   #include    <a.out.h>
  212. + #ifndef xenix
  213.   #include    <stab.h>
  214. + #endif
  215.   #include     "mprof.h"
  216.   
  217.   #ifdef mips
  218. ***************
  219. *** 16,22 ****
  220.   #include <ldfcn.h>
  221.   #endif
  222.   
  223. ! #if defined(mips) || defined(vax)
  224.   char *
  225.   strdup(s)
  226.   char    *s;
  227. --- 28,34 ----
  228.   #include <ldfcn.h>
  229.   #endif
  230.   
  231. ! #if defined(mips) || defined(vax) || defined(xenix)
  232.   char *
  233.   strdup(s)
  234.   char    *s;
  235. ***************
  236. *** 694,699 ****
  237. --- 706,798 ----
  238.   }
  239.   
  240.   #else
  241. + #ifdef xenix
  242. + void
  243. + st_read(exec_name)
  244. + char    *exec_name;
  245. + {
  246. +     int        aout_file = open(exec_name, (O_RDONLY));
  247. +     extern char *index();
  248. +     extern char *malloc();
  249. +     char    *stmp;
  250. +     int        string_size;
  251. +     char    *fname;
  252. +     int        i;
  253. +     struct xseg *cseg;
  254. +     long str_offset, nsyms, address, ntaboff;
  255. +     struct xseg *find_segment();
  256. +     struct gas_nlist nl;
  257. +     
  258. +     process_a_out(aout_file, exec_name);
  259. +     /* read in the global symbol table from the x.out */
  260. +     if (cseg = find_segment(XS_TSYMS, 1))
  261. +     {
  262. +       char *symdata, *p;
  263. +       struct sym symb;
  264. +       symdata = p = malloc(cseg->xs_psize + 1);
  265. +       lseek(aout_file, cseg->xs_filpos, 0);
  266. +       read(aout_file, symdata, cseg->xs_psize);
  267. +       while (p < symdata + cseg->xs_psize)
  268. +       {
  269. +     symb = *((struct sym *)p);
  270. +     p += sizeof(struct sym);
  271. +     if ((symb.s_type & S_TYPE) == S_TEXT)
  272. +     {
  273. +       stab_name(stab_i) = *p == '_' ? p + 1 : p;
  274. +       stab_addr(stab_i) = symb.s_value;
  275. +       stab_incr(stab_i);
  276. +     }
  277. +     p += strlen(p) + 1;
  278. +       }
  279. +     }
  280. +     /* read in the string table
  281. +      */
  282. +     if (cseg = find_segment(XS_TSYMS, 4))
  283. +     {
  284. +       lseek(aout_file, cseg->xs_filpos, 0);
  285. +       st_strings = malloc(cseg->xs_psize);
  286. +       read(aout_file, st_strings, cseg->xs_psize);
  287. +     }
  288. +     else st_strings = 0;
  289. +     
  290. +     /* read in the symbols one at a time
  291. +      */
  292. +     init_fileinfo_processing();
  293. +     while (get_next_fileinfo(&str_offset, &nsyms, &address, &ntaboff))
  294. +     {
  295. +       lseek(aout_file, ntaboff, 0);
  296. +       while (nsyms--)
  297. +       {
  298. +         read(aout_file, &nl, sizeof(nl));
  299. +     if (nl.n_type & N_STAB)
  300. +     {
  301. +       if ((unsigned char)nl.n_type == N_LSYM ||
  302. +           (unsigned char)nl.n_type == N_GSYM)
  303. +       {
  304. +         /* a local symbol that may be a structure definition
  305. +          */
  306. +         st_read_structure(st_strings + str_offset + nl.n_un.n_strx);
  307. +       }
  308. +     }
  309. +       }
  310. +     }
  311. +     stab_name(stab_i) = "unknown";
  312. +     stab_addr(stab_i) = stab_addr(stab_i - 1) + 0x10000;
  313. +     stab_incr(stab_i);
  314. +     stab_name(stab_i) = "end_marker";
  315. +     stab_addr(stab_i) = 0xffffffff;
  316. +     stab_incr(stab_i);
  317. +     qsort(stab, stab_i, sizeof(struct finfo), stab_compare);
  318. + }
  319. + #else /* !xenix */
  320.   
  321.   void
  322.   st_read(exec_name)
  323. ***************
  324. *** 774,779 ****
  325. --- 873,880 ----
  326.       qsort(stab, stab_i, sizeof(struct finfo), stab_compare);
  327.   }
  328.   
  329. + #endif /* xenix */
  330.   void
  331.   st_read_structure(symp)
  332.   char    *symp;
  333. ***************
  334. *** 1376,1379 ****
  335.   
  336.       exit(0);
  337.   }    
  338. --- 1477,1479 ----
  339. diff -c -r -N mprof.orig/mprof.h mprof/mprof.h
  340. *** mprof.orig/mprof.h    Fri Sep 14 22:01:24 1990
  341. --- mprof/mprof.h    Wed Jun 26 07:31:50 1991
  342. ***************
  343. *** 109,115 ****
  344.   
  345.   extern    char    *strdup();
  346.   
  347. ! #if (defined(vax) || (defined(sun) && !defined(sun4)))
  348.   #define get_current_fp(first_local) ((unsigned)&(first_local) + 4)
  349.   #endif
  350.   
  351. --- 109,115 ----
  352.   
  353.   extern    char    *strdup();
  354.   
  355. ! #if (defined(vax) || (defined(sun) && !defined(sun4)) || defined(xenix))
  356.   #define get_current_fp(first_local) ((unsigned)&(first_local) + 4)
  357.   #endif
  358.   
  359. ***************
  360. *** 119,124 ****
  361. --- 119,132 ----
  362.   #define prev_fp_from_fp(fp)    (unsigned)(((struct frame *)(fp))->fr_savfp)
  363.   #define ret_addr_from_fp(fp)    (unsigned)(((struct frame *)(fp))->fr_savpc)
  364.   #endif
  365. + #if (defined(xenix))
  366. + struct frame {
  367. +   unsigned long fr_savfp;
  368. +   unsigned long fr_savpc;
  369. + };
  370. + #define prev_fp_from_fp(fp)    (unsigned)(((struct frame *)(fp))->fr_savfp)
  371. + #define ret_addr_from_fp(fp)    (unsigned)(((struct frame *)(fp))->fr_savpc)
  372. + #endif
  373.   
  374.     
  375.   /* for ultrix 0x38, 4.3 bsd 0x3d, other?
  376. ***************
  377. *** 134,137 ****
  378. --- 142,149 ----
  379.   
  380.   #ifdef mips
  381.   #define CRT0_ADDRESS        0x0  /* to be filled in later */
  382. + #endif
  383. + #ifdef xenix
  384. + #define CRT0_ADDRESS        0x0
  385.   #endif
  386. diff -c -r -N mprof.orig/mprof_mon.c mprof/mprof_mon.c
  387. *** mprof.orig/mprof_mon.c    Fri Sep 14 18:19:47 1990
  388. --- mprof/mprof_mon.c    Tue Jun 25 15:29:49 1991
  389. ***************
  390. *** 5,10 ****
  391. --- 5,14 ----
  392.    */
  393.   
  394.   #include    <stdio.h>
  395. + #ifdef xenix
  396. + #include    <sys/types.h>
  397. + #include    <fcntl.h>
  398. + #endif
  399.   #include    <sys/file.h>
  400.   #include    "mprof.h"
  401.   
  402. ***************
  403. *** 411,416 ****
  404. --- 415,423 ----
  405.   #ifdef sun
  406.       on_exit(mprof_exit, NULL);
  407.   #endif    
  408. + #if defined(xenix) && defined(USE_ATEXIT)
  409. +     atexit(mprof_exit);
  410. + #endif
  411.       if (strcmp(mprof_filename, "") == 0) {
  412.       mprof_file = 1;
  413.       } else {
  414. ***************
  415. *** 445,451 ****
  416. --- 452,460 ----
  417.       char    stats[256];
  418.       extern    int mprof_fmemC, mprof_dmemC, mprof_lmemC, mprof_smemC;
  419.   
  420. + #ifndef xenix
  421.       ftruncate(mprof_file, 0);
  422. + #endif
  423.       lseek(mprof_file, 0L, 0);
  424.       
  425.       sprintf(stats, "alloc=%d free=%d depth=%d same=%d all=%d\n",
  426. diff -c -r -N mprof.orig/pagesz.c mprof/pagesz.c
  427. *** mprof.orig/pagesz.c
  428. --- mprof/pagesz.c    Tue Jun 25 08:04:00 1991
  429. ***************
  430. *** 0 ****
  431. --- 1,4 ----
  432. + int getpagesize()
  433. + {
  434. +   return 4096;
  435. + }
  436. diff -c -r -N mprof.orig/test1.c mprof/test1.c
  437. *** mprof.orig/test1.c    Fri Sep 14 18:19:49 1990
  438. --- mprof/test1.c    Tue Jun 25 08:10:31 1991
  439. ***************
  440. *** 11,17 ****
  441.   extern    char    *realloc();
  442.   extern    char    *calloc();
  443.   extern    char    *memalign();
  444. ! extern  long    random();
  445.   
  446.   int
  447.   main()
  448. --- 11,17 ----
  449.   extern    char    *realloc();
  450.   extern    char    *calloc();
  451.   extern    char    *memalign();
  452. ! extern  int    rand();
  453.   
  454.   int
  455.   main()
  456. ***************
  457. *** 37,45 ****
  458.       c = calloc(1, sizeof(struct tstruct));
  459.       c = realloc(c, sizeof(struct tstruct) / 2);
  460.       free(c);
  461. !     c = malloc(random() % 57);
  462.       free(c);
  463. !     c = calloc(1, random() % 57);
  464.       if (i % 2) {
  465.           free(c);
  466.       }
  467. --- 37,45 ----
  468.       c = calloc(1, sizeof(struct tstruct));
  469.       c = realloc(c, sizeof(struct tstruct) / 2);
  470.       free(c);
  471. !     c = malloc(rand() % 57);
  472.       free(c);
  473. !     c = calloc(1, rand() % 57);
  474.       if (i % 2) {
  475.           free(c);
  476.       }
  477. diff -c -r -N mprof.orig/xgasstab.h mprof/xgasstab.h
  478. *** mprof.orig/xgasstab.h
  479. --- mprof/xgasstab.h    Tue Jun 25 11:30:50 1991
  480. ***************
  481. *** 0 ****
  482. --- 1,28 ----
  483. + #define N_GSYM        0x20 
  484. + #define N_FNAME        0x22 
  485. + #define N_FUN        0x24 
  486. + #define N_STSYM        0x26 
  487. + #define N_LCSYM        0x28 
  488. + #define N_MAIN        0x2a 
  489. + #define N_RSYM        0x40 
  490. + #define N_SSYM        0x60 
  491. + #define N_PSYM        0xa0 
  492. + #define N_LSYM        0x80 
  493. + #define N_ENTRY        0xa4 
  494. + #define N_SO        0x64 
  495. + #define N_SOL        0x84 
  496. + #define N_SLINE        0x44 
  497. + #define N_DSLINE    0x46 
  498. + #define N_BSLINE    0x48 
  499. + #define N_BINCL        0x82 
  500. + #define N_EINCL        0xa2 
  501. + #define N_EXCL        0xc2 
  502. + #define N_LBRAC        0xc0 
  503. + #define N_RBRAC        0xe0 
  504. + #define N_BCOMM        0xe2 
  505. + #define N_ECOMM        0xe4 
  506. + #define N_ECOML        0xe8 
  507. + #define N_LENG        0xfe 
  508. + #define N_PC        0x30 
  509. + #define N_M2C        0x42 
  510. + #define N_SCOPE        0xc4 
  511. diff -c -r -N mprof.orig/xsym.c mprof/xsym.c
  512. *** mprof.orig/xsym.c
  513. --- mprof/xsym.c    Tue Jun 25 12:29:27 1991
  514. ***************
  515. *** 0 ****
  516. --- 1,341 ----
  517. + #include <stdio.h>
  518. + #include <a.out.h>
  519. + #include <fcntl.h>
  520. + #include <sys/types.h>
  521. + #include <sys/relsym.h>
  522. + #include <sys/param.h>
  523. + #include <sys/file.h>
  524. + #include "gas-nlist.h"
  525. + /* XENIX symbol segment shape definitions */
  526. + struct section2 {      /* File info table shape */
  527. +   short    segment;  /* segment number */
  528. +   unsigned long  address;  /* start address for this file */
  529. +   unsigned short  textsize;  /* size of the text for this file */
  530. +   long    type3off;  /* offset to type3 records, psym tab */
  531. +   long    type4off;  /* offset to type4 records, nlist tab */
  532. +   long    type5off;  /* offset to type5 records, str tab */
  533. +   long    type6off;  /* offset to type6 records */
  534. +   unsigned short  type3sz;  /* size of type3 records */
  535. +   unsigned short  type4sz;  /* size of type4 records */
  536. +   unsigned short  type5sz;  /* size of type5 records */
  537. +   unsigned short  type6sz;  /* size of type6 records */
  538. +   char    filelen;  /* length of filename */
  539. + };
  540. + /* psymtable (attribute 3) symbol segment shape */
  541. + struct psymbol_seg {
  542. +   long    address;  /* core address */
  543. +   short    segid;    /* segment number */
  544. +   short    typeid;    /* variable's type */
  545. +   char    varlen;    /* variable's length */
  546. + /*  char    name[0];  trailing name varlen long */
  547. + } record3;
  548. + /*  Info maintenance structures */
  549. + struct fileinfo {    /* per file info */
  550. +   unsigned long  address;  /* start address for this file */
  551. +   unsigned short  textsize;  /* size of text for this file */
  552. +   long    psymoff;  /* psyms table */
  553. +   long    strtaboff;  /* string table aka $$TYPES */
  554. +   long    ntaboff;  /* nlist table aka $$SYMBOLS */
  555. +   unsigned short  psymsz;    /* size of psyms table */
  556. +   unsigned short  strtabsz;  /* size of string table */
  557. +   unsigned short  ntabsz;    /* size of nlist table */
  558. +   int    mscdebuginfo;  /* compiled with cc -g not gcc -g */
  559. +   char    *filename;  /* name of this file */
  560. +   struct fileinfo *next;
  561. + };
  562. + static struct fileinfo *fi_table = 0;
  563. + struct xseg *seg_table;
  564. + long num_seg_table_entries;
  565. + #ifdef __GNUC__
  566. + #define alloca __builtin_alloca
  567. + #endif
  568. + #define IGNORE_ATTR (-1)
  569. + static error (string, arg1, arg2, arg3)
  570. +      char *string;
  571. +      int arg1, arg2, arg3;
  572. + {
  573. +   fflush (stdout);
  574. +   fprintf (stderr, string, arg1, arg2, arg3);
  575. +   fprintf (stderr, "\n");
  576. +   exit(1);
  577. + }
  578. + static char * xmalloc (size)
  579. +      long size;
  580. + {
  581. +   register char *val = (char *) malloc (size);
  582. +   if (!val)
  583. +     error ("virtual memory exhausted.");
  584. +   return val;
  585. + }
  586. + static perror_with_name (string)
  587. +      char *string;
  588. + {
  589. +   extern int sys_nerr;
  590. +   extern char *sys_errlist[];
  591. +   extern int errno;
  592. +   char *err;
  593. +   char *combined;
  594. +   if (errno < sys_nerr)
  595. +     err = sys_errlist[errno];
  596. +   else
  597. +     err = "unknown error";
  598. +   combined = (char *) alloca (strlen (err) + strlen (string) + 3);
  599. +   strcpy (combined, string);
  600. +   strcat (combined, ": ");
  601. +   strcat (combined, err);
  602. +   error ("%s.", combined);
  603. + }
  604. + static char *savestring (ptr, size)
  605. +      char *ptr;
  606. +      int size;
  607. + {
  608. +   register char *p = (char *) xmalloc (size + 1);
  609. +   memcpy(p, ptr, size);
  610. +   p[size] = 0;
  611. +   return p;
  612. + }
  613. + static read_fileinfo_table(fp, segsize, name)
  614. + FILE *fp;
  615. + int segsize;
  616. + char *name;
  617. + {
  618. +   extern char *strrchr(), *xmalloc();
  619. +   char *fi_name;
  620. +   char *filename;
  621. +   struct section2 fi_entry;
  622. +   struct fileinfo *fi;
  623. +   fi_table = fi = (struct fileinfo *)xmalloc(sizeof(struct fileinfo));
  624. +   while (segsize > 0)
  625. +   {
  626. +     if ((fread((char *)&fi_entry.segment, sizeof(short), 1, fp) != 1)
  627. +       || (fread((char *)&fi_entry.address, sizeof(unsigned long), 1, fp) != 1)
  628. +       || (fread((char *)&fi_entry.textsize, sizeof(unsigned short),1,fp) != 1)
  629. +       || (fread((char *)&fi_entry.type3off, sizeof(long), 1, fp) != 1)
  630. +       || (fread((char *)&fi_entry.type4off, sizeof(long), 1, fp) != 1)
  631. +       || (fread((char *)&fi_entry.type5off, sizeof(long), 1, fp) != 1)
  632. +       || (fread((char *)&fi_entry.type6off, sizeof(long), 1, fp) != 1)
  633. +       || (fread((char *)&fi_entry.type3sz, sizeof(unsigned short),1,fp) != 1)
  634. +       || (fread((char *)&fi_entry.type4sz, sizeof(unsigned short),1,fp) != 1)
  635. +       || (fread((char *)&fi_entry.type5sz, sizeof(unsigned short),1,fp) != 1)
  636. +       || (fread((char *)&fi_entry.type6sz, sizeof(unsigned short),1,fp) != 1)
  637. +       || (fread((char *)&fi_entry.filelen, sizeof(char), 1, fp) != 1))
  638. +       perror_with_name(name);
  639. +     segsize -= sizeof(short) + sizeof(unsigned long) + 5*sizeof(unsigned short)
  640. +          + 4 * sizeof(long) + sizeof(char);
  641. +     fi_name = alloca(fi_entry.filelen + 1);
  642. +     if (fread(fi_name, fi_entry.filelen, 1, fp) != 1)
  643. +       perror_with_name(name);
  644. +     fi_name[fi_entry.filelen] = '\0';
  645. +     segsize -= fi_entry.filelen;
  646. +     if ((filename = strrchr(fi_name, '/')) != (char *)0)
  647. +       fi_name = filename + 1;
  648. +     if ((filename = strrchr(fi_name, '(')) != (char *)0)
  649. +       fi_name = filename + 1;
  650. +     if ((filename = strrchr(fi_name, ')')) != (char *)0)
  651. +         *filename = '\0';
  652. +    
  653. +     {
  654. +       int len = strlen(fi_name);
  655. +       if (len > 2 && fi_name[len - 1] == 'o' && fi_name[len - 2] == '.')
  656. +       fi_name[len - 1] = 'c';
  657. +     }
  658. +     fi_name = savestring(fi_name, strlen(fi_name) + 1);
  659. +     fi->next = (struct fileinfo *)xmalloc(sizeof(struct fileinfo));
  660. +     fi = fi->next;
  661. +     fi->address = fi_entry.address;
  662. +     fi->textsize = fi_entry.textsize;
  663. +     fi->psymoff = fi_entry.type3off;
  664. +     fi->psymsz = fi_entry.type3sz;
  665. +     fi->strtaboff = fi_entry.type4off;
  666. +     fi->strtabsz = fi_entry.type4sz;
  667. +     fi->ntaboff = fi_entry.type5off;
  668. +     fi->ntabsz = fi_entry.type5sz;
  669. +     fi->mscdebuginfo = (fi_entry.type6sz != 0);
  670. +     fi->filename = fi_name;
  671. +   }
  672. +   fi->next = 0;  fi = fi_table;  fi_table = fi_table->next;  free(fi);
  673. + #ifdef X_DEBUG
  674. +     printf("\naddress   textsz  symoff   symsz  stroff   strsz  taboff   tabsz  name\n\n");
  675. +   for (fi = fi_table; fi != 0; fi = fi->next)
  676. +   {
  677. +     printf("% 8x  % 6d  % 6d  % 6d  % 6d  % 6d  % 6d  %6d  %s\n", fi->address, fi->textsize, fi->psymoff, fi->psymsz, fi->strtaboff, fi->strtabsz, fi->ntaboff, fi->ntabsz, fi->filename);
  678. +   }
  679. +   printf("\n");
  680. + #endif /* X_DEBUG */
  681. + }
  682. + static read_seg_table(fp, pos, size, name)
  683. + FILE *fp;
  684. + long pos, size;
  685. + {
  686. +   seg_table = (struct xseg *) xmalloc(size);
  687. +   fseek(fp, pos, 0);
  688. +   if (fread((char *)seg_table, size, 1, fp) != 1)
  689. +     perror_with_name(name);
  690. +   num_seg_table_entries = size / sizeof (struct xseg);
  691. + }
  692. + struct xseg *find_segment(type, attr)
  693. + int type, attr;
  694. + {
  695. +   struct xseg *cseg;
  696. +   for (cseg = seg_table; cseg < seg_table + num_seg_table_entries; ++cseg)
  697. +   if (cseg->xs_type == type &&
  698. +     (attr == IGNORE_ATTR || attr == cseg->xs_attr))
  699. +     return cseg;
  700. +   return NULL;
  701. + }
  702. + process_a_out(desc, name)
  703. + int desc;
  704. + char *name;
  705. + {
  706. +   struct xexec exec_aouthdr;
  707. +   struct xext *xext;
  708. +   struct xseg *cseg;
  709. +   FILE *fp;
  710. +   lseek(desc, 0L, 0);
  711. +   if ((fp = fdopen(dup(desc), "r")) == NULL)
  712. +     perror_with_name(name);
  713. +   if (fread((char *)&exec_aouthdr, sizeof(struct xexec), 1, fp) != 1)
  714. +     perror_with_name(name);
  715. +   
  716. +   xext = (struct xext *) alloca(exec_aouthdr.x_ext);
  717. +   if (fread((char *)xext, exec_aouthdr.x_ext, 1, fp) != 1)
  718. +     perror_with_name(name);
  719. +   
  720. +   read_seg_table(fp, xext->xe_segpos, xext->xe_segsize, name);
  721. +   if (cseg = find_segment(XS_TSYMS, 2))
  722. +   {
  723. +     fseek(fp, cseg->xs_filpos, 0);
  724. +     read_fileinfo_table(fp, cseg->xs_psize, name);
  725. +   }
  726. +   fclose(fp);
  727. + }
  728. + static struct fileinfo *current_fi;
  729. + static int first_get_fileinfo_call = 1;
  730. + init_fileinfo_processing()  /* start processing the list of files */
  731. + {
  732. +   first_get_fileinfo_call = 1;
  733. + }
  734. + long get_next_fileinfo(stroff, nsyms, address, symtaboff)
  735. + long *stroff, *nsyms, *address, *symtaboff;
  736. + {
  737. +   struct xseg *cseg;
  738. +   if (first_get_fileinfo_call)
  739. +   {
  740. +     current_fi = fi_table;
  741. +     first_get_fileinfo_call = 0;
  742. +   }
  743. +   else
  744. +     current_fi = current_fi->next;
  745. +   
  746. +   if (current_fi == 0)
  747. +     return 0;
  748. +   if (current_fi->mscdebuginfo)
  749. +   {
  750. +     *stroff = 0;
  751. +     *nsyms = 0;
  752. +     *address = current_fi->address;
  753. +   }
  754. +   else if (cseg = find_segment(XS_TSYMS, 5))
  755. +   {
  756. +     *symtaboff = cseg->xs_filpos + current_fi->ntaboff;
  757. +     *stroff = current_fi->strtaboff;
  758. +     *nsyms = current_fi->ntabsz / sizeof(struct gas_nlist);
  759. +     *address = current_fi->address;
  760. +     return 1;
  761. +   }
  762. +   else
  763. +   {
  764. +     *symtaboff = 0;
  765. +     *stroff = 0;
  766. +     *nsyms = 0;
  767. +     *address = 0;
  768. +   }
  769. + }
  770. + #ifdef TEST
  771. + main()
  772. + {
  773. +   char *stab;
  774. +   long str_offset, nsyms, address, ntaboff;
  775. +   int desc;
  776. +   struct xseg *cseg;
  777. +   process_a_out((desc = open("a.out", O_RDONLY, 0)), "a.out");
  778. +   printf("\n");
  779. +   if (cseg = find_segment(XS_TSYMS, 4))
  780. +   {
  781. +     lseek(desc, cseg->xs_filpos, 0);
  782. +     stab = alloca(cseg->xs_psize);
  783. +     read(desc, stab, cseg->xs_psize);
  784. +   }
  785. +   else
  786. +     stab = 0;
  787. +   init_fileinfo_processing();
  788. +   while (get_next_fileinfo(&str_offset,&nsyms,&address,&ntaboff))
  789. +   {
  790. +     lseek(desc, ntaboff, 0);
  791. +     printf("\n  type    desc     value  stroff  string (%#x)\n", address);
  792. +     while (nsyms--)
  793. +     {
  794. +       struct gas_nlist nl;
  795. +       read(desc, &nl, sizeof(nl));
  796. +       printf("% 6x  % 6x  % 8x  % 6x %s\n",
  797. +        (unsigned char)nl.n_type,
  798. +        (unsigned short)nl.n_desc,
  799. +        (unsigned int)nl.n_value,
  800. +        (unsigned int)nl.n_un.n_strx,
  801. +        nl.n_un.n_strx ? stab + str_offset + nl.n_un.n_strx : "");
  802. +     }
  803. +     lseek(desc, 0L, 0);
  804. +   }
  805. + }
  806. + #endif /* TEST */
  807. -- 
  808. Steve.Bleazard@RoboBar.Co.Uk        | Phone:  +44 81 991 1142 x153
  809. Snr Software Engineer, Robobar Ltd. | Fax:    +44 81 998 8343 (G3)
  810. 22 Wadsworth Road, Perivale.        |
  811. Middx., UB6 7JD ENGLAND.            | ...!ukc!robobar!steve
  812.