Completely unmangled symbol?


#1

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 _foo.
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.


#2

no_mangle should do exactly that, I’m not sure why you’re seeing the behavior you’re seeing. What platform are you on?


#3

You can also use the link_name attribute:

#[link_name = "__GPIOA"]    pub static mut GPIOA: gpio::Block;

where __GPIOA is the unmangled symbol name.


#4

I’m using 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 _foo.


#5

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?


#6

I it rustc or llvm that’s doing this?
In the latter case, #[link_name = "\1foo"] might work better.


#7

@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'.


#8

@jjpe: sorry, the syntax should have been this: #[link_name = "\x01foo"].

But apparently #[link_name] attribute only works on “extern” functions, so you can ignore my suggestion.


#9

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.


#10

@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.