From eba8e41c038fa12b82b73d5f1eb06fecaf09a4e4 Mon Sep 17 00:00:00 2001 From: japabu Date: Sun, 4 Oct 2026 18:52:38 +0200 Subject: [PATCH] The fixtures object parses are 8-aligned by their type, and its header refusal is loud `object` 0.38.1, built without its `unaligned` feature as both dev-dependencies are, reads an ELF file header in place: `Bytes::read_at` refuses a misaligned offset and `FileHeader::parse` answers "Invalid ELF header size or alignment". `include_bytes!` promises alignment 1, so `toyos-symbols/tests/name.rs` and `toyos-elf/tests/real.rs` passed only where the linker happened to place their fixtures on an 8-byte boundary; #726's ready run (37216757996) went red on exactly that in `every_function_names_what_object_reads` with no change to the code under test. Each fixture is now the field of a `#[repr(C, align(8))]` wrapper, so its alignment is the type's and not the link's. `toyos-elf`'s `objects_build_id` turned a header `object` refused into `None`, which made `a_toyos_ld_binary_without_the_flag_carries_no_build_id` agree with a refusal; it now panics instead, so the oracle can only answer about bytes it read. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01WcU2Dsw6mDYtwYfzVHPzM8 --- toyos-elf/tests/real.rs | 14 +++++++++----- toyos-symbols/tests/name.rs | 6 +++++- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/toyos-elf/tests/real.rs b/toyos-elf/tests/real.rs index 51740d70238..a5a2a2005f0 100644 --- a/toyos-elf/tests/real.rs +++ b/toyos-elf/tests/real.rs @@ -12,7 +12,11 @@ use toyos_elf::{Layout, Machine}; -const HEADERS: &[u8] = include_bytes!("fixtures/toyos-ld-headers.bin"); +/// `object` reads an ELF header in place, so the bytes need its 8-byte alignment. +#[repr(C, align(8))] +struct Aligned(T); + +static HEADERS: &[u8] = &Aligned(*include_bytes!("fixtures/toyos-ld-headers.bin")).0; #[test] fn a_toyos_ld_binary_parses_to_what_readelf_says() { @@ -55,14 +59,14 @@ fn a_toyos_ld_binary_parses_to_what_readelf_says() { /// The first 4 KiB of `/system/bin/shell` as rust-lld linked it with /// `--build-id`: `dd if=userland/target/x86_64-unknown-toyos/toyos/shell /// of=toyos-elf/tests/fixtures/lld-headers.bin bs=4096 count=1`. -const LLD_HEADERS: &[u8] = include_bytes!("fixtures/lld-headers.bin"); +static LLD_HEADERS: &[u8] = &Aligned(*include_bytes!("fixtures/lld-headers.bin")).0; /// The build-id `object` reads out of `file`'s program headers. fn objects_build_id(file: &[u8]) -> Option> { use object::read::elf::{FileHeader, ProgramHeader}; - let header = object::elf::FileHeader64::::parse(file).ok()?; - let endian = header.endian().ok()?; - for phdr in header.program_headers(endian, file).ok()? { + let header = object::elf::FileHeader64::::parse(file).expect("object reads the file header"); + let endian = header.endian().expect("object reads the byte order"); + for phdr in header.program_headers(endian, file).expect("object reads the program headers") { let Ok(Some(mut notes)) = phdr.notes(endian, file) else { continue }; while let Ok(Some(note)) = notes.next() { if note.name() == b"GNU" && note.n_type(endian) == object::elf::NT_GNU_BUILD_ID { diff --git a/toyos-symbols/tests/name.rs b/toyos-symbols/tests/name.rs index 1cead501cbb..96ab6984bda 100644 --- a/toyos-symbols/tests/name.rs +++ b/toyos-symbols/tests/name.rs @@ -6,7 +6,11 @@ use object::{Object, ObjectSymbol, SymbolKind}; use toyos_symbols::frame::BuildId; use toyos_symbols::{name, Check, Named, Unnamed}; -const BINARY: &[u8] = include_bytes!("fixtures/input-test.bin"); +/// `object` reads an ELF header in place, so the bytes need its 8-byte alignment. +#[repr(C, align(8))] +struct Aligned(T); + +static BINARY: &[u8] = &Aligned(*include_bytes!("fixtures/input-test.bin")).0; /// `input-test` with its `PT_GNU_EH_FRAME` turned into a `PT_NOTE` over a /// build-id note appended past its end, far past its header page.