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
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
Hello Nick, yes, this is exactly, what I wanted [not ;-)] to read. Thank you very much for your time and help! Regards Tom
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). "