/* Orion Lawlor's Short UNIX Examples, olawlor@acm.org 2003/8/18

Walk through the system's RAM, printing out
a memory map of mmap-able and unmappable regions.
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/mman.h>

char check_address(void *addr,int len) {
	void *ret;
	int merr;
	errno=0;
	ret=mmap(addr,len,PROT_READ|PROT_WRITE,
		MAP_PRIVATE|MAP_ANONYMOUS, -1,0);
	merr=errno;
	munmap(ret,len);
	if (addr==ret) return ' ';
	switch (merr) {
	case EINVAL: return 'i';
	case EACCES: return 'a';
	case ENOMEM: return 'm';
	case 0: return '.';
	default: return '?';
	};
}

unsigned int slotSize=1024*1024; /* Granularity of memory map */
/* Return the pointer at this slot */
void *addrFmSlot(unsigned int slotNo) {
	return (void *)(slotNo*slotSize);
}
/* Return the number of megs at this address: */
int mbFmAddr(void *ptr) {
	return ((unsigned int)(long)ptr)/(1024u*1024u);
}

/*Print some information about this address: */
void printAddr(void *ptr,const char *desc) {
	printf("%s: %d MB, %p\n",desc,mbFmAddr(ptr),ptr);
}

int main() {
	int r,c;
	int nc=64;
	void *test;
	printAddr(0,"NULL");
	test=malloc(2);printAddr(test,"Tiny heap allocations");free(test);
	test=malloc(8*1024*1024);printAddr(test,"Big heap allocations"); free(test);
	printAddr(&slotSize,"Globals");
	printAddr((void *)main,"Subroutines");
	printAddr((void *)fprintf,"Dynamic symbols");
	printAddr(&r,"Stack");
	for (r=0;r<64;r++) {
		printf("%4d MB: |",mbFmAddr(addrFmSlot(r*nc+0)));
		for (c=0;c<nc;c++)
			printf("%c",check_address(addrFmSlot(r*nc+c),slotSize));
		printf("|\n");
	}
}

/*<@>
<@> ******** Program output: ********
<@> NULL: 0 MB, (nil)
<@> Tiny heap allocations: 6 MB, 0x602010
<@> Big heap allocations: 2223 MB, 0x2ae58af92010
<@> Globals: 6 MB, 0x6012b8
<@> Subroutines: 4 MB, 0x4009b0
<@> Dynamic symbols: 2220 MB, 0x2ae58ac821f0
<@> Stack: 524 MB, 0x7fff20c4a6ac
<@>    0 MB: |.   . .                                                         |
<@>   64 MB: |                                                                |
<@>  128 MB: |                                                                |
<@>  192 MB: |                                                                |
<@>  256 MB: |                                                                |
<@>  320 MB: |                                                                |
<@>  384 MB: |                                                                |
<@>  448 MB: |                                                                |
<@>  512 MB: |                                                                |
<@>  576 MB: |                                                                |
<@>  640 MB: |                                                                |
<@>  704 MB: |                                                                |
<@>  768 MB: |                                                                |
<@>  832 MB: |                                                                |
<@>  896 MB: |                                                                |
<@>  960 MB: |                                                                |
<@> 1024 MB: |                                                                |
<@> 1088 MB: |                                                                |
<@> 1152 MB: |                                                                |
<@> 1216 MB: |                                                                |
<@> 1280 MB: |                                                                |
<@> 1344 MB: |                                                                |
<@> 1408 MB: |                                                                |
<@> 1472 MB: |                                                                |
<@> 1536 MB: |                                                                |
<@> 1600 MB: |                                                                |
<@> 1664 MB: |                                                                |
<@> 1728 MB: |                                                                |
<@> 1792 MB: |                                                                |
<@> 1856 MB: |                                                                |
<@> 1920 MB: |                                                                |
<@> 1984 MB: |                                                                |
<@> 2048 MB: |                                                                |
<@> 2112 MB: |                                                                |
<@> 2176 MB: |                                                                |
<@> 2240 MB: |                                                                |
<@> 2304 MB: |                                                                |
<@> 2368 MB: |                                                                |
<@> 2432 MB: |                                                                |
<@> 2496 MB: |                                                                |
<@> 2560 MB: |                                                                |
<@> 2624 MB: |                                                                |
<@> 2688 MB: |                                                                |
<@> 2752 MB: |                                                                |
<@> 2816 MB: |                                                                |
<@> 2880 MB: |                                                                |
<@> 2944 MB: |                                                                |
<@> 3008 MB: |                                                                |
<@> 3072 MB: |                                                                |
<@> 3136 MB: |                                                                |
<@> 3200 MB: |                                                                |
<@> 3264 MB: |                                                                |
<@> 3328 MB: |                                                                |
<@> 3392 MB: |                                                                |
<@> 3456 MB: |                                                                |
<@> 3520 MB: |                                                                |
<@> 3584 MB: |                                                                |
<@> 3648 MB: |                                                                |
<@> 3712 MB: |                                                                |
<@> 3776 MB: |                                                                |
<@> 3840 MB: |                                                                |
<@> 3904 MB: |                                                                |
<@> 3968 MB: |                                                                |
<@> 4032 MB: |                                                                |
<@> */
