On Thu, Oct 30, 2014 at 12:22 PM, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
On 30 October 2014 11:31, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> On 30 October 2014 11:20, Jens Wiklander <jens.wiklander@linaro.org> wrote:
>> 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?
>>
>
> If you can confirm that the first step correctly produces a kernel
> with all the pager dependencies, couldn't you wrap all remaining code
> into a static library and link against that? This would solve the
> multiple definition issue as the archive members will be pulled in on
> demand. The only thing you need to ensure is that the granularity is
> sufficient, i.e., if the linker decides to pull a .o from the static
> lib, it will pull all contents including symbols that may conflict,
> but I would expect the -ffunction-sections -fdata-sections to take
> care of that.
>

Hmm, I suppose that is what you meant with libtee_core.a?
Yes. :-)
 

I suppose you can use objcopy to separate .text and .data sections
into separate .o files and wrap those up into an archive.
There is also --localize-symbol and --weaken-symbol options in
objcopy, but I making all symbols weak in libtee_core.a is probably
not the way to go.

Is there any way to make sure the conflicts are over .text or .rodata
symbols only? That would at least eliminate the duplicate data hazard,
leaving only the code bloat due to duplication.
Yes, we could let all .data and .bss go into the pager, but I don't like the code bloat.

Regards,
Jens 

--
Ard.


> Another trick that I know bionic uses for the loader is to prefix all
> symbols using objcopy --prefix-symbols=...
> That way, you can work around the multiple definitions, but you may
> end up with duplicate data which is a bit of a hazard.
>
> --
> Ard.
>
>
>> 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