Dirk Mueller
d059de2dbc
- double-free.patch: Fix Node_elem_new op, replacing upref.patch - pma.patch: Replace with upstream solution - nan-sign.patch: Fix negative NaN issue on RiscV, replacing nan-tests.patch OBS-URL: https://build.opensuse.org/request/show/1004924 OBS-URL: https://build.opensuse.org/package/show/Base:System/gawk?expand=0&rev=91
41 lines
2.2 KiB
Diff
41 lines
2.2 KiB
Diff
Index: gawk-5.2.0/support/pma.c
|
|
===================================================================
|
|
--- gawk-5.2.0.orig/support/pma.c
|
|
+++ gawk-5.2.0/support/pma.c
|
|
@@ -340,16 +340,20 @@ static void flr(ao_t *p) { // remove ao
|
|
#define MMAP(N) mmap(NULL, (N), PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0)
|
|
#define MUNMAP(A, N) do { if (0 != munmap((A), (N))) { ERR("munmap()" ERN); SERN; } } while (0)
|
|
static void * addrgap(off_t n) { // find big gap in address space to map n bytes
|
|
- void *A, *Amax = NULL; size_t L = 0, U, Max = 0, N = (size_t)n; char *r;
|
|
+ void *A, *Amax = NULL; size_t L, U, Max = 0, N = (size_t)n; char *r;
|
|
FYI("addrgap(%jd)\n", (intmax_t)n); // TODO: better way to handle off_t
|
|
if (N < sizeof(pma_hdr_t) + 40960) { ERR("file size %zu too small\n", N); SERN; }
|
|
- for (U = 1; ; U *= 2) // double upper bound until failure
|
|
- if (MAP_FAILED == (A = MMAP(U))) break;
|
|
- else MUNMAP(A, U);
|
|
- while (1 + L < U) { // binary search between bounds
|
|
+ // Binary search to find max length of successfull mmap().
|
|
+ // Invariants:
|
|
+ // Larger max might lie in range [L,U] inclusive.
|
|
+ // If a previous max has been found, it must lie in [1,L-1].
|
|
+ // A larger max cannot lie in [U+1,UINT64_MAX].
|
|
+ L = 1; // mmap fails if length == 0 (SUSv3)
|
|
+ U = UINT64_MAX;
|
|
+ while (L <= U) {
|
|
size_t M = L + (U - L) / 2; // avoid overflow
|
|
- if (MAP_FAILED == (A = MMAP(M))) { U = M; }
|
|
- else { Amax = A; Max = M; MUNMAP(A, M); L = M; }
|
|
+ if (MAP_FAILED != (A = MMAP(M))) { assert(Max < M); Max = M; Amax = A; MUNMAP(A, M); if (UINT64_MAX == M) break; L = M + 1; }
|
|
+ else { assert(0 < M); U = M - 1; }
|
|
}
|
|
FYI("max gap: %zu bytes at %p\n", Max, Amax);
|
|
if (Max < N + (size_t)ALGN * 2) { // safety margin
|
|
@@ -392,6 +396,7 @@ int pma_init(int verbose, const char *fi
|
|
assert((himask | lomask) == ~((uintptr_t)0));
|
|
if (! (WDSZ == sizeof(void *) && // in C11 we'd static_assert()
|
|
WDSZ == sizeof(size_t) &&
|
|
+ WDSZ == sizeof(off_t) &&
|
|
WDSZ == sizeof(unsigned long))) { ERR("word size not 64 bits\n"); SERL; }
|
|
assert(0 == sizeof(pma_hdr_t) % WDSZ);
|
|
if (NULL == file) {
|