This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[ARM Cortex M3] Generating special PLT entries that establishes correct static-(data)-base register for individual libraries


Hi,

currently I'm trying to adapt a shared library approach for an ARM
Cortex M3 embedded system. As the targeted board has no MMU I can't
address .data relative to the code thus GOT too.

Therefore I'm using following gcc compiler switches:

"-fPIE -msingle-pic-base -mpic-register=r9 -mno-pic-data-is-text-relative"

So register r9 (static-base, SB) have to point to the start of GOT and
each global variable is accessed indirect with an offset to r9.

The problem is now to establish the correct value for SB, when calling
an external function. I manually created an executable that proofs my
following concept:

* For each used library there's some special GOT entry that points to
the SB address of that library.

* For each used library, there have to be generated a special PLT entry
that establishes the SB register for that library (see libFoo & libBar
in example code below).

* Each other PLT entry has to know to which library it belongs to, for
establishing the correct SB value.

Now I wonder if this could be integrated into bfd / ld. Because that
concept differs strongly from the standard PLT behaviour I suspect that
this wouldn't be so easy!?

I traced the patch for this bug [1] to get some idea where the code for
PLT is generated. But as I have not yet a greater knowledge of the bfd /
ld codebase I have no idea if external symbols could get matched to
their library.

I added my test PLT below, so I hope my idea becomes clear.

Thanks,
Sascha

[1] https://sourceware.org/bugzilla/show_bug.cgi?id=16017

---------------
GOT content for main executable:

GOT[0]	= address for GOT of libFoo = sb-register for libFoo
GOT[1]	= address for GOT of libBar = sb-register for libBar
GOT[2]	= address of function_1 from libFoo
GOT[3]	= address of function_2 from libBar

.plt

libFoo:
        movw    ip, #0        ; GOT offset for libFoo SB address
        ldr.w   r9, [r9, ip]  ; establish new sb register	
        pop     {ip}          ; get function call adress from stack
        blx     ip            ; call function
        pop     {r9, pc}      ; restore old sb and return to main-caller

libBar:
        movw    ip, #4        ; GOT offset for libBar SB address
        ldr.w   r9, [r9, ip]
        pop     {ip}
        blx     ip
        pop     {r9, pc}

function_1@libFoo:
        push    {r9, lr}         ; save old sb and return address to
                                   main-caller
        movw    ip, #8           ; GOT offset for function_1
        ldr.w   ip, 	[r9, ip] ; load function_1 address from GOT
        push    {ip}             ; save function_1 address on stack
        b       libFoo           ; call code that sets up SB for libFoo

function_2@libBar:
        push    {r9, lr}
        movw    ip, #12
        ldr.w   ip, [r9, ip]
        push    {ip}
        b       libBar           ; call code that sets up SB for libBar
---------------


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]