refactor(elf): centralize fixed header type and flags decoding

This commit is contained in:
morluto committed 2026-10-26 13:53:25 +08:00
1 parent 991a240606
commit 941838fdd9
6 files changed
+22 -12

No files matched your search

+2 -2
View File
@@ -84,8 +84,8 @@ export const readMipsElfMetadata = async (
fixedHeader.value.elfClass !== 32 ||
fixedHeader.value.byteOrder !== metadata.byteOrder ||
fixedHeader.value.machine !== 8 ||
u16(bytes, 16) !== metadata.type ||
u32(bytes, 36) !== metadata.flags
fixedHeader.value.type !== metadata.type ||
fixedHeader.value.flags !== metadata.flags
)
return err("MIPS ELF header no longer matches the resolved identity");
if (fixedHeader.value.headerSize !== 52)
+4 -8
View File
@@ -390,22 +390,18 @@ const parseElf = (
): Result<ExecutableMetadata, string> => {
const fixedHeader = readElfFixedHeader(bytes, fileSize);
if (!fixedHeader.ok) return fixedHeader;
const { elfClass, byteOrder, architecture } = fixedHeader.value;
const little = byteOrder === "little";
const { elfClass, byteOrder, architecture, type, flags } = fixedHeader.value;
if (architecture === null) return err("unsupported ELF architecture");
if (
architecture === "mips" ||
architecture === "riscv" ||
architecture === "powerpc"
) {
const flagsOffset = elfClass === 32 ? 36 : 48;
const metadata: ElfFamilyMetadata = {
elfClass,
byteOrder: little ? "little" : "big",
type: little ? bytes.readUInt16LE(16) : bytes.readUInt16BE(16),
flags: little
? bytes.readUInt32LE(flagsOffset)
: bytes.readUInt32BE(flagsOffset),
byteOrder,
type,
flags,
};
if (architecture === "powerpc")
return ok({
+10
View File
@@ -11,6 +11,14 @@ it.each([
"reads common fixed header commitments for %s",
(_name, cls, data) => {
const bytes = elf(cls, data, cls === 1 ? 3 : 62);
const flagsOffset = cls === 1 ? 36 : 48;
if (data === 1) {
bytes.writeUInt16LE(0xfe01, 16);
bytes.writeUInt32LE(0x89abcdef, flagsOffset);
} else {
bytes.writeUInt16BE(0xfe01, 16);
bytes.writeUInt32BE(0x89abcdef, flagsOffset);
}
expect(readElfFixedHeader(bytes)).toEqual({
ok: true,
value: {
@@ -18,6 +26,8 @@ it.each([
byteOrder: data === 1 ? "little" : "big",
headerSize: cls === 1 ? 52 : 64,
machine: cls === 1 ? 3 : 62,
type: 0xfe01,
flags: 0x89abcdef,
osAbi: 0,
architecture: cls === 1 ? "x86" : "x86_64",
},
+4
View File
@@ -15,6 +15,8 @@ export interface ElfFixedHeader {
readonly byteOrder: "little" | "big";
readonly headerSize: number;
readonly machine: number;
readonly type: number;
readonly flags: number;
readonly osAbi: number;
readonly architecture: ElfArchitecture | null;
}
@@ -68,6 +70,8 @@ export const readElfFixedHeader = (
byteOrder: littleEndian ? "little" : "big",
headerSize,
machine,
type: readU16(16),
flags: readU32(elfClass === 32 ? 36 : 48),
osAbi: bytes[7]!,
architecture: elfArchitecture(machine) ?? null,
});
+1 -1
View File
@@ -93,7 +93,7 @@ export const readElfHeader = (
return { failure: { reason: "unsupported ELF byte order" } };
if (fixedHeader.value.headerSize !== headerBytes)
return { failure: { reason: "unsupported ELF header size" } };
const e_type = reader.u16(0x10);
const e_type = fixedHeader.value.type;
if (e_type !== 1 && e_type !== 2 && e_type !== ET_DYN)
return { failure: { reason: "unsupported ELF type" } };
const e_shoff = is64 ? reader.u64(0x28) : reader.u32(0x20);
+1 -1
View File
@@ -327,7 +327,7 @@ export const parseElfNotes = (
header.elfClass,
);
const wide = header.elfClass === 64;
const type = reader.u16(16);
const type = header.type;
const phoff = reader.word(wide ? 32 : 28);
const shoff = reader.word(wide ? 40 : 32);
const phentsize = reader.u16(wide ? 54 : 42);