-
Notifications
You must be signed in to change notification settings - Fork 201
FrameLayoutChange-based .eh_frame support #902
FrameLayoutChange-based .eh_frame support #902
Conversation
cranelift-faerie/src/backend.rs
Outdated
reg_info: RegInfo, | ||
} | ||
|
||
impl<'a> DwarfRegMapper<'a> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mentioned this on irc a few days ago but DwarfRegMapper
could arguably live in cranelift-codegen as it's fundamentally an int->int
function, and doesn't need to return a gimli::Register
. This and CFIEncoder
might also make sense in cranelift-module
as they are, pulling in a gimli
dependency there and not in cranelift-codegen
. @yurydelendik would cranelift-module
be a useful place to share this logic translating FrameLocationChange
to CFI instructions for your use in wasmtime?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Issue #729 is about the register mapping.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've moved this to cranelift-module
and noted some reasoning in that issue. I'll leave this unresolved until we decide here or there what to do with DwarfRegMapper
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yurydelendik would cranelift-module be a useful place to share this logic translating FrameLocationChange to CFI instructions for your use in wasmtime?
@iximeow yes, and in fact, I would like to have entire cratelift-module change for other reasons.
cranelift-faerie/src/backend.rs
Outdated
gimli::Encoding { | ||
format: gimli::Format::Dwarf32, | ||
version: 1, | ||
address_size: 4, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This probably should be 8. Not sure if it will be used for the data you are writing though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should only be 8 on x86_64.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had definitely misunderstood the point of the address_size
field here to be "size of an encoded pointer", rather than "size of a pointer for the target ISA". I'll make this pick the right size for the target.
4 and the asserts later about address size/pointer encoding, are a relic of trying to match CIE bytes I'd known work, in tracking down a crash in libgcc
. In reality, I eventually figured out the issue I'd had is that libgcc
doesn't handle escaped length fields in 64-bit DWARF, so I just tried absptr
encodings and it still works fine! 🎉
I ought to add a note about why this specifically uses Dwarf32
regardless of architecture - in other places I at least wanted to at least comment about architecture-specific magic values, so format
deserves a Do not change this!
mention.
Thinking through my confusion with the meaning of this and the write_eh_pointer
argument, it seems like write_eh_pointer
ought to not take address_size
as a parameter. Since it only matters for absolute pointer encodings, I think it could work better to provide address_size
as a field of an absptr
variant for DwEhPe
? Then it would be clear just from the function signature that the implementer is to write an address matching the encoding, and that gimli
is not making assumptions about the number of bytes that would be written via address_size
. If that sounds interesting, I can sketch out a PR to gimli to try that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Encoding::address_size
field is used for all DWARF, where the normal format of an address is an unencoded pointer. .eh_frame
is different from DWARF in that it encodes pointers, but even then it can't be the encoded pointer size because it is possible to use multiple encodings of different sizes.
DwEhPe
is used to represent the constants, so it can't be changed. The size
parameter to write_eh_pointer
is documented as only being used for absolute pointers. I'm not sure we can do better than that. Maybe renaming the parameter to absolute_address_size
would be worthwhile.
We may want to add a check in gimli to ensure you don't write .eh_frame
with Dwarf64
, since the LSB requires 32-bit length fields.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉
Next step will be running user code during cleanup.
.link_with( | ||
faerie::Link { | ||
to: name, | ||
from: ".eh_frame", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this __eh_frame
for machO?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good question, I'll at least see what other toolchains name it. I also need to use a machO-appropriate relocation.
|
||
frame_sink.add_fde(cie, fd_entry); | ||
} else { | ||
// we have a frame sink to write .eh_frames into, but are not collecting debug |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please panic here to make it easier to debug in that case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realized this morning that there's a case where we will reach this arm but not be a bug: if the user of cranelift has a per-function nounwind
-like attribute, a nounwind
function wouldn't need unwind information collected, even though there still would be a frame sink for other functions. Right now it happens to be that Lucet is all-or-nothing on unwind info, but as a rustc backend for example I could see some function being opt-out.
Given that, would you rather a panic to identify the case for later discussion, or should I discard the else
entirely?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but as a rustc backend for example I could see some function being opt-out.
I believe unwinding enabled/disabled is done per crate (using -Cpanic=abort
), not per function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rustc has the unstable #[unwind(allowed/aborts)]
to control per function, as well I think it has different requirements for extern "C"
, but I don't know the details of that and it is under ongoing discussion.
ac21f47
to
9ac709e
Compare
// we need to retain function names to hand out usize identifiers for FDE addresses, | ||
// which are then used to look up function names again for relocations, when `write_address` is | ||
// called. | ||
fn_names: Vec<String>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ModuleContents
does already contain something like this, not sure if it is worth trying to reuse that, but maybe FuncId::as_u32
can be the identifier.
some x86-ism magic numbers are still present, but they at least should be suboptimal (rather than invalid) for non-x86 architectures.
73e2a03
to
b1c81fd
Compare
Thanks for the PR again, and as a procedural note the Cranelift repository has now merged into the wasmtime repository. PRs are no longer landing in this repository, and unfortunately there's no "one button" solution to move a PR to the wasmtime repository. A script has been prepared, however, to assist you in transferring this PR to the wasmtime repo. Feel free to reach out on Zulip with any questions! |
This teaches
cranelift-faerie
how to write.eh_frame
sections that are appropriate with respect to call frames for functions that produce layout information.This builds quite directly on #679, which is still open, and whose changes are alongside this as a result. For the time being, my changes on top of @yurydelendik 's PR are best seen as a diff between our branches.
Being dependent on an already-floating PR, I want to mostly call attention to the points that:
I do have some comments in-line in case any readers do take a closer look at the changes here, but I'm not sure it makes sense to sweat the details until #679 is figured out, since it seems like we've bitrotted with respect to today's
master
anyway.