Bug 16163 - ld generates static relocations in shared library
Summary: ld generates static relocations in shared library
Status: NEW
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: unspecified
: P2 minor
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-11-13 10:24 UTC by Thomas Schmid
Modified: 2014-11-19 14:45 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Schmid 2013-11-13 10:24:47 UTC
Hi,
I have a problem concerning the relocations generated by the linker:

If I compile the example code at the bottom with

    arm-elf-gcc init.c -o lib.so -Wl,-shared -nostdlib

I get a shared library with some relocations (readelf lib.so -r):

    0000032c  00000d02 R_ARM_ABS32       000004b8   plpv1
    00000330  00001302 R_ARM_ABS32       00000000   lpv2
    000004b8  00000b02 R_ARM_ABS32       00000000   lpv1

Till now I believed, that the linker resolves all static relocations and generates dynamic relocations (to be handled by the loader), where it is necessary.
Why are there static relocations left in the linker output?
The document "ELF for the ARM Architecture" at
http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044e/IHI0044E_aaelf.pdf
says, R_ARM_ABS32 is a static relocation and also:

> Static relocations are processed by a static linker; they are normally either fully resolved or used to produce dynamic relocations

> for processing by a post-linking step or a dynamic loader. A well formed image will have no static relocations after static linking

> is complete, so a post-linker or dynamic loader will normally only haveto deal with dynamic relocations.

BTW, this can also be reproduced using i386-elf-gcc, the static relocation used there is R_386_32.

Can anyone tell me, why and tell me, which relocations should really be handled in the loader?
In the meantime, I was told to use the option "-fPIC" - which in fact doesn't help, also after that a static relocation (R_ARM_ABS32) is left in the library.

Example code:

    extern unsigned char lpv1;
    extern unsigned char lpv2;

    unsigned char* plpv1 = &lpv1;

    void func(void)
    {
        lpv2 = *plpv1;
    }

I got a first answer on that from the binutils mailing list from Nick Clifton:

> Hi Thomas,
> > If I compile the example code at the bottom with
> >
> >      arm-elf-gcc init.c -o lib.so -Wl,-shared -nostdlib
> >
> > I get a shared library with some relocations (readelf lib.so -r):
> >
> >      0000032c  00000d02 R_ARM_ABS32      000004b8  plpv1
> 
> Yes - this is correct...
> 
> >> >Static relocations are processed by a static linker; they are normally either fully resolved or used to produce dynamic relocations
> >> >for processing by a post-linking step or a dynamic loader. A well formed image will have no static relocations after static linking
> >> >is complete,
> 
> Right - but libso.so is not a fully linked binary.  It is a shared
> library that is going to be used as part of another static link operation.
> 
> For example:
> 
>   % cat main.c
>   extern void func (void);
>   extern int printf (const char *, ...);
> 
>   unsigned char lpv1, lpv2;
> 
>   int main (void)
>   {
>     lpv1 = 1;
>     lpv2 = 2;
> 
>     func ();
> 
>     return printf ("lpv1 = %d lpv2 = %d\n", lpv1, lpv2);
>   }
> 
>   % arm-elf-gcc main.c -L. lib.so
> 
>   % readelf -r a,out
>   Relocation section '.rel.plt' at offset 0x8220 contains 5 entries:
>     Offset    Info    Type            Sym.Value  Sym. Name
>   0001a984  00000216 R_ARM_JUMP_SLOT  00000000  malloc
>   0001a988  00000416 R_ARM_JUMP_SLOT  00000000  __deregister_frame_inf
>   0001a98c  00000916 R_ARM_JUMP_SLOT  0000828c  func
>   0001a990  00000e16 R_ARM_JUMP_SLOT  00000000  __register_frame_info
>   0001a994  00001016 R_ARM_JUMP_SLOT  00000000  free
> 
> 
> So now all of the static relocations have been resolved and only dynamic
> relocations remain.
> 
> Cheers
>   Nick

Ok, on the one hand, libso.so is used at static link-time of an executable, as described here.
But on the other hand, libso.so is installed (=loaded) as dynamic library on the target - and that's the point I don't understand:
What shall the loader do with this static relocations?
Which static relocations can occur in a shared library and must be handled by the loader ?

Regards,
Tom
Comment 1 Nick Clifton 2013-11-21 14:38:16 UTC
Hi Thomas,

  OK, I think I can see your point now,  I think that the answer to your original question is as follows:

	R_ARM_ABS12
	R_ARM_ABS32
	R_ARM_ABS32_NOI
	R_ARM_REL32
	R_ARM_REL32_NOI
	R_ARM_MOVW_ABS_NC
	R_ARM_MOVT_ABS
	R_ARM_MOVW_PREL_NC
	R_ARM_MOVT_PREL
	R_ARM_THM_MOVW_ABS_NC
	R_ARM_THM_MOVT_ABS
	R_ARM_THM_MOVW_PREL_NC
	R_ARM_THM_MOVT_PREL

This is from looking at the code in bfd/elf32-arm.c and searching for may_become_dynamic_p.

Of course the next question is "does this mean that the linker is generating illegal shared objects", at least as according to the AAEABI ?  I am afraid that the answer appears to be "yes", and I do not have a solution to this.  I think that it may be that established practice is that loaders need to be able to handle these relocations, even though strictly speaking they should not.

Does this help at all ?

Cheers
  Nick
Comment 2 Thomas Schmid 2013-11-22 09:02:13 UTC
Hello Nick,

yes, this is exactly, what I wanted [not ;-)] to read.
Thank you very much for your time and help!

Regards
Tom
Comment 3 Jonas Maebe 2014-11-19 14:45:12 UTC
While I would personally agree with your interpretation of the ARM ELF ABI and would consider this a linker bug, ARM themselves have an Application Note in which they say that dynamic R_ARM_ABS32 relocations are perfectly fine: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0242a/BCGHDBCB.html

Quote (emphasis mine):

"
... When the ELF object, generated from this example code, is statically linked with the shared library (Example 7.2) that defines bar and x, a dynamic relocation section, .dyn, is generated in the executable image, for example:

** Section #5 '.dyn' (SHT_REL)
    Size    : 16 bytes (alignment 4)
    Symbol table #3 '.dynsym'
    2 relocations applied to section #0 '[Anonymous Section]'

    #    Offset        Relocation Type      Wrt    Symbol    Defined in

    0    0x0000800C    2 R_ARM_ABS32        2      bar       Ref
    1    0x00008024    2 R_ARM_ABS32        3      x         Ref

The relocation type added to the image is R_ARM_ABS32 (relocation number 2 from section 4.6.18 of the ABI ELF for the ARM Architecture document). This is an ARM absolute 32-bit relocation, which is commonly found in static *and dynamic* relocation sections.

...

At load or run-time the dynamic linker might load the shared library into memory, if it is required by the application or another shared library (module).
"