bootloader: rebase onto upstream 1.0.0, sync firmware-loader version
Bootloader fork rebase:
- Base changed from 0.1.0 pre-patched archive to upstream 1.0.0 tag (c7eeb9f)
- Applied 0001-redbear-local-forks.patch (Cargo.toml crate path redirects)
- Applied fix-uefi-alloc-panic.patch equivalents (4 panic!() -> graceful
error handling in src/main.rs)
- Applied P5-live-preload-cap-1gib.patch (1 GiB cap on live image preload)
- Skipped: P0 GPT partition scan (requires new module + integration),
P1 timeout/default-resolution, P2 live preload guard (subsumed by
panic fixes + cap), P3 live image safe read, P4 large ISO boot,
redox.patch — to be applied in dedicated rebase session.
firmware-loader/Cargo.toml: version 0.1.0 -> 0.3.0 (sync with other
Red Bear custom crates which are at 0.3.0).
fork-upstream-map.toml: bootloader back from PENDING_REBASE to 1.0.0
since the partial rebase matches upstream 1.0.0 content.
fork-upstream-map.toml: base restored to 'main' tracked (was correctly
tracked by build-redbear.sh).
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
/* Analyze differences between two vectors.
|
||||
|
||||
Copyright (C) 1988-1989, 1992-1995, 2001-2004, 2006-2017 Free Software
|
||||
Copyright (C) 1988-1989, 1992-1995, 2001-2004, 2006-2025 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
@@ -14,7 +14,7 @@
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
/* The basic idea is to consider two vectors as similar if, when
|
||||
@@ -28,13 +28,13 @@
|
||||
The basic algorithm is described in:
|
||||
"An O(ND) Difference Algorithm and its Variations", Eugene W. Myers,
|
||||
Algorithmica Vol. 1, 1986, pp. 251-266,
|
||||
<http://dx.doi.org/10.1007/BF01840446>.
|
||||
<https://doi.org/10.1007/BF01840446>.
|
||||
See especially section 4.2, which describes the variation used below.
|
||||
|
||||
The basic algorithm was independently discovered as described in:
|
||||
"Algorithms for Approximate String Matching", Esko Ukkonen,
|
||||
Information and Control Vol. 64, 1985, pp. 100-118,
|
||||
<http://dx.doi.org/10.1016/S0019-9958(85)80046-2>.
|
||||
<https://doi.org/10.1016/S0019-9958(85)80046-2>.
|
||||
|
||||
Unless the 'find_minimal' flag is set, this code uses the TOO_EXPENSIVE
|
||||
heuristic, by Paul Eggert, to limit the cost to O(N**1.5 log N)
|
||||
@@ -48,13 +48,21 @@
|
||||
OFFSET A signed integer type sufficient to hold the
|
||||
difference between two indices. Usually
|
||||
something like ptrdiff_t.
|
||||
OFFSET_MAX (Optional) The maximum value of OFFSET (e.g.,
|
||||
PTRDIFF_MAX). If omitted, it is inferred in a
|
||||
way portable to the vast majority of C platforms,
|
||||
as they lack padding bits.
|
||||
EXTRA_CONTEXT_FIELDS Declarations of fields for 'struct context'.
|
||||
NOTE_DELETE(ctxt, xoff) Record the removal of the object xvec[xoff].
|
||||
NOTE_INSERT(ctxt, yoff) Record the insertion of the object yvec[yoff].
|
||||
NOTE_ORDERED (Optional) A boolean expression saying that
|
||||
NOTE_DELETE and NOTE_INSERT calls must be
|
||||
issued in offset order.
|
||||
EARLY_ABORT(ctxt) (Optional) A boolean expression that triggers an
|
||||
early abort of the computation.
|
||||
USE_HEURISTIC (Optional) Define if you want to support the
|
||||
heuristic for large vectors.
|
||||
|
||||
It is also possible to use this file with abstract arrays. In this case,
|
||||
xvec and yvec are not represented in memory. They only exist conceptually.
|
||||
In this case, the list of defines above is amended as follows:
|
||||
@@ -63,37 +71,35 @@
|
||||
XVECREF_YVECREF_EQUAL(ctxt, xoff, yoff)
|
||||
A three-argument macro: References xvec[xoff] and
|
||||
yvec[yoff] and tests these elements for equality.
|
||||
|
||||
Before including this file, you also need to include:
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
#include "minmax.h"
|
||||
*/
|
||||
|
||||
/* Maximum value of type OFFSET. */
|
||||
#define OFFSET_MAX \
|
||||
((((OFFSET)1 << (sizeof (OFFSET) * CHAR_BIT - 2)) - 1) * 2 + 1)
|
||||
#ifndef OFFSET_MAX
|
||||
# define OFFSET_MAX \
|
||||
((((OFFSET) 1 << (sizeof (OFFSET) * CHAR_BIT - 2)) - 1) * 2 + 1)
|
||||
#endif
|
||||
|
||||
/* Default to no early abort. */
|
||||
#ifndef EARLY_ABORT
|
||||
# define EARLY_ABORT(ctxt) false
|
||||
#endif
|
||||
|
||||
/* Use this to suppress gcc's "...may be used before initialized" warnings.
|
||||
Beware: The Code argument must not contain commas. */
|
||||
#ifndef IF_LINT
|
||||
# if defined GCC_LINT || defined lint
|
||||
# define IF_LINT(Code) Code
|
||||
# else
|
||||
# define IF_LINT(Code) /* empty */
|
||||
# endif
|
||||
#ifndef NOTE_ORDERED
|
||||
# define NOTE_ORDERED false
|
||||
#endif
|
||||
|
||||
/* As above, but when Code must contain one comma. */
|
||||
#ifndef IF_LINT2
|
||||
# if defined GCC_LINT || defined lint
|
||||
# define IF_LINT2(Code1, Code2) Code1, Code2
|
||||
# else
|
||||
# define IF_LINT2(Code1, Code2) /* empty */
|
||||
/* Suppress gcc's "...may be used before initialized" warnings,
|
||||
generated by GCC versions up to at least GCC 14.2.
|
||||
Likewise for gcc -fanalyzer's "use of uninitialized value" warnings. */
|
||||
#if _GL_GNUC_PREREQ (4, 7)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
# if _GL_GNUC_PREREQ (13, 0)
|
||||
# pragma GCC diagnostic ignored "-Wanalyzer-use-of-uninitialized-value"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@@ -279,6 +285,11 @@ diag (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, bool find_minimal,
|
||||
continue;
|
||||
|
||||
#ifdef USE_HEURISTIC
|
||||
bool heuristic = ctxt->heuristic;
|
||||
#else
|
||||
bool heuristic = false;
|
||||
#endif
|
||||
|
||||
/* Heuristic: check occasionally for a diagonal that has made lots
|
||||
of progress compared with the edit distance. If we have any
|
||||
such, find the one that has made the most progress and return it
|
||||
@@ -287,7 +298,7 @@ diag (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, bool find_minimal,
|
||||
With this heuristic, for vectors with a constant small density
|
||||
of changes, the algorithm is linear in the vector size. */
|
||||
|
||||
if (200 < c && big_snake && ctxt->heuristic)
|
||||
if (200 < c && big_snake && heuristic)
|
||||
{
|
||||
{
|
||||
OFFSET best = 0;
|
||||
@@ -367,19 +378,13 @@ diag (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, bool find_minimal,
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* USE_HEURISTIC */
|
||||
|
||||
/* Heuristic: if we've gone well beyond the call of duty, give up
|
||||
and report halfway between our best results so far. */
|
||||
if (c >= ctxt->too_expensive)
|
||||
{
|
||||
OFFSET fxybest;
|
||||
OFFSET fxbest IF_LINT (= 0);
|
||||
OFFSET bxybest;
|
||||
OFFSET bxbest IF_LINT (= 0);
|
||||
|
||||
/* Find forward diagonal that maximizes X + Y. */
|
||||
fxybest = -1;
|
||||
OFFSET fxybest = -1, fxbest;
|
||||
for (d = fmax; d >= fmin; d -= 2)
|
||||
{
|
||||
OFFSET x = MIN (fd[d], xlim);
|
||||
@@ -397,7 +402,7 @@ diag (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, bool find_minimal,
|
||||
}
|
||||
|
||||
/* Find backward diagonal that minimizes X + Y. */
|
||||
bxybest = OFFSET_MAX;
|
||||
OFFSET bxybest = OFFSET_MAX, bxbest;
|
||||
for (d = bmax; d >= bmin; d -= 2)
|
||||
{
|
||||
OFFSET x = MAX (xoff, bd[d]);
|
||||
@@ -464,55 +469,99 @@ compareseq (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim,
|
||||
#define XREF_YREF_EQUAL(x,y) XVECREF_YVECREF_EQUAL (ctxt, x, y)
|
||||
#endif
|
||||
|
||||
/* Slide down the bottom initial diagonal. */
|
||||
while (xoff < xlim && yoff < ylim && XREF_YREF_EQUAL (xoff, yoff))
|
||||
while (true)
|
||||
{
|
||||
xoff++;
|
||||
yoff++;
|
||||
}
|
||||
/* Slide down the bottom initial diagonal. */
|
||||
while (xoff < xlim && yoff < ylim && XREF_YREF_EQUAL (xoff, yoff))
|
||||
{
|
||||
xoff++;
|
||||
yoff++;
|
||||
}
|
||||
|
||||
/* Slide up the top initial diagonal. */
|
||||
while (xoff < xlim && yoff < ylim && XREF_YREF_EQUAL (xlim - 1, ylim - 1))
|
||||
{
|
||||
xlim--;
|
||||
ylim--;
|
||||
}
|
||||
/* Slide up the top initial diagonal. */
|
||||
while (xoff < xlim && yoff < ylim && XREF_YREF_EQUAL (xlim - 1, ylim - 1))
|
||||
{
|
||||
xlim--;
|
||||
ylim--;
|
||||
}
|
||||
|
||||
/* Handle simple cases. */
|
||||
if (xoff == xlim)
|
||||
while (yoff < ylim)
|
||||
{
|
||||
NOTE_INSERT (ctxt, yoff);
|
||||
if (EARLY_ABORT (ctxt))
|
||||
return true;
|
||||
yoff++;
|
||||
}
|
||||
else if (yoff == ylim)
|
||||
while (xoff < xlim)
|
||||
{
|
||||
NOTE_DELETE (ctxt, xoff);
|
||||
if (EARLY_ABORT (ctxt))
|
||||
return true;
|
||||
xoff++;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct partition part IF_LINT2 (= { .xmid = 0, .ymid = 0 });
|
||||
/* Handle simple cases. */
|
||||
if (xoff == xlim)
|
||||
{
|
||||
while (yoff < ylim)
|
||||
{
|
||||
NOTE_INSERT (ctxt, yoff);
|
||||
if (EARLY_ABORT (ctxt))
|
||||
return true;
|
||||
yoff++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (yoff == ylim)
|
||||
{
|
||||
while (xoff < xlim)
|
||||
{
|
||||
NOTE_DELETE (ctxt, xoff);
|
||||
if (EARLY_ABORT (ctxt))
|
||||
return true;
|
||||
xoff++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
struct partition part;
|
||||
|
||||
/* Find a point of correspondence in the middle of the vectors. */
|
||||
diag (xoff, xlim, yoff, ylim, find_minimal, &part, ctxt);
|
||||
|
||||
/* Use the partitions to split this problem into subproblems. */
|
||||
if (compareseq (xoff, part.xmid, yoff, part.ymid, part.lo_minimal, ctxt))
|
||||
return true;
|
||||
if (compareseq (part.xmid, xlim, part.ymid, ylim, part.hi_minimal, ctxt))
|
||||
return true;
|
||||
OFFSET xoff1, xlim1, yoff1, ylim1, xoff2, xlim2, yoff2, ylim2;
|
||||
bool find_minimal1, find_minimal2;
|
||||
if (!NOTE_ORDERED
|
||||
&& ((xlim + ylim) - (part.xmid + part.ymid)
|
||||
< (part.xmid + part.ymid) - (xoff + yoff)))
|
||||
{
|
||||
/* The second problem is smaller and the caller doesn't
|
||||
care about order, so do the second problem first to
|
||||
lessen recursion. */
|
||||
xoff1 = part.xmid; xlim1 = xlim;
|
||||
yoff1 = part.ymid; ylim1 = ylim;
|
||||
find_minimal1 = part.hi_minimal;
|
||||
|
||||
xoff2 = xoff; xlim2 = part.xmid;
|
||||
yoff2 = yoff; ylim2 = part.ymid;
|
||||
find_minimal2 = part.lo_minimal;
|
||||
}
|
||||
else
|
||||
{
|
||||
xoff1 = xoff; xlim1 = part.xmid;
|
||||
yoff1 = yoff; ylim1 = part.ymid;
|
||||
find_minimal1 = part.lo_minimal;
|
||||
|
||||
xoff2 = part.xmid; xlim2 = xlim;
|
||||
yoff2 = part.ymid; ylim2 = ylim;
|
||||
find_minimal2 = part.hi_minimal;
|
||||
}
|
||||
|
||||
/* Recurse to do one subproblem. */
|
||||
bool early = compareseq (xoff1, xlim1, yoff1, ylim1, find_minimal1, ctxt);
|
||||
if (early)
|
||||
return early;
|
||||
|
||||
/* Iterate to do the other subproblem. */
|
||||
xoff = xoff2; xlim = xlim2;
|
||||
yoff = yoff2; ylim = ylim2;
|
||||
find_minimal = find_minimal2;
|
||||
}
|
||||
|
||||
return false;
|
||||
#undef XREF_YREF_EQUAL
|
||||
}
|
||||
|
||||
#if _GL_GNUC_PREREQ (4, 7)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#undef ELEMENT
|
||||
#undef EQUAL
|
||||
#undef OFFSET
|
||||
|
||||
Reference in New Issue
Block a user