allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (01/30/89)
Posting-number: Volume 6, Issue 19 Submitted-by: wht@tridom.UUCP (Warren Tucker) Archive-name: xlist [People, not everyone's going to read even a "short and sweet" program to find out why they should save it. Include README's or at minimum document it somewhere other than the code. ++bsa] This program is short and sweet, so no README or Makefile is included. It has been tested with SCO XENIX/286 2.2.1 and XENIX/386 2.3.1. [Since the author didn't document it, I will: This program displays symbol information from /xenix (it's for Xenix V, and will most likely be useless for any other OS) and optionally displays the value of kernel memory at the symbol address. Usage is: xlist symbol[:count] ... !WARNING! There may be a program called "xlist" in some Xenixes, especially more recent ones. Let the installer beware.... ++bsa] #!/bin/sh # shar: Shell Archiver (v1.22) # # Run the following text with /bin/sh to create: # xlist.c # sed 's/^X//' << 'SHAR_EOF' > xlist.c && X/* CHK=0x935A */ X/* vi: set tabstop=4 shiftwidth=4: */ X/*+------------------------------------------------------------------------- X xlist.c - Xenix System V xlist utility X by Warren H. Tucker, III. ...!gatech!{emory,kd4nc}!tridom!wht X X This program reads and displays /xenix symbol table information using X xlist and optionally reads and displays /dev/kmem. See usage() below. X X Compile instructions: X 386: cc -Ox -K xlist.c -o xlist X 286: cc -M2l -O xlist.c -o xlist X--------------------------------------------------------------------------*/ X/*+:EDITS:*/ X/*:01-18-1989-12:26-wht-get ready for net submisssion */ X/*:01-17-1989-19:43-wht-add dump feature and usage */ X/*:01-18-1989-12:25-wht-creation */ X X#include <stdio.h> X#include <fcntl.h> X#include <sys/a.out.h> X X#define XENIX_KERNEL "/xenix" X X#define UINT8 unsigned char X#define UINT16 unsigned short X#define UINT32 unsigned long X Xint fd_kmem; X Xchar *usage_text[]= X{ X"usage: xlist arg [ arg ...]\n", X"where arg is of the form symbol[:count]\n", X"and symbol is a public symbol in /xenix as shown in a map file (i.e.,\n", X"with leading underscore as appropriate). count is a number of bytes\n", X"prefixed with a colon. xlist looks up the symbol by xlist'ing /xenix\n", X"and displays the xlist information on stdout. If ':count' is present,\n", X"xlist reads kmem starting at 'symbol' and displays 'count' bytes in hex.\n", X#if defined(M_I286) X"On the 286, count is limited to 32767.\n", X#endif X(char *)0 X}; X X/*+------------------------------------------------------------------------- X usage() X--------------------------------------------------------------------------*/ Xvoid Xusage() X{ Xregister char **text = usage_text; X X while(*text) X fprintf(stderr,*text++); X exit(1); X} /* end of usage */ X X#define dump_putc(ch) fputc((ch),stdout) X#define dump_puts(str) fputs(str,stdout) X X/*+----------------------------------------------------------------------- X hex_dump#... subservient routines X------------------------------------------------------------------------*/ Xvoid hex_dump4(int4) XUINT8 int4; X{ X int4 &= 15; X dump_putc((int4 >= 10) ? (int4 + 'A' - 10) : (int4 + '0')); X} X Xvoid hex_dump8(int8) XUINT8 int8; X{ X hex_dump4(int8 >> 4); X hex_dump4(int8); X} X Xvoid hex_dump16(int16) XUINT16 int16; X{ X hex_dump8(int16 >> 8); X hex_dump8(int16); X} X Xvoid hex_dump32(int32) XUINT32 int32; X{ X hex_dump16((UINT16)(int32 >> 16)); X hex_dump16((UINT16)int32); X} X X/*+----------------------------------------------------------------- X hex_dump(str,len) X------------------------------------------------------------------*/ Xvoid Xhex_dump(str,len,offset) XUINT8 *str; Xunsigned int len; Xlong offset; X{ Xregister unsigned int itmp; Xregister unsigned int istr = 0; X X while (istr < len) X { X hex_dump32(offset + istr); X for (itmp = 0; itmp < 16; ++itmp) X { X dump_putc(' '); X if( istr + itmp >= len) X { X dump_putc(' '); X dump_putc(' '); X continue; X } X hex_dump8(str[istr + itmp]); X } X dump_puts(" | "); X for (itmp = 0; itmp < 16; ++itmp) X { X register char dchar; X if(istr + itmp >= len) X dump_putc(' '); X else X { X dchar = str[istr + itmp] & 0x7F; X dump_putc(((dchar >= ' ') && (dchar < 0x7f)) ? dchar : '.' ); X } X } X dump_puts(" |\n"); X istr += 16; X } /* end of while(istr < len) */ X X} /* end of hex_dump */ X X/*+------------------------------------------------------------------------- X dump_kmem(seekpos,length) X--------------------------------------------------------------------------*/ Xvoid Xdump_kmem(seekpos,length) Xlong seekpos; Xunsigned int length; X{ Xchar *kmemdata; Xchar *malloc(); Xlong lseek(); X X if((kmemdata = malloc(length)) == NULL) X { X printf("cannot allocate %u bytes\n",length); X return; X } X X if(lseek(fd_kmem,seekpos,0) < 0) X { X fprintf(stderr,"cannot seek kmem (%d) to %08lx",fd_kmem,seekpos); X perror(""); X free(kmemdata); X return; X } X X if(read(fd_kmem,kmemdata,length) != length) X { X perror("kmem read"); X free(kmemdata); X return; X } X X hex_dump(kmemdata,length,seekpos); X free(kmemdata); X X} /* end of dump_kmem */ X X/*+------------------------------------------------------------------------- X open_kmem() X--------------------------------------------------------------------------*/ Xvoid Xopen_kmem() X{ X if((fd_kmem = open("/dev/kmem",O_RDONLY,0)) < 0) X { X perror("/dev/kmem"); X exit(1); X } X} /* end of open_kmem */ X X/*+------------------------------------------------------------------------- X main(argc,argv,envp) X--------------------------------------------------------------------------*/ Xmain(argc,argv,envp) Xint argc; Xchar **argv; Xchar **envp; X{ Xregister int iargv; Xstruct xlist *xlst; Xregister struct xlist *xx; Xint need_kmem = 0; Xunsigned long *count; Xchar *cptr; Xchar *strrchr(); Xchar *calloc(); Xlong atol(); X X if(argc < 2) X usage(); X X if((xlst = (struct xlist *)calloc(argc,sizeof(struct xlist))) == X (struct xlist *)0) X { X fprintf(stderr,"memory not available\n"); X exit(1); X } X X if((count = (long *)calloc(argc,sizeof(long))) == (long *)0) X { X fprintf(stderr,"memory not available\n"); X exit(1); X } X X xx = xlst; X for(iargv = 1; iargv < argc; iargv++) X { X if(cptr = strrchr(argv[iargv],':')) X { X *cptr++ = 0; X#if defined(M_I286) X if((count[iargv - 1] = atol(cptr)) > 32767L) X { X printf("max count is 32767 on 286: %s\n",argv[iargv]); X count[iargv - 1] = 32767; X } X#else X count[iargv - 1] = atol(cptr); X#endif X need_kmem = 1; X } X xx->xl_name = argv[iargv]; X xx++; X } X X xlist(XENIX_KERNEL, xlst); X X if(need_kmem) X open_kmem(); X X xx = xlst; X for(iargv = 1; iargv < argc; iargv++) X { X if(xx->xl_type == 0) X { X printf("%s: can't xlist (try _%s ?)\n", X xx->xl_name,xx->xl_name); X continue; X } X X printf("%s type: %04x seg: %04x value: %08lx\n", X xx->xl_name,xx->xl_type,xx->xl_seg,xx->xl_value); X X if(count[iargv - 1]) X dump_kmem(xx->xl_value,(unsigned int)count[iargv - 1]); X X xx++; X } X X exit(0); X} /* end of main */ SHAR_EOF chmod 0644 xlist.c || echo "restore of xlist.c fails" exit 0