Ah, I forgot to mention, but the visibility rules are different for
libraries than they are for executables (for better or for worse).

An executable only has reachable C functions exported. I don't think
statics are exported, but that's arguably a bug. Libraries, however,
have all functions/symbols exported.

If you're building an application which is invoked primarily through
some other binding, I'd recommend using a staticlib output rather than
an executable output (and just using the object file). This is
primarily what staticlibs exist for.

On Wed, Apr 30, 2014 at 10:41 AM, Vladimir Pouzanov <[email protected]> wrote:
> Ok, seems that I found a reasonably good solution.
>
> The "app" is now an rlib, and the actual staticlib app that gets linked is a
> wrapper, that sources all external crates and re-exports required symbols
> like this:
>
> #[no_split_stack]
> #[no_mangle]
> #[start]
> pub extern fn main() {
>   app::main();
> }
>
> I also had to move __STACK_LIMIT into external C file, as I couldn't define
> it as external in one crate and provide it in another crate down the chain.
>
>
> On Wed, Apr 30, 2014 at 5:29 PM, Vladimir Pouzanov <[email protected]>
> wrote:
>>
>> Right, so I have a publicly reachable symbol __STACK_LIMIT inside my
>> libzinc rlib:
>>
>> #[no_mangle]
>> pub static mut __STACK_LIMIT: u32 = 0;
>>
>> which is present in rlib's object file:
>>
>> % arm-none-eabi-nm zinc.o|grep __STACK_LIMIT
>> 00000000 B __STACK_LIMIT
>>
>> Now, I compile my application, which is a staticlib, emiting an obj (I
>> could change staticlib to binary, that doesn't really change anything at
>> this emit level):
>>
>> rustc -Z no-landing-pads -C relocation_model=static --target
>> thumbv7m-linux-eabi -Ctarget-cpu=cortex-m3 --opt-level 2 -Z lto --emit obj
>> -L ./build -o ./build/intermediate/app.o ./apps/app_sched.rs
>>
>> Which implicitly links to libzinc-de5e5c68-0.0.rlib.
>>
>> Given the lto nature, ./build/intermediate/app.o will contain all the
>> required code from libzinc (and libcore), so I proceed to linker:
>>
>> arm-none-eabi-ld -Map ./build/zinc.map -o ./build/zinc.elf -T
>> ./src/hal/lpc17xx/layout.ld ./build/intermediate/app.o
>> -L/opt/gcc-arm-none-eabi-4_7-2013q3/lib/gcc/arm-none-eabi/4.7.4/armv7-m
>> --gc-sections -lgcc
>>
>> Which fails due to "undefined reference to `__STACK_LIMIT'", as the lto
>> step didn't keep the __STACK_LIMIT (which is, along with __morestack, used
>> implicitly).
>>
>> I have the same problem with ISRs that re defined in libzinc. For now, I
>> make trampolines in the app code:
>>
>> #[no_mangle]
>> #[inline(never)]
>> #[no_split_stack]
>> pub unsafe fn task_scheduler() {
>>   task::task_scheduler();
>> }
>>
>> that look bad, but I don't yet know a better way to do it.
>>
>> I cannot move __STACK_LIMIT or __morestack in a dedicated object file and
>> pass it to linker, as those depend on libzinc which isn't reaching the
>> linker explicitly.
>>
>>
>> On Wed, Apr 30, 2014 at 5:17 PM, Alex Crichton <[email protected]> wrote:
>>>
>>> In an rlib, all publicly reachable symbols will be exported from the
>>> object, for example:
>>>
>>>
>>>     mod foo { pub static BAR: int = 3; }
>>>
>>> That symbol is not exported because BAR is not reachable from the outside
>>> world.
>>>
>>>     pub use foo::BAR;
>>>     mod foo { pub static BAR: int = 3; }
>>>
>>> This time, BAR will be an exported symbol because it is publicly
>>> reachable (you could also make 'foo' public).
>>>
>>> Would that help your use case, or are you thinking of something more
>>> complex?
>>>
>>> On Wed, Apr 30, 2014 at 6:49 AM, Vladimir Pouzanov <[email protected]>
>>> wrote:
>>> > I have the following setup:
>>> >
>>> >   libzinc, compiles as rlib, provides all the stuff
>>> >   support, compiles as obj, provides __morestack, memset/memcpy and
>>> > other
>>> > required things
>>> >   libapp, compiles as staticlib emitting obj, depends on libzinc,
>>> > builds
>>> > with lto.
>>> >
>>> > I link libapp.o and support.o to get the final binary.
>>> >
>>> > Now, to make multitasking work, I need to move __morestack into
>>> > libzinc, so
>>> > that I can access task API from the function. The problem is that
>>> > publicly
>>> > visible __morestack in libzinc is not visible from libapp, which
>>> > requires it
>>> > implicitly via function prologues. Other static symbols (like
>>> > __STACK_LIMIT)
>>> > are not available as well.
>>> >
>>> > Is there any way to promote the visibility of symbols from libzinc to
>>> > libapp
>>> > in this case?
>>> >
>>> > --
>>> > Sincerely,
>>> > Vladimir "Farcaller" Pouzanov
>>> > http://farcaller.net/
>>> >
>>> > _______________________________________________
>>> > Rust-dev mailing list
>>> > [email protected]
>>> > https://mail.mozilla.org/listinfo/rust-dev
>>> >
>>
>>
>>
>>
>> --
>> Sincerely,
>> Vladimir "Farcaller" Pouzanov
>> http://farcaller.net/
>
>
>
>
> --
> Sincerely,
> Vladimir "Farcaller" Pouzanov
> http://farcaller.net/
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to