Hi all,
I am trying to understand how shared libraries and PLT works. As per my current understanding linking a shared library should output code that calls a function (function from the shared library) by going through the PLT. And the function itself should not be present in the linked output.
For example.
fun.c (Compiled into a shared library)
unsigned int fun ( unsigned int x ) { return(x+3); }
so.c (main executable)
extern unsigned int fun ( unsigned int x ); unsigned int x; unsigned int y; unsigned int z; void centry ( void ) { x=7; y=8; z=fun(77); while(1){ } }
I am compiling using the following steps.
rm -rf boot.o so.o fun.o so.elf so.srec so.list so.bin arm-none-eabi-as -g -mcpu=cortex-m4 -mthumb --warn boot.s -o boot.o arm-none-eabi-gcc -g -Wall -O0 -fpic -mcpu=cortex-m4 -mthumb -c so.c -o so.o arm-none-eabi-gcc -g -shared -Wall -O0 -fpic -mcpu=cortex-m4 -mthumb -c fun.c -o libfun.so arm-none-eabi-ld -g -o so.elf -T flash.ld boot.o so.o -shared -L. -lfun arm-none-eabi-objdump -D so.elf > so.list arm-none-eabi-objcopy --srec-forceS3 so.elf -O srec so.srec arm-none-eabi-objcopy so.elf so.bin -O binary
Complete code is at: https://github.com/rgujju/STM32-projects/tree/master/got_plt
question 1) The output of the above code should not have the function <fun> right? But the output elf file <so.elf> has the function <fun> in it. The call to <fun> and <centry> both go through the plt which I think is correct and the dynamic linker will patch these entries. But why does it contain the function <fun>?
question 2) In the disassembly of the PLT there are instructions which contain a register <ip>. As per my understanding there isnt any register called <ip> in cortex M4. see line 9 and 10 below.
Disassembly of section .plt: 08000084 <.plt>: 8000084: b500 push {lr} 8000086: f8df e008 ldr.w lr, [pc, #8] ; 8000090 <.plt+0xc> 800008a: 44fe add lr, pc 800008c: f85e ff08 ldr.w pc, [lr, #8]! 8000090: 00000220 andeq r0, r0, r0, lsr #4 8000094: f240 2c1c movw ip, #540 ; 0x21c 8000098: f2c0 0c00 movt ip, #0 800009c: 44fc add ip, pc 800009e: f8dc f000 ldr.w pc, [ip] 80000a2: bf00 nop 80000a4: f240 2c10 movw ip, #528 ; 0x210 80000a8: f2c0 0c00 movt ip, #0 80000ac: 44fc add ip, pc 80000ae: f8dc f000 ldr.w pc, [ip] 80000b2: bf00 nop
Thank you for your help.
arm-none-eabi-gcc -g -shared -Wall -O0 -fpic -mcpu=cortex-m4 -mthumb -c fun.c -o libfun.so
The above command does not build a shared object. For greater clarity, you may want to separate the linking steps from the compilation steps.
Searching on the internet for "arm register ip" can assist with the question about the register named ip.
Thank you for your reply.
Yes I had to remove the "-c" from that command and now it works as expected.
ip register is just another name for the r12 register.
Edit: I also had to remove -shared from the
arm-none-eabi-ld -g -o so.elf -T flash.ld boot.o so.o -shared -L. -lfun