home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / bprof-1.1 / bprof-1 / bprof / execute.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-31  |  2.1 KB  |  97 lines

  1. /* The executable class.  Opens an executable file and reads info to
  2.    get a pc to line mapping.  This only works with files in a.out
  3.    format.  */
  4.  
  5. #include <std.h>
  6. #include <iostream.h>
  7. #include <sys/mman.h>
  8. #include <sys/stat.h>
  9. #include <stab.h>
  10. #include "execute.h"
  11.  
  12. /* Some people seem to have include files where this is not defined */
  13. #ifndef MAP_FILE
  14. #define MAP_FILE 0
  15. #endif
  16.  
  17. executable::executable(const char* file)
  18. {
  19.     fd = open(file, O_RDONLY);
  20.     if (fd == -1) {
  21.     perror(file);
  22.     exit(1);
  23.     }
  24.  
  25.     stat flstat;
  26.     if (stat(file, &flstat) == -1) {
  27.     perror("Cannot stat executable");
  28.     exit(1);
  29.     }
  30.     filesize = flstat.st_size;
  31.     if (filesize < sizeof(exec)) {
  32.     cerr << "File is too small to be an executable\n";
  33.     exit(1);
  34.     }
  35.     _mtime = flstat.st_mtime;
  36.     
  37.     start = (unsigned int)mmap(0, filesize, PROT_READ, MAP_FILE|MAP_PRIVATE, fd, 0);
  38.     if (start == (unsigned int)-1) {
  39.     perror("Cannot map executable");
  40.     exit(1);
  41.     }
  42.     exec& header = *(exec*)start;
  43.     if (N_BADMAG(header)) {
  44.     cerr << "File doesn't seem to be an executable\n";
  45.     exit(1);
  46.     }
  47.  
  48.     if (!header.a_syms) {
  49.     cerr << "No symbols in file!\n";
  50.     exit(1);
  51.     }
  52.     cursym = (nlist*)(start + N_SYMOFF(header));
  53.     strs = (char*)(start + N_STROFF(header));
  54.     maxsym = (nlist*)((unsigned)cursym + header.a_syms);
  55.  
  56.     // Go to first line.
  57.     shift();
  58. }
  59.  
  60. executable::~executable(void)
  61. {
  62.     munmap((caddr_t)start, filesize);
  63.     close(fd);
  64. }
  65.  
  66. int executable::shift(void)
  67. {
  68.     while (++cursym < maxsym) {
  69.     switch (cursym->n_type) {
  70.     case N_SO:
  71.         const char* nm = strs + (unsigned)cursym->n_un.n_name;
  72.         if (nm[strlen(nm)-1] == '/') {
  73.         cdir = nm;
  74.         } else {
  75.         cfile = nm;
  76.         }
  77.         break;
  78.     case N_SOL:
  79.         cfile = strs + (unsigned)cursym->n_un.n_name;
  80.         break;
  81.     case N_SLINE:
  82.         cline = cursym->n_desc;
  83.         clow = cursym->n_value;
  84.         /* Look for next symbol to get high pc */
  85.         nlist* nextsym = cursym;
  86.         do {
  87.         if (++nextsym == maxsym)
  88.             return 0;
  89.         } while (nextsym->n_type != N_SLINE);
  90.         chigh = nextsym->n_value;
  91.         return 1;
  92.     }
  93.     }
  94.  
  95.     return 0;            // No more symbols.
  96. }
  97.