diff --git a/double-free.patch b/double-free.patch new file mode 100644 index 0000000..129bf82 --- /dev/null +++ b/double-free.patch @@ -0,0 +1,44 @@ +diff --git a/interpret.h b/interpret.h +index 57d060e6..26010ada 100644 +--- a/interpret.h ++++ b/interpret.h +@@ -213,7 +213,7 @@ top: + case Node_var_new: + uninitialized_scalar: + if (op != Op_push_arg_untyped) { +- /* convert untyped to scalar */ ++ /* convert very original untyped to scalar */ + m->type = Node_var; + m->var_value = dupnode(Nnull_string); + } +@@ -222,6 +222,7 @@ uninitialized_scalar: + _("reference to uninitialized argument `%s'") : + _("reference to uninitialized variable `%s'"), + save_symbol->vname); ++ // set up local param by value + if (op != Op_push_arg_untyped) + m = dupnode(Nnull_string); + UPREF(m); +@@ -230,14 +231,20 @@ uninitialized_scalar: + + case Node_elem_new: + if (op != Op_push_arg_untyped) { +- /* convert untyped to scalar */ +- m = elem_new_to_scalar(m); ++ /* convert very original untyped to scalar */ ++ m->type = Node_var; ++ m->var_value = dupnode(Nnull_string); + } + if (do_lint) + lintwarn(isparam ? + _("reference to uninitialized argument `%s'") : + _("reference to uninitialized variable `%s'"), + save_symbol->vname); ++ // set up local param by value ++ if (op != Op_push_arg_untyped) { ++ m = elem_new_to_scalar(m); ++ } ++ + PUSH(m); + break; + diff --git a/gawk.changes b/gawk.changes index 045d9b8..efe33b7 100644 --- a/gawk.changes +++ b/gawk.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Tue Sep 20 07:45:49 UTC 2022 - Andreas Schwab + +- 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 + ------------------------------------------------------------------- Tue Sep 13 17:43:05 UTC 2022 - Andreas Schwab diff --git a/gawk.spec b/gawk.spec index 0a85baf..78b96c9 100644 --- a/gawk.spec +++ b/gawk.spec @@ -28,8 +28,8 @@ Source2: http://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz.sig Source3: http://savannah.gnu.org/people/viewgpg.php?user_id=80653#/gawk.keyring Source4: gawk.rpmlintrc Patch0: pma.patch -Patch1: nan-tests.patch -Patch2: upref.patch +Patch1: nan-sign.patch +Patch2: double-free.patch Provides: awk BuildRequires: mpfr-devel BuildRequires: readline-devel diff --git a/nan-sign.patch b/nan-sign.patch new file mode 100644 index 0000000..cb4101e --- /dev/null +++ b/nan-sign.patch @@ -0,0 +1,50 @@ +diff --git a/eval.c b/eval.c +index 1069570b7..44f614d22 100644 +--- a/eval.c ++++ b/eval.c +@@ -39,6 +39,8 @@ static int num_exec_hook = 0; + static Func_pre_exec pre_execute[MAX_EXEC_HOOKS]; + static Func_post_exec post_execute = NULL; + ++static double fix_nan_sign(double left, double right, double result); ++ + extern void frame_popped(); + + int OFSlen; +@@ -1901,3 +1903,16 @@ elem_new_to_scalar(NODE *n) + + return n; + } ++ ++/* fix_nan_sign --- fix NaN sign on RiscV */ ++ ++static double ++fix_nan_sign(double left, double right, double result) ++{ ++ if (isnan(left) && signbit(left)) ++ return copysign(result, -1.0); ++ else if (isnan(right) && signbit(right)) ++ return copysign(result, -1.0); ++ else ++ return result; ++} +diff --git a/interpret.h b/interpret.h +index 26010ada1..955d918f1 100644 +--- a/interpret.h ++++ b/interpret.h +@@ -583,6 +583,7 @@ uninitialized_scalar: + plus: + t1 = TOP_NUMBER(); + r = make_number(t1->numbr + x2); ++ r->numbr = fix_nan_sign(t1->numbr, x2, r->numbr); + DEREF(t1); + REPLACE(r); + break; +@@ -597,6 +598,7 @@ plus: + minus: + t1 = TOP_NUMBER(); + r = make_number(t1->numbr - x2); ++ r->numbr = fix_nan_sign(t1->numbr, x2, r->numbr); + DEREF(t1); + REPLACE(r); + break; diff --git a/nan-tests.patch b/nan-tests.patch deleted file mode 100644 index 8b93555..0000000 --- a/nan-tests.patch +++ /dev/null @@ -1,20 +0,0 @@ -Index: gawk-5.2.0/test/inf-nan-torture.in -=================================================================== ---- gawk-5.2.0.orig/test/inf-nan-torture.in -+++ gawk-5.2.0/test/inf-nan-torture.in -@@ -1 +1 @@ ---inf -inform inform -nan -nancy nancy -123 0 123 +123 nancy +nancy +nan inform +inform +inf -+-inf -inform inform +nan -nancy nancy -123 0 123 +123 nancy +nancy +nan inform +inform +inf -Index: gawk-5.2.0/test/inf-nan-torture.ok -=================================================================== ---- gawk-5.2.0.orig/test/inf-nan-torture.ok -+++ gawk-5.2.0/test/inf-nan-torture.ok -@@ -1,7 +1,7 @@ - 1 -inf -inf - 2 -inform 0 - 3 inform 0 --4 -nan -nan -+4 +nan +nan - 5 -nancy 0 - 6 nancy 0 - 7 -123 -123 diff --git a/pma.patch b/pma.patch index cb9cb76..9368ac6 100644 --- a/pma.patch +++ b/pma.patch @@ -2,11 +2,39 @@ Index: gawk-5.2.0/support/pma.c =================================================================== --- gawk-5.2.0.orig/support/pma.c +++ gawk-5.2.0/support/pma.c -@@ -346,6 +346,7 @@ static void * addrgap(off_t n) { // fin - for (U = 1; ; U *= 2) // double upper bound until failure - if (MAP_FAILED == (A = MMAP(U))) break; - else MUNMAP(A, U); -+ if (U == 0) U = -1; - while (1 + L < U) { // binary search between bounds +@@ -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; } +- 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) { diff --git a/upref.patch b/upref.patch deleted file mode 100644 index baed65f..0000000 --- a/upref.patch +++ /dev/null @@ -1,12 +0,0 @@ -Index: gawk-5.2.0/interpret.h -=================================================================== ---- gawk-5.2.0.orig/interpret.h -+++ gawk-5.2.0/interpret.h -@@ -238,6 +238,7 @@ uninitialized_scalar: - _("reference to uninitialized argument `%s'") : - _("reference to uninitialized variable `%s'"), - save_symbol->vname); -+ UPREF(m); - PUSH(m); - break; -