[cper-lib] Fix unaligned access and C++20 compatibility issues
This patch addresses several compatibility and safety issues discovered
when integrating the library with stricter toolchains and sanitizers
(specifically the Google cc_toolchain with UBSan enabled).
- Fix SIGILL/Unaligned Access: UEFI CPER structures are inherently
unaligned. Accessing packed struct members directly can trigger
illegal instruction traps on strict platforms. Tests now use a
memcpy-based `getField<T>` helper to safely access unaligned fields.
- C++20 & Toolchain Compatibility:
- Added missing <vector> and <span> headers to cper_encoder.hpp.
- Added a virtual destructor to CperEncoder to satisfy
-Wnon-virtual-dtor.
- Fixed Class Template Argument Deduction (CTAD) warnings for
SeqMemcopy.
- Thread Safety: Switched from `gmtime` to `gmtime_r` for timestamp
creation to ensure thread safety and avoid static buffer issues.
- Compliance: Maintained all __attribute__((packed)) definitions
and static_assert offset checks to ensure the library remains
binary-compatible with the UEFI CPER specification.
Tested:
- Verified all tests pass via Meson inside the gbmc_dev container.
- Verified all tests pass via Bazel/Blaze using the Google cc_toolchain.
Google-Bug-Id: 505395424
Change-Id: I61863b8fad1b2b7fafdba662fcbeba10c71d809b
Signed-off-by: Aryk Ledet <arykledet@google.com>
This is a header-only library which provides a generic interface for users to write application specific UEFI CPER log encoders.
The UEFI specification for CPER logs allows for many combinations of Record Header and Section Descriptor properties based on the application. However, the underlying data structure does not change from application to application. To make it easier for gBMC applications to log faults in the CPER format the user only needs to specify the type of Record and Section type(s) that the encoder will need to create.
When developing and testing your application specific encoders, you will need to install this library into your development container.
Below is some pseudo code of how a user would setup their application specific CPER encoder which takes in char array types.
class MyCperEncoder : public CperEncoder<char> { RecordHeader createRecordHeader(...) override {...} SectionDescriptor createSectionDescriptor(...) override { if (sectionType == kPlatformMemory) { return createPlatformMemoryDescriptor(); } else if (sectionType == kOemSection) { return createOemDescriptor(); } ... } SectionDescriptor createPlatformMemoryDescriptor() {...} SectionDescriptor createOemDescriptor() {...} }
meson setup -C builddir meson install -C builddir
meson test -C builddir