1 /* This program should crash and produce coredump */ 2 3 #include "compiler.h" 4 5 #include <stdio.h> 6 #include <stdint.h> 7 #include <stdlib.h> 8 #include <unistd.h> 9 #ifdef __FreeBSD__ 10 #include <sys/types.h> 11 #include <sys/sysctl.h> 12 #include <sys/user.h> 13 #endif 14 15 #if defined(__linux__) 16 void write_maps(char *fname) 17 { 18 char buf[512], path[128]; 19 char exec; 20 uintmax_t addr; 21 FILE *maps = fopen("/proc/self/maps", "r"); 22 FILE *out = fopen(fname, "w"); 23 24 if (!maps || !out) 25 exit(EXIT_FAILURE); 26 27 while (fgets(buf, sizeof(buf), maps)) 28 { 29 if (sscanf(buf, "%jx-%*x %*c%*c%c%*c %*x %*s %*d /%126[^\n]", &addr, &exec, path+1) != 3) 30 continue; 31 32 if (exec != 'x') 33 continue; 34 35 path[0] = '/'; 36 fprintf(out, "0x%jx:%s ", addr, path); 37 } 38 fprintf(out, "\n"); 39 40 fclose(out); 41 fclose(maps); 42 } 43 #elif defined(__FreeBSD__) 44 void 45 write_maps(char *fname) 46 { 47 FILE *out; 48 char *buf, *bp, *eb; 49 struct kinfo_vmentry *kv; 50 int mib[4], error; 51 size_t len; 52 53 out = fopen(fname, "w"); 54 if (out == NULL) 55 exit(EXIT_FAILURE); 56 57 len = 0; 58 mib[0] = CTL_KERN; 59 mib[1] = KERN_PROC; 60 mib[2] = KERN_PROC_VMMAP; 61 mib[3] = getpid(); 62 error = sysctl(mib, 4, NULL, &len, NULL, 0); 63 if (error == -1) 64 exit(EXIT_FAILURE); 65 len = len * 4 / 3; 66 buf = malloc(len); 67 if (buf == NULL) 68 exit(EXIT_FAILURE); 69 error = sysctl(mib, 4, buf, &len, NULL, 0); 70 if (error == -1) 71 exit(EXIT_FAILURE); 72 73 for (bp = buf, eb = buf + len; bp < eb; bp += kv->kve_structsize) { 74 kv = (struct kinfo_vmentry *)(uintptr_t)bp; 75 if (kv->kve_type == KVME_TYPE_VNODE && 76 (kv->kve_protection & KVME_PROT_EXEC) != 0) { 77 fprintf(out, "0x%jx:%s ", kv->kve_start, kv->kve_path); 78 } 79 } 80 81 fprintf(out, "\n"); 82 fclose(out); 83 free(buf); 84 } 85 #else 86 #error Port me 87 #endif 88 89 #ifdef __GNUC__ 90 int c(int x) NOINLINE ALIAS(b); 91 #define compiler_barrier() asm volatile(""); 92 #else 93 int c(int x); 94 #define compiler_barrier() 95 #endif 96 97 int NOINLINE a(void) 98 { 99 *(volatile int *)32 = 1; 100 return 1; 101 } 102 103 int NOINLINE b(int x) 104 { 105 int r; 106 107 compiler_barrier(); 108 109 if (x) 110 r = a(); 111 else 112 r = c(1); 113 return r + 1; 114 } 115 116 int 117 main (int argc, char **argv) 118 { 119 if (argc > 1) 120 write_maps(argv[1]); 121 b(0); 122 return 0; 123 } 124 125