gcc arm compiler option -mno-pic-data-is-text-relative doesn't work sometimes

Asked by Yan Zhang on 2018-03-29


I'm working on a cortex-A7 processor using gcc 5.4.0. I've been trying to relocate text and data segment to different addresses, rather than what's in the link map. I found this post https://answers.launchpad.net/gcc-arm-embedded/+question/236744 and was hoping to get it working by forcing all data references through GOT table.

However, I have a test_app.elf built with -fPIE, -mno-pic-data-is-text-relative and linked with -pie. And there are libraries that statically linked to this test_app.elf. For example, libc.a and libcrc.a, they both are built with -fPIE, -mno-pic-data-is-text-relative and linked with -pie. The interesting thing I saw is that: read-only variables in libcrc.a are referenced through GOT table. But read-only variables in libc.a are referenced using pc relative offset. So my test_app.elf doesn't work when it calls function in libc.a because the read-only data variables are messed up.

The makefiles for the two libraries are almost identical except for library names, source and, include directories. And they are all statically linked to test_app.elf.

Really appreciate if anyone sheds some light on this.

Thank you,

Question information

English Edit question
GNU Arm Embedded Toolchain Edit question
No assignee Edit question
Solved by:
Tejas Belagod
Last query:
Last reply:
Tejas Belagod (belagod-tejas) said : #1

Hi Yan,

Are you attempting to achieve position independence of sections without the aid of dynamic linking. AFAIK, statically linking position independent code (no -shared) does not make sense to me. When you want to refer data/functions using GOT/PLT, you need a dynamic linker/loader to populate the extra level of indirection needed.

In your case, if you just want to place data and code sections in a user-defined fashion, all it takes is some linker script magic and static linking.

Is that what you want to achieve? Are you really looking for dynamic linking here?

Yan Zhang (echo-yan) said : #2

Hi Tejas,

Thank you for answering my question.

Yes I'm looking for dynamic linking here and I wrote my own small dynamic loader.

Here the statically linking means that the PIE libraries are statically built into a PIE image. Thus there is no shared libraries. Hence, in my little loader, I just need to fix data relocations in .rel.dyn section.

What I want to achieve is that the places for data and code sections are dynamically allocated during loading by dynamic loader. So static linker script won't help. That's why I have to use -mno-pic-data-is-text-relative to force every data references through GOT table. Because where the data and text sections are placed is unknown until run-time. And I can force to put GOT table in the section as text in linker script. So as far as I'm concerned, the offset between text and GOT is fixed. So text is able to correctly refer to GOT. And GOT refers to data section, which is done by dynamic loader.

And my problem is that when I built everything including the libraries with -mno-pic-data-is-text-relative, for some libraries, all data references go through GOT. But for others, data references still use pc relative offset. That doesn't make sense as I built all libraries with same flags.

Thank you for reply again.

Best Tejas Belagod (belagod-tejas) said : #3

Can your dynamic loader handle shared objects and loading from libc.so(generated using -shared) instead of libc.a?

When you say some data is referenced through GOT and some through PC-relative, can you tell me which libraries are GOT and which ones are pc-relative? can you also check the library build logs to see if the libs that are pc-relative referenced get the right options for build (i.e. -mno-pic... )


Yan Zhang (echo-yan) said : #4

Thanks Tejas Belagod, that solved my question.

Yan Zhang (echo-yan) said : #5

I rebuilt all my files again and all data references go through GOT. Looks like previous environment is not clean and there some causing the incorrect build. Everything looks good after I cleaned the environment and restart over.

Thank you for your reply.