From ba7ac7908db2c2a8e05b75df032cb175ab069669 Mon Sep 17 00:00:00 2001 From: morluto <76467478+morluto@users.noreply.github.com> Date: Mon, 26 Oct 2026 14:08:35 +0800 Subject: [PATCH] refactor(elf): carry parsed header facts into native consumers --- src/native/elf/KernelModuleParser.ts | 10 ++++------ src/native/metadata/BinaryContainer.ts | 1 + src/native/metadata/ElfImage.ts | 10 ++++++++-- src/native/metadata/NativeSectionDirectory.ts | 13 +++++++++---- 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/native/elf/KernelModuleParser.ts b/src/native/elf/KernelModuleParser.ts index fca7c650b2..ac741eb83d 100644 --- a/src/native/elf/KernelModuleParser.ts +++ b/src/native/elf/KernelModuleParser.ts @@ -92,15 +92,13 @@ const baseLimitations = (): Limitations => [ ]; const headerFacts = ( - bytes: Buffer, - image: BinaryContainer, + image: Extract, ): Pick => { - const little = image.byte_order === "little"; - const type = little ? bytes.readUInt16LE(16) : bytes.readUInt16BE(16); + const { type } = image.elf; return { format: image.bits === 64 ? "elf64" : "elf32", byte_order: image.byte_order, - machine: image.format === "elf" ? image.elf.machine : null, + machine: image.elf.machine, type, type_name: elfObjectTypeName(type), }; @@ -514,7 +512,7 @@ export const parseKernelModule = ( if (compression !== null) return unsupportedCompression(artifact, compression); const image = readElfImage(bytes); - const facts = headerFacts(bytes, image); + const facts = headerFacts(image); if (facts.type !== 1) return notApplicable(artifact, facts); const sections = image.sections.filter( (section): section is ElfSection => section.format === "elf", diff --git a/src/native/metadata/BinaryContainer.ts b/src/native/metadata/BinaryContainer.ts index dad27cfde8..c076a826cb 100644 --- a/src/native/metadata/BinaryContainer.ts +++ b/src/native/metadata/BinaryContainer.ts @@ -142,6 +142,7 @@ export type BinaryContainer = BinaryContainerFacts & readonly format: "elf"; readonly elf: { readonly machine: number; + readonly type: number; readonly dynamicSegments: readonly ElfDynamicSegment[]; }; } diff --git a/src/native/metadata/ElfImage.ts b/src/native/metadata/ElfImage.ts index 82e1209479..c48058d9ba 100644 --- a/src/native/metadata/ElfImage.ts +++ b/src/native/metadata/ElfImage.ts @@ -13,7 +13,9 @@ import { elfArchitecture } from "../../domain/elfFixedHeader.js"; import { readElfDirectoryFromBuffer } from "./NativeSectionDirectory.js"; /** Read ELF sections and file-backed program mappings without interpreting language metadata. */ -export const readElfImage = (bytes: Buffer): BinaryContainer => { +export const readElfImage = ( + bytes: Buffer, +): Extract => { const directory = readElfDirectoryFromBuffer(bytes); const { bits } = directory; const reader = new BinaryReader(bytes, directory.little); @@ -86,7 +88,11 @@ export const readElfImage = (bytes: Buffer): BinaryContainer => { } return { format: "elf", - elf: { machine: directory.machine, dynamicSegments }, + elf: { + machine: directory.machine, + type: directory.elf_type, + dynamicSegments, + }, architecture: architectureForElfMachine(directory.machine), bits, byte_order: reader.little ? "little" : "big", diff --git a/src/native/metadata/NativeSectionDirectory.ts b/src/native/metadata/NativeSectionDirectory.ts index 85c4f9f4cc..2e9b09d2fa 100644 --- a/src/native/metadata/NativeSectionDirectory.ts +++ b/src/native/metadata/NativeSectionDirectory.ts @@ -52,6 +52,11 @@ export interface NativeSectionDirectory { readonly programs: readonly ElfProgramDeclaration[]; readonly sections: readonly NativeSection[]; } +type ElfSectionDirectory = NativeSectionDirectory & { + readonly format: "elf"; + readonly elf_type: number; +}; + const STRUCTURE_BYTES = 16 * 1024 * 1024; const reject = (message: string): never => { throw new BinaryFormatFailure("malformed", message); @@ -85,7 +90,7 @@ const request = ( /** One ELF interpretation for in-memory images and bounded descriptor-backed inspections. */ export function* readElfSectionDirectory( fileSize: number, -): Generator { +): Generator { const prefix = yield request(fileSize, 0n, 16n); const headerSize = prefix[4] === 1 ? 52 : 64; const bytes = yield request(fileSize, 0n, BigInt(headerSize)); @@ -95,7 +100,6 @@ export function* readElfSectionDirectory( const { elfClass: bits, byteOrder, machine } = header; const little = byteOrder === "little"; const wide = bits === 64; - const r = new BinaryReader(bytes, little); const { offset: program_offset, width: program_width, @@ -247,10 +251,11 @@ export function* readElfSectionDirectory( return { format: "elf", elf_os_abi: header.osAbi, + elf_type: header.type, bits, little, machine, - flags: r.u32(wide ? 48 : 36), + flags: header.flags, ...(section_names_limitation === undefined ? {} : { section_names_limitation }), @@ -348,7 +353,7 @@ export function* readPeSectionDirectory( /** Borrow ELF bytes; file drivers satisfy the identical requests without loading payloads. */ export const readElfDirectoryFromBuffer = ( bytes: Buffer, -): NativeSectionDirectory => { +): ElfSectionDirectory => { const steps = readElfSectionDirectory(bytes.length); let next = steps.next(); while (!next.done) {