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
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