Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get the return address of a function?

Tags:

rust

llvm

I am writing a Rust library containing an implementation of the callbacks for LLVM SanitizerCoverage. These callbacks can be used to trace the execution of an instrumented program.

A common way to produce a trace is to print the address of each executed basic block. However, in order to do that, it is necessary to retrieve the address of the call instruction that invoked the callback. The C++ examples provided by LLVM rely on the compiler intrinsic __builtin_return_address(0) in order to obtain this information.

extern "C" void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {   if (!*guard) return;   void *PC = __builtin_return_address(0);   printf("guard: %p %x PC %p\n", guard, *guard, PC); } 

I am trying to reproduce the same function in Rust but, apparently, there is no equivalent to __builtin_return_address. The only reference I found is from an old version of Rust, but the function described is not available anymore. The function is the following:

pub unsafe extern "rust-intrinsic" fn return_address() -> *const u8

My current hacky solution involves having a C file in my crate that contains the following function:

void* get_return_address() {   return __builtin_return_address(1); } 

If I call it from a Rust function, I am able to obtain the return address of the Rust function itself. This solution, however, requires the compilation of my Rust code with -C force-frame-pointers=yes for it to work, since the C compiler intrinsic relies on the presence of frame pointers.

Concluding, is there a more straightforward way of getting the return address of the current function in Rust?

edit: The removal of the return_address intrinsic is discussed in this GitHub issue.

edit 2: Further testing showed that the backtrace crate is able to correctly extract the return address of the current function, thus avoiding the hack I described before. Credit goes to this tweet.

The problem with this solution is the overhead that is generated creating a full backtrace when only the return address of the current function is needed. In addition, the crate is using C libraries to extract the backtrace; this looks like something that should be done in pure Rust.

edit 3: The compiler intrinsic __builtin_return_address(0) generates a call to the LLVM intrinsic llvm.returnaddress. The corresponding documentation can be found here.

like image 733
Elia Geretto Avatar asked Mar 05 '19 09:03

Elia Geretto


People also ask

How do you get an address of a function?

We can get the address of a function by just writing the function's name without parentheses. Please refer function pointer in C for details. In C/C++, name of a function can be used to find address of function.

Is it possible to return address from a function?

We can pass pointers to the function as well as return pointer from a function. But it is not recommended to return the address of a local variable outside the function as it goes out of scope after function returns.

Where is the return address of a function stored?

The return address is pushed on the stack by the caller by means of the callq instruction. At the moment of entering the callee function it is at the top of the stack, i.e.: at that moment, rsp contains the address where the return address is stored.

How do I get a return address in stack?

On some architectures, you can find it on the stack relative to the first parameter. On ia32, for example, the parameters are pushed (in opposite order) and then a call is made that will push the return address. Remember that the stack almost always (and on ia32) grows downward.

What is the use of the address function in Excel?

The ADDRESS function in Excel is meant to exactly this. It takes the row and the column number and gives you the cell address of that specific cell. Below is the syntax of the ADDRESS function:

How to get the address of a function in C++?

We can get the address of a function by just writing the function’s name without parentheses. Please refer function pointer in C for details. In C/C++, name of a function can be used to find address of function. Writing code in comment? Please use ide.geeksforgeeks.org , generate link and share the link here.

How to look up a value and return cell address in Excel?

Lookup a value and return cell address with formula 1 Type BB into a cell, here I type BB into cell A10. See screenshot: 2 In the cell adjacent to the cell A10 (the cell you typed BB), type this formula =SMALL (IF ($A$10=$A$2:$A$8, ROW ($A$2:$A$8)-ROW ($A$2)+1), ROW (1:1)), and press Shift + Ctrl ... 3 Then you can delete #NUM!. See screenshot:

What is the difference between address and cell in Excel?

While the ADDRESS function was made specifically to give you the cell reference of the specified row and column number, there is another function that also does this. It’s called the CELL function (and it can give you a lot more information about the cell than the ADDRESS function).


1 Answers

I could not find any official documentation about this, but found out by asking in the rust-lang repository: You can link against LLVM intrinsics, like llvm.returnaddress, with only a few lines of code:

extern {     #[link_name = "llvm.returnaddress"]     fn return_address() -> *const u8; }  fn foo() {     println!("I was called by {:X}", return_address()); } 

The LLVM intrinsic llvm.addressofreturnaddress might also be interesting.

like image 122
Maurice Kayser Avatar answered Oct 07 '22 07:10

Maurice Kayser