The .data.rel.* of local variable is not generated while compile option -fpic -msingle-pic-base -mno-pic-data-is-text-relative are set

Bug #1523315 reported by Justin
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
GNU Arm Embedded Toolchain
New
Undecided
Unassigned

Bug Description

Here is the code to reproduce the problem.

uint32 * global_var[] = [ "123", "234", "456" ];

void function (void) {

    uint32 * local_var[] = [ "123", "234", "456" ];
     ....
}

After compiling code with option -msingle-pic-base -mno-pic-data-is-text-relative,

The data.rel.global_var is generated in object file as expected.

But the data.rel.local_var is not !!!!!

So I did not know how to relocate the data.rel.local_var during run-time.

The problem may lead to relocation fail for local_var[].

BR, Justin

Justin (ckc1222)
description: updated
description: updated
Revision history for this message
Andre Vieira (andre-simoesdiasvieira) wrote :

Hi Justin,

I am not sure what you are trying to achieve here. The 'local_var' variable as the name points out is a local variable and will thus end up on the stack. The variable itself can not be relocated, however the values used to initialize it "123", "234", "456" will be in .rodata and maybe these are the ones you are trying to relocate?

Can you provide us with a working example (the code you posted does not compile) and the command line you used to compile such that we can try to reproduce your problem.

Cheers,
Andre

Revision history for this message
Justin (ckc1222) wrote :

Hi Andre:

      It 's great to hear your reply.

      Yes , you are right. "123" , "234", "456" will be in .rodata. But in case of PIC application, sometimes we may need GOT or data.rel.* to achieve the PIC (position independent code) requirement.

      At compile time, you can specify any default address to compile and work fine. But, in case of PIC application, you may want to load binary into non-default address, then you need to do data and code relocation. That means you need to change the address of "123" , "234", "456" during the runtime. So data.rel.* and GOT section can help to do this, if every data access reference the data.rel.* and GOT. you can relocate the "123", "234", "456" at runtime.

     BTW, my compile command is listed in below

      /projects/ntsw-tools/gnu/gcc-arm-none-eabi-4_8-2014q1/bin/arm-none-eabi-gcc -g -std=gnu99 -Wunused -Wall -Werror -fpic -msingle-pic-base -mno-pic-data-is-text-relative -ffunction-sections -fdata-sections -msoft-float -mtpcs-frame -mlittle-endian -fno-builtin -fms-extensions -D__ARM__ -mthumb -mcpu=cortex-r4 -Wa,-meabi=5 -MP -MD -o test.o test.c -c

Revision history for this message
Andre Vieira (andre-simoesdiasvieira) wrote :

Hi Justin,

So using the following code:

$ cat t.c
char * function (void)
{
      char * local_var[] = { "a", "b", "c" };
      return *local_var;
}

and using your compile command and to generate a t.o. look at the generated dumps by
'arm-none-eabi-readelf -Wa t.o > dump.a' and 'arm-none-eabi-objdump -D t.o > dump.D'.

From dump.D you can see:
00000000 <function>:
...
   6: 4b07 ldr r3, [pc, #28] ; (24 <function+0x24>)
   8: f859 3003 ldr.w r3, [r9, r3]
...
  24: 00000000 andeq r0, r0, r0

And from dump.a
Relocation section '.rel.text.function' at offset 0xa3c contains 1 entries:
 Offset Info Type Sym. Value Symbol's Name
00000024 0000081a R_ARM_GOT_BREL 00000000 .LC4

From the ELF for ARM Architecture doc in
http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044f/IHI0044F_aaelf.pdf

You can read that R_ARM_GOT_BREL indicates the following relocation operation: GOT(S) + A – GOT_ORG, Where A is addend (0 here) and S is .LC4 so GOT (LC4) - GOT_ORG

Now if you go back to dump.D you will also find:

Disassembly of section .data:

00000000 <.LC4>:
   0: 00000000 andeq r0, r0, r0
   4: 00000004 andeq r0, r0, r4
   8: 00000008 andeq r0, r0, r8

And from dump.a:

Relocation section '.rel.data' at offset 0xa24 contains 3 entries:
 Offset Info Type Sym. Value Symbol's Name
00000000 00000502 R_ARM_ABS32 00000000 .rodata
00000004 00000502 R_ARM_ABS32 00000000 .rodata
00000008 00000502 R_ARM_ABS32 00000000 .rodata

So .LC4 I guess is pointing at rodata, which contains "a", "b" and "c' as you may inspect.

And I believe this is how it is all linked.

The function loads the address of our "a", "b", "c" array by...

Loading the index of the address of the array into the GOT table with:
   6: 4b07 ldr r3, [pc, #28] ; (24 <function+0x24>)

since function+0x24 will hold 'GOT(LC4) - GOT_ORG'. And then it adds that index to r9 and loads the value there:
   8: f859 3003 ldr.w r3, [r9, r3]

r9 is the default pic register, so it should be holding the address of the GOT, i.e. GOT_ORG, so that instruction should be loading the address of the relocated .rodata. Since .rel.data points to .rodata, which is the address of our array.

I'm hoping this answers your question, or at least helps you a little further.

Cheers,
Andre

Revision history for this message
Justin (ckc1222) wrote :

Hi Andre:

          Thank for your reply. I think you are right. And we do have the same page.

But my question is how to relocate it during runtime.

 The difficulty I face that is .rel.data.global_var of global_var[] is belong to .rel.data which is a special section.

Any data points in the .rel.data are the target needed to relocated at runtime if I change the execution address.

But the .LC4 of local_var[] is belong to .data which is a generic section.

The ".data" section may includes data/data points with various types and are not only for relocation.

So I need to do a lot of extra effort to identify where the .LC4 is in data section.

But in my point of view, the best solution is the .LC4 of local_var[] should belong to .rel.data. not .data. then I don't need do anything extra for relocate .LC4 at runtime.

That is my problem.

Anyway thank for your time and sorry to reply late, and looking forward your reply.

BR, Justin

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.