Please consider a donation to the Higher Intellect project. See https://preterhuman.net/donate.php or the Donate to Higher Intellect page for more info.

Showmem.shar

From Higher Intellect Vintage Wiki
Jump to navigation Jump to search
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	Makefile
#	showmem.c
# This archive created: Sun Jul 30 12:11:04 2000
export PATH; PATH=/bin:$PATH
if test -f 'Makefile'
then
	echo shar: will not over-write existing file "'Makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'Makefile'
X
XABI=-32
X
X
XCFLAGS= -g $(ABI)
X
Xall: showmem
X
Xshowmem: showmem.c
X	$(CC) $(CFLAGS) showmem.c -o showmem
X
Xclobber clean:
X	-rm -f showmem
X	-rm -f showmem.shar
X
Xshar:
X	shar -p X Makefile showmem.c >showmem.shar
SHAR_EOF
fi # end of overwriting check
if test -f 'showmem.c'
then
	echo shar: will not over-write existing file "'showmem.c'"
else
sed 's/^X//' << \SHAR_EOF > 'showmem.c'
X/* showmem.c -- Sample program which prints a list of its own memory regions.
X * $Id: showmem.c,v 1.7 2000/07/30 19:05:41 davea Exp $
X *
X * Copyright 2000 Silicon Graphics, Inc. -- All Rights Reserved.
X * Use, copying, and redistribution are granted subject to the terms
X * listed at <URL:http://reality.sgi.com/Disclaimer.html>.
X *
X * Edits:
X * 000726 [email protected]	Created in response to a question on an
X *			internal SGI newsgroup.
X * 000729 [email protected]	Fix parameter to PIOCMAP call ("&p" -> "p").
X * 000729 [email protected]	Add "dlopen()" of all command-line args.
X *			Use "calloc()" for PIOCMAP table. [Paranoia!]
X *			Add generous excess for PIOCMAP table. [Paranoia!]
X *			Stop dumping at first entry for which pr_size == 0.
X *
X * Related software:
X *   dsolist.c <URL:http://reality.sgi.com/davea_engr/dsolist.shar>
X *
X * Usage:  showmem [-h] dso-to-open ...
X */
X
X#include <sys/types.h>
X#include <sys/signal.h>
X#include <sys/fault.h>
X#include <sys/syscall.h>
X#include <sys/procfs.h>
X#include <sys/stat.h>
X#include <stdio.h>
X#include <errno.h>
X#include <fcntl.h>
X#include <dlfcn.h>
X
Xstruct ma_msg_s {
X    long flag;
X    char *name;
X} ma_msgs[] = {
X	{MA_READ,      "READ"},
X	{MA_WRITE,     "WRITE"},
X	{MA_EXEC,      "EXEC"},
X	{MA_SHARED,    "SHARED"},
X	{MA_BREAK,     "BREAK"},
X	{MA_STACK,     "STACK"},
X	{MA_PHYS,      "PHYS"},
X	{MA_MAPZERO,   "MAPZERO"},
X	{MA_FETCHOP,   "FETCHOP"},
X	{MA_PRIMARY,   "PRIMARY"},
X	{MA_SREGION,   "SREGION"},
X	{MA_COW,       "COW"},
X	{MA_NOTCACHED, "NOTCACHED"},
X	{MA_SHMEM,     "SHMEM"}
X};
X
Xint main(int argc, char *argv[]) 
X{
X    int i, j, fd, err, nmaps, nmaps_allocd, not_first_flag_bit;
X    char procfile[100];
X    int more_flags = 1;
X    prmap_t *p;
X    int suppress_header = 0;
X
X    /* Construct the name of our own "/proc/${PID}" file, then open it. */
X    sprintf(procfile, "/proc/%d", getpid());
X    fd = open(procfile, O_RDONLY);
X    if (fd < 0) {
X        fprintf(stderr, "open of %s failed! -- (%d) ", procfile, errno);
X	perror(NULL);
X	exit(1);
X    }
X
X    /*
X     * Consider any remaining command-line arguments to be filenames
X     * of DSOs to "dlopen()" before displaying the memory map.
X     */
X    for (i = 1; i < argc; ++i) {
X	void *dummy = 0;
X	char *op= argv[i];
X	if(more_flags && op[0] == '-') {
X	    if(op[1] == '-' ) {
X		more_flags = 0;
X		continue;
X	    }
X	    if(op[1] == 'h' ) {
X	        /* -h means suppress header line from output */
X		suppress_header = 1;
X		continue;
X	    }
X	    else {
X		fprintf(stderr,"Ignored unknown option \"%s\" \n",op);
X	    }
X	    continue;
X	}
X	dummy = dlopen(op, RTLD_NOW);
X        if (dummy == NULL) {
X	    const char *msg = dlerror();
X            fprintf(stderr, "dlopen(\"%s\") failed!\n%s\n",
X				   argv[i],          msg);
X	    exit(1);
X        }
X    }
X
X    /* Find out (approximately) how many map entries we have. */
X    err = ioctl(fd, PIOCNMAP, &nmaps);
X    if (err < 0) {
X        fprintf(stderr, "PIOCNMAP failed! -- (%d) ", errno);
X	perror(NULL);
X	exit(1);
X    
X    }
X
X    /* create space to hold that many entries, plus a generous buffer,
X     * since PIOCNMAP can lie.
X     */
X    nmaps_allocd = 2 * nmaps + 10;
X    p = (prmap_t *) calloc(nmaps_allocd, sizeof(prmap_t));
X    if (p == NULL) {
X	fprintf(stderr,"Unable to malloc prmap_t entries!\n");
X	exit(1);
X    }
X    err = ioctl(fd, PIOCMAP, p);
X    if (err < 0) {
X        fprintf(stderr, "PIOCMAP failed! -- (%d) ", errno);
X	perror(NULL);
X	exit(1);
X    }
X
X    /* Basic cross-check between PIOCNMAP & PIOCMAP. Complicated by the
X     * fact that PIOCNMAP *always* seems to report one less than PIOCMAP,
X     * so we quietly ignore that little detail...
X
X       The PIOCMAP entry on the proc man page says that
X       one more is needed, so a minimum  one more than
X       is returned by PIOCNMAP is required.
X
X     */
X    for (i = 0; p[i].pr_size != 0 && i < nmaps_allocd; ++i)
X	; /*empty*/
X    if (i != nmaps + 1)
X	if(!suppress_header) {
X	    printf("warning: inconsistent number of segments:"
X	       "PIOCNMAP -> %d, but PIOCNMAP -> %d\n\n",
X			    nmaps,               i);
X	}
X    else
X	if(!suppress_header) {
X            printf("Total memory segments: %d\n", nmaps + 1);
X	}
X
X    if(!suppress_header) {
X      printf("       vaddr       size     offset      flags\n");
X    }
X    for (i = 0; p[i].pr_size != 0 && i < nmaps_allocd; ++i) {
X	long flags = p[i].pr_mflags & ((1 << MA_REFCNT_SHIFT) - 1);
X	/* ensure portability across -n32, -64 */
X	unsigned long long vaddr = (unsigned long long) p[i].pr_vaddr;
X	unsigned long long offset = (unsigned long long) p[i].pr_off;
X
X	printf("%2d: 0x%08llx 0x%08lx 0x%08llx 0x%08x=<",
X		 i, vaddr, p[i].pr_size, offset, flags);
X        for (j = 0, not_first_flag_bit = 0;
X	     j < (sizeof ma_msgs / sizeof (struct ma_msg_s));
X	     ++j) {
X	    if (flags & ma_msgs[j].flag) {
X		if (not_first_flag_bit++)
X		    printf(",");
X		printf("%s", ma_msgs[j].name);
X	    }
X	}
X        printf(">\n");
X    }
X
X    exit(0);
X}
SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0