10f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata/* This program should crash and produce coredump */
20f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata
3e3e49dc28aee0dc78f0243d932a5c950aaec7e3eTommi Rantala#include "compiler.h"
4e3e49dc28aee0dc78f0243d932a5c950aaec7e3eTommi Rantala
50f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata#include <stdio.h>
60f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata#include <stdint.h>
70f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata#include <stdlib.h>
80f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov#include <unistd.h>
90f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov#ifdef __FreeBSD__
100f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov#include <sys/types.h>
110f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov#include <sys/sysctl.h>
120f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov#include <sys/user.h>
130f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov#endif
140f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata
150f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov#if defined(__linux__)
160f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milatavoid write_maps(char *fname)
170f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata{
180f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata    char buf[512], path[128];
190f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata    char exec;
200f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata    uintmax_t addr;
210f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata    FILE *maps = fopen("/proc/self/maps", "r");
220f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata    FILE *out = fopen(fname, "w");
230f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata
240f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata    if (!maps || !out)
250f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata        exit(EXIT_FAILURE);
260f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata
270f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata    while (fgets(buf, sizeof(buf), maps))
280f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata    {
29ff0c6ccf6b526cbf3a17230541ba0793ac391d0bTommi Rantala        if (sscanf(buf, "%jx-%*x %*c%*c%c%*c %*x %*s %*d /%126[^\n]", &addr, &exec, path+1) != 3)
300f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata            continue;
310f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata
320f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata        if (exec != 'x')
330f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata            continue;
340f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata
350f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata        path[0] = '/';
360f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata        fprintf(out, "0x%jx:%s ", addr, path);
370f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata    }
380f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata    fprintf(out, "\n");
390f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata
400f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata    fclose(out);
410f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata    fclose(maps);
420f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata}
430f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov#elif defined(__FreeBSD__)
440f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousovvoid
450f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousovwrite_maps(char *fname)
460f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov{
470f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov    FILE *out;
480f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov    char *buf, *bp, *eb;
490f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov    struct kinfo_vmentry *kv;
500f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov    int mib[4], error;
510f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov    size_t len;
520f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov
530f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov    out = fopen(fname, "w");
540f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov    if (out == NULL)
550f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov        exit(EXIT_FAILURE);
560f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov
570f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov    len = 0;
580f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov    mib[0] = CTL_KERN;
590f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov    mib[1] = KERN_PROC;
600f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov    mib[2] = KERN_PROC_VMMAP;
610f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov    mib[3] = getpid();
620f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov    error = sysctl(mib, 4, NULL, &len, NULL, 0);
630f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov    if (error == -1)
640f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov	exit(EXIT_FAILURE);
650f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov    len = len * 4 / 3;
660f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov    buf = malloc(len);
670f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov    if (buf == NULL)
680f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov	exit(EXIT_FAILURE);
690f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov    error = sysctl(mib, 4, buf, &len, NULL, 0);
700f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov    if (error == -1)
710f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov	    exit(EXIT_FAILURE);
720f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov
730f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov    for (bp = buf, eb = buf + len; bp < eb; bp += kv->kve_structsize) {
740f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov        kv = (struct kinfo_vmentry *)(uintptr_t)bp;
750f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov	if (kv->kve_type == KVME_TYPE_VNODE &&
760f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov	  (kv->kve_protection & KVME_PROT_EXEC) != 0) {
770f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov	    fprintf(out, "0x%jx:%s ", kv->kve_start, kv->kve_path);
780f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov	}
790f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov    }
800f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov
810f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov    fprintf(out, "\n");
820f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov    fclose(out);
830f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov    free(buf);
840f6c8313b78b9bc292a36388b23436d0e71a8fd9Konstantin Belousov}
850f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata#else
860f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata#error Port me
870f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata#endif
880f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata
8904c77cced4975d2d4f8e1fd76b49e5884d9cbae4Konstantin Belousov#ifdef __GNUC__
905e7e890a0b75fc9b64838dd197f554c6c6285d88Tommi Rantalaint c(int x) NOINLINE ALIAS(b);
9104c77cced4975d2d4f8e1fd76b49e5884d9cbae4Konstantin Belousov#define compiler_barrier() asm volatile("");
9204c77cced4975d2d4f8e1fd76b49e5884d9cbae4Konstantin Belousov#else
9304c77cced4975d2d4f8e1fd76b49e5884d9cbae4Konstantin Belousovint c(int x);
9404c77cced4975d2d4f8e1fd76b49e5884d9cbae4Konstantin Belousov#define compiler_barrier()
9504c77cced4975d2d4f8e1fd76b49e5884d9cbae4Konstantin Belousov#endif
9604c77cced4975d2d4f8e1fd76b49e5884d9cbae4Konstantin Belousov
97e3e49dc28aee0dc78f0243d932a5c950aaec7e3eTommi Rantalaint NOINLINE a(void)
980f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata{
9904c77cced4975d2d4f8e1fd76b49e5884d9cbae4Konstantin Belousov  *(volatile int *)32 = 1;
10004c77cced4975d2d4f8e1fd76b49e5884d9cbae4Konstantin Belousov  return 1;
1010f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata}
1020f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata
103e3e49dc28aee0dc78f0243d932a5c950aaec7e3eTommi Rantalaint NOINLINE b(int x)
1040f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata{
10504c77cced4975d2d4f8e1fd76b49e5884d9cbae4Konstantin Belousov  int r;
10604c77cced4975d2d4f8e1fd76b49e5884d9cbae4Konstantin Belousov
10704c77cced4975d2d4f8e1fd76b49e5884d9cbae4Konstantin Belousov  compiler_barrier();
10804c77cced4975d2d4f8e1fd76b49e5884d9cbae4Konstantin Belousov
1090f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata  if (x)
11004c77cced4975d2d4f8e1fd76b49e5884d9cbae4Konstantin Belousov    r = a();
1110f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata  else
11204c77cced4975d2d4f8e1fd76b49e5884d9cbae4Konstantin Belousov    r = c(1);
11304c77cced4975d2d4f8e1fd76b49e5884d9cbae4Konstantin Belousov  return r + 1;
1140f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata}
1150f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata
1160f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milataint
1170f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milatamain (int argc, char **argv)
1180f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata{
1190f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata  if (argc > 1)
1200f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata      write_maps(argv[1]);
1210f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata  b(0);
1220f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata  return 0;
1230f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata}
1240f9a540c8c67ec4bb2e03130feea00a0cc9bf30cMartin Milata
125