void free(void *ptr) { size_t usable,size,cnt = 0u; unsigned int i; char *p; /* If ptr is NULL, no operation is performed.*/ if (ptr == NULL){ return real_free(ptr); } usable = malloc_usable_size(ptr); /* At the first, check fixed redzone. If overwritten, following size info is maybe invalid */ for (p = (char *)P_F_RZ(ptr, usable); p < (char *)P_F_RZ(ptr, usable) + SIZEOF_F_RZ; p++){ if(*p != MAGIC_BYTE) cnt++; } if (cnt == SIZEOF_F_RZ){ ofc_count = cnt; /* for testing */ /* Maybe size info was broken */ OFC_DUMP_COUNT_MAYBE(cnt); ofc_bt(); real_free(ptr); return; } size = *(size_t *)P_SIZE(ptr, usable); OFC_DUMP(ptr, usable, size); p = P_RZ(ptr, usable, size); for (i = 0; i < SIZEOF_RZ(usable ,size) - SIZEOF_F_RZ; i++) { if(*(p + i) != MAGIC_BYTE) cnt++; } if (cnt){ ofc_count = cnt; /* for testing */ OFC_DUMP_COUNT(cnt); OFC_DUMP_INFO(ptr,size); ofc_bt(); } real_free(ptr); return; }
mp_size_t mpn_gcdext (mp_ptr gp, mp_ptr s0p, mp_size_t *s0size, mp_ptr ap, mp_size_t an, mp_ptr bp, mp_size_t n) { mp_size_t init_scratch, orig_n = n; mp_size_t scratch, un, u0n, u1n; mp_limb_t t; mp_ptr tp, u0, u1; int swapped = 0; struct ngcd_matrix M; mp_size_t p; mp_size_t nn; mp_limb_signed_t a; int c; TMP_DECL; ASSERT (an >= n); if (an == 1) { if (!n) { /* shouldn't ever occur, but we include for completeness */ gp[0] = ap[0]; s0p[0] = 1; *s0size = 1; return 1; } gp[0] = mpn_gcdinv_1(&a, ap[0], bp[0]); if (a < (mp_limb_signed_t) 0) { s0p[0] = -a; (*s0size) = -1; } else { s0p[0] = a; (*s0size) = 1 - (s0p[0] == 0); } return 1; } init_scratch = MPN_NGCD_MATRIX_INIT_ITCH (n-P_SIZE(n)); scratch = mpn_nhgcd_itch ((n+1)/2); /* Space needed for mpn_ngcd_matrix_adjust */ if (scratch < 2*n) scratch = 2*n; if (scratch < an - n + 1) /* the first division can sometimes be selfish!! */ scratch = an - n + 1; /* Space needed for cofactor adjust */ scratch = MAX(scratch, 2*(n+1) + P_SIZE(n) + 1); TMP_MARK; if (5*n + 2 + MPN_GCD_LEHMER_N_ITCH(n) > init_scratch + scratch) tp = TMP_ALLOC_LIMBS (7*n+4+MPN_GCD_LEHMER_N_ITCH(n)); /* 2n+2 for u0, u1, 5*n+2 + MPN_GCD_LEHMER_N_ITCH(n) for Lehmer and copies of ap and bp and s (and finally 3*n+1 for t and get_t) */ else tp = TMP_ALLOC_LIMBS (2*(n+1) + init_scratch + scratch); if (an > n) { mp_ptr qp = tp; mpn_tdiv_qr (qp, ap, 0, ap, an, bp, n); an = n; MPN_NORMALIZE (ap, an); if (an == 0) { MPN_COPY (gp, bp, n); TMP_FREE; (*s0size) = 0; return n; } } if (BELOW_THRESHOLD (n, GCDEXT_THRESHOLD)) { n = mpn_ngcdext_lehmer (gp, s0p, s0size, ap, bp, n, tp); TMP_FREE; return n; } u0 = tp; /* Cofactor space */ u1 = tp + n + 1; MPN_ZERO(tp, 2*(n+1)); tp += 2*(n+1); /* First iteration, setup u0 and u1 */ p = P_SIZE(n); mpn_ngcd_matrix_init (&M, n - p, tp); ASSERT(tp + init_scratch > M.p[1][1] + M.n); nn = mpn_nhgcd (ap + p, bp + p, n - p, &M, tp + init_scratch); if (nn > 0) { n = mpn_ngcd_matrix_adjust (&M, p + nn, ap, bp, p, tp + init_scratch); /* (ap'', bp'')^T = M^-1(ap', bp')^T and (ap', bp') = (1*ap + ?*bp, 0*ap + ?*bp) We let u0 be minus the factor of ap appearing in the expression for bp'' and u1 be the factor of ap appearing in the expression for ap'' */ MPN_COPY(u0, M.p[1][0], M.n); MPN_COPY(u1, M.p[1][1], M.n); un = M.n; while ((u0[un-1] == 0) && (u1[un-1] == 0)) un--; /* normalise u0, u1, both cannot be zero as det = 1*/ } else { mp_size_t gn; un = 1; u0[0] = 0; /* bp = 0*ap + ?*bp, thus u0 = -0 */ u1[0] = 1; /* ap = 1*ap + ?*bp, thus u1 = 1 */ n = mpn_ngcdext_subdiv_step (gp, &gn, s0p, u0, u1, &un, ap, bp, n, tp); if (n == 0) { /* never observed to occur */ (*s0size) = un; ASSERT(s0p[*s0size - 1] != 0); TMP_FREE; return gn; } } while (ABOVE_THRESHOLD (n, GCDEXT_THRESHOLD)) { struct ngcd_matrix M; mp_size_t p = P_SIZE(n); mp_size_t nn; mpn_ngcd_matrix_init (&M, n - p, tp); nn = mpn_nhgcd (ap + p, bp + p, n - p, &M, tp + init_scratch); if (nn > 0) { n = mpn_ngcd_matrix_adjust (&M, p + nn, ap, bp, p, tp + init_scratch); ngcdext_cofactor_adjust(u0, u1, &un, &M, tp + init_scratch); /* (ap'', bp'')^T = M^-1(ap', bp')^T and (ap', bp') = (u1*ap + ?*bp, -u0*ap + ?*bp) So we need u0' = -(-c*u1 + a*-u0) = a*u0 + c*u1 and we need u1' = (d*u1 -b*-u0) = b*u0 + d*u1 */ ASSERT(un <= orig_n + 1); } else { mp_size_t gn; n = mpn_ngcdext_subdiv_step (gp, &gn, s0p, u0, u1, &un, ap, bp, n, tp); ASSERT(un <= orig_n + 1); if (n == 0) { (*s0size) = un; ASSERT(((*s0size) == 0) || (s0p[ABS(*s0size) - 1] != 0)); TMP_FREE; return gn; } } } ASSERT (ap[n-1] > 0 || bp[n-1] > 0); ASSERT (u0[un-1] > 0 || u1[un-1] > 0); if (ap[n-1] < bp[n-1]) { MP_PTR_SWAP (ap, bp); MP_PTR_SWAP (u0, u1); swapped = 1; } an = n; /* {ap, an} and {bp, bn} are normalised, {ap, an} >= {bp, bn} */ MPN_NORMALIZE (bp, n); if (n == 0) { /* If bp == 0 then gp = ap with cofactor u1 If we swapped then cofactor is -u1 This case never seems to happen */ MPN_COPY (gp, ap, an); MPN_NORMALIZE(u1, un); MPN_COPY(s0p, u1, un); (*s0size) = un; if (swapped) (*s0size) = -(*s0size); TMP_FREE; return an; } /* If at this point we have s*ap' + t*bp' = gp where gp is the gcd and (ap', bp') = (u1*ap + ?*bp, -u0*ap + ?*bp) then gp = s*u1*ap - t*u0*ap + ?*bp and the cofactor we want is (s*u1-t*u0). First there is the special case u0 = 0, u1 = 1 in which case we do not need to compute t... */ ASSERT(u1 + un <= tp); u0n = un; MPN_NORMALIZE(u0, u0n); /* {u0, u0n} is now normalised */ if (u0n == 0) /* u1 = 1 case is rare*/ { mp_size_t gn; gn = mpn_ngcdext_lehmer (gp, s0p, s0size, ap, bp, n, tp); if (swapped) (*s0size) = -(*s0size); TMP_FREE; return gn; } else { /* Compute final gcd. */ mp_size_t gn, sn, tn; mp_ptr s, t; mp_limb_t cy; int negate = 0; /* Save an, bn first as gcdext destroys inputs */ s = tp; tp += an; MPN_COPY(tp, ap, an); MPN_COPY(tp + an, bp, an); if (mpn_cmp(tp, tp + an, an) == 0) { /* gcd is tp or tp + an return smallest cofactor, either -u0 or u1 */ gn = an; MPN_NORMALIZE(tp, gn); MPN_COPY(gp, tp, gn); MPN_CMP(c, u0, u1, un); if (c < (mp_limb_signed_t) 0) { MPN_COPY(s0p, u0, u0n); (*s0size) = -u0n; } else { MPN_NORMALIZE(u1, un); MPN_COPY(s0p, u1, un); (*s0size) = un; } TMP_FREE; return gn; } gn = mpn_ngcdext_lehmer (gp, s, &sn, tp, tp + an, an, tp + 2*an); /* Special case, s == 0, t == 1, cofactor = -u0 case is rare*/ if (sn == 0) { MPN_COPY(s0p, u0, u0n); (*s0size) = -u0n; if (swapped) (*s0size) = -(*s0size); TMP_FREE; return gn; } /* We'll need the other cofactor t = (gp - s*ap)/bp */ t = tp; tp += (an + 1); gcdext_get_t(t, &tn, gp, gn, ap, an, bp, n, s, sn, tp); ASSERT((tn == 0) || (t[tn - 1] > 0)); /* {t, tn} is normalised */ ASSERT(tn <= an + 1); /* We want to compute s*u1 - t*u0, so if s is negative t will be positive, so we'd be dealing with negative numbers. We fix that here. */ if (sn < 0) { sn = -sn; negate = 1; } /* Now we can deal with the special case u1 = 0 */ u1n = un; MPN_NORMALIZE(u1, u1n); /* {u1, u1n} is now normalised */ if (u1n == 0) /* case is rare */ { MPN_COPY(s0p, t, tn); (*s0size) = -tn; if (swapped ^ negate) (*s0size) = -(*s0size); TMP_FREE; return gn; } /* t may be zero, but we need to compute s*u1 anyway */ if (sn >= u1n) mpn_mul(s0p, s, sn, u1, u1n); else mpn_mul(s0p, u1, u1n, s, sn); (*s0size) = sn + u1n; (*s0size) -= (s0p[sn + u1n - 1] == 0); ASSERT(s0p[*s0size - 1] > 0); /* {s0p, *s0size} is normalised now */ if (tn == 0) /* case is rare */ { if (swapped ^ negate) (*s0size) = -(*s0size); TMP_FREE; return gn; } /* Now compute the rest of the cofactor, t*u0 and subtract it We're done with u1 and s which happen to be consecutive, so use that space */ ASSERT(u1 + tn + u0n <= t); if (tn > u0n) mpn_mul(u1, t, tn, u0, u0n); else mpn_mul(u1, u0, u0n, t, tn); u1n = tn + u0n; u1n -= (u1[tn + u0n - 1] == 0); ASSERT(u1[u1n - 1] > 0); /* Recall t is now negated so s*u1 - t*u0 involves an *addition* */ if ((*s0size) >= u1n) { cy = mpn_add(s0p, s0p, *s0size, u1, u1n); if (cy) s0p[(*s0size)++] = cy; } else { cy = mpn_add(s0p, u1, u1n, s0p, *s0size); (*s0size) = u1n; if (cy) s0p[(*s0size)++] = cy; } if (swapped ^ negate) (*s0size) = -(*s0size); TMP_FREE; return gn; } }