-
-
Notifications
You must be signed in to change notification settings - Fork 14.8k
Implement core::arch::return_address and tests
#154972
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -76,3 +76,30 @@ pub macro global_asm("assembly template", $(operands,)* $(options($(option),*))? | |
| pub fn breakpoint() { | ||
| core::intrinsics::breakpoint(); | ||
| } | ||
|
|
||
| /// The `core::arch::return_address!()` macro returns a pointer with an address that corresponds to the caller of the function that invoked the `return_address!()` macro. | ||
| /// The pointer has no provenance, as if created by `core::ptr::without_provenance`. It cannot be used to read memory (other than ZSTs). | ||
| /// | ||
| /// The value returned by the macro depends highly on the architecture and compiler (including any options set). | ||
| /// In particular, it is allowed to be wrong (particularly if inlining is involved), or even contain a nonsense value. | ||
| /// The result of this macro must not be relied upon for soundness or correctness, only for debugging purposes. | ||
| /// | ||
| /// As a best effort, if a useful value cannot be determined (for example, due to limitations on the current codegen), | ||
| /// this macro tries to return a null pointer instead of nonsense (this cannot be relied upon for correctness, however). | ||
| /// | ||
| /// Formally, this function returns a pointer with a non-deterministic address and no provenance. | ||
| /// | ||
| /// This is equivalent to the gcc `__builtin_return_address(0)` intrinsic (other forms of the intrinsic are not supported). | ||
| /// Because the operation can be always performed by the compiler without crashing or causing undefined behaviour, invoking the macro is a safe operation. | ||
| /// | ||
| /// ## Example | ||
| /// ``` | ||
| /// # #![cfg(not(miri))] // FIXME: Figure out how to make miri work before stabilizing this macro | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Miri should probably just pick an arbitrary 64bit integer and return that? Or is that too adversarial and we should return null?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It probably should (though I see it doing either). Right now, I'd like something landed though. My plan is to figure out miri (and codegen_gcc) before stabilization.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (I suppose we could briefly discuss whether it is "fine" to return just null tomorrow)
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's more of a Miri thing than an opsem thing so I'd prefer to discuss that in the PR which implements it.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair. In any case, the main thing a random implementation would detect is someone doing a null test, then some form of stupid shenanigans like transmuting to a function pointer and calling it (or |
||
| /// #![feature(return_address)] | ||
| /// | ||
| /// let addr = core::arch::return_address!(); | ||
| /// println!("Caller is {addr:p}"); | ||
| /// ``` | ||
| #[unstable(feature = "return_address", issue = "154966")] | ||
| #[allow_internal_unstable(core_intrinsics)] | ||
| pub macro return_address() {{ core::intrinsics::return_address() }} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| //@ ignore-wasm | ||
|
|
||
| #![crate_type = "lib"] | ||
| #![feature(core_intrinsics, return_address)] | ||
|
|
||
| // CHECK-LABEL: @call_return_address_intrinsic | ||
| #[no_mangle] | ||
| #[inline(never)] | ||
| pub fn call_return_address_intrinsic() -> *const () { | ||
| // CHECK: call ptr @llvm.returnaddress(i32 0) | ||
| core::intrinsics::return_address() | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.