| 1 | |
| 2 | |
| 3 | @@ -858,9 +858,6 @@
|
| 4 | # define MAINSTACKADDR_AVAILABLE 0
|
| 5 | # endif
|
| 6 | #endif
|
| 7 | -#if MAINSTACKADDR_AVAILABLE && !defined(get_main_stack)
|
| 8 | -# define get_main_stack(addr, size) get_stack(addr, size)
|
| 9 | -#endif
|
| 10 |
|
| 11 | #ifdef STACKADDR_AVAILABLE
|
| 12 | /*
|
| 13 | @@ -942,6 +939,55 @@
|
| 14 | return 0;
|
| 15 | #undef CHECK_ERR
|
| 16 | }
|
| 17 | +
|
| 18 | +#if defined(__linux__) && !defined(__GLIBC__) && defined(HAVE_GETRLIMIT)
|
| 19 | +
|
| 20 | +#ifndef PAGE_SIZE
|
| 21 | +#include <unistd.h>
|
| 22 | +#define PAGE_SIZE sysconf(_SC_PAGE_SIZE)
|
| 23 | +#endif
|
| 24 | +
|
| 25 | +static int
|
| 26 | +get_main_stack(void **addr, size_t *size)
|
| 27 | +{
|
| 28 | + size_t start, end, limit, prevend = 0;
|
| 29 | + struct rlimit r;
|
| 30 | + FILE *f;
|
| 31 | + char buf[PATH_MAX+80], s[8];
|
| 32 | + int n;
|
| 33 | + STACK_GROW_DIR_DETECTION;
|
| 34 | +
|
| 35 | + f = fopen("/proc/self/maps", "re");
|
| 36 | + if (!f)
|
| 37 | + return -1;
|
| 38 | + n = 0;
|
| 39 | + while (fgets(buf, sizeof buf, f)) {
|
| 40 | + n = sscanf(buf, "%zx-%zx %*s %*s %*s %*s %7s", &start, &end, s);
|
| 41 | + if (n >= 2) {
|
| 42 | + if (n == 3 && strcmp(s, "[stack]") == 0)
|
| 43 | + break;
|
| 44 | + prevend = end;
|
| 45 | + }
|
| 46 | + n = 0;
|
| 47 | + }
|
| 48 | + fclose(f);
|
| 49 | + if (n == 0)
|
| 50 | + return -1;
|
| 51 | +
|
| 52 | + limit = 100 << 20; /* 100MB stack limit */
|
| 53 | + if (getrlimit(RLIMIT_STACK, &r)==0 && r.rlim_cur < limit)
|
| 54 | + limit = r.rlim_cur & -PAGE_SIZE;
|
| 55 | + if (limit > end) limit = end;
|
| 56 | + if (prevend < end - limit) prevend = end - limit;
|
| 57 | + if (start > prevend) start = prevend;
|
| 58 | + *addr = IS_STACK_DIR_UPPER() ? (void *)start : (void *)end;
|
| 59 | + *size = end - start;
|
| 60 | + return 0;
|
| 61 | +}
|
| 62 | +#else
|
| 63 | +# define get_main_stack(addr, size) get_stack(addr, size)
|
| 64 | +#endif
|
| 65 | +
|
| 66 | #endif
|
| 67 |
|
| 68 | static struct {
|