#include #include #include #include #include #include // Function definitions. void stack(); void heap(); void address(); void sigHandler(int); /* * Learned about these from: * https://linux.die.net/man/3/etext */ extern char etext, edata, end; // Data variables. int UNINITIALIZED1; int INITIALIZED1 = 0; int INITIALIZED2 = 0; int INITIALIZED3 = 0; int UNINITIALIZED2; int UNINITIALIZED3; int UNINITIALIZED4; int INITIALIZED4 = 0; /** * Main function for driving program. */ int main() { // Binding signal handler. signal(SIGINT, sigHandler); /* * Getting addresses relating to static program segments * (See man page referenced above for sample code) */ printf("===\n"); printf("First address past:\n"); printf("Program text (etext) %10p\n", &etext); printf("Initialized data (edata) %10p\n", &edata); printf("Uninitialized data (end) %10p\n", &end); printf("===\n"); // Getting some initialized data addresses. printf("INITIALIZED\n"); printf("1: %p\n", &INITIALIZED1); printf("2: %p\n", &INITIALIZED2); printf("3: %p\n", &INITIALIZED3); printf("4: %p\n", &INITIALIZED4); printf("===\n"); // Getting some unitialized data addresses. printf("UNINITIALIZED\n"); printf("1: %p\n", &UNINITIALIZED1); printf("2: %p\n", &UNINITIALIZED2); printf("3: %p\n", &UNINITIALIZED3); printf("4: %p\n", &UNINITIALIZED4); printf("===\n"); // Adding some variables on the stack (will be stored in reverse). int stackvar1 = 12313; int stackvar2 = 12313; int stackvar3 = 12313; // Main stack addresses. printf("Main Stack\n"); printf("%p\n", &stackvar1); printf("%p\n", &stackvar2); printf("%p\n", &stackvar3); printf("===\n"); // Function stack addresses (should be lower than main). printf("Function Call Stack\n"); stack(); printf("===\n"); // Printing heap addresses. heap(); // Getting the address of the pow function. printf("Address of pow: %p\n", &pow); // Getting the address of the pthread_create function. address(); // Pausing so we can examine headers / maps info. pause(); // Probably never will reach here, but bye if we do. return 0; } /** * Puts some variables in the function's * stack frame and prints out their addresses. * Should be lower than main function's addresses, * although variables seem to increase in address * as we print them out (vars stored in reverse * order on the stack) */ void stack() { int stackvar1 = 12313; int stackvar2 = 12313; int stackvar3 = 12313; printf("%p\n", &stackvar1); printf("%p\n", &stackvar2); printf("%p\n", &stackvar3); } /** * Asks for some heap space and prints out the * locations of the memory we receive. */ void heap() { printf("Heap\n"); char *heap1 = malloc(16 * sizeof(char)); char *heap2 = malloc(32 * sizeof(char)); char *heap3 = malloc(64 * sizeof(char)); char *heap4 = malloc(128 * sizeof(char)); char *heap5 = malloc(256 * sizeof(char)); char *heap6 = malloc(512 * sizeof(char)); char *heap7 = malloc(1024 * sizeof(char)); char *heap8 = malloc(2048 * sizeof(char)); printf("1: %p\n", heap1); printf("2: %p\n", heap2); printf("3: %p\n", heap3); printf("4: %p\n", heap4); printf("5: %p\n", heap5); printf("6: %p\n", heap6); printf("7: %p\n", heap7); printf("8: %p\n", heap8); printf("===\n"); free(heap1); free(heap2); free(heap3); free(heap4); free(heap5); free(heap6); free(heap7); free(heap8); } /** * Prints a function address from a dynamic library. */ void address() { printf("Address of pthread_create: %p\n", &pthread_create); } /** * Handler for signals. Bound for the one signal handled * in this application: SIGINT (program interrupt signal ^C). * * @param sigNum, the identifying number of the signal * sent and now being handled. According to the * man page for signal, SIGINT = 2. */ void sigHandler(int sigNum) { // Just exit if we ^C. if (sigNum == SIGINT) { // Exiting program. exit(0); } }