arm-elf-gcc shared flat support

vivek tyagi vivek.list@gmail.com
Sat Mar 31 09:39:00 GMT 2007


Hi Richard ,Paul

>This is the wrong list for these sorts of questions, you should really
>be asking on gcc-help.


The project I am working on require changes to be made in the gcc
backend(probably front end too for complete solution).so I thought
best to discuss it with developers.

>Is there some reason why linker-generated PLT sequences aren't a
>reasonable solution?

and for Paul

>Why on earth do you need to do this? Can't you get the linker to generate PLT
>sequences like we do for normal shared libraries?
>

As my major work area is ARM uClinux ,My apologies if my explanation
on this compiler project is erroneous.Kindly ignore if this is already
known.

As per my understanding ( Kindly bear with me)  the file format for
NO MMU ARM in uClinux is "Binary Flat format commonly known as BFLT"
(http://www.beyondlogic.org/uClinux/bflt.htm  for reference).This
format is achieved by running "elf2flt" tool on the ELF file generated
by the cross compiler tool chain(here arm-elf-gcc).Now the flat files
do not have a PLT .They are very simple format with
TEXT:GOT:DATA:RELCO sections(in that order).so IMHO  the generic
linker modification for PLT sequences cannot be  done.This matter was
discussed long back in the same list by  John Lee,Bernardo Innocenti
et al around 11 Jun 2004..
For providing shared Library support for uClinux environment,which is
essentially without MMU some changes are required in the
toolchain.One approach was developed by snapgear team for m86k
(http://www.ucdot.org/article.pl?sid=03/11/25/1126257&mode=thread).But
 there is no similar implementation (read open source) for ARM..Just
to be sure, I raised this issue at uClinux developer forum and
received the same answer.So I proceeded to spare some time and work on
an opensource implementation for ARM on similar lines that is done for
m68k.

The pivot is to handle PIC register r10(sl) and the "-R" option in ld.
The way it works is the symbol information are copied(via -R) option
form the library to the main executable at compile time.The load time
values are taken care by the binfmt_flat loader via GOT. For this to
work  every thing (data variable,functions)should be accessed via GOT
so that the copied symbol information can be fixed up by the linker.

Taking my original example
> ******c-code**************
> foo()
> {}
> main()
> {
> foo();
> }
>
> ******************************


In the  actual senario  the function foo() would be part of shared library.

****exe********   **********shared-lib*******
extern foo();                foo()
main()                         {
{                                  }
foo();
}
****exe********   **********shared-lib*******

now the object files would be linked as
arm-elf-gcc  exe.o -Wl,-R,shared-lib.o

Here you could see the need of modifying the compiler for generating
call to foo() via GOT rather than calling it by "bl" .The -R flag
would copy a value for foo() in exe( from shared-lib ) which does not
make any sense .On the other hand if foo() is called via GOT ,-R would
copy  the reloc value for foo() in exe. This is fixed up by the
binfmt_flat loader to point to the correct address of foo() in
shared-lib (the library is loaded first by the loader...).

Hope this explains the requirement of indirect function call



The other changes require store/ restore of  PIC register for all
function calls and loading PIC register with the address of relevant
GOT (the GOT address are maintained in a array updated by binfmt_flat
loader.

I have implemented -mshared-library-id flag for arm.

so the gcc -mshared-library-id=1

generates following function prologue and epilogue(for gcc 2.95)
        mov     ip ,sp
        stmdb   sp!,{sl,fp,ip,lr,pc}    /*store sl on stack*/
        sub     sl,sl,#8                /*bad hack to update sl ,sl is
to be loaded with address of new GOT which lies 2 words before the
current location for lib id =1*/
        ldr     sl,[sl]         /*bad hack continues.. ideally this
should be one instruction  i.e ldr  sl,[sl,# - 8] ...its in my TODO
list*/
        ....................
        ...................
        ...................
        ldmdb   fp,{sl,fp,sp,pc}        /*restore sl */


Now I am not sure if this is a very efficient  approach.But lack of
MMU does not leave us with too many choices.Implementing this for ARM
would take care of inefficiency caused in ARM uClinux due to lack of
shared Library support.The above mentioned changes can be done for the
latest gcc  also.But I am facing some relocation issues with the
uClibc compiled with 3.4.0 with PIC reg modification hacks.It works
fine with 2.95 so I worked with that first.


All this is flexible,feel free to add in your suggestions..


Thanks
Vivek Tyagi



More information about the Gcc mailing list