Hi toolchain champions,
[please keep me in cc as I'm not subscribed to linaro-toolchain@lists.linaro.org]
In OP-TEE we are going to activate a pager which is an integrated part of the statically linked secure OS binary (compiled for ARMv7/Aarch32 now, but at some point also Aarch64).
The pager in OP-TEE allows use of more memory than the amount of available physical memory. This makes it possible to for instance have an OP-TEE binary that requires more memory than the amount of available memory. What the pager does is to map a physical page at the virtual address where the memory is needed and populate it which what is expected on demand. The pager also unmaps physical pages that hasn't been used in a while to be able to recycle it.
The code used by the pager to map and populate a page must always be mapped since we would otherwise get a deadlock. The problem is that the pager is also part of OP-TEE so we need to partition the binary in a way that all code needed to handle a page fault is in one area in the binary and always mapped.
Annotating functions and such as it's done in the Linux kernel with __init will not scale here since the pager will need routines from "third-party" libraries. We can make small changes to the libraries but identifying and annotating everything needed by the pager is too much. We would also run into troubles with strings.
I have a couple ideas below that I need help exploring.
What if we do an incremental linking of the entire TEE Core with garbage collect only keeping the entry functions of the pager? Then we would get an object file with everything the pager depends on included but not much more. It would be easy to put this single object file in a separate part of the OP-TEE binary. The procedure would be something like:
Compile everything with -ffunction-sections -fdata-sections ld -i --gc-sections -u pager_entry -o pager_code.o $(objs) $(link-ldadd) $(libgcc) ld $(link-ldflags) pager_code.o $(objs) $(link-ldadd) $(libgcc)
But the problem comes with linking in the rest of the code in the last step, we would get lots of multiple defined symbols. We could create a libtee_core.a file where we put all the $(objs) files and the linker would only use the needed object files. But we would still have some multiple defined symbols left since each .o file contains more than just one section.
Any ideas how to solve this?
We could perhaps split each .o file into several .o files each with only one section. Would it work? Would it make the resulting binary larger or inefficient?
Another option could be to mark all symbols in libtee_core.a and other libaries as weak, but the problem here is that we already have some weak functions in TEE Core so this would break that. Perhaps if it would be possible to have different levels of weakness.
Any ideas are welcome, either along this path or different approaches.
Regards, Jens