Lazy linking issues

Alan Modra alan@linuxcare.com.au
Tue, 26 Sep 2000 19:08:20 +1100 (EST)


OK, here's what I've come up with.

First four entries of the .got are
 0x0 - pointer to dynamic section (as before)
 0x4 - pointer to this object's struct link_map (as before)
 0x8 - address of the fixup function (normal or profile)
 0xc - the LTP value for the fixup function

Code at the start of the .plt looks like:
	b,l	1f,%r26
	depi	0,31,2,%r26
1:	addil	LD'_GLOBAL_OFFSET_TABLE_ + 8 - ($PIC_pcrel$0 - 8),%r26
	ldwm	RD'_GLOBAL_OFFSET_TABLE_ + 8 - ($PIC_pcrel$0 - 12)(%r1),%r26
	copy	%r19,%r25
	ldw	4(%r1),%r19
	bv	%r0(%r26)
	ldw	-4(%r1),%r26

which puts struct link_map * in %r26, reloc offset in %r25, fixup LTP in
%r19, &got[2] in %r1, and branches to the address in got[2].  Funny
enough, this code exposed the fact that gas currently doesn't handle
relocs using the LD and RD field selectors.

A non-pic version saving 2 instructions, but meaning the dynamic linker
needs to relocate some insns:
	ldil	LD'_GLOBAL_OFFSET_TABLE_ + 8,%r1
	ldwm	RD'_GLOBAL_OFFSET_TABLE_ + 8(%r1),%r26
	copy	%r19,%r25
	ldw	4(%r1),%r19
	bv	%r0(%r26)
	ldw	-4(%r1),%r26

We still need some means for elf_machine_runtime_setup to figure out
where the .got starts.  One way is to make PLTGOT do this for us, which is
my preferred solution.  Alternatives would be a) read the elf section
headers, or b) look at the first iplt reloc to find an entry in the .plt,
read the function pointer which give us the above code, extract the .got
pointer from the addil/ldil and ldwm insns.  Was that retching I heard?

Hmm, one variation on this theme that occurs to me, is to put the above
code at the _end_ of the plt - the advantage is that the .got is right
next-door, so we don't need the addil, and case b) above becomes a little
simpler.

Alan Modra
-- 
Linuxcare.  Support for the Revolution.