mirror of
https://github.com/morluto/rea
synced 2026-10-28 06:46:47 -04:00
refactor(elf): carry parsed header facts into native consumers
This commit is contained in:
@@ -92,15 +92,13 @@ const baseLimitations = (): Limitations => [
|
||||
];
|
||||
|
||||
const headerFacts = (
|
||||
bytes: Buffer,
|
||||
image: BinaryContainer,
|
||||
image: Extract<BinaryContainer, { format: "elf" }>,
|
||||
): Pick<Report, "format" | "byte_order" | "machine" | "type" | "type_name"> => {
|
||||
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",
|
||||
|
||||
@@ -142,6 +142,7 @@ export type BinaryContainer = BinaryContainerFacts &
|
||||
readonly format: "elf";
|
||||
readonly elf: {
|
||||
readonly machine: number;
|
||||
readonly type: number;
|
||||
readonly dynamicSegments: readonly ElfDynamicSegment[];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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<BinaryContainer, { format: "elf" }> => {
|
||||
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",
|
||||
|
||||
@@ -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<NativeReadRequest, NativeSectionDirectory, Buffer> {
|
||||
): Generator<NativeReadRequest, ElfSectionDirectory, Buffer> {
|
||||
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) {
|
||||
|
||||
Reference in New Issue
Block a user