This was reported in #215
The field access engine does casts such as
const uint32_t *quadletPtr = (const uint32_t *)(pdu + quadletId * 4);
uint32_t quadletHostOrder = Avtp_BeToCpu32(*quadletPtr);
This seems to work fine on things like amd64 or larger arm cores, however as Open1722 pdu structs are packed and nested, an uint32 casted like this may not be aligned to a word boundary and the access may fail (I actually do know this from personal experience from older arm7/armv3 cores)
C99 standard (final draft, referenced here https://en.wikipedia.org/wiki/C99 ) https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf says in 6.3.2.3
"A pointer to an object or incomplete type may be converted to a pointer to a different object or incomplete type. If the resulting pointer is not correctly aligned57) for the pointed-to type, the behavior is undefined."
which means we can not trust the compiler to fix this.
AI says (have not verified all instances)
x86-64, AArch64, ARMv7+ handle unaligned 32-bit loads
--> This is what we observed
It faults on strict-alignment targets — Cortex-M0/M0+ (ARMv6-M HardFault), MIPS, SPARC, many small RISC-V cores, some DSPs
This is important for us. Those are potential targets
It seems this could be caught via warnings
AI
Current flags won't warn: only -Wall -Wextra -Wconversion -Wsign-conversion -Wcast-qual (src/CMakeLists.txt:41); -Wcast-align is not enabled, and on x86 even that needs -Wcast-align=strict.
Suggested Fix AI
Fix cost is zero
memcpy-ing 4 bytes into an aligned local compiles to the identical single load on x86/ARM64 (the idiom is recognized), while generating safe code elsewhere. Only extra detail is the include: Utils.h would need <string.h>, or <linux/string.h> under LINUX_KERNEL1722, mirroring Byteorder.h:32.
Sounds reasonable but we should double check whether this really collapses to a single load on the relevant architectures (because if not, an alternative might be a compile time option to switch between casts and memcpy)
This was reported in #215
The field access engine does casts such as
This seems to work fine on things like amd64 or larger arm cores, however as Open1722 pdu structs are packed and nested, an uint32 casted like this may not be aligned to a word boundary and the access may fail (I actually do know this from personal experience from older arm7/armv3 cores)
C99 standard (final draft, referenced here https://en.wikipedia.org/wiki/C99 ) https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf says in 6.3.2.3
which means we can not trust the compiler to fix this.
AI says (have not verified all instances)
It seems this could be caught via warnings
AI
Suggested Fix AI
Sounds reasonable but we should double check whether this really collapses to a single load on the relevant architectures (because if not, an alternative might be a compile time option to switch between casts and memcpy)