Attempts to load position-independent code on Corex-m3

I have a built-in application that will have a bootloader that decides to launch 1 of two applications directly from the internal flash. I am trying to make these applications independent, so that they can both be compiled for the same base address. There is no operating system, so the dynamic linker is not available. So far I have been trying to build with the -fpie option (using gcc) with not too much success. Function calls look correct, but global data does not have the correct address. Locally-defined global data appears to have an offset address of the amount that the application is offset from its original base address. Global data that is declared in other files has a completely wrong address (and if I create with -fpic, then global data declared locally and global data in other files are completely erroneous). I suspect that I need to manipulate the GOT section a bit when the application starts, but I'm not sure.

+6
arm position fpic
source share
2 answers

Finally, I started to work. It looks like I need to do the following: All code must be executed -fpic (I tried -fpie before)

Also, I needed my linker script. I forced the GOT into the sram section, and it was located after the dynamic section, which was in a flash state. Everything seems to work correctly if the GOT partition is located before the dynamic partition in flash. I'm not sure why this matters, but it seems to fix it all - before that it was as if the code had not found a suitable GOT, since the GOT had the correct values ​​stored in it, but the address of all my variables was incorrect.

+6
source share

The PIE (and PIC) code needs to go through the process after loading at some address (other than the default) and before it starts. I suggest you familiarize yourself with the ld.so code. In addition, you should check the relocation table in your binary format (e.g. using readelf -r ).

Here is a good presentation at PIE (this is about OpenBSD, but the process is the same). http://www.openbsd.org/papers/nycbsdcon08-pie/ or http://www.dcbsdcon.org/speakers/slides/miller_dcbsdcon2009.pdf

I think you should not only change the GOT, but also find all the Relocations and make them.

Basically, processing a binary PIE file using ld.so is almost the same as processing a dynamic library using PIC, not moving the library, but the executable image itself.

The “wrong addresses” you see is the place where the actual value will be written by relocation. Regarding i386 http://books.google.com/books?id=Id9cYsIdjIwC&pg=PA174 , i.e. moving:

  • R_386_GOTPC
  • R_386_GOT32
  • R_386_GOTOFF
  • R_386_RELATIVE

The linker should allow all of them before the code can access global data.

Readelf -r sample:

Dynamically linked

 $ readelf -r fdyn Relocation section '.rel.dyn' at offset 0x27c contains 1 entries: Offset Info Type Sym.Value Sym. Name 08049ff0 00000106 R_386_GLOB_DAT 00000000 __gmon_start__ Relocation section '.rel.plt' at offset 0x284 contains 2 entries: Offset Info Type Sym.Value Sym. Name 0804a000 00000107 R_386_JUMP_SLOT 00000000 __gmon_start__ 0804a004 00000207 R_386_JUMP_SLOT 00000000 __libc_start_main 

PIE:

 $ readelf -r fPIE Relocation section '.rel.dyn' at offset 0x388 contains 6 entries: Offset Info Type Sym.Value Sym. Name 00001fe8 00000008 R_386_RELATIVE 00001ff0 00000008 R_386_RELATIVE 00002010 00000008 R_386_RELATIVE 00001fe0 00000106 R_386_GLOB_DAT 00000000 __gmon_start__ 00001fe4 00000206 R_386_GLOB_DAT 00000000 _Jv_RegisterClasses 00001fec 00000406 R_386_GLOB_DAT 00000000 __cxa_finalize Relocation section '.rel.plt' at offset 0x3b8 contains 3 entries: Offset Info Type Sym.Value Sym. Name 00002000 00000107 R_386_JUMP_SLOT 00000000 __gmon_start__ 00002004 00000307 R_386_JUMP_SLOT 00000000 __libc_start_main 00002008 00000407 R_386_JUMP_SLOT 00000000 __cxa_finalize 
+5
source share

All Articles