-
Notifications
You must be signed in to change notification settings - Fork 109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix relocation #28
Comments
@alevy I played around with the relocation problem the whole weekend but I am completely lost now. My findings: Relocations are not emitted by default. They can be emitted via I am not sure whether
If, on the other hand, I build the code using
In any case, no matter which relocation model I choose:
Do you think I am on the right track? |
@torfmaster and I were finally able to prove that trait objects can work in Tock OS. See #56 for more details. Unfortunately, I cannot recommend applying the strategy mentioned in the PR. It has too many drawbacks (like no real position independence) and relies on hacks or details that might cease to be valid in a newer version of In order to get
@alevy What do you think about those problems? We would be happy if someone else could help fixing the |
There are at least two problems getting in the way of
In the meantime, static linking of Rust apps appears to be possible (avoiding relocation entirely). I'm putting together a PR to implement static linking. Fortunately, static linking doesn't require any code changes that are incompatible with ROPI-RWPI, although it requires linker script changes. |
Static linking works as of #64 ; making ROPI-RWPI relocation work correctly is a larger problem that'll take longer to solve. |
someone(TM) really should fix tock#28.
Will this be achieveable on platforms other than ARM? We may wish to execute embassy on more achitectures. |
From the perspective of I think the latest status of RISC-V ROPI/RWPI can be followed here: riscv-non-isa/riscv-elf-psabi-doc#128 And the latest status for the issues with ARM thumb targets can be followed here: rust-lang/rust#54431 |
I'm also rather interested in working relocations. Having read the Rust-lang thread, LLVM exchange, and the rust-embedded IRC log, I noted two statements that stand out. In the LLVM emails, "I don't think such transformation belongs into clang.", regarding initializers, and "for apps you could roll your own in-kernel dynamic linker", from the IRC discussion. Was it considered to ignore the ROPI/RWPI approach, and instead rely on relocations and fix them up using a linker? That step could even take place in tockloader, while flashing (assuming that applications once flashed aren't going to be moved again). If there are still problems with relocations not being emitted enough, the actual step of linking object files could be moved to flash-time, with the relevant offsets (or linker files) calculated based on where the app is going to land. If any of those approaches is not totally crazy, I'm willing to try implementing it - loadable applications are a must for me. |
lowRISC is working on an ePIC implementation for RISC-V and hopes to upstream it to LLVM: https://github.com/lowRISC/epic-c-example / https://github.com/lowRISC/llvm-project/commits/epic. Our current hope is that this work will at least make loadable applications possible for RISC-V, though support for ARM may take longer as I do not believe lowRISC currently plans port this work to other architectures. |
I'm pretty sure that your idea is workable. It is not a solution that works for every user of One other solution that the Tock project has looked at (which |
Didn't libtock-c use actually position-independent binaries? That's what I gathered from the discussion about libtock-rs. |
|
Thanks. I just realized that static linking also makes the RAM address fixed, which is rather suboptimal when applications are meant to be able to be loaded in any order. Perhaps some form of PIC with rwdata section relocations at runtime could solve that - if such relocations are supported by the compiler. |
Yes -- when I said "compile each process multiple times for different locations", each "location" is a combination of a flash address range and a RAM address range.
I do not think that is possible with any relocation mode that LLVM supports, unfortunately. |
@dcz-self this (rather old) blog post explains a little bit of the complexity with PIC: https://www.tockos.org/blog/2016/dynamic-loading/ libtock-c works because GCC supports the particular kinds of variants of PIC we need, while LLVM doesn't (actually there was a reasonably complete patch from somebody at ARM, I believe, back in the day but it wasn't accepted).
Proposals are very welcome! The main constraint are: (1) code lives in flash, not RAM, and we probably don't want to be rewriting flash on every process reboot (because of write degredation and performance) and (2) the binary size should be reasonably small---all the extra information retained for dynamic loading in, e.g., Linux ELFs results in executables the are typically way too big for the target platforms. But neither of these means there isn't some sweet spot design that is possible. |
With Rust merged into GCC 13, will that eventually make it possible to resolve this as the implementation matures? |
rustc_codegen_gcc is on track to be usable well before GCC's Rust frontend, so I don't think that changes anything. Either way, GCC only supports the necessary relocation mode on ARM, not RISC-V, so it's not a complete solution. If ePIC ends up being RISC-V only, we may end up implementing relocation using |
Is there any updates on this? I'm aware that this seems to be blocked by either |
@silvergasp the answer right now is that waiting for LLVM and RISC-V (and any other non-cortex-m architecture) to support something that would work as we hope is not a good plan. There are basically four ways forward as far as I understand, two of which have a good chance of happening soon:
|
In order to make global variables and dynamic dispatch work, we need to compile binaries conforming to the R_ARM_SBREL32 relocation model.
As far as I understand we need to perform two steps:
tock/userland/libtock/crt0.c
to RustThe text was updated successfully, but these errors were encountered: