Subject: Text relocations in shared libs
To: None <port-sh3@netbsd.org>
From: Valeriy E. Ushakov <uwe@ptc.spbu.ru>
List: tech-toolchain
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