Hello! I'm trying to add a new target to rustc, however it requires a specific linker script to be used with lld. I already have a target JSON working with a local linker script and
pre_link_args, however I would like to open a PR to merge it upstream as a built in target, along with this mandatory linker script. Is this possible at the moment?
What does the linker script do?
It has specific sections that look like .rodata.xxx which* can’t be merged into .rodata as the platform needs to read them separately
So the script just ensures they are output correctly
Interesting. Is there a rule for what goes in each
And does the program's own read-only data go in
.rodata or in one of those sections?
The regular read only data goes into .rodata, but there is special meta information about the output ELF that needs to be stored in these .rodata.xxx sections (such as a pointer to the entry function or name of your module)
The platform also uses these sections for linking, so you declare your imports in one of these libraries. Similarly there is a special .text section for stubs though IIRC that gets passed through correctly with the default LLD script
Is it possible to teach LLVM about this as part of the target's linker defaults? It seems like you'd need this for C and C++, too.
It is probably possible, but I'm not sure there is any demand for that. For context this is a homebrew game system target from 2005 that has a fairly decent unofficial GCC-based toolchain (Sony PSP). There doesn't seem to be any demand for enabling LLVM C/C++ support. If it's the only way, I'll end up giving that a shot, but keeping it only in rust with a single linker script would be much easier
Ah, I see.
It's certainly not the only way; it's more that it's likely the easiest way, from a technical perspective. Of course, policies may vary.
Has someone tried getting the target and linker script into LLVM and gotten rejected?
I do think, in general, Rust has much more inclination to add tier-3 targets if at least some folks care about those targets.
I feel like LLVM ought to have the same kind of "tiering" policy, since there is interest in uncommon targets, and developers just don't want to guarantee that they'll remain working.
I am not aware that anybody has attempted to do this with LLVM. There was at one point a CPU target, though it was discovered to be basically identical to MIPS2 later down the line and they removed it (cpu = "mips2" works perfectly with rust atm).
For some context I've found the targets here: https://github.com/rust-lang/rust/tree/master/src/librustc_target/spec
Though none of them use a custom linker script, so I'm not sure how to go about adding one.
If it's not too much trouble, and the target really just needs a linker script and is otherwise identical to some existing target, you might consider submitting the patch to LLVM. If they decline to support it, then I imagine it could be added as a tier-3 target in Rust anyway.
(As for how to add a target-specific linker script to a Rust target, I don't know, but it absolutely ought to be possible.)
The target is basically identical to a bare metal
mipseltarget, but I've never submitted a patch to LLVM, so I'm not sure where I would even begin. Do you know anybody who would know how to add such a linker script to a rust built in target? Or perhaps where I could ask for help? If the LLVM patch method is strongly preferred, I'll have to go down that route.
As it stands, I think it's much more likely I'd succeed in adding it to rustc than LLVM, if that is acceptable. (The homebrew community does not seem to care about LLVM support currently, so it's very low priority)
You're likely in the right place, and you might also try filing an issue and asking for help, with the linker script attached.
To be clear, there's nothing wrong with just having support in Rust; it just means that that target may have issues working with C and C++.
Ok. Thank you for the tips! I'll watch this thread for a bit to see if anybody can help. Otherwise I'll go ahead and file an issue.