Load ARM64 and ARMNT COFF objects - #724
Conversation
|
THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS Validation record for head
Reproducer, using clang 21.1.8 rather than a fixture so it can be rerun from source: On the baseline that last line raises
The bit patterns follow lld-link's Caveats:
Corpus measurement of the open queue, 2026-08-15 — a prerequisite, not an independent recoveryCorrecting the record. The open pull-request queue was scored against 733 objects drawn from a sweep's own failing units (35 error classes, 49 architectures, 16 containers), with each repository's current master as the baseline rather than the revisions the sweep pinned. Each object is loaded with The class here is
Alone, all 24 move from So the corpus effect of this change is real but conditional, and the record should say so: this PR is a prerequisite for the class rather than a change that clears any of it by itself. Loading is a separate claim from analysis, and the loading claim above — that |
|
Corpus decompilation diffs can be found at angr/dec-snapshots@master...angr/cle_724 |
b1b16c3 to
6551c7a
Compare
The COFF backend rejected every machine type but I386 and AMD64. CoffParser raised NotImplementedError, which is not a CLEError, and Coff.is_compatible applied the same two-machine filter, so autodetection never reached the backend either and loading an ARM64 or ARMNT object ended in "Unable to find a loader backend". Both are ordinary output of Windows-on-ARM toolchains, and archinfo resolves both to the architectures the PE backend already uses for them. Both are accepted now. The machine check and is_compatible read the same COFF_MACHINE_TO_ARCH_NAME table, and an unsupported machine raises CLECompatibilityError naming the type it rejected instead of NotImplementedError naming nothing. Accepting the header alone does not make the object useful, so this also implements the relocation types those objects carry. ADDR32, ADDR32NB, ADDR64, REL32, SECREL and SECTION are the patch shapes the existing classes already handle. BRANCH26, PAGEBASE_REL21 and PAGEOFFSET_12A/12L patch an immediate field inside a single ARM64 instruction, and MOV32T and BRANCH24T patch the two halfwords of a Thumb-2 instruction. ARMNT code is Thumb-2 only, so function symbols carry the Thumb bit the way CLE already reports Thumb code elsewhere, and so do the extern stubs that stand in for undefined functions. Nothing in the object states this, so without it every function address the backend reports is an ARM address. ADDR32NB and ADDR64 ignored the addend held in the field they patch, unlike DIR32, DIR32NB and REL32 beside them. The .pdata of the x86_64 object in the binaries repository shows the cost: the second ADDR32NB of a RUNTIME_FUNCTION record holds the function's end offset as its addend, so BeginAddress and EndAddress were relocated to the same address. Both apply the addend now, which the ARM64 objects need as well. The tests load the ARM64, ARMNT and R4000 objects the binaries repository now carries, relocate each one through cle.Loader and decode the patched fields back out, rather than assembling a COFF container of their own. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
6551c7a to
42ac276
Compare
THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS
The COFF backend accepted only I386 and AMD64, so an ARM64 or ARMNT object failed
autodetection with "Unable to find a loader backend", and naming the backend
raised
NotImplementedError, which is not aCLEError.Both load now, with the relocation types those objects carry. ARMNT code is
Thumb-2 only, so its function symbols and extern stubs carry the Thumb bit.
ADDR32NBandADDR64also apply the addend held in the patched field, whichx86_64
.pdataneeded already: without it aRUNTIME_FUNCTIONgot the samebegin and end address.
The regression tests load the ARM64, ARMNT and R4000 COFF objects that
angr/binariesmaster already carries, rather than assembling a container oftheir own, so nothing here waits on a fixture change.
angr.Projecton theseobjects additionally needs a Win32 syscall convention angr lacks for AArch64 and
ARM; that gap is not addressed here and
cle.Loaderis unaffected.Validation: #724 (comment)