vosen/ZLUDA · error · io::Error
io::Error::new(io::ErrorKind::InvalidData, e.to_string())
Error message
io::Error::new(io::ErrorKind::InvalidData, e.to_string())
What it means
`write_object` wraps any failure from parsing the supplied `main_elf` bytes as an ELF64 file header into an `io::Error` with kind `InvalidData`. The library needs the input ELF's OS/ABI, machine type, and flags to emit a companion metadata object file, so if the bytes are not a valid ELF64 the whole write is aborted. This keeps the failure surfaced as a plain `io::Result` error rather than a panic.
Source
Thrown at kernel_metadata/src/lib.rs:80
}
pub fn copy_object<'a>(elf_bytes: &'a [u8]) -> Option<ModuleMetadata32Bit> {
read_object::<ArchivedModuleMetadata32Bit>(elf_bytes, Self::SECTION, Self::VERSION)
.and_then(|archived| rkyv::deserialize::<_, rkyv::rancor::Failure>(archived).ok())
}
}
pub fn write_object(
this: &impl for<'a, 'b> Serialize<
HighSerializer<AlignedVec, ArenaHandle<'b>, rkyv::rancor::Failure>,
>,
section: &str,
version: u64,
main_elf: &[u8],
writer: &mut impl io::Write,
) -> io::Result<()> {
let main_header = elf::FileHeader64::<object::Endianness>::parse(main_elf)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e.to_string()))?;
let endian = main_header
.endian()
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e.to_string()))?;
let data = rkyv::to_bytes::<rkyv::rancor::Failure>(this)
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
let mut buf = Vec::new();
let mut writer_elf = elf_write::Writer::new(endian, true, &mut buf);
writer_elf.reserve_file_header();
let section_name = writer_elf.add_section_name(section.as_bytes());
writer_elf.reserve_section_index();
let section_offset = writer_elf.reserve(data.len() + mem::size_of::<u64>(), 8);
writer_elf.reserve_shstrtab_section_index();
writer_elf.reserve_shstrtab();
writer_elf.reserve_section_headers();
writer_elf
.write_file_header(&elf_write::FileHeader {
os_abi: main_header.e_ident().os_abi,
abi_version: main_header.e_ident().abi_version,View on GitHub (pinned to 9c8b43f242)
Solutions
- Verify `main_elf` begins with the 4-byte ELF magic `\x7fELF` before calling `write_object`
- Check the file is a complete ELF64 (e_ident[EI_CLASS] == ELFCLASS64) and at least 64 bytes long
- Make sure you pass the final linked ELF (e.g. from the CUDA/cubin compilation step), not a PTX file or a partial buffer
- Log the first 16 bytes of `main_elf` when the error occurs to spot wrong-file wiring
Example fix
// before
let mut elf = Vec::new();
File::open("kernel.ptx")?.read_to_end(&mut elf)?;
write_object(&meta, ".zluda", 1, &elf, &mut out)?;
// after
let mut elf = Vec::new();
File::open("kernel.cubin")?.read_to_end(&mut elf)?;
assert_eq!(&elf[..4], b"\x7fELF", "not an ELF file");
write_object(&meta, ".zluda", 1, &elf, &mut out)?; Defensive patterns
Strategy: validation
Validate before calling
fn is_elf64(bytes: &[u8]) -> bool {
bytes.len() >= 64 && &bytes[..4] == b"\x7fELF" && bytes[4] == 2 // EI_CLASS = ELFCLASS64
}
if !is_elf64(&main_elf) {
return Err(io::Error::new(io::ErrorKind::InvalidData, "main_elf is not a valid ELF64"));
} Type guard
fn looks_like_elf(bytes: &[u8]) -> bool {
bytes.len() >= 4 && &bytes[..4] == b"\x7fELF"
} Try / catch
match write_object(&meta, ".zluda", VERSION, &main_elf, &mut out) {
Ok(()) => (),
Err(e) if e.kind() == io::ErrorKind::InvalidData =>
eprintln!("bad ELF input: {e}"),
Err(e) => return Err(e),
} Prevention
- Always assert the ELF magic and EI_CLASS before passing bytes to write_object
- Pass the final linked ELF output, never PTX text or intermediate objects
- Check that the producer of the ELF completed successfully (file size > header size)
When it happens
Trigger: Calling `write_object` (directly or via `ModuleMetadata::write_object`) with a `main_elf` slice that is truncated (<64 bytes), empty, starts with bytes other than the `\x7fELF` magic, is a 32-bit ELF where a 64-bit header is expected, or is otherwise a corrupted/non-ELF binary.
Common situations: Pointing the build script at a wrong file path, passing a `.ptx`/text file or an intermediate object instead of the final ELF, a compiler/linker change producing ELF32 output, or the ELF being cut off by a failed write/read upstream.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Unexpected key `{}`. Expected `type`, `data`, `arguments`, `
- Unexpected key `{}`, expected `repr` or `space
- Could not guess if `{}` is a read or write argument. Name sh
AI-assisted analysis of vosen/ZLUDA@9c8b43f242 (2026-09-06).
Data as JSON: /api/errors/49db5cbd4f3075ce.
Report an issue: GitHub.