This is a continuation of the closed topic at Pre-RFC: Defining function aliases .
An alias is a second name for a function or global variable that is defined in the same object file. Because it's a second name for the same memory, it does not have its own address, rather a pointer to it and to the other name must compare equal.
These are useful in certain low-level systems programming circumstances when you have to define or use an interface like IRQ tables or similar (for example, a toolchain for an OS-less machine that requires a function named "irq_sio4" to be the handler for that interrupt, and is space constrained, you can use aliases to emit the empty function once and alias all the other IRQ handlers to that one).
In my case, I'm defining an interface to be used by non-Rust code, which my rust program will load via dlopen
. Part of my interface includes the stack probing symbol, which may go by different names on different platforms. I'd like to expose it in my interface under a consistent name. One apparent option is to write a wrapper function that calls __rust_probestack
but this is incorrect because stack prober does not follow the ABI of a function, and wrapping it in a function breaks the expected ABI and causes real bugs.
Aliases are an important feature for low-level systems programming, despite the fact that they aren't standardized in C or C++. In practice, ELF, Mach-O and COFF all support symbol aliases, and all production C and C++ toolchains support it either in the compiler by language extensions or in the linker with linker scripts. LLVM supports it with the @newname = alias %type, %type* @origname
syntax.
There's a related feature that I'm explicitly not asking for. In some object file formats it's possible for the alias name to have different properties (linkage, visibility, ...) than the original. Although useful I'd like to be conservative now, focus on what I know I need as a rust user and what we know all platforms support, and leave other that feature to a future enhancement request.
One possible implementation would be to place an alias("")
attribute on a declaration to indicate that this declaration is an alias of the other symbol, and require that the other symbol be defined and have matching types.
#[alias("sum")]
#[no_mangle]
pub extern "C" fn alias_of_sum(a: i32, b: i32) -> i32;