Subject: Text relocations in shared libs
To: None <port-sh3@netbsd.org>
From: Valeriy E. Ushakov <uwe@ptc.spbu.ru>
List: port-sh3
Date: 12/25/2005 16:02:11
[Thanks to Nick Hudson for discovering this]

For sh3 a few shared libraries in the base system has text
relocations.  This means that ld.so needs to perform relocations
during startup.  E.g.

nada# ktruss echo                                                              
...
   600      1 echo     open("/lib/libc.so.12", 0, 0xfffff804) = 3, 6214
   600      1 echo     __fstat30(0x3, 0x7fffd82c)  = 0, 6214
   600      1 echo     mmap(0, 0x1000, 0x1, 0x1, 0x3, 0, 0, 0) = 0x20434000
   600      1 echo     munmap(0x20434000, 0x1000)  = 0, 541254268
   600      1 echo     mmap(0, 0xdc000, 0x5, 0x10000002, 0x3, 0, 0, 0) = 0x20440000
   600      1 echo     mmap(0x20505000, 0x8000, 0x3, 0x12, 0x3, 0, 0xb5000, 0) = 0x20505000
   600      1 echo     mmap(0x2050d000, 0xf000, 0x3, 0x1012, 0xffffffff, 0, 0, 0) = 0x2050d000
   600      1 echo     mprotect(0x204f6000, 0xf000, 0) = 0
   600      1 echo     close(0x3)                  = 0, 831372
!->600      1 echo     mprotect(0x20440000, 0xb6000, 0x7) = 0
!->600      1 echo     mprotect(0x20440000, 0xb6000, 0x5) = 0

This also means that the pages are no longer shared.


Offending libraries are libc, libposix, and libpthread.  Text
relocations come from the handwritten asm files.  libc and libposix
(that borrows SYS.h code from libc) has a lot of relocs for cerror:

#define _SYSCALL(x,y)					\
		.text;					\
	911:	mov.l	912f, r3;			\
		braf	r3;				\
		nop;					\
		.align	2;				\
	912:	.long	cerror-(911b+6);		\
                ^^^^^^^^^^^^^^^^^^^^^^^
		_SYSCALL_NOERROR(x,y);			\
		bf	911b;				\
		nop

A proper PIC call would be to set up r12 and do the call via plt, but
that raises a number of questions.

plt destroys r0, where syscall code passes errno, so that would either
cause a flag day, or we will need to introduce a flag or'ed into the
syscall number, that would tell the kernel to use a different return
convention.

The benefits of calling cerror via plt are not clear, b/c there's
little point in allowing cerror to be overridden, after all it's just
the error path factored out of all the syscalls.  I'm really inclined
to think that making cerror .protected or even .hidden is the right
thing to do.

libposix will need a copy of cerror to compensate for that change.
Another possible solution is to change libposix to (tail)call into
libc instead of duplicating the actual syscall code in libposix.

Ideas?

SY, Uwe
-- 
uwe@ptc.spbu.ru                         |       Zu Grunde kommen
http://snark.ptc.spbu.ru/~uwe/          |       Ist zu Grunde gehen