mirror of
https://github.com/morluto/rea.git
synced 2026-10-31 20:06:14 +00:00
* feat(ghidra): admit 32-bit big-endian PowerPC ELF Recognize EM_PPC as a provider-neutral `powerpc` family that keeps its ELF class, byte order, type and flags, and admit ELF32 big-endian ET_EXEC through a bounded Ghidra lane. ELF64, little-endian, relocatable/shared objects and EF_PPC_EMB are refused with a specific reason; Hopper and IDA do not gain PowerPC support, and Windows Ghidra P0 is unchanged. Ghidra's ELF loader selects PowerPC:BE:32:e500:default for a plain EM_PPC header, which misreads 750-family code. The lane binds PowerPC:BE:32:default/default in the profile (language_selection "admitted-lane-v1"), imports with it and checks the reported language. A language set through REA_GHIDRA_LANGUAGE_ID still replaces the lane default. Add a source-owned fixture, fixed-encoding probe, GNU readelf cross-check and the optional `verify:ghidra:ppc` real-provider lane, plus docs/ghidra-ppc.md. Refs #1741 * style(ghidra): format shared PowerPC profile integration * fix(ghidra): preserve caller-selected PowerPC languages --------- Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
63 lines
1.9 KiB
JavaScript
63 lines
1.9 KiB
JavaScript
import { execFile } from "node:child_process";
|
|
import { createHash } from "node:crypto";
|
|
import { readFile } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { promisify } from "node:util";
|
|
|
|
const execute = promisify(execFile);
|
|
|
|
/** Build a source-owned freestanding ELF; never execute its target code. */
|
|
export async function buildPowerPcFixture(directory) {
|
|
const compiler = process.env.REA_PPC_CLANG ?? "clang";
|
|
const target = "powerpc-unknown-linux-gnu";
|
|
const source = fileURLToPath(new URL("../c/ppc.c", import.meta.url));
|
|
const probe = fileURLToPath(new URL("./ppc-probe.S", import.meta.url));
|
|
const path = join(directory, `${target}.elf`);
|
|
const args = [
|
|
`--target=${target}`,
|
|
// A 750-family core with the classic FPU, unlike the e500 SPE variant.
|
|
"-mcpu=750",
|
|
"-fno-pic",
|
|
"-fuse-ld=lld",
|
|
"-nostdlib",
|
|
"-static",
|
|
"-O0",
|
|
"-g",
|
|
"-Wl,-e,rea_ppc_entry",
|
|
"-Wl,--build-id=none",
|
|
source,
|
|
probe,
|
|
"-o",
|
|
path,
|
|
];
|
|
const version = await execute(compiler, ["--version"], { timeout: 10000 });
|
|
await execute(compiler, args, { timeout: 60000 });
|
|
const bytes = await readFile(path);
|
|
if (
|
|
bytes.length < 52 ||
|
|
bytes.toString("hex", 0, 4) !== "7f454c46" ||
|
|
bytes[4] !== 1 ||
|
|
bytes[5] !== 2 ||
|
|
bytes.readUInt16BE(16) !== 2 ||
|
|
bytes.readUInt16BE(18) !== 20 ||
|
|
bytes.readUInt32BE(36) !== 0
|
|
)
|
|
throw new Error(
|
|
"Compiler did not produce the declared ELF32 big-endian PowerPC fixture",
|
|
);
|
|
return {
|
|
path,
|
|
flags: bytes.readUInt32BE(36),
|
|
sha256: createHash("sha256").update(bytes).digest("hex"),
|
|
source_sha256: createHash("sha256")
|
|
.update(await readFile(source))
|
|
.digest("hex"),
|
|
probe_sha256: createHash("sha256")
|
|
.update(await readFile(probe))
|
|
.digest("hex"),
|
|
compiler: version.stdout.trim(),
|
|
arguments: args,
|
|
};
|
|
}
|