The ARM guy told me clang have no GCC’s PIC configuration options, and told me to ask here.
Acutally I also asked another ARM guy, but gives me no answer.
So, what he mean is clang does not have equivalent options as GCC pic options or clang does not support this? I mean support to generate pic code with pic-register, which is normally R9 in ARM chips.
I have tried -fropi and -frwpi. It is used for embedded position indenpendent, and it’s not equivalent to GCC options -fPIC -msingle-pic-base -mpic-register=r9. Because for GCC case with these options, GOT-based position indenpendence code is generated(with section .plt, .got and .got.plt), and static base register r9 is the address of the GOT.
So is there any option in clang to generate GOT-based position indenpendence code with r9 as GOT address? I now, understand why the ARM guy don’t know this.
I have edited the title to avoid ambiguous information.
I was very confused why you’d want something like this, but then I realized the key option is actually -mno-pic-data-is-text-relative. Which allows the loader to shift around both the GOT and global variables relative to the code. So, similar to -frwpi, but worse, because it needs an extra indirection to compute the addresses of global variables.
No, clang currently doesn’t support that ABI. But I expect it would be straightforward to port your code to use -frwpi instead.
I’m implementing a fake linux in cortex-m chips, almost done. Now, I’m adding a dynamic load feature. All the code is in flash, so GOT is needed to do all the reallocating.
I’m fimilar with GCC, so I know the options in GCC to generate the code I want, although there is a BUG in GCC while accessing GOT in veneer functions, which will use PC + offset instead of static base R9, but this can be patched. This bug exists in arm-none-eabi-gcc at least seversal years ago.
So, my loader will allocate bss and data section, and generate a GOT table according to rel(for variable) and jmprel(for functions) sections, and pass to R9. I will implement a POC with GCC, if all done. I will try to use clang, because even if the same bug exists in llvm, the ARM guys will fix it, but they will not fix the same bug in arm-none-eabi-gcc.
A GOT-based position independent elf target will be generated. And while loading the elf, just allocate .bss, .data, .noinit and .got sections. All relocations will be applied to GOT sections. So .text, .plt and .rodata sections remain in flash(XIP).
for ropi/rwpi(embedded position independent), I have no idea how external symbols are relocated. I have read the source code of a ropi/rwpi loader, but can not find the relocation of extern symbols. Maybe only GOT-based position independent can support this. As in the image, there is a log about reloate printf, this is a external symbol.
clang support is done, implemented by a virtual_plt. Because clang will not generate plt for external functions. So simply construct a virtual plt. _start entry should accept 3 parameters, the last one is pointer to virtual plt provided by loader.
I have the same problem. When I use rust-lang in Embedded. I want to compile a .a file generated by Rust with pic/pie. Then connect it with c to generate a binary, and then copy it to flash. In loader, setup the got to ram.
But Rust/llvm can’t generate the GOT-based pic. It is incompatible with code generated by C.