{"record":{"id":"e28cad677a9768c8","repo":"jdx/mise","slug":"unexpected-elf-e-phentsize-e-phentsize","errorCode":null,"errorMessage":"unexpected ELF e_phentsize {e_phentsize}","messagePattern":"unexpected ELF e_phentsize (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/packages/brew/elf.rs","lineNumber":114,"sourceCode":"    b[off..off + 8].copy_from_slice(&v.to_le_bytes());\n}\n\n#[derive(Clone, Copy)]\nstruct Phdr {\n    p_type: u32,\n    p_offset: u64,\n    p_vaddr: u64,\n    p_filesz: u64,\n    p_memsz: u64,\n    p_align: u64,\n}\n\nfn read_phdrs(content: &[u8]) -> Result<Vec<Phdr>> {\n    let e_phoff = rd_u64(content, 32)? as usize;\n    let e_phentsize = rd_u16(content, 54)? as usize;\n    let e_phnum = rd_u16(content, 56)? as usize;\n    if e_phentsize != PHDR_SIZE {\n        bail!(\"unexpected ELF e_phentsize {e_phentsize}\");\n    }\n    if e_phnum >= 0xffff {\n        bail!(\"ELF uses PN_XNUM program header counts\");\n    }\n    let mut phdrs = Vec::with_capacity(e_phnum);\n    for i in 0..e_phnum {\n        let off = e_phoff + i * PHDR_SIZE;\n        phdrs.push(Phdr {\n            p_type: rd_u32(content, off)?,\n            p_offset: rd_u64(content, off + 8)?,\n            p_vaddr: rd_u64(content, off + 16)?,\n            p_filesz: rd_u64(content, off + 32)?,\n            p_memsz: rd_u64(content, off + 40)?,\n            p_align: rd_u64(content, off + 48)?,\n        });\n    }\n    Ok(phdrs)\n}","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/packages/brew/elf.rs#L96-L132","documentation":"The ELF patcher parses the program header table using the standard 64-bit ELF entry size (PHDR_SIZE, 56 bytes) only. If e_phentsize in the ELF header differs, the parser cannot safely index the table, so read_phdrs bails instead of reading garbage. This protects patch/read_linkage from corrupting binaries laid out with non-standard program header entries.","triggerScenarios":"Calling elf::patch, read_linkage, or the test helpers on an ELF whose e_phentsize is not 56 — e.g. a 32-bit ELF (though those are skipped earlier), an unusual linker's output, or a corrupted/truncated file whose header bytes were misread.","commonSituations":"Bottling or relinking a binary produced by an exotic toolchain or packer; processing a corrupted or deliberately malformed ELF; feeding a stripped/rewritten binary that altered header fields.","solutions":["Verify the binary is a normal 64-bit LE ELF (readelf -l) and rebuild it with the standard toolchain if e_phentsize is non-standard.","Re-download or re-extract the bottle/binary — the file may be corrupted.","Handle the error: the patcher intentionally refuses such files; skip or fall back to an external tool like patchelf for them."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// check before patching\nlet e_phentsize = u16::from_le_bytes([content[54], content[55]]);\nif e_phentsize != 56 { /* skip or use fallback tool */ }","typeGuard":"fn has_standard_phdr_entry_size(elf: &[u8]) -> bool {\n    elf.len() > 56 && u16::from_le_bytes([elf[54], elf[55]]) == 56\n}","tryCatchPattern":"match elf::patch(&mut content, &opts, &path) {\n    Err(e) if e.to_string().contains(\"e_phentsize\") => {\n        warn!(\"{}: non-standard ELF layout, skipping\", path.display());\n    }\n    other => other?,\n}","preventionTips":["Only process binaries built by the standard 64-bit toolchain.","Validate bottle integrity (checksums) before relocation.","Treat the ELF patcher as best-effort: skip unsupported files rather than force-patching."],"tags":["elf","binary-parsing","brew","linux"],"backgroundTag":"invalid-argument-format","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}