The docs are not entirely clear what glyphs qualify as digits.
The function is supposed to be locale-dependent, but I couldn't
get it to return true on any non-ascii digits I tried.
But it's better to be safe than sorry, let's use our trivial
replacement instead.
The SBAT section was included in a special section in the EFI code, but
the contents weren't directly visible in any way. Let's add a "test" that
prints them for visual inspection.
If there's some external linter for this format, we could hook it up in the
future.
We would return the result of strcmp(), i.e. some positive/negative value.
Now that we want to make this a documented interface for other people
to implement, let's make the implementation more contstrained, even if
we ourselves don't care about whether the specific values.
ASSERT_SE_PTR() is like ASSERT_PTR() but uses assert_se() instead of
assert() internally.
Code should use ASSERT_SE_PTR() where the check should never be
optimized away, even if NDEBUG is set.
Rationale: assert() is the right choice for validating assumptions about
our own code, i.e. checking conditions that are "impossible" to not
hold, because we ourselves hacked things up the "right" way of course.
assert_se() is the right choice for tests that come with a weaker
guarantee, they encode assumptions over other's API behaviour, i.e.
whether something can fail there or not.
When developing tools that are not oom-safe assert_se() is the right
choice: we know that on Linux OOM doesn't really happen, even though
theoretically the API allows it to happen.
Usecase for ASSERT_SE_PTR() is mostly the fatal memory allocation logic
for EFI memory allocations. So far it used regular assert() i.e. OOM
failurs would be totally ignored if NDEBUG is set. We'd rather have our
EFI program to print an assert message and freeze instead though.
We'd connect to the bus twice: the first time to check networkd namespace,
and then the second time to do the deed we were asked to do. It's nicer
to open the bus just once, for efficience and also to avoid the open call
in all functions.
An ASSERT_PTR helper is added:
- sd_bus *bus = userdata;
...
- assert(bus);
+ sd_bus *bus = ASSERT_PTR(userdata);
...
It can be used in other place too, but I'm leaving that for a later
refactoring.
I think we should stick to the rule that stuff defined in
types-fundamental.h either:
1. adds a prefixed concept "sd_xyz" that maps differently in the two
environments
2. adds a non-prefixed concept "xyz" that adds a type otherwise missing
in one of the two environments but with the same definition as in the
other.
i.e. if have have some concept that might differ the way its set up in
the two environments it really should be prefixed by "sd_" to make clear
it has semantics we defined. Only drop the prefix if it really means the
exact same thin in all environments.
Now, sd_bool is defined prefixed, because its either mapped to "BOOLEAN"
(which is an integer) in UEFI or "bool" (which is C99 _Bool) in
userspace. size_t is not defined prefixed, because it's mapped to the
same thing ultimately (on the UEFI its mapped to UINTN, but that in turn
is defined as being the type for the size of memory objects, thus it's
really the same as userspace size_t).
So far "true" and "false" where defined unprefixed even though they map
to values of different types. typeof(true) in userspace would reveal
_Bool, but typeof(false) in UEFI would reveal BOOLEAN. The distinction
actually does matter in comparisons (i.e. (_Bool) 1 == (_Bool) 2 holds
while (BOOLEAN) 1 == (BOOLEAN) 2 does not hold).
Hence, let's add sd_true and sd_false, thus indicating we defined our
own concept here, and it has similar but different semantics in UEFI and
in userspace.
"type.h" is a very generic name, but this header is very specific to
making the "fundaemtnal" stuff work, it maps genric types in two
distinct ways. Hence let's make clear in the header name already what
this is about.
Let's make sure IMAGE_ID/IMAGE_VERSION are properly honoured, and
explain in a long comment why.
Let's also use ID= field again, which was lost by accident.
(While we are at it do some minimal OOM checks wherever we touch
something)
We only need the PE header offset from the DOS header, not
its size. Previously, the section table could be cut off in the middle.
While we are at it, also modernize the remaining code.
There is a ASSERT() macro from gnu-efi, but that does not show any
output to ConOut. Having to do some additional setup just to get
some debug output is tedious and outright difficult on real hardware.
This checked for strict type compatibility so far, which mean CONST_MAX()
couldn't be used on two differently signed integers, even though
conceptually there's nothing wrong with allowing that here, as C
correctly picks the larger type in the ternary op.
hence, let's explicitly whitelist integer comparisons here, as long as
the signedness matches.
Every location that this macro is used, it will be true the first
time it's checked, then false each time after that.
This can be useful for things such as one-time logging.
Add SBAT support, when -Dsbat-distro value is specified. One can use
-Dsbat-distro=auto for autodetection of all sbat options. Many meson configure
options added to customize SBAT CSV values, but sensible defaults are auto
detected by default. SBAT support is required if shim v15+ is used to load
systemd-boot binary or kernel.efi (Type II BootLoaderSpec).
Fixes#19247
Unfortunately, strverscmp() from libc or str_verscmp() do not correctly
handle pre-release version, e.g. 247 vs 247~rc1.
This implement a new comparison function, which is based on the RPM's
rpmvercmp().
sd-boot has a copy of a subset of codes from libbasic. This makes
sd-boot share the code with libbasic, and dedup the code.
Note, startswith_no_case() is dropped from sd-boot, as
- it is not used,
- the previous implementation is not correct,
- gnu-efi does not have StrniCmp() or so.