I have a rust project in which I need to define a symbol (presumably a top-level
static, see below) with a very specific name. However, even with
#[no_mangle] cargo/rustc seems to mangle the name a little bit, by prepending
_. So if I need the symbol
foo, it gets mangled to
I need that mangling to stop, ideally for only that symbol so as not to disturb anything else. How can I deactivate it?
A bit of background: I need to compile the project to work in a C environment which requires a global symbol to be defined with a certain name (and as a C
int. So far my
pub static mut FOO: std::os::raw::c_int; declaration seems to come closest to what I need).
The environment doesn't actually do anything with the symbol, it just requires the its presence.
no_mangle should do exactly that, I'm not sure why you're seeing the behavior you're seeing. What platform are you on?
You can also use the
#[link_name = "__GPIOA"] pub static mut GPIOA: gpio::Block;
__GPIOA is the unmangled symbol name.
OS X 10.10 and
rustc 1.12.0-nightly (9316ae515 2016-07-24). However it also happens with stable
rustc 1.10.0 (cfcb716cf 2016-07-03).
@japaric: I found that out about half an hour ago from the rust manual, but when I use that e.g.
#[link_name = "foo"]
pub static mut foo: c_int = 0;
I get the exact same end result i.e.
foo gets mangled to
Interesting problem. It's hard-coded into Rust that on OS X symbol names are prefixed with
_. Funny this has never come up as a problem before. I can't think of a workaround off hand that doesn't require working in a non-Rust language, but one hack that would work and be portable would be to define it as a wrapper function in assembly or C (just on OS X) that calls into the Rust function.
Can you file a bug about this?
I it rustc or llvm that's doing this?
In the latter case,
#[link_name = "\1foo"] might work better.
@brson I just submitted it, you can find it here.
@vadimcn I just tried your suggestion, however
rustc rejects it:
src/lib.rs:8:17: 8:18 error: unknown character escape: 1 src/lib.rs:8 #[link_name = "\1foo"] ^ error: aborting due to previous error error: Could not compile 'emm'.
@jjpe: sorry, the syntax should have been this:
#[link_name = "\x01foo"].
#[link_name] attribute only works on "extern" functions, so you can ignore my suggestion.
By the way, are you sure that your C environment actually requires the underscore to be omitted? On OS X, this should only be the case if it uses the
asm GNU extension (or actual assembly files); normal C symbols get the underscore, and
dlsym prepends it to the requested name.
@vadimcn Yeah @alexcrichton mentioned this on GitHub. I tried it but it turns out not to be what I need. Thanks anyway for the suggestion though, this might come in handy some day.
@comex Turns out that
#[no_mangle] works properly after all, see the github bug page for details. But Emacs still refuses to load it, suggesting it may be an issue at that side.