Help with nlist(3c)
Colburn
mhc at aicchi.UUCP
Tue Feb 23 01:29:28 AEST 1988
Since there are probably more than one other person who is interested in
this, I thought that I would post it to the net.
> I found /usr/include/sys/sysinfo.h to be interesting. There is a structure
> sysinfo that I want to get some stuff out of. In this file is:
> extern struct sysinfo sysinfo;
> This is all fine and good, but sysinfo is in /unix. This is not the sort of
> thing you find laying around in a library. How does one ld this sort of
> thing?
> nm -x /unix | grep sysinfo
> gives me:
> sysinfo |0x00026ea0|extern| | | |.bss
>
> I am trying to accomplish this on an AT&T UNIXpc. My guess is that there is
> a trick with the /lib/shlib.ifile that can be made to work, since that must
> be how shared libraries are being done anyway. Please correct me if I'm wrong.
>
> I want to goof around in the kernal for fun, and this is where I'm stuck
> right now. BTW how does one know the format of /dev/kmem?
One does not know the format of /dev/kmem. Only the kernel knows.
/dev/kmem is the actual kernel memory image of the currently executing
kernel. You can find the address of things in /dev/kmem by using the
nlist(3c) function.
The nlist(3c) function will return the address of a named symbol in
/dev/kmem. In the case of functions and predefined data objects,
the address returned by nlist(3c) will be same as that printed out
by nm(1) (usually anyways :-).
By the way, I would not advise writing to /dev/kmem unless you REALLY know
what you are doing :-)
As an aside, when using the nlist(3) function as described in the
3B1 Manual, you must be careful to '#undef n_name' if you include
a.out.h. It appears that AT&T and/or Convergent screwed up when writing
the header files for the UNIX PC. In the attached program, the #undef in
the program is required.
Below is a program which will pull the information located in the
sysinfo, syswait and syserr structures (all defined in the
/usr/include/sys/sysinfo.h header file) and display it on the screen.
One last comment. The attached program must be run as root, or as some
other id which has read permission to /dev/kmem. The program itself is
pretty simple.
I hope that this will help! Please let me know how you make out.
------------------------------- cut here --------------------------------
/*
* mnl.c - print out the sysinfo, syswait and syserr structures in /dev/kmem
*
* Comments:
* This program must be run as root or as some other user which has
* read access to /dev/kmem. This program was written as an example.
* It will probably not pass lint, and I don't really care.
*
* BTW: the undef of n_name is required to bypass a bug which
* Convergent dropped into the a.out.h header file.
*
* Author: Mark H. Colburn (mark at jhereg.mn.org)
*/
#include <stdio.h>
#include <a.out.h>
#undef n_name
#include <fcntl.h>
#include <sys/sysinfo.h>
struct nlist mynl[] = {
"sysinfo", 0, 0, 0, 0, 0,
"syswait", 0, 0, 0, 0, 0,
"syserr", 0, 0, 0, 0, 0,
"", 0, 0, 0, 0, 0
};
struct syserr myerr;
struct syswait mywait;
struct sysinfo mysys;
int
main()
{
int fd;
if (nlist("/unix", mynl) == -1) {
fprintf(stderr, "Unable perform nlist() call\n");
perror("");
exit(1);
}
if ((fd = open("/dev/kmem", O_RDONLY)) == -1) {
fprintf(stderr, "Unable open /dev/kmem\n");
perror("");
exit(1);
}
printf("n_value = %d\n", mynl[0].n_value);
if (mynl[0].n_value != 0) {
if (lseek(fd, mynl[0].n_value, 0) != -1 &&
read(fd, (char *)&mysys, sizeof(mysys)) != -1) {
printsys();
}
if (lseek(fd, mynl[1].n_value, 0) != -1 &&
read(fd, (char *)&mywait, sizeof(mywait)) != -1) {
printwait();
}
if (lseek(fd, mynl[2].n_value, 0) != -1 &&
read(fd, (char *)&myerr, sizeof(myerr)) != -1) {
printerr();
}
} else {
printf("n_value = 0, lookup failed!\n");
}
exit(0);
}
printsys()
{
printf("\nsysinfo:\n");
printf("cpu[IDLE] = %d\t", mysys.cpu[CPU_IDLE]);
printf("cpu[USER] = %d\n", mysys.cpu[CPU_USER]);
printf("cpu[KERNAL] = %d\t", mysys.cpu[CPU_KERNAL]);
printf("cpu[WAIT] = %d\n", mysys.cpu[CPU_WAIT]);
printf("wait[IO] = %d\t", mysys.wait[W_IO]);
printf("wait[SWAP] = %d\t", mysys.wait[W_SWAP]);
printf("wait[PIO] = %d\n", mysys.wait[W_PIO]);
printf("bread = %d\t", mysys.bread);
printf("bwrite = %d\n", mysys.bwrite);
printf("lread = %d\t", mysys.lread);
printf("lwrite = %d\n", mysys.lwrite);
printf("phread = %d\t", mysys.phread);
printf("phwrite = %d\n", mysys.phwrite);
printf("swapin = %d\t", mysys.swapin);
printf("swapout = %d\n", mysys.swapout);
printf("bswapin = %d\t", mysys.bswapin);
printf("bswapout = %d\n", mysys.bswapout);
printf("pswitch = %d\t", mysys.pswitch);
printf("syscall = %d\n", mysys.syscall);
printf("sysread = %d\t", mysys.sysread);
printf("syswrite = %d\n", mysys.syswrite);
printf("sysfork = %d\t", mysys.sysfork);
printf("sysexec = %d\n", mysys.sysexec);
printf("runque = %d\t", mysys.runque);
printf("runocc = %d\n", mysys.runocc);
printf("swpque = %d\t", mysys.swpque);
printf("swpocc = %d\n", mysys.swpocc);
printf("iget = %d\t", mysys.iget);
printf("namei = %d\t", mysys.namei);
printf("dirblk = %d\n", mysys.dirblk);
printf("readch = %d\t", mysys.readch);
printf("writech = %d\n", mysys.writech);
printf("rcvint = %d\t", mysys.rcvint);
printf("xmtint = %d\t", mysys.xmtint);
printf("mdmint = %d\n", mysys.mdmint);
printf("rawch = %d\t", mysys.rawch);
printf("canch = %d\t", mysys.canch);
printf("outch = %d\n", mysys.outch);
printf("msg = %d\t", mysys.msg);
printf("sema = %d\n", mysys.sema);
printf("pgin = %d\t", mysys.pgin);
printf("pgout = %d\n", mysys.pgout);
}
printwait()
{
printf("\nsyswait:\n");
printf("iowait = %d\t", mywait.iowait);
printf("swap = %d\t", mywait.swap);
printf("physio = %d\n", mywait.physio);
}
printerr()
{
printf("\nsyserr:\n");
printf("inodeovf = %d\t", myerr.inodeovf);
printf("fileovf = %d\t", myerr.fileovf);
printf("textovf = %d\t", myerr.textovf);
printf("procovf = %d\n", myerr.procovf);
}
--
Mark H. Colburn mark at jhereg.MN.ORG
ihnp4!chinet!jhereg!mark
More information about the Unix-pc.general
mailing list