This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[ARM Cortex M3] Generating special PLT entries that establishes correct static-(data)-base register for individual libraries
- From: Sascha Münzberg <samu0007 at stud dot fh-kl dot de>
- To: <binutils at sourceware dot org>
- Date: Sat, 13 Sep 2014 18:35:37 +0200
- Subject: [ARM Cortex M3] Generating special PLT entries that establishes correct static-(data)-base register for individual libraries
- Authentication-results: sourceware.org; auth=none
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
---------------