from the glue code in _rtld_start(). This is used to set objself.relocbase,
rather than assuming that it's the same as objself.mapbase (or 0 on MIPS).
Now -- with a bug fix to the kernel -- ld.elf_so can be linked at any VMA.
_rtld_relocate_nonplt_self(), which is called from _rtld_start.
Now we're completely relocated before main() is called.
We also no longer need _GOT_END_, so junk the ld script.
This code assumes that ld.elf_so only contains RELATIVE relocs, but that's
supposed to be the case for -Bsymbolic anyway.
* Add a ld.so.script that exports _GOT_END_.
* Prebind the GOT in _rtld_start.
* Skip over GOT relocs in _rtld_relocate_nonplt_objects().
This makes debugging work better at least.
Large programs need multiple GOTs. The lazy binding stub in the PLT
can be reached from any of these GOTs, but the dynamic linker only
has enough information to fix up the first GOT entry. Thus, calls
through the other GOTs went through the time-consuming lazy binding
process on every call.
This fix rewrites the PLT entries themselves to bypass the lazy binding
for those GOT entries that the dynamic linker can't fixup.
Fix from FreeBSD.
Note that now that we patch up the PLT, we need to put back the "imb"
that was removed from the binder exit path.
indicates whether we're relocating ld.elf_so itself. Use this in some places
rather than hackish tests on `dodebug'. (The Alpha and HPPA `dodebug' tests
were actually noops, because RTLD_RELOCATE_SELF is not set, and therefore
dodebug is always true.)
executable was of type ET_DYN. Use this instead of `mainprog' to determine
whether we need to do base-relative fixups of the PLT. (This allows loading
non-relocatable objects, should we desire to do that at some point...)
* _rtld_relocate_plt_lazy() fixes up all the relocs pointing to the PLT. (On
most platforms it just does a simple base-relative fixup; on SPARC it does
nothing.)
* _rtld_relocate_plt_object() does immediate binding for a PLT entry.
The basic gist is that this saves a bit of time on SPARC (where the iteration
through the pltrela table was gratuitous), and a little less time on all other
platforms. A whole lot of #ifdef'ed crap is moved out of reloc.c, too.
NOT tested on: hppa sh x86_64
symbol' errors, probably because the increment gets interrupted occasionally by
a signal. In general, _rtld_bind() should not modify ANY internal state.
* Pass a symbol number to _rtld_find_symdef(), not a r_info.
* Don't try to do a symbol lookup when we find an unsupported relocation;
instead get the symbol name from the referencing object's strtab.
* Add preliminary support for `-z combreloc'-style startup optimization on
i386, `#ifdef COMBRELOC'.
executable that uses the library on that line has the rather cryptic
"sysctl" printed when it starts executing.
Switch to (_PATH_LD_HINTS": unknown sysctl for %s", name);
Discovered after someone copied /etc from an i386 to a sparc64 box.
- implement SIMPLEQ_REMOVE(head, elm, type, field). whilst it's O(n),
this mirrors the functionality of SLIST_REMOVE() (the other
singly-linked list type) and FreeBSD's STAILQ_REMOVE()
- remove the unnecessary elm arg from SIMPLEQ_REMOVE_HEAD().
this mirrors the functionality of SLIST_REMOVE_HEAD() (the other
singly-linked list type) and FreeBSD's STAILQ_REMOVE_HEAD()
- remove notes about SIMPLEQ not supporting arbitrary element removal
- use SIMPLEQ_FOREACH() instead of home-grown for loops
- use SIMPLEQ_EMPTY() appropriately
- use SIMPLEQ_*() instead of accessing sqh_first,sqh_last,sqe_next directly
- reorder manual page; be consistent about how the types are listed
- other minor cleanups
- SHLIBDIR Location to install shared libraries if ${USE_SHLIBDIR}
is "yes". Defaults to "/usr/lib".
- USE_SHLIBDIR If "yes", install shared libraries in ${SHLIBDIR}
instead of ${LIBDIR}. Defaults to "no".
Sets ${_LIBSODIR} to the appropriate value.
This may be set by individual Makefiles as well.
- SHLINKDIR Location of shared linker. Defaults to "/usr/libexec".
If != "/usr/libexec", change the dynamic-linker
encoded in shared programs
* Set USE_SHLIBDIR for libraries used by /bin and /sbin:
libc libcrypt libcrypto libedit libipsec libkvm libm libmi387
libtermcap libutil libz
* If ${_LIBSODIR} != ${LIBDIR}, add symlinks from ${LIBDIR}/${LIB}.so*
to ${_LIBSODIR}/${LIB}.so* for compatibility.
* Always install /sbin/init statically (for now)
The net effect of these changes depends on how the variables are set:
1.) If nothing is set or changed, there is no change from the
current behaviour:
- Static /bin, /sbin, and bits of /usr/*
- Dynamic rest
- Shared linker is /usr/libexec/ld*so
2.) If the following make variables are set:
LDSTATIC=
SHLINKDIR=/lib
SHLIBDIR=/lib
Then the behaviour becomes:
- Dynamic tools
- .so libraries used by /bin and /sbin are installed to /lib,
with symlinks from /usr/lib/lib*so to -> /lib/lib*so
where appropriate
- Shared linker is /lib/ld*so
3.) As per 2.), but add the following variable:
USE_SHLIBDIR=yes
This forces all .so's to be instaleld in /lib (with compat
symlinks), not just those tagged by their Makefiles to be.
Again, compat symlinks are installed
thus isolating the "iffy hueristic" from the rest of the relocation code.
* In the "iffy hueristic", use _GOT_END_, not _DYNAMIC.
* Include the addend in Alpha R(RELATIVE) relocations.
old PLT format, and one that works with the new.
XXX We currently always use _rtld_bind_start_old() in
_rtld_setup_alpha_pltgot(). We need to add code to peek
into one of the PLT entries to see which format it's in
and pick the correct binding routine.
relocs for local symbols as section-relative REL32 relocs with values based
at 0, whereas previously BFD generated those relocs with values based at the
start address of the section.
This code adjusts all STT_SECTION REL32 relocs which have values less than
the start of the section by adding in the base address of the section. This
may limit section sizes to 2GB, but that shouldn't be a problem for now.
XXX: Needs to be followed-up with binutils list to get closure on which
interpretation is correct (the new ABI or the old one), I just haven't
yet had the time to chase that.
use to find the end of the GOT, rather than relying on _DYNAMIC
to immediately follow the GOT. (A change in current binutils
moved _DYNAMIC, and thus would have broken our Alpha ld.elf_so).
* Add #ifdef'd out code to deal with the new PLT format.
with them, rather than defaulting them to zero. This caused breakage with
the drawf EH stuff and init/fini code when they weren't used by the caller
(and hence the appropriate handlers were left undefined). Also fix an un-
initialized variable in symbol.c that only MIPS MD code tripped over.
_rtld_bind_start must save and restore the condition codes. Varargs functions
(like, say, printf()) depend on the state of cr1 to determine whether they need
to store floating point registers in the save area. Without this, the first
call to any particular varargs function will fail if floating point values were
passed.
was ambiguous in the case of a weak symbol that was not defined. This caused
RTLD_NOW to fail badly with shared libraries linked against the new crtbegin.o.
<uvm/uvm_param.h> does not exist under 1.5. Tested on i386 and sparc.
Anyway, if it is indeed needed by other platforms then we'll put it back,
but I don't see how since it does not define any types.
0 to be unloaded. Make sure that when we unload those objects we remove
any references to them from the globals list... This fixes SIGSEGV with
apache+mod_php+mysql.
XXX: This fix should be pulled up.
christos
`switch()' code may be translated using a jump table approach which causes
it to reference the equivalent of a global variable, something that must
be avoided before _rtld_init() has run.
* Apply DT_PLTRELSZ to (one of) pltrel or pltrela *after* we've finished
parsing the headers, so we know which one.
* Fix sparc64 bogons. (It works now!)
some unsatisfied references (most often when compiled without necessary
-Wl,-R), so check for that instead of causing null-dereference;
this way the code has a chance to cleanup after itself and report
the error to caller
Thanks to Jason Thorpe for helping fix this!
than by itself. Besides being duplicated code the open-coded version
also did not take care of cleaning up after the object's DAG(!).
Fixes PR bin/8905.
testing and archival for now. I don't expect anyone to work with it
since the binutils and gas changes are still pending. But you got to
crawl before you walk.
region first (using the data/bss protection) covering it, then overlay
the text and data regions at the appropriate offsets within the region,
and then unmap any gap between the text and data.
The previous method of maping the entire address space with the actual
file object itself is incorrect, as it may extend past the end of the
file if the section alignment is large enough.
This bug was the source of the libposix failure on the SPARC and another
similar failure (with libc!) on the Alpha (failure was accompanied by
a "uvn_io: size check fired" message on the console).
runpath > built-in default; this is the behaviour of the SVR4 shared loader,
and gives users the opportunity to override the runpath. (Addresses a report
on current-users by John Kohl.)
no need to save the stack pointer. Just push the space for the cleanup
and obj_main pointers before calling _rtld(), and pop it after loading those
pointers into the appropriate argument registers for the program entry point.
and rename them to match the executable format. Introduce a new link.h
file which automatically picks the correct header based on the target of
the toolchain.
try to check _rtld_objself when doing R_TYPE(RELATIVE) relocs, as the
Alpha ld.elf_so contains them!
I'm not sure the logic for the RELATIVE fix is quite right; it happens to
Work on alpha, but do we actually need to make sure we aren't relocating
ld.elf_so there?
XXX: I am working on making use of RTLD_RELOCATE_SELF on alpha, which may
make this hack of a fix moot.