dev builds
themes manual
device status forums
mailing lists
IRC bugs
dev guide

Search | Go
Wiki > Main > BFLT
This page is about Blackfin Flat Format (usally abbreviated bFLT) and idea to adapt it for rockbox plugins/codecs. First one should read basic material about bFLT.

The idea is appealing as this would allow to load and execute plugins/codecs at arbitrary memory address. This would open many new possibilities like a few plugins running at the same time or would allow to split main binary into modules and load only those needed.

I started exploring the idea and some of my attempts are collected on gerrit.

Technical difficulties


The utility to convert elf binary into bFLT (elf2flt) is a mess. It leaks memory like a hell, is full of ifdefs, gotos and so on. It uses binutils internal libs which are poorly documented. Over the time it evolved and supports two modes of operation which are not truly documented. One mode takes not fully linked binary and calculates relocations, the second takes fully resolved binary linked at address 0 which means most of the hard work is already done by the linker. Some platforms support both modes, some only one. If we want to use the format we need to fork the utility, clean it up and adapt to our needs.


There is a 'feature' of gnu linker which breaks elf2flt produced binaries. Basically ARM can jump directly to the code within +/- 16MB range. If the destination function is further in address space the call needs to go through so called veneer function. Insertion of veneers is linker responsibility as it knows during final link what is relative distance of the jump. Since veneers are inserted at the very end of link process binutils people don't see the need to emit reloc for veneers. In normal situation this is no problem but for bFLT it is a bug. The workaround is to pass -mlong-calls to gcc when building objects. It produces slightly slower code however. The true solution would be to patch ld to include relocs for veneers in final binary. The interesting thing is that veneer templates do contain relocation info, the info is processed in arm32_elf_final_link_relocate() but the info itself is discarded. (see binutils bfd/elf32-arm.c for reference).


elf2flt cleanup needed.


elf2flt supports only first mode of operation (fixing relocs in not fully resolved binary). It should be fairly easy to adapt as basically we care only about R_SH_DIR32 reloc.


elf2flt lacks MIPS support. There are some patches against ancient versions which add limited support for the architecture. The main problem is that commonly emitted R_MIPS_HI16, R_MIPS_LO16 and R_MIPS_26 don't fit in the way flat relocations work.

3c0280f0        lui     v0,0x80f0           R_MIPS_HI16
8c4267fc        lw      v0,26620(v0)        R_MIPS_LO16

This snippet loads word from 0x80f067fc address. R_MIPS_HI16 contains upper 16bit of address, R_MIPS_LO16 contains lower 16bits of address. This two relocations can't be expressed as simple addend.

0c3c12d4        jal     80f04b50 <setjmp>   R_MIPS_26

This snippet jumps to address 0x80f05b50. Addend is coded in lower 26 bits of instruction and is expressed in words. So addend = (instruction & 0x3ffffff) << 2. As top 6 bits are used for instruction coding it is again impossible to express this reloc as simple addend.

The End

After some discussion on IRC the conclusion is that bFLT is dead end. Solving all technical issues is about as complex as adopting some simplified elf loader for our needs. Loader used in Prex seems to be fairly simple and clean. It is licensed under revised BSD so I'll take it as a starting point probably.

-- MarcinBukat - 28 Sep 2012
r3 - 02 Apr 2021 - 20:46:06 - UnknownUser

Copyright © by the contributing authors.