/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* bos720 src/bos/usr/bin/sysdumpdev/dumpfmt/unpack.c.S 1.1 */ /* */ /* Licensed Materials - Property of IBM */ /* */ /* Restricted Materials of IBM */ /* */ /* COPYRIGHT International Business Machines Corp. 1996 */ /* All Rights Reserved */ /* */ /* US Government Users Restricted Rights - Use, duplication or */ /* disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ /* */ /* IBM_PROLOG_END_TAG */ static char sccsid[] = "@(#)69 1.1 src/bos/usr/bin/sysdumpdev/dumpfmt/unpack.c.S, cmdcrash, bos720 1/11/96 14:48:08"; /* * COMPONENT_NAME: (CMDCRASH) dump table extraction routines * * FUNCTIONS: * get_cdt - get a component dump table's header and entry structures. * unpack - return data for a table entry. * * ORIGINS: 27 * * (C) COPYRIGHT International Business Machines Corp. 1996 * All Rights Reserved * Licensed Materials - Property of IBM * * US Government Users Restricted Rights - Use, duplication or * disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ #ifdef _KERNEL #undef _KERNEL #endif #include #include #include #include #include #include #define min(a,b) ((a)<(b)?(a):(b)) /* * Read the component dump table from where mem is positioned at. * This reads the data structures, but not the dumped data. * * Input: mem - memory object's file descriptor. * struct cdt * - Address of table to fill in. * (see /usr/include/sys/dump.h) * len - length of the structure area. * * Returns: * 0 - success, -1 failure and errno is set as follows: * EINVAL - The header did not contain DMP_MAGIC (apparently it's * not a dump table.) * ENOMEM - Not enough memory was specified. The file will be positioned * back at the original place. The function reads as much data * as it can. * error from read() - returned if read() fails. */ int get_cdt(int mem, struct cdt *c,int len) { ulong start; int rc = 0; /* Make sure there's enough memory to read the header. */ if (len < sizeof(struct cdt_head)) { errno = ENOMEM; return(-1); } /* read header */ start = lseek(mem,0,SEEK_CUR); /* Get current mem offset */ if(read(mem,c,sizeof(struct cdt_head)) != sizeof(struct cdt_head)) { return(-1); } /* Make sure the magic number is right */ if (c->cdt_magic != DMP_MAGIC) { errno = EINVAL; /* Not a dump table */ return(-1); } /* Read in the entries */ if (len < c->cdt_len) { /* Not enough buffer space */ rc = ENOMEM; } else { len = c->cdt_len; } /* Read the entries. */ len = len - sizeof(struct cdt_head); if(read(mem,c->cdt_entry,len) != len) { return(-1); } if (rc) { lseek(mem,start,SEEK_SET); /* Reposition mem */ errno = rc; rc = -1; } return(rc); } /* * unpack cdt's data from a dump into callers buffer, * filling in holes with 0BADD, and return bytes read * * Input: * mem - memory file descriptor. * index - index of entry to retrieve, the first one is index 0. * c - pointer to component dump table structure. * ubuf - output buffer. * * Returns: * number of bytes read. * -1 on error and errno is set. * errno = EINVAL if the index is out of range. * errno = read() result on a read error. * mem is not repositioned on an error. */ ulong unpack(int mem, int index, struct cdt *c, char *ubuf) { ulong bitmap_off; /* will go back here when finished. */ bitmap_t bitmap[8192]; /* allows up to 64M per data area */ ulong npages; /* # pages represented in bitmap */ int i,j,k; char *buf; /* Working buffer pointer */ ulong addr,count,actual_cnt; /* check the index. */ if (index >= NUM_ENTRIES(c)) { errno = EINVAL; return(-1); } buf = ubuf; /* position offset at start of data areas (at the bitmap) */ bitmap_off = lseek(mem,0,SEEK_CUR); /* for each data area in this cdt */ for(j=0; j<=index; j++) { /* Get # pages involved */ npages = (ulong) NPAGES(c->cdt_entry[j].d_ptr,c->cdt_entry[j].d_len); /* read bitmap for this data area. */ i = BITMAPSIZE(c->cdt_entry[j].d_ptr,c->cdt_entry[j].d_len); if (read(mem,bitmap,i) != i) return(-1); addr = (ulong)c->cdt_entry[j].d_ptr; count = (ulong)c->cdt_entry[j].d_len; /* for each page */ for(i = 0; i < npages; i++) { /* Actual # bytes to read on this page. */ actual_cnt = min(count,PAGESIZE-(addr%PAGESIZE)); /* if the page is in the dump. */ if(ISBITMAP(bitmap,i)) { /* If this is the data we want. */ if(j==index) { /* Get the data. */ if (read(mem,buf,actual_cnt) != actual_cnt) return(-1); buf = (char *)((ulong)buf + actual_cnt); } else { /* Not the entry we want. just seek past this data. */ lseek(mem,actual_cnt,SEEK_CUR); } } else { /* page is NOT in dump. */ if (j==index) { /* we want this data, fill in zeros. */ for (k=actual_cnt; k==0; k--) *(buf++) = '\0'; #ifndef DONT_PRINT printf("page at address 0x%x is not in the dump.\n",addr); #endif } } count -= actual_cnt; addr += actual_cnt; } } /* Finished, seek back to the start of the 1st bitmap. */ lseek(mem,bitmap_off,SEEK_SET); return(c->cdt_entry[j].d_len); }