Relative PIC data not addressed correctly in structs?

Asked by Henrik

Hi,

I'm using the options -std=c99 -mcpu=cortex-a7 -mfpu=vfpv4 -fpic -mpic-data-is-text-relative
gcc version 4.9.3 20150529 (release) [ARM/embedded-4_9-branch revision 224288] (GNU Tools for ARM Embedded Processors)

My code looks like.

   typedef struct
   {
      const char* msg;
   } str_t;

   static str_t str_tab[] =
   {
      {"string1"},
      {"string2"}
   };

   int main(void)
   {
      str_t* str = str_tab;
      const char* msg = str_tab[0].msg;
      return 0;
   }

Linker file:

SECTIONS
{
   ENTRY(__main)

   .text 0x86000000:
   {
      RO_CODE_LMA = . ;
      RO_CODE_VMA = . ;
      hwc_boot.obj (.text .rodata)
      RW_CODE_LMA = . ;
      hwa_exc.obj (.text .rodata)
      RW_CODE_LMA_END = . ;
      *(.text* .rodata*)
      *(.glue_7t)
      *(.glue_7)
      RO_CODE_LMA_END = . ;
   }

   .ARM.extab . :
   {
      *(.ARM.extab*) *(.gnu.linkonce.armextab.*)
   }

   .ARM.exidx . :
   {
      __exidx_start = . ;
      *(.ARM.exidx* .gnu.linkonce.armexidx.*)
      __exidx_end = . ;
   }

   .data . :
   {
      RW_DATA_LMA = . ;
      RW_DATA_VMA = . ;
      *(.data)
      RW_DATA_LMA_END = . ;
   }

   .bss . :
   {
      ZI_DATA = . ;
      *(.bss)
      ZI_DATA_END = . ;
   }

   .nidata . :
   {
      NI_DATA = . ;
      hwa_stack.obj(.nidata)
      *(.nidata)
      NI_DATA_END = . ;
   }

   .rwtext ALIGN(256) : AT (RW_CODE_VMA)
   {
      RW_CODE_VMA = . ;
      RW_EXC_CODE = . ;
      hwa_exc.obj (.text .rodata)
   }

   RW_STACK_BOOT_CODE = . ;

   .shared 0x8603fe00 (NOLOAD) :
   {
      RW_SHARED_LMA = . ;
      RW_SHARED_LMA_END = . + 256 ;
   }

   RO_CODE_LEN = RO_CODE_LMA_END - RO_CODE_LMA;
   RW_CODE_LEN = RW_CODE_LMA_END - RW_CODE_LMA;
   RW_DATA_LEN = RW_DATA_LMA_END - RW_DATA_LMA;
   NI_DATA_LEN = NI_DATA_END - NI_DATA;
   ZI_DATA_LEN = ZI_DATA_END - ZI_DATA;
   RW_SHARED_LEN = RW_SHARED_LMA_END - RW_SHARED_LMA;

   RW_TT_LMA = . ;
   RW_TT_LMA_END = . ;
   RW_TT_VMA = . ;
   RW_TT_LEN = 0;
}

I load my SW into the memory at an offset from the original linkage offset that is specified in my linker file. I.e. instead of 0x86000000 I force my SW to be loaded into 0x86000100. Now the line str_t* str = str_tab works perfectly fine and that variable is relative to the PC. But when I try to fetch a string in the string table the pointer to that string always points to a fixed address as if the SW was loaded in 0x86000000.

Am I expecting to much from -mpic-data-is-text-relative? My goal is to be able to load my SW anywhere in the memory without having to recompile with a different linker file (offset). I am using my own bare metal SW.

Thanks.

/ Henrik

Question information

Language:
English Edit question
Status:
Answered
For:
GNU Arm Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
Henrik (henrik-t) said :
#1

Just some clarification: the C code presented above is an short example I made to show my problem while the linker file is actually related to my barebone SW which is really not represented by the C code above :-)

Revision history for this message
Joey Ye (jinyun-ye) said :
#2

Hi, Henrik,

If I understand your usage case correctly, you are trying to dynamically load this file. What looks missing is the -shared flag from the linker command line.

What will happen after -shared is that linker will put a dynamic relocation in your case at str_tab. You can check these symbols with arm-none-eabi-objdump -R. In your case it should be R_ARM_RELATIVE relocation. When the program is loaded, the loader should be responsible to resolve all dynamic relocation symbols, which makes your str_tab contain the right address to const strings.

The solution will be the enable the dynamic symbol resolving mechanism in the loader your used.

Thanks,
Joey

Revision history for this message
Henrik (henrik-t) said :
#3

Is it possible to resolve symbols (i.e. changing the offset) by letting the binary modify its own sections?

Or do I need the obj file to find out which symbols are R_ARM_RELATIVE to I only relocate those?

I am just running a simple bare bone OS and would prefer not to have to use the obj file to find out which symbols I need to relocate.

Can you help with this problem?

Provide an answer of your own, or ask Henrik for more information if necessary.

To post a message you must log in.