Mach-O: Register the LC_FUNCTION_STARTS entries as function hints - #754
Mach-O: Register the LC_FUNCTION_STARTS entries as function hints#754zardus wants to merge 1 commit into
Conversation
|
THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS Validation record for head Re-keyed from Measured configuration: a detached worktree of cle at the revision named, archinfo at
What the entries are, and why this is a hint source of its own rather than a symbol table. Measured on a GHC-produced x86-64 Removed rather than re-keyed. The The merge order itself is unchanged and does not rest on those numbers. angr/angr#6861 reads Caveats: the address is recorded as the linked virtual address and rebased with the object, matching the ELF FDE hints; a 32-bit ARM Mach-O records the Thumb bit in the entry, which this branch passes through untouched. Hosted CI at head Re-keyed 2026-09-04. Head is now The Hosted CI at this head, read live 2026-09-04: 20 terminal checks, every one |
|
Corpus decompilation diffs can be found at angr/dec-snapshots@master...angr/cle_754 |
b987439 to
95b7c8f
Compare
95b7c8f to
fb669d6
Compare
|
THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS Corpus measurement for this change, on AArch64 Mach-O. This is the whole affected population rather than a sample: all 21 objects that show the symptom, out of 686 that carry Denominators are fixed by the files and were checked per object to be identical across configurations. 1,192 of 1,195 removed, 99.7%, and eighteen of the twenty-one objects go to zero. On the oracle, since it matters here: the Three things belong with the headline.
Correction, after taking those 34 to mechanism. The original text above claimed all 34 as a real regression. That overstates it. On the master side 27 of the 34 were already in The 6 are lost in One object regresses, from 1 instance to 3, with This masks angr/angr#6836 rather than fixing it. Under master, 1,031 of the 1,195 instances (86.3%) have a swallowing block that begins in Of the added functions, 5,330 of 5,635 (94.6%) are in Oracle hazards were cleared rather than assumed: 0 of 1,195 flagged addresses are in an The pin and current master differ slightly on neighbouring metrics here, unlike the ELF case, but Objects are from a non-public corpus; counts and shapes only. |
fb669d6 to
46cf6a4
Compare
|
THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS Full function-hint report for Before — the table is parsed and then discarded, so the object exposes no hints: cle at the merge base, 929991dAfter — all 36 entries are registered under the new source, and each one lands inside with this change, 4be4ea5 |
e374a46 to
4be4ea5
Compare
The backend parses LC_FUNCTION_STARTS into lc_function_starts and then uses it for nothing, so a Mach-O object hands its consumer no function hints at all while an ELF one gets a hint for every FDE in .eh_frame. On a stripped image the table is the only record of where the functions begin. Each entry becomes a FunctionHint under a new FunctionHintSource.FUNCTION_STARTS. It is a source of its own rather than an export or an unwind record because ld64 records the address of every atom it placed in an executable section, and a producer's data atoms -- a Haskell closure's info table, a Swift offset table -- are atoms like any other, so the consumer has to be able to tell this table apart from one that names only functions. No size is recorded. The distance to the next entry is not a function length: one function can hold several atoms, and a consumer that reads the gap as a size gets a boundary the file never stated.
4be4ea5 to
1bdd501
Compare
|
THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS Closing this: cle#810 landed the same change on 2026-09-04 as Master now has Rebasing was how that got established rather than assumed. The only conflict is the enum line, and resolving it leaves this branch's The one thing that did carry: cle#789 numbers its new |
THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS
Problem
A Mach-O object hands its consumer no function hints at all, while an ELF one gets a hint for every FDE in
.eh_frame. Ontests/aarch64/dyld_ios15.machothe backend decodes the wholeLC_FUNCTION_STARTStable and then reports nothing:On a stripped image that table is the only record of where the functions begin, so a consumer seeding on
Backend.function_hintsstarts from nothing on every Mach-O.Root cause
MachO._load_lc_function_startsdecodes the ULEB deltas intoself.lc_function_startsand nothing reads that list afterwards.Backend.__init__setsself.function_hints: list[FunctionHint] = []and the Mach-O constructor never appends to it, soBackend.__getstate__and every consumer see the empty list.FunctionHintSourcealso had no member such a hint could carry:Fix
_register_function_start_hintsturns each entry into aFunctionHintunder a newFunctionHintSource.FUNCTION_STARTS, called from the constructor beside_parse_mod_funcs. It is a source of its own rather than an export or an unwind record because ld64 records every atom it placed in an executable section, data atoms included, so a consumer has to be able to tell this table from one that names only functions. No size is recorded — the distance to the next entry is not a function length — so each hint is built asFunctionHint(address, 0, FunctionHintSource.FUNCTION_STARTS).All 36 entries then arrive as hints, and every one lands inside
__TEXT,__textat0x100006ebc, size0x998:Testing
test_function_starts_hintsasserts[h.addr for h in hints] == macho.lc_function_startsontests/aarch64/dyld_ios15.macho, that there are 36 of them, and that each falls inside the bounds of__TEXT,__text. It fails on the merge base, where the list is empty.Land this before angr/angr#6861, which decides which entries to use and reads the hint source added here. Landing this half on its own is not neutral either: angr master's
_load_func_addr_and_names_from_hintsadmits every hint source exceptEH_FRAME, so the newFUNCTION_STARTSentries become definite function starts the day this merges, with none of the validation the angr half adds — the defect that pull request's Problem section measures ontests/armhf/FileProtection-05.armv7.macho. Land the two together, or this one first and the angr one straight after.Fixes #750. Validation: #754 (comment)
sync: angr/angr#6861
session: sharpen