core.c

Go to the documentation of this file.
00001 /* 
00002  * core.c for mdb
00003  *
00004  * reads information from 'core' file
00005  * Partly derived from 'adb' by D. Dugger.
00006  */
00007 #include <pm/const.h>
00008 
00009 #include "mdb.h"
00010 
00011 #include <signal.h>
00012 #include <fcntl.h>
00013 #include <stdlib.h>
00014 #include <unistd.h>
00015 #include <stdio.h>
00016 #include <string.h>
00017 #include <sys/ptrace.h>
00018 
00019 #include <pm/type.h>
00020 #include <pm/mproc.h>
00021 
00022 #include <kernel/const.h>
00023 #include <kernel/type.h>
00024 #include <kernel/proc.h>
00025 
00026 /* defined in kernel.c */
00027 extern struct proc *prc; 
00028 
00029 #include "proto.h"
00030 
00031 #define BSIZE  512
00032 #define LOGBS  9
00033 
00034 PRIVATE struct file {
00035   int fid;
00036   char *name;
00037   long cblock;
00038   long tmap[3];
00039   long dmap[3];
00040   long smap[3];
00041   char buf[BSIZE + BSIZE];
00042 } Core_File, *core_file;
00043 
00044 #define b1      tmap[0]
00045 #define e1      tmap[1]
00046 #define f1      tmap[2]
00047 #define b2      dmap[0]
00048 #define e2      dmap[1]
00049 #define f2      dmap[2]
00050 #define b3      smap[0]
00051 #define e3      smap[1]
00052 #define f3      smap[2]
00053 
00054 PRIVATE long cnt[3];                    /* Sizes of segments   */
00055 PRIVATE int h_size;                     /* Size of core header */
00056 PRIVATE char def_name[] = "core";       /* Default core name   */
00057 
00058 #define SIZE_MP_SEG (sizeof(struct mem_map) * NR_LOCAL_SEGS)
00059 #define SIZE_KINFO sizeof(struct proc)
00060 #define SIZE_HEADER SIZE_MP_SEG
00061 
00062 FORWARD _PROTOTYPE( int kernel_info , (int fd ));
00063 FORWARD _PROTOTYPE( void setmap , (struct file *fp ));
00064 FORWARD _PROTOTYPE( void read_info , (struct file *fp ));
00065 FORWARD _PROTOTYPE( void ill_addr , (long d , int segment ));
00066 FORWARD _PROTOTYPE( long map_addr , (long d , int segment ));
00067 FORWARD _PROTOTYPE( unsigned long c_status, (void));
00068 FORWARD _PROTOTYPE( long getn, (long d, int s) );
00069 
00070 /* 
00071  * set and display mapping for core file 
00072  */
00073 PRIVATE void setmap(fp)
00074 struct file *fp;
00075 {
00076 long h = (long) h_size;
00077 
00078   fp->b1 = st_addr;
00079   fp->e1 = st_addr + cnt[T];
00080   fp->f1 = h;
00081 
00082   fp->b2 = sd_addr; 
00083   fp->e2 = sd_addr + cnt[D];
00084   fp->f2 = cnt[T] + h;
00085 
00086   fp->b3 = sk_addr;
00087   fp->e3 = sk_addr + cnt[S];
00088   fp->f3 = cnt[T] + cnt[D] + h;
00089 
00090 #ifdef MINIX_PC
00091   if(is_separate) {
00092         if ( end_addr < et_addr ) end_addr = et_addr;
00093   }
00094   else {
00095         fp->b2 = st_addr;
00096         fp->e2 = st_addr + cnt[T] + cnt[D];
00097         fp->f2 = h;
00098         end_addr = fp->e2;
00099 
00100         fp->b1 = 0;
00101         fp->e1 = -1;
00102         fp->f1 = 0;
00103   }
00104 #endif
00105   Printf("From core file:\n");
00106   Printf("T\t%8lx %8lx %8lx\n", core_file->b1, core_file->e1, core_file->f1);
00107   Printf("D\t%8lx %8lx %8lx\n", core_file->b2, core_file->e2, core_file->f2);
00108   Printf("S\t%8lx %8lx %8lx\n", core_file->b3, core_file->e3, core_file->f3);
00109   Printf("\n");
00110 
00111 }
00112 
00113 /* Print mapping */
00114 PUBLIC void prtmap()
00115 {
00116   Printf("%s I & D space\t", (is_separate) ? "Separate " : "Combined ");
00117   if (corepid > 0) {
00118         Printf("File: %s\n\n", core_file->name);
00119         setmap(core_file);
00120         disp_maps();
00121   }
00122   else {
00123         Printf("Pid:  %d\n\n", curpid);
00124         update();
00125         disp_maps();
00126   }
00127 }
00128 
00129 /* Illegal address */
00130 PRIVATE void ill_addr(d, segment)
00131 long d;
00132 int segment;
00133 {
00134   Printf("Bad addr=%lx seg=%d",d,segment);
00135   mdb_error("\n");
00136 }
00137 
00138 /* Map virtual address -> core file addresses
00139  * depends on current segment if Separate I & D
00140  */
00141 PRIVATE long map_addr(d, segment)
00142 long d;
00143 int segment;
00144 {
00145 #ifdef MINIX_PC
00146   if (is_separate) 
00147         switch (segment) {
00148             case T:
00149                 if (d >= core_file->b1 && d < core_file->e1)
00150                         d += core_file->f1 - core_file->b1;
00151                 else
00152                         ill_addr(d,segment);
00153                 break;
00154             case D:
00155             case S:
00156                 if (d >= core_file->b2 && d < core_file->e2)
00157                         d += core_file->f2 - core_file->b2;
00158                 else if (d >= core_file->b3 && d < core_file->e3)
00159                         d += core_file->f3 - core_file->b3;
00160                 else
00161                         ill_addr(d,segment);
00162                 break;
00163         }
00164   else {
00165 #endif
00166         if (d >= core_file->b1 && d < core_file->e1)
00167                 d += core_file->f1 - core_file->b1;
00168         else if (d >= core_file->b2 && d < core_file->e2)
00169                 d += core_file->f2 - core_file->b2;
00170         else if (d >= core_file->b3 && d < core_file->e3)
00171                 d += core_file->f3 - core_file->b3;
00172         else
00173                 ill_addr(d,segment);
00174 #ifdef  MINIX_PC
00175   }
00176 #endif
00177   return d;
00178 }
00179 
00180 
00181 /* Get value with address d and segment s */
00182 PRIVATE long getn(d, s)
00183 long d;
00184 int s;
00185 {
00186   long b;
00187   register int o,i;
00188   union {
00189         unsigned long l;
00190         unsigned char c[4];
00191   } data;
00192 
00193   /* Map address */
00194   d = map_addr(d, s);
00195 
00196   b = d >> LOGBS;
00197   o = d & (BSIZE - 1);
00198 
00199   if (core_file->cblock != b) {
00200         core_file->cblock = b;
00201         lseek(core_file->fid, b << LOGBS, 0);
00202         read(core_file->fid, core_file->buf, sizeof(core_file->buf));
00203   }
00204 
00205   for(i = 0; i<4; i++) 
00206         data.c[i] = core_file->buf[o+i];
00207 
00208 #ifdef DEBUG
00209   if (debug) 
00210         Printf("getn at %8lx val %8lx\n", d, data.l);
00211 #endif
00212   return data.l;
00213 }
00214 
00215 /* Read kernel info from core file into lbuf[] */
00216 PRIVATE int kernel_info(fd)
00217 int fd;
00218 {
00219   int r;
00220   int ks;
00221 
00222   /* Round SIZE_KINFO to multiple of sizeof(long) */
00223   /* See mm/signal.c to see how a 'core' file is written */
00224   ks = ( SIZE_KINFO / sizeof(long) ) * sizeof(long);    
00225   r = read(fd, (char *)lbuf, ks);
00226   return(r == ks) ? ks : -1;
00227 }
00228 
00229 /* 
00230  * Print status info from core  - returns PC
00231  */
00232 PRIVATE unsigned long c_status()
00233 {
00234   fprintf(stderr, "WARNING: don't know pid from core; using proc nr for pid.\n");
00235 
00236   Printf("Proc = %6d\n", prc->p_nr);
00237 
00238   /* Set current pid to that of core */
00239   curpid = corepid = prc->p_nr;
00240   disp_maps();
00241   Printf("\nPC  = 0x%0*lx\t", 2 * ADDRSIZE, PC_MEMBER(prc) & MASK(ADDRSIZE));
00242   symbolic((long) PC_MEMBER(prc), '\n');
00243   dasm((long) PC_MEMBER(prc), 1, 1);
00244   return PC_MEMBER(prc);
00245 }
00246 
00247 /* Read memory maps and kernel info from core file */
00248 PRIVATE void read_info(fp)
00249 struct file *fp;
00250 {
00251   struct mproc mm_info;
00252   struct mproc *rmp;
00253   int r;
00254   int i;
00255 
00256   rmp = &mm_info;
00257   lseek(fp->fid, 0L, 0L);
00258 
00259   /* First read memory map of all segments. */
00260   if (read(fp->fid, (char *) rmp->mp_seg, (int) SIZE_MP_SEG) < 0) {
00261         close(fp->fid);
00262         Printf("mdb: cannot read core header\n");
00263         fp->fid = -1;
00264         return; 
00265   }
00266   h_size = SIZE_HEADER;
00267 
00268   /* Read kernel dependent info */
00269   r = kernel_info(fp->fid);
00270   if (r < 0) {
00271         close(fp->fid);
00272         Printf("mdb: cannot read kernel info from 'core' file\n");
00273         fp->fid = -1;
00274         return;
00275   } else
00276         h_size += r;
00277 
00278   /* copy info */       
00279   for (i = T; i <= S; i++)
00280         cnt[i] = (long) rmp->mp_seg[i].mem_len << CLICK_SHIFT;
00281 
00282   /* This needs to be set for map_addr() below */
00283   if(coreonly && cnt[T] != 0) is_separate = TRUE;
00284 
00285   st_addr = (long) rmp->mp_seg[T].mem_vir << CLICK_SHIFT;
00286   et_addr = st_addr + ((long) rmp->mp_seg[T].mem_len << CLICK_SHIFT);
00287 
00288   sd_addr = (long) rmp->mp_seg[D].mem_vir << CLICK_SHIFT;
00289   end_addr = ed_addr = 
00290         sd_addr + ((long) rmp->mp_seg[D].mem_len << CLICK_SHIFT);
00291 
00292   sk_addr = (long) rmp->mp_seg[S].mem_vir << CLICK_SHIFT;
00293   sk_size = (long) rmp->mp_seg[S].mem_len << CLICK_SHIFT;
00294 
00295   setmap(fp);
00296 }
00297 
00298 /* initialization for core files 
00299  * returns PC address from core file 
00300  */ 
00301 PUBLIC unsigned long core_init(filename)
00302 char *filename;
00303 {
00304   core_file = &Core_File;
00305   core_file->name = (filename != NULL) ? filename : def_name;
00306 
00307   core_file->fid = open(core_file->name, 0);
00308   if (filename != NULL && core_file->fid < 0) {
00309         Printf("mdb - warning cannot open: %s\n", core_file->name);
00310         return -1;
00311   }
00312 
00313   core_file->b1 = core_file->b2 = core_file->b3 = 0;
00314   core_file->e1 = core_file->e2 = core_file->e3 = -1;
00315   core_file->f1 = core_file->f2 = core_file->f3 = 0;
00316   core_file->cblock = -1;
00317 
00318   if (core_file->fid > 0) {
00319         read_info(core_file);
00320         return c_status();
00321   }
00322   return 0;
00323 }
00324 
00325 
00326 /* initialization for a file ( -f option )  
00327  * always returns 0
00328  * Similar to core files.
00329  */ 
00330 PUBLIC unsigned long file_init(filename)
00331 char *filename;
00332 {
00333   core_file = &Core_File;
00334   core_file->name = (filename != NULL) ? filename : def_name;
00335 
00336   core_file->fid = open(core_file->name, 0);
00337   if (filename != NULL && core_file->fid < 0) {
00338         Printf("mdb - warning cannot open: %s\n", core_file->name);
00339         return -1;
00340   }
00341 
00342   core_file->b1 = core_file->b2 = core_file->b3 = 0;
00343   core_file->e1 = core_file->e2 = core_file->e3 = -1;
00344   core_file->f1 = core_file->f2 = core_file->f3 = 0;
00345   core_file->cblock = -1;
00346 
00347   is_separate = FALSE;  
00348   core_file->e1 = file_size(core_file->fid);
00349   curpid = corepid = 1;
00350   return 0;
00351 
00352 }
00353 
00354 /* 
00355  * Read from core file 
00356  * Called by mdbtrace()
00357  */
00358 PUBLIC long read_core(req,  addr, data)
00359 int req;
00360 long addr, data;
00361 {
00362 int i;
00363 int segment;
00364 long val;
00365 
00366         switch (req) {
00367             case T_GETINS:
00368             case T_GETDATA:
00369                 /* Check segment and address - call getn to read core file */
00370                 segment = (req == T_GETINS) ? T : D;
00371                 addr &= MASK(ADDRSIZE);
00372                 val = getn(addr, segment);
00373 #ifdef  DEBUG
00374                 if (debug) Printf("val=>%lx\n", val);
00375 #endif
00376                 return val;
00377                 break;
00378             case T_GETUSER:
00379                 /* Convert addr to index to long array */
00380                 i = (int) (addr >> 2);
00381 #ifdef DEBUG
00382                 if (debug) Printf("lbuf[%d] %lx\n", i, lbuf[i]);
00383 #endif
00384                 return lbuf[i];
00385                 break;
00386             case T_OK:
00387             case T_EXIT:        
00388                 return 0L;
00389                 break;
00390             default:
00391                 mdb_error("Not supported with 'core' files\n");
00392         }
00393 }
00394 

Generated on Fri Apr 14 22:56:59 2006 for minix by  doxygen 1.4.6