X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FRtsUtils.c;h=ef7cbb72e2d06329161e8e7da4f892aa9b593fc4;hb=0dbbf1932d550293986af6244202cb735b2cd966;hp=ce1c0a2493a67077bb234d71cbede8a71cd02237;hpb=153b9cb9b11e05c4edb1b6bc0a7b972660e41f70;p=ghc-hetmet.git diff --git a/ghc/rts/RtsUtils.c b/ghc/rts/RtsUtils.c index ce1c0a2..ef7cbb7 100644 --- a/ghc/rts/RtsUtils.c +++ b/ghc/rts/RtsUtils.c @@ -40,6 +40,24 @@ #include #endif +#if defined(openbsd_HOST_OS) || defined(linux_HOST_OS) +#include +#include +#include + +/* no C99 header stdint.h on OpenBSD? */ +#if defined(openbsd_HOST_OS) +typedef unsigned long my_uintptr_t; +#else +#include +typedef uintptr_t my_uintptr_t; +#endif +#endif + +#if defined(_WIN32) +#include +#endif + /* ----------------------------------------------------------------------------- Result-checking malloc wrappers. -------------------------------------------------------------------------- */ @@ -73,11 +91,14 @@ stgReallocBytes (void *p, int n, char *msg) void * stgCallocBytes (int n, int m, char *msg) { - int i; - int sz = n * m; - char* p = stgMallocBytes(sz, msg); - for (i = 0; i < sz; i++) p[i] = 0; - return p; + char *space; + + if ((space = (char *) calloc((size_t) n, (size_t) m)) == NULL) { + /* don't fflush(stdout); WORKAROUND bug in Linux glibc */ + MallocFailHook((W_) n*m, msg); /*msg*/ + stg_exit(EXIT_INTERNAL_ERROR); + } + return space; } /* To simplify changing the underlying allocator used @@ -89,15 +110,6 @@ stgFree(void* p) free(p); } -void -_stgAssert (char *filename, unsigned int linenum) -{ - fflush(stdout); - fprintf(stderr, "ASSERTION FAILED: file %s, line %u\n", filename, linenum); - fflush(stderr); - abort(); -} - /* ----------------------------------------------------------------------------- Stack overflow @@ -177,9 +189,13 @@ time_str(void) if (now == 0) { time(&now); +#if HAVE_CTIME_R + ctime_r(&now, nowstr); +#else strcpy(nowstr, ctime(&now)); - strcpy(nowstr+16,nowstr+19); - nowstr[21] = '\0'; +#endif + memmove(nowstr+16,nowstr+19,7); + nowstr[21] = '\0'; // removes the \n } return nowstr; } @@ -310,3 +326,42 @@ int genericRaise(int sig) { return raise(sig); #endif } + +/* ----------------------------------------------------------------------------- + Allocating executable memory + -------------------------------------------------------------------------- */ + +/* Heavily arch-specific, I'm afraid.. */ + +/* + * Allocate len bytes which are readable, writable, and executable. + * + * ToDo: If this turns out to be a performance bottleneck, one could + * e.g. cache the last VirtualProtect/mprotect-ed region and do + * nothing in case of a cache hit. + */ +void* +stgMallocBytesRWX(int len) +{ + void *addr = stgMallocBytes(len, "mallocBytesRWX"); +#if defined(i386_HOST_ARCH) && defined(_WIN32) + /* This could be necessary for processors which distinguish between READ and + EXECUTE memory accesses, e.g. Itaniums. */ + DWORD dwOldProtect = 0; + if (VirtualProtect (addr, len, PAGE_EXECUTE_READWRITE, &dwOldProtect) == 0) { + barf("mallocBytesRWX: failed to protect 0x%p; error=%lu; old protection: %lu\n", + addr, (unsigned long)GetLastError(), (unsigned long)dwOldProtect); + } +#elif defined(openbsd_HOST_OS) || defined(linux_HOST_OS) + /* malloced memory isn't executable by default on OpenBSD */ + my_uintptr_t pageSize = sysconf(_SC_PAGESIZE); + my_uintptr_t mask = ~(pageSize - 1); + my_uintptr_t startOfFirstPage = ((my_uintptr_t)addr ) & mask; + my_uintptr_t startOfLastPage = ((my_uintptr_t)addr + len - 1) & mask; + my_uintptr_t size = startOfLastPage - startOfFirstPage + pageSize; + if (mprotect((void*)startOfFirstPage, (size_t)size, PROT_EXEC | PROT_READ | PROT_WRITE) != 0) { + barf("mallocBytesRWX: failed to protect 0x%p\n", addr); + } +#endif + return addr; +}