Repository navigation
Conversation
…tions A concrete function instance (DW_AT_abstract_origin) can take different arguments than its source declaration: GCC's .isra, .constprop, and .part clones remove, reorder, or replace parameters. Rebuild the signature of such an instance from where each parameter is at its entry PC instead of from the declaration, mapping DWARF registers to the platform's argument slots. A register-sized scalar on the stack (DW_OP_fbreg from a CFA frame base, or the stack pointer at entry) takes the stack argument slot after the argument registers, past any space reserved for them (Win64). A passed slot with no DIE becomes an unnamed gap, and a parameter GCC removed (DW_OP_GNU_parameter_ref, including a location list made only of such entries that does not cover the entry PC) takes no slot. When a parameter was removed, unnamed placeholders pad the signature to the source parameter count, since DWARF only gives a lower bound on the clone's arity: a trailing replacement piece can be passed with no DIE and no call-site parameter describing it. Anything that cannot be placed with confidence keeps the existing behavior: aggregates or misaligned values on the stack, pieces, constants, a parameter without a location at entry, a possibly aggregate return (resolved through abstract origins and specifications), split functions, unreadable attributes or expressions, and architectures other than x86-64.
ElykDeer
requested changes
Nov 10, 2026
ElykDeer
left a comment
Member
There was a problem hiding this comment.
The general shape here is good, but it's got some rough edges.
- You've hardcoded
X86_64_DWARF_REGISTERS, when gimli hasgimli::X86_64::name_to_register()/register_name()that'll let you resolve that for all(?) architectures we care about, and be resilient to spec changes. This is probably the most important to address. - The raw stack offset can flow to this index iteration here and potentially cause a very large allocation. Add a setting to filter very large offsets? Or just choose something reasonable and document it?
- You added a member variable to
DebugInfoBuilderContextwhich should probably be initialized in the constructor rather than an optional extra call which could get missed and silently disable reconstruction some time in the future. - This is mostly a style note, caused me to raise an eyebrow so figured I'd mention it: You made a
has_attributewhich translates result values rather than using them directly. See how we handle similar patterns here and here. Clippy doesn't catch this one, so I don't think it needs to change. That said, clippy pedantic+nursery find a few other things you might want to consider. - One last finding from my bot that I wasn't able to verify: it seems convinced that with enough normal parameters followed by a floating point value, this code will place it on the stack rather than through the correct register. You may need to check the type's encoding to see if it can be passed on the stack.
Another design question: is it worth retaining the original arguments, or should this run and overwrite those so we only have one list to query/maintain?
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
GCC's .isra, .constprop and .part clones can drop, reorder or replace parameters, but their DWARF entries point back (DW_AT_abstract_origin) to the original declaration. We used that declaration's parameter list, so every parameter after a dropped one was assigned to the wrong register.
This change rebuilds a clone's signature from where each parameter actually arrives at the function's entry point. The DWARF register numbers are mapped to the platform's argument registers. In the result:
Anything that can't be placed with confidence keeps the current behavior:
Example: _set_status_v2.isra.0 in Xen 4.20 (xen-syms, 0xffff82d0402212d0). GCC dropped rd, the third parameter, so everything after it moved up one register.
before: int(shah, status, struct domain* rd, struct active_grant_entry* act, int readonly, int mapflag, domid_t ldomid)
rdi rsi rdx ✗ rcx ✗ r8 ✗ r9 ✗ stack ✗
after: int(shah, status, struct active_grant_entry* act, int readonly, int mapflag, domid_t ldomid, uint64_t arg7)
rdi rsi rdx ✓ rcx ✓ r8 ✓ r9 ✓ placeholder
The body now reads act->pin from rdx as a struct active_grant_entry. Before, that register was named rd and typed as a struct domain*.