341 lines
9.3 KiB
C
341 lines
9.3 KiB
C
static char sccsid[] = "@(#)81 1.7 src/bos/usr/bin/sysdumpdev/fmt.c, cmddump, bos411, 9428A410j 7/16/91 11:42:56";
|
|
/*
|
|
* COMPONENT_NAME: CMDDUMP system dump control and formatting
|
|
*
|
|
* FUNCTIONS: jdumpinit, jdump, jdumpterm, jdump_paged
|
|
*
|
|
* ORIGINS: 27
|
|
*
|
|
* IBM CONFIDENTIAL -- (IBM Confidential Restricted when
|
|
* combined with the aggregated modules for this product)
|
|
* SOURCE MATERIALS
|
|
* (C) COPYRIGHT International Business Machines Corp. 1988, 1989
|
|
* All Rights Reserved
|
|
*
|
|
* US Government Users Restricted Rights - Use, duplication or
|
|
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
|
*/
|
|
|
|
/*
|
|
* jdumpinit, jdump, jdumpterm
|
|
*
|
|
* Format the data from a dump file from calls from xtr.c
|
|
* These routines take raw buffers/length as input and make no
|
|
* assumption as to where the data comes from.
|
|
* Note that jdumpinit() does take a 'vaddr' parameter to set the starting
|
|
* offset. It is not used for anything except printing.
|
|
*
|
|
* These routines use a 'dmp_diplayopts' structure to describe the display
|
|
* options. This structure is filled in by opts.c but is only used by the
|
|
* jdump routines. These display attributes are programmable:
|
|
* fieldsize = number of bytes in a field (1 - 16) dflt=4
|
|
* nfields = number of fields in a line dflt=4
|
|
* align = alignment of the start of a line dflt=16
|
|
* wrapwidth = width of screen. dflt=0 (don't care)
|
|
* asciiflg = display ascii equivalent on right dflt=0
|
|
* compactflg = don't display duplicate line (like od) dflt=0
|
|
*
|
|
|
|
Example:
|
|
|
|
fieldsize = 4 (bytes)
|
|
Bincol = 3
|
|
WBincol = 3
|
|
Fieldc = 2
|
|
|
|
XXXXXXXX XXXXXXXX XXXXXXXX XXXX31XX XXXXXXXX XXXXXXXX .............1.........
|
|
|<---->| ^ ^ ^ ^ ^
|
|
^ | | | | |
|
|
| | | | | |
|
|
+----------------+ | | | | |
|
|
| | | | | |
|
|
fieldsize = 4 --+ | | | | |
|
|
WBincol = 3 ------------+ | | | |
|
|
Bincol = 3 | | | |
|
|
Fieldc = 2 ----------------+ | | |
|
|
Wrapcol = 6 ---------------------------------------+ | |
|
|
Charoff0 = 58 ------------------------------------------+ |
|
|
Charcol = 14 |<---------->|
|
|
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include "dmpfmt.h"
|
|
|
|
extern struct dmp_displayopts Opt; /* contains screen display options */
|
|
|
|
static Fieldc; /* in-field byte index */
|
|
static Vaddr0; /* address field at beginning of line */
|
|
static Bincol; /* field index */
|
|
static WBincol; /* screen-oriented field index */
|
|
static Charcol; /* ascii expansion character index */
|
|
static Charoff0; /* start in Line[] of ascii expansion */
|
|
static Wrapcol; /* max screen-oriented field index (WBincol) */
|
|
|
|
#define BC_SEP 2 /* separation between binary and ascii expansion */
|
|
#define ADDR_WIDTH 10 /* width of the address field */
|
|
#define LINEWIDTH 2048 /* max width of screen */
|
|
|
|
static char Line[LINEWIDTH+1]; /* line gets printed into this buffer */
|
|
static char Prevline[LINEWIDTH+1]; /* previous line gets copied to here */
|
|
int Prevlen; /* length of previous line */
|
|
int skipflg; /* previous line was compacted out */
|
|
|
|
static spaceflg; /* override with spaces (' ') */
|
|
|
|
static binprint();
|
|
static charprint();
|
|
static lineflush();
|
|
static lineflush_clr();
|
|
/*
|
|
* NAME: jdumpinit
|
|
* FUNCTION: Set up the formatting control variables and indent output
|
|
* for proper starting alignment for the data area
|
|
* INPUTS: vaddr Starting logical virtual address for this data area
|
|
* RETURNS: none
|
|
*/
|
|
jdumpinit(vaddr,inmemflg)
|
|
{
|
|
int n;
|
|
int i;
|
|
|
|
if(Opt.opt_align == 0 || Opt.opt_align > 16)
|
|
Opt.opt_align = 16;
|
|
if(Opt.opt_fieldsize == 0)
|
|
Opt.opt_fieldsize = 4;
|
|
if(Opt.opt_fieldsize > 16)
|
|
Opt.opt_fieldsize = 16;
|
|
if(Opt.opt_nfields == 0)
|
|
Opt.opt_nfields = 4;
|
|
if(Opt.opt_wrapwidth == 0) {
|
|
Wrapcol = Opt.opt_nfields;
|
|
} else {
|
|
n = ADDR_WIDTH;
|
|
if(Opt.opt_asciiflg)
|
|
n += (Opt.opt_nfields * Opt.opt_fieldsize) + BC_SEP;
|
|
Wrapcol = (Opt.opt_wrapwidth - n) / (2 * Opt.opt_fieldsize+1);
|
|
if(Wrapcol <= 0)
|
|
Wrapcol = 1;
|
|
if(Wrapcol > Opt.opt_nfields)
|
|
Wrapcol = Opt.opt_nfields;
|
|
}
|
|
lineflush_clr();
|
|
WBincol = 0;
|
|
Bincol = 0;
|
|
Charoff0 = (2 * Opt.opt_fieldsize + 1) * Wrapcol + BC_SEP;
|
|
Charcol = 0;
|
|
Fieldc = 0;
|
|
spaceflg = 0;
|
|
n = vaddr % Opt.opt_align;
|
|
Vaddr0 = vaddr - n;
|
|
Debug("Wrapcol=%d Charoff0=%d Vaddr0=%x vaddr=%x\n",
|
|
Wrapcol,Charoff0,Vaddr0,vaddr);
|
|
if(n > 0) {
|
|
if(inmemflg) {
|
|
spaceflg = 1;
|
|
jdump(0,n);
|
|
spaceflg = 0;
|
|
} else {
|
|
Vaddr0 += n;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* NAME: jdumpterm
|
|
* FUNCTION: flush the Line buffer as filled in by jdump()
|
|
* INPUTS: none
|
|
* RETURNS: none
|
|
*/
|
|
jdumpterm()
|
|
{
|
|
int i;
|
|
int n;
|
|
|
|
n = 0;
|
|
if(Fieldc > 0)
|
|
n += Opt.opt_fieldsize - Fieldc;
|
|
if(WBincol > 0)
|
|
n += Opt.opt_fieldsize * (Wrapcol - WBincol);
|
|
if(n > 0) {
|
|
spaceflg = 1;
|
|
jdump(0,n);
|
|
spaceflg = 0;
|
|
}
|
|
lineflush();
|
|
if(skipflg) {
|
|
printf("*\n");
|
|
printf("%08x:\n",Vaddr0);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* NAME: jdump
|
|
* FUNCTION: Handle the binary dump buffer output line-ny-line.
|
|
* INPUTS: buf pointer to character buffer
|
|
* count size of 'buf' in bytes
|
|
* RETURNS: none
|
|
*
|
|
* The jdump() routine does not know about data areas or the format of the
|
|
* dump file. That part is handled by disp_da(). jdump works with a character
|
|
* buffer and byte count passed as function parameters.
|
|
* Note: The lineflush() routine does maintain a variable 'Vaddr0' which
|
|
* is the virtual address of the start of the line it is printing. Its
|
|
* starting value is calculated by jdumpinit(). The only thing it is
|
|
* used for is to keep track of the virtual address of start of the line,
|
|
* as is incremented by the number of bytes output on the previous line.
|
|
* So in this sense it is not related to virtual addresses within the
|
|
* dump file.
|
|
*/
|
|
jdump(buf,count)
|
|
unsigned char *buf;
|
|
{
|
|
int i;
|
|
int x;
|
|
|
|
Debug("jdump(%x,%x)\n",buf,count);
|
|
for(i = 0; i < count; i++) {
|
|
x = buf ? buf[i] : 0;
|
|
binprint(x);
|
|
if(Opt.opt_asciiflg)
|
|
charprint(x);
|
|
if(Bincol >= Opt.opt_nfields) {
|
|
Bincol = 0;
|
|
lineflush();
|
|
} else if(WBincol >= Wrapcol) {
|
|
lineflush();
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* NAME: jdump_paged
|
|
* FUNCTION: Called when page in not in memory.
|
|
* INPUTS: count size of 'buf' in bytes. Used to update Vaddr0.
|
|
* RETURNS: none
|
|
*/
|
|
jdump_paged(count)
|
|
{
|
|
|
|
Debug("jdump_paged(%x) Vaddr=%x\n",count,Vaddr0);
|
|
printf("%08x: not in memory\n",Vaddr0);
|
|
lineflush_clr();
|
|
Vaddr0 += count;
|
|
}
|
|
|
|
/*
|
|
* hex to ascii conversion macros
|
|
*/
|
|
#define N(x) ( (x) & 0x0F )
|
|
#define ITOC(x) ( N(x) >= 0x0A ? N(x) - 0x0A + 'A' : N(x) + '0' )
|
|
#define ISPRINT(c) (' ' < (c) && (c) < 0x7F)
|
|
|
|
/*
|
|
* NAME: binprint
|
|
* FUNCTION: print the binary byte value 'x' into the
|
|
* internal ascii line buffer 'Line'
|
|
* INPUTS: x binary byte value to print
|
|
* RETURNS: none
|
|
*
|
|
* If the global flag 'spaceflg' is set, print spaces instead. This
|
|
* lets jdumpinit() position the starting indentation easily.
|
|
*/
|
|
static binprint(x)
|
|
{
|
|
char *cp;
|
|
|
|
cp = Line + WBincol * (2*Opt.opt_fieldsize+1) + Fieldc * 2;
|
|
if(spaceflg) {
|
|
cp[0] = ' ';
|
|
cp[1] = ' ';
|
|
} else {
|
|
cp[0] = ITOC(x / 16);
|
|
cp[1] = ITOC(x % 16);
|
|
}
|
|
if(++Fieldc >= Opt.opt_fieldsize) {
|
|
Bincol++;
|
|
WBincol++;
|
|
Fieldc = 0;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* NAME: charprint
|
|
* FUNCTION: print the ascii byte value 'x' into the
|
|
* internal ascii line buffer 'Line'
|
|
* INPUTS: x binary byte value to print
|
|
* RETURNS: none
|
|
*
|
|
* If the global flag 'spaceflg' is set, print spaces instead. This
|
|
* lets jdumpinit() position the starting indentation easily.
|
|
* If the value 'x' is not straight ascii, a '.' will be placed in
|
|
* the Line buffer instead.
|
|
*/
|
|
static charprint(x)
|
|
{
|
|
char *cp;
|
|
char c;
|
|
|
|
c = x;
|
|
cp = Line + Charoff0 + Charcol;
|
|
if(spaceflg)
|
|
cp[0] = ' ';
|
|
else
|
|
cp[0] = ISPRINT(c) ? c : '.';
|
|
Charcol++;
|
|
}
|
|
|
|
/*
|
|
* NAME: lineflush
|
|
* FUNCTION: flush the 'Line' buffer and update Vaddr0 address pointer.
|
|
* INPUTS: initflg When set, just clear col counters and Line[].
|
|
* RETURNS: none
|
|
*
|
|
* Output "compaction" is done in this routine.
|
|
* When Line[] is identical to the previous line Prevline[], output is
|
|
* suppressed. The variable 'skipflg' is used to print a '*' once, to
|
|
* denote that an area is compacted.
|
|
*/
|
|
static lineflush()
|
|
{
|
|
char *cp;
|
|
int currlen;
|
|
|
|
if(WBincol > 0) {
|
|
cp = Line + Charoff0 + Opt.opt_nfields + 11;
|
|
cp[1] = '\0';
|
|
while(*cp == ' ' && cp > Line)
|
|
*cp-- = '\0';
|
|
if(Opt.opt_compactflg) {
|
|
currlen = cp - Line + 1;
|
|
if(!(currlen == Prevlen && strncmp(Prevline,Line,currlen) == 0)) {
|
|
memcpy(Prevline,Line,currlen);
|
|
Prevlen = currlen;
|
|
if(skipflg)
|
|
printf("*\n");
|
|
printf("%08x: %s\n",Vaddr0,Line); /* ADDR_WIDTH */
|
|
skipflg = 0;
|
|
} else {
|
|
skipflg++;
|
|
}
|
|
} else {
|
|
skipflg = 0;
|
|
printf("%08x: %s\n",Vaddr0,Line); /* ADDR_WIDTH */
|
|
}
|
|
WBincol = 0;
|
|
Charcol = 0;
|
|
}
|
|
Vaddr0 += (Opt.opt_fieldsize * Wrapcol);
|
|
}
|
|
|
|
static lineflush_clr()
|
|
{
|
|
|
|
memset(Line,' ',LINEWIDTH);
|
|
WBincol = 0;
|
|
Charcol = 0;
|
|
Prevlen = 0;
|
|
skipflg = 0;
|
|
}
|
|
|