History log of /freebsd-current/libexec/rtld-elf/rtld.c
Revision Date Author Comments
# 1cd90a2c 13-May-2024 Andrew Turner <andrew@FreeBSD.org>

rtld: Move powerpc specific code to powerpc files

There are two variables set by dynamic tags in the powerpc runtime
linker. Now we have a way to split out architecture-specific dynamic
tags use it to handle these.

Reviewed by: kib, jhibbits
Obtained from: jhibbits (earlier version)
Sponsored by: Arm Ltd
Differential Revision: https://reviews.freebsd.org/D45182


# dd4155be 07-May-2024 Andrew Turner <andrew@FreeBSD.org>

rtld: Add arch_digest_dynamic

This will be used to handle the DT_AARCH64_VARIANT_PCS tag.

Reviewed by: kib
Sponsored by: Arm Ltd
Differential Revision: https://reviews.freebsd.org/D45117


# ef2694f3 28-Apr-2024 Konstantin Belousov <kib@FreeBSD.org>

rtld direct exec: make -u behavior match the description

Instead of only ignoring insecure env vars, clear them all.

Reviewed by: emaste, markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D44999


# d1cd0cc3 27-Apr-2024 Konstantin Belousov <kib@FreeBSD.org>

rtld: add direct-exec option -o

allowing to set any known LD_ parameter for the current rtld invocation,
but without polluting the activated' binary environment. In other
words, the set parameter is not exported into the environment.

Reviewed by: markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D44988


# d8925a5f 05-Apr-2023 Andrew Turner <andrew@FreeBSD.org>

Support BTI in rtld

Read the elf note to decide when to set the guard page on arm64.

Reviewed by: kib
Sponsored by: Arm Ltd
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D39452


# c44bf7d2 22-Mar-2024 Stefan Eßer <se@FreeBSD.org>

rtld: reduce debug messages after fix on big-endian hosts

Remove a debug message that had been added to support the debugging
of a mis-detection of the hint files endianness on powerpc64.

MFC after: 3 days


# da2d6e28 22-Mar-2024 Michael Tuexen <tuexen@FreeBSD.org>

rtld: fix check for endianess of elf hints file

Don't check if the elf hints file is in host byte order, but check
if it is in little endian by looking at the magic number.
This fixes rtld on big endian platforms.
Reviewed by: se, kib (prior version of the patch)
Fixes: 7b77d37a561b ("rtld-elf: support either byte-order of hints")
MFC after: 3 days
Differential Revision: https://reviews.freebsd.org/D44472


# 17395318 21-Mar-2024 Stefan Eßer <se@FreeBSD.org>

rtld-elf: add some debug print statements

The byte-order independent code has been reported to fail on powerpc64.
Add some more debug statements to help identify the parametrs used and
to verify the correct operation of the byte-swap macros used..


# 7b77d37a 26-Feb-2024 Stefan Eßer <se@FreeBSD.org>

rtld-elf: support either byte-order of hints file

Accept either little-endian or big-endian representation of the ELF
hints magic number in the header of a hints file and convert the
parameters to the native byte-order of the repsective system.

This is a pre-requisite for a planned change to always write the byte
order in little-endian format on all architectures. The only relvant
architecture that uses big-endian data is powerpc64, and it is not
likely that new architectures will choose that representation of data
in memory.

When all supported architectures use little-endian data in the hints
file, the byte swap logic can be enabled for big-endian CPUs at
compile time. Up to that point, there is a very small run-time penalty
that is paid on all systems to check the byte-order of the hints file
and to provide the option to byte-swap the parameters read from the
hints file header.

This commit contains the changes from review D44080 (which had been
split off from this patch for easier review),

Reviewed by: kib
MFC after: 1 month
Differential Revision: https://reviews.freebsd.org/D44053


# 452c5e99 21-Feb-2024 Konstantin Belousov <kib@FreeBSD.org>

fdlopen(3): do not create a new object mapping if already loaded

This is expected behavior for both dlopen(3) and fdlopen(3).

PR: 277169
Reviewed by: emaste
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D44019


# 968a1897 12-Feb-2024 Konstantin Belousov <kib@FreeBSD.org>

rtld: ignore load_filtees() calls if we already loading filtees for the obj

in addition to avoiding it for already loaded filtees. Issue is that
during load, rtld needs to resolve some special ABI symbols, like
executable stack fixer and static TLS initializer, which might trigger
recursion.

Example is libthr which is filter for libsys, and which exports
__pthread_distribute_static_tls.

Tested by: kevans, krion
Reviewed by: markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D43858


# 30b5f6b3 12-Feb-2024 Konstantin Belousov <kib@FreeBSD.org>

rtld load_filtees(): reindent and reduce block nesting

Reviewed by: markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D43858


# 9ea864b5 12-Feb-2024 Konstantin Belousov <kib@FreeBSD.org>

rtld symlook_obj: move common code to check filtees into helper

Revieved by: markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D43858


# e7951d0b 01-Feb-2024 Mark Johnston <markj@FreeBSD.org>

rtld-elf: Avoid unnecessary lock_restart_for_upgrade() calls

In order to atomically upgrade the rtld bind lock, load_filtees() may
trigger a longjmp back to _rtld_bind() so that the binding can be done
with the write lock held. However, the write lock is only needed when
filtee objects haven't already been loaded, so move the
lock_restart_for_upgrade() call to avoid unnecessary lock upgrades when
a filtee is defined.

Reviewed by: kib
Tested by: brooks
MFC after: 1 week
Sponsored by: Innovate UK


# 9daf6cd0 29-Nov-2023 Konstantin Belousov <kib@FreeBSD.org>

RTLD_DEEPBIND: make lookup not just symbolic, but walk all refobj' DAGs

before starting the walk over the global list. Effectively we visit
needed objects first as well, instead of just the object itself.
This seems to better match the semantic offered by the glibc flag.

Reported by: kevans
PR: 275393
Reviewed by: kevans
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D42841


# a6fe717c 24-Nov-2023 Warner Losh <imp@FreeBSD.org>

libexec: Automated cleanup of cdefs and other formatting

Apply the following automated changes to try to eliminate
no-longer-needed sys/cdefs.h includes as well as now-empty
blank lines in a row.

Remove /^#if.*\n#endif.*\n#include\s+<sys/cdefs.h>.*\n/
Remove /\n+#include\s+<sys/cdefs.h>.*\n+#if.*\n#endif.*\n+/
Remove /\n+#if.*\n#endif.*\n+/
Remove /^#if.*\n#endif.*\n/
Remove /\n+#include\s+<sys/cdefs.h>\n#include\s+<sys/types.h>/
Remove /\n+#include\s+<sys/cdefs.h>\n#include\s+<sys/param.h>/
Remove /\n+#include\s+<sys/cdefs.h>\n#include\s+<sys/capsicum.h>/

Sponsored by: Netflix


# 95335dd3 29-Oct-2023 Stephen J. Kiernan <stevek@FreeBSD.org>

rtld: introduce STATIC_TLS_EXTRA

The new STATIC_TLS_EXTRA variable provides a means for applications
to increases the size of the extra static TLS space allocated by
rtld beyond the default of '128'. This extra static TLS space is used
for objects loaded with dlopen.

The value specified in the variable must be no less than the default
value and no greater than the maximum allowed value for size_t type.

If an invalid value is specified, rtld will ignore it and just use
the default value.

The rtld(1) man page is updated to document this new option.

Obtained from: Juniper Networks, Inc.
Differential Revision: https://reviews.freebsd.org/D42025


# 72d97e1d 15-Sep-2023 Konstantin Belousov <kib@FreeBSD.org>

rtld: output rtld errors into the dbg channel

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# feaae6ba 29-Jul-2023 Konstantin Belousov <kib@FreeBSD.org>

rtld: switch from malloc_aligned() to __crt_aligned_alloc()

Use regular free(), since it works now.

Reviewed by: markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D41150


# b1d3e2b7 18-Aug-2023 Konstantin Belousov <kib@FreeBSD.org>

rtld: unlock bind lock when calling into crt __pthread_distribute_static_tls method

The method might require resolving and binding symbols, which means
recursing on the bind lock. It is safe to unlock the bind lock,
since we operate on the private object list, and user attempting to
unload an object from the list of not yet fully loaded objects caused
self-inflicted race.

It is similar to how we treat user' init/fini methods.

Reported by: stevek
Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 1d386b48 16-Aug-2023 Warner Losh <imp@FreeBSD.org>

Remove $FreeBSD$: one-line .c pattern

Remove /^[\s*]*__FBSDID\("\$FreeBSD\$"\);?\s*\n/


# 1005d3d0 14-Jul-2023 Konstantin Belousov <kib@FreeBSD.org>

rtld: fix dlopen() for an object that is already mapped but not yet initialized

For instance, dso might be mapped as needed but not yet initialized from
the other subtree of needed objects, while current object' constructor
does dlopen() for the dso. Right now rtld does relocations and other
processing based on the arrival of new objects in the global list, which
is not happens there. Directly check for the initialization state of
the object, for which we would return the handle.

One practical use case of this support is e.g. dlopen("libthr.so",
RTLD_NOLOAD) by libraries that are threading-aware but happy to live
with libc pthread shims if the program is not multithreaded.

Reviewed by: tijl
Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks


# f940929d 09-Jul-2023 Jessica Clarke <jrtc27@FreeBSD.org>

rtld-elf: Migrate from COMPAT_32BIT to generic COMPAT_libcompat/LIBCOMPAT

We still have a tiny amount of libcompat-specific code in rtld_paths.h,
but it's been deduplicated as much as possible, and in future we may
wish to just push these variables down to the few consumers of them and
make them use the double-underscore variants with a libcompat argument
rather than give them names here.

See commit 8fad2cda93c7 ("bsd.compat.mk: Provide new CPP and sub-make
variables") for the context behind this change.

Reviewed by: kib, brooks, jhb
Differential Revision: https://reviews.freebsd.org/D40925


# 38efd4df 20-Jun-2023 John Baldwin <jhb@FreeBSD.org>

rtld-elf: Mark tls_init_align __unused in free_tls for Variant I TLS.

Some architectures (powerpc and RISC-V) always use 0 for the post TLS
size in which case tls_init_align isn't used by
calculate_tls_post_size. Use __unused to quiet the warning for these
platforms.

Reviewed by: kib
Differential Revision: https://reviews.freebsd.org/D40673


# e9a38ed2 08-Jun-2023 Konstantin Belousov <kib@FreeBSD.org>

rtld: fix allocate_module_tls() variant I fallback to static allocation

Submitted by: Joerg Sonnenberger
Fixes: 91880e07f605edb90339685bc934699a4344de3bESC
MFC after: 1 week


# 91880e07 04-Jun-2023 Konstantin Belousov <kib@FreeBSD.org>

rtld: do not allow both dynamic DTV index and static TLS offset

If we are allocating static offset for an object with dynamic index,
return failure. In the opposite case, if dynamic index is requested for
statically allocated TLS area, directly use the offset instead of
setting the index.

Taken from NetBSD Joerg Sonnenberger change for src/libexec/ld.elf_so/tls.c
rev. 1.18.

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 283a4f40 04-Jun-2023 Konstantin Belousov <kib@FreeBSD.org>

rtld: rename tls_done to tls_static

The meaning of the flag is that static TLS allocation was done.

Taken from NetBSD Joerg Sonnenberger change for src/libexec/ld.elf_so/tls.c
rev. 1.18.

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 4d846d26 10-May-2023 Warner Losh <imp@FreeBSD.org>

spdx: The BSD-2-Clause-FreeBSD identifier is obsolete, drop -FreeBSD

The SPDX folks have obsoleted the BSD-2-Clause-FreeBSD identifier. Catch
up to that fact and revert to their recommended match of BSD-2-Clause.

Discussed with: pfg
MFC After: 3 days
Sponsored by: Netflix


# 7cdfe51f 12-Apr-2023 Konstantin Belousov <kib@FreeBSD.org>

rtld: fixes for handling of the grouped options

Do not terminate scanning group when 'd' is encountered.
The 'b' option must be last in the group, same as 'f'.

Reviewed by: markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D39544


# 29e3a065 12-Apr-2023 Ed Maste <emaste@FreeBSD.org>

rtld: fix SysV hash function overflow

Quoting from https://maskray.me/blog/2023-04-12-elf-hash-function:

The System V Application Binary Interface (generic ABI) specifies the
ELF object file format. When producing an output executable or shared
object needing a dynamic symbol table (.dynsym), a linker generates a
.hash section with type SHT_HASH to hold a symbol hash table. A DT_HASH
tag is produced to hold the address of .hash.

The function is supposed to return a value no larger than 0x0fffffff.
Unfortunately, there is a bug. When unsigned long consists of more than
32 bits, the return value may be larger than UINT32_MAX. For instance,
elf_hash((const unsigned char *)"\xff\x0f\x0f\x0f\x0f\x0f\x12") returns
0x100000002, which is clearly unintended, as the function should behave
the same way regardless of whether long represents a 32-bit integer or
a 64-bit integer.

Reviewed by: kib, Fangrui Song
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D39517


# 87443cb6 12-Apr-2023 Ed Maste <emaste@FreeBSD.org>

rtld: reindent and style(9) elf_hash()

In preparation for an upcoming change (D39517).

Sponsored by: The FreeBSD Foundation


# b069d3e0 04-Jan-2023 John Baldwin <jhb@FreeBSD.org>

rtld: Revert "When loading dso without PT_GNU_STACK phdr, only call"

After the removal of ia64 and sparc64, all current architectures
support executable stacks at an architectural level.

This reverts commit 1290d38ac50b3afa7e5781d9d97346a1042c736c.

Reviewed by: kib
Sponsored by: DARPA
Differential Revision: https://reviews.freebsd.org/D37904


# 8cc44a1e 10-Nov-2022 Konstantin Belousov <kib@FreeBSD.org>

rtld: add support for the $LIB token

similar to the same token in glibc.

Requested and reviewed by: bapt
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D37329


# f585d13d 21-Oct-2022 Konstantin Belousov <kib@FreeBSD.org>

rtld: remove unused macro FPTR_TARGET

It is a remnant from the ia64 removal

Sponsored by: The FreeBSD Foundation
MFC after: 3 days


# 2f72ee98 17-Sep-2022 Konstantin Belousov <kib@FreeBSD.org>

ldd: remove '[preloaded]' marker for the preloaded objects

for the default output. For '-a' (per-object needed printout) the
[preloaded] banner is kept.

Instead, use special format2 for printing the preloaded objects (and
vdso), which does not include DT_NEEDED, since there is no object
needing the printed one.

In this way, the output is more compatible with glibc.

Example:
LD_PRELOAD=/lib/libthr.so.3 LD_TRACE_LOADED_OBJECTS=1 /libexec/ld-elf.so.1 /bin/ls
libutil.so.9 => /lib/libutil.so.9 (0x801099000)
libncursesw.so.9 => /lib/libncursesw.so.9 (0x8010b0000)
libc.so.7 => /lib/libc.so.7 (0x801123000)
[vdso] (0x7ffffffff000)
/lib/libthr.so.3 (0x80106c000)
Note the absense of the part before and including '=>' for preloaded
libthr.so.3, and for vdso.

PR: 265750
Reviewed by: jhb
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D36616


# daa85548 15-Sep-2022 Konstantin Belousov <kib@FreeBSD.org>

rtld: teach LD_SHOW_AUXV about AT_USRSTACK*

Reviewed by: brooks, imp (previous version)
Discussed with: markj
Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks
Differential revision: https://reviews.freebsd.org/D36540


# 832b40f7 30-Aug-2022 Konstantin Belousov <kib@FreeBSD.org>

rtld.c: remove extra blank line

Reviewed by: markj
Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks
Differential revision: https://reviews.freebsd.org/D36396


# 008475d3 14-Aug-2022 Konstantin Belousov <kib@FreeBSD.org>

rtld: fix display of the mapbase for the traced objects

Commit 24d0c9c1f565bab6e introduced the following regression:
% ldd /bin/ls
/bin/ls:
libutil.so.9 => /lib/libutil.so.9 (0x1021000)
libncursesw.so.9 => /lib/libncursesw.so.9 (0x1021000)
libc.so.7 => /lib/libc.so.7 (0x1021000)
Note that the base address is the same for all displayed libraries.

Fix it by passing correct object to trace_print_obj().

Fixes: 24d0c9c1f565bab6e
Reviewed by: jrtc27
MFC after: 3 days
Sponsored by: The FreeBSD Foundation
MFC after: 3 days
Differential revision: https://reviews.freebsd.org/D36198


# becd9908 12-Jul-2022 Jessica Clarke <jrtc27@FreeBSD.org>

rtld-elf: Fix leaks and wild frees in origin_subst

55abf23dd36b inverted the value passed to origin_subst_one when rolling
up the existing code into a loop. If the first token is found ($ORIGIN),
this results in a wild free of part of strtab. Processing the second
token works fine and will act how the first should have regardless of
whether found, allocating memory for the string without freeing.
Processing subsequent tokens however will then leak, regardless of
whether found, as they will also believe they need to allocate memory
and can't free the string.

Found by: CHERI
Reviewed by: kib, markj
Fixes: 55abf23dd36b ("rtld: make token substitution table-driven")
MFC after: 3 days
Differential Revision: https://reviews.freebsd.org/D35792


# e85eaa93 04-Apr-2022 Andrew Turner <andrew@FreeBSD.org>

Have rtld query the page size from the kernel

To allow for a dynamic page size on arm64 have the runtime linker
query the kernel for the currentl page size.

Reviewed by: kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D34765


# 0913953c 30-Mar-2022 Konstantin Belousov <kib@FreeBSD.org>

rtld: trace preloaded objects

Before, preloaded objects, if not listed as needed for any normally
linked objects, were silently ignored.

Preloaded objects are printed with the `[preloaded]` herald. The list
includes the objects not listed explicitly as recursive dependencies of
the main object, effectively dsos loaded by LD_PRELOAD mechanism.
vdso is listed as well, since it is not needed by anything.

Since there is no DT_NEEDED entry for LD_PRELOADed objects, they are
usually printed using LD_TRACE_LOADED_OBJECTS_FTM2 format due to the
failure of the heuristic based on the presence of the 'lib' prefix.

Reviewed by: markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D34716


# db037280 30-Mar-2022 Konstantin Belousov <kib@FreeBSD.org>

rtld trace_loaded_objects(): use bool for the list_containers variable

Reviewed by: markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D34716


# b0bc8cc7 30-Mar-2022 Konstantin Belousov <kib@FreeBSD.org>

rtld: use style(9) for trace_loaded_objects()

Reviewed by: markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D34716


# 24d0c9c1 30-Mar-2022 Konstantin Belousov <kib@FreeBSD.org>

rtld: extract printer for a single traced object into a helper

Reviewed by: markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D34716


# c25f36f6 30-Mar-2022 Konstantin Belousov <kib@FreeBSD.org>

rtld: extract calculation of the format strings for trace into a helper

Reviewed by: markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D34716


# b1b51741 11-Feb-2022 Konstantin Belousov <kib@FreeBSD.org>

rtld: Add ${TOKEN} aliases to $TOKEN

it seems that glibc supports them, and such spelling is mentioned in the
ld.bfd manual. Idea seems to auto-correct some quoting/makefile sytnax
errors on linker command line.

Reviewed by: emaste, markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D34247


# 55abf23d 11-Feb-2022 Konstantin Belousov <kib@FreeBSD.org>

rtld: make token substitution table-driven

Reviewed by: emaste, markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D34247


# d33d8f7e 27-Jan-2022 John Baldwin <jhb@FreeBSD.org>

rtld: Fix assertion I broke.

textrel is a bool, not a pointer.

Pointy hat to: jhb
Reported by: kevans
Fixes: 6a2d75d24857 rtld: Trim a few more MIPS #ifdefs.


# 6a2d75d2 27-Jan-2022 John Baldwin <jhb@FreeBSD.org>

rtld: Trim a few more MIPS #ifdefs.

Reviewed by: imp, kib
Sponsored by: The University of Cambridge, Google Inc.
Differential Revision: https://reviews.freebsd.org/D34052


# 2bf21b0e 06-Jan-2022 Konstantin Belousov <kib@FreeBSD.org>

Restore DT_DEBUG processing

Pointed out by: kevans
Fixes: 292cba9b4919ee188ca08cc8bf5057e346514383
Sponsored by: The FreeBSD Foundation


# 292cba9b 05-Jan-2022 Konstantin Belousov <kib@FreeBSD.org>

rtld: remove mips-specific cases from generic code

Reviewed by: imp
Sponsored by: The FreeBSD Foundation
Differential revision: https://reviews.freebsd.org/D33763


# 8bcdb144 09-Dec-2021 John Baldwin <jhb@FreeBSD.org>

TLS: Use <machine/tls.h> for libc and rtld.

- Include <machine/tls.h> in MD rtld_machdep.h headers.

- Remove local definitions of TLS_* constants from rtld_machdep.h
headers and libc using the values from <machine/tls.h> instead.

- Use _tcb_set() instead of inlined versions in MD
allocate_initial_tls() routines in rtld. The one exception is amd64
whose _tcb_set() invokes the amd64_set_fsbase ifunc. rtld cannot
use ifuncs, so amd64 inlines the logic to optionally write to fsbase
directly.

- Use _tcb_set() instead of _set_tp() in libc.

- Use '&_tcb_get()->tcb_dtv' instead of _get_tp() in both rtld and libc.
This permits removing _get_tp.c from rtld.

- Use TLS_TCB_SIZE and TLS_TCB_ALIGN with allocate_tls() in MD
allocate_initial_tls() routines in rtld.

Reviewed by: kib, jrtc27 (earlier version)
Differential Revision: https://reviews.freebsd.org/D33353


# c210ef13 11-Nov-2021 Konstantin Belousov <kib@FreeBSD.org>

rtld: load preloaded vdso

Reviewed by: emaste
Discussed with: jrtc27
Tested by: pho
Sponsored by: The FreeBSD Foundation
MFC after: 1 month
Differential revision: https://reviews.freebsd.org/D32960


# 01c77a43 11-Nov-2021 Konstantin Belousov <kib@FreeBSD.org>

Pass vdso address to userspace

Reviewed by: emaste
Discussed with: jrtc27
Tested by: pho
Sponsored by: The FreeBSD Foundation
MFC after: 1 month
Differential revision: https://reviews.freebsd.org/D32960


# b61bce17 13-Nov-2021 Konstantin Belousov <kib@FreeBSD.org>

rtld dump_auxv: be pedantic and distiguish between auxv union members based on format

Reviewed by: jrtc27
Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 3a902ef2 13-Nov-2021 Konstantin Belousov <kib@FreeBSD.org>

rtld dump_auxv: consistently use long modifier for non-pointer auxv vals

Reviewed by: jrtc27
Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 64ba1f4c 12-Nov-2021 Konstantin Belousov <kib@FreeBSD.org>

rtld: Implement LD_SHOW_AUXV

It dumps auxv as seen by interpreter, right before starting any user
code.

Copied from: glibc
Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 74aec961 05-Nov-2021 Konstantin Belousov <kib@FreeBSD.org>

rtld: style adjustments

Consistently use `return ()'.
Fix some spacing issues with types formatting, and around binary ops.

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# c5637b8b 05-Nov-2021 Konstantin Belousov <kib@FreeBSD.org>

rtld: ignore fstatfs(2) errors when checking MNT_NOEXEC flag

File descriptor we operate on might reference something that is not a
file, e.g. shmfd. In this case, we cannot check MNT_NOEXEC in
principle.

If fstatfs(2) caused some failure on normal filesystem, then typical
expectation is that read or mmap of this file would also fail. If not,
mmap(2) PROT_EXEC on MNT_NOEXEC filesystem returns EACCES.

Reported by: obiwac@gmail.com
Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 8363963a 05-Nov-2021 Konstantin Belousov <kib@FreeBSD.org>

rtld: fix dangerous_ld_env calculation for ld_dynamic_weak

Default value for ld_dynamic_weak is true, non-default settings should
be activated for the false value.

Reported by: obiwac@gmail.com
Sponsored by: The FreeBSD Foundation
MFC after: 3 days


# 40ddde6e 25-Oct-2021 Konstantin Belousov <kib@FreeBSD.org>

rtld: Print currently configured search path for libraries for -v

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 33dba3bb 12-Oct-2021 Konstantin Belousov <kib@FreeBSD.org>

rtld-elf/paths.h: Make it usable outside rtld

but still for tightly coupled things like ldd(1)

Rename paths.h to rtld_paths.h.
Add guard for rtld-specific externs declarations.
Add _COMPAT32_BASENAME_RTLD and _COMPAT32_PATH_RTLD.

Reviewed by: arichardson, jhb
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D32464


# a7d137fc 16-Oct-2021 Fangrui Song <i@maskray.me>

rtld: Support DT_RELR relative relocation format

PIE and shared objects usually have many relative relocations. In
2017/2018, a compact relative relocation format RELR was proposed on
https://groups.google.com/g/generic-abi/c/bX460iggiKg/m/GxjM0L-PBAAJ
("Proposal for a new section type SHT_RELR") and is a pre-standard.
RELR usually takes 3% or smaller space than R_*_RELATIVE relocations.
The virtual memory size of a mostly statically linked PIE is typically
5~10% smaller.

ld.lld --pack-dyn-relocs=relr emits RELR relocations. DT_RELR has been
adopted by Android bionic, Linux kernel's arm64 port, Chrome OS (patched
glibc).

This patch adds DT_RELR support to FreeBSD rtld-elf.

MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D32524


# ba7f9c1b 11-Oct-2021 Konstantin Belousov <kib@FreeBSD.org>

rtld direct exec: add -d option

to ignore lack of execute permission on the binary. The check is a
bad security theatre anyway.

Reviewed by: arichardson, imp
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D32464


# aa68b3bb 16-Aug-2021 Konstantin Belousov <kib@FreeBSD.org>

rtld: constify most variables holding references to the environment values

Reviewed by: markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D31545


# b4b27488 16-Aug-2021 Konstantin Belousov <kib@FreeBSD.org>

rtld: provide private getenv(3)

Reviewed by: arichardson, markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D31545


# bfd4c875 16-Aug-2021 Konstantin Belousov <kib@FreeBSD.org>

rtld: avoid use of of getenv(3) for evaluating rtld env vars (LD_XXX)

Scan through the set of environment variables during initialization and
store values in the corresponding ld_env_var_desc structure, in the
single pass at init time. This does not eliminate use of getenv(3) and
unsetenv(3) completely, but provides a foundation to do that as the next
step.

Also organize the scan in a way that makes it easier to support aliases
like LD_DEBUG vs. LD_64_DEBUG.

Suggested by: arichardson
Reviewed by: arichardson, markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D31545


# 451dc2b7 15-Aug-2021 Konstantin Belousov <kib@FreeBSD.org>

rtld: rework how environment variables are named

Instead of specifying the main name part of the environment variable as the
string literal, create array of the var names and access them by symbolic
index. Convert main name parts into complete names by prefixing with
ABI-specific ld_env_vars.

This way the name is not repeated, and also it can carry additional
proporties explicitly. For instance, cleanup of the environment for
the setuid image does not require retyping all names.

Reviewed by: arichardson, markj
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
Differential revision: https://reviews.freebsd.org/D31545


# 7da378f9 14-Aug-2021 Fangrui Song <i@maskray.me>

rtld: Switch to the standard symbol lookup behavior if LD_DYNAMIC_WEAK is set

The current lookup prefers a strong definition to a STB_WEAK definition
(similar to glibc pre-2.2 behavior) which does not conform to the ELF
specification.

The non-compliant behavior provoked https://reviews.llvm.org/D4418
which was intended to fix -shared-libasan but introduced
new problems (and caused some sanitizer tests (e.g.
test/asan/TestCases/interception_failure_test.cpp) to fail): sanitizer
interceptors are STB_GLOBAL instead of STB_WEAK, so defining a second
STB_GLOBAL interceptor can lead to a multiple definition linker error.
For example, in a -fsanitize={address,memory,...} build, libc functions
like malloc/free/strtol/... cannot be provided by user object files.

See
https://docs.freebsd.org/cgi/getmsg.cgi?fetch=16483939+0+archive/2014/freebsd-current/20140716.freebsd-current
for discussions.

This patch implements the ELF-compliant behavior when LD_DYNAMIC_WEAK is
set. STB_WEAK wrestling in symbol lookups in `Search the dynamic linker
itself` are untouched.

Reviewed by: kib
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D26352


# 8f63fa78 14-Aug-2021 Fangrui Song <i@maskray.me>

rtld: Remove calculate_tls_end

Variant I architectures use off and Variant II ones use size + off.
Define TLS_VARIANT_I/TLS_VARIANT_II symbols similarly to how libc
handles it.

Reviewed by: kib
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D31539
Differential revision: https://reviews.freebsd.org/D31541


# c9f833ab 11-Aug-2021 Konstantin Belousov <kib@FreeBSD.org>

rtld: Round down relro_size

lld rounds up p_memsz(PT_GNU_RELRO) to satisfy common-page-size. If the
page size is smaller than common-page-size, rounding up relro_size may
incorrectly make some RW pages read-only.

GNU ld, gold, and ld.lld ensures p_vaddr+p_memsz is a multiple of
common-page-size. While max-page-size >= system the page size,
common-page-size can be smaller than the system page size.

Submitted by: MaskRay
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D31498


# e3be51b2 22-Jun-2021 Alex Richardson <arichardson@FreeBSD.org>

rtld-elf: Check the return value of obj_enforce_relro()

The mprotect() call was failing on CheriBSD when changing rtld's relro
page permissions due to missing CHERI capability permissions on the
mprotect() argument but did not report an error since the return value
was being ignored. It should never fail on any supported FreeBSD
architecture, but checking the return value seems like a good
sanity check to me.

Reviewed By: kib, imp
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D30820


# e3149e0a 02-Jun-2021 Konstantin Belousov <kib@FreeBSD.org>

rtld: Rename -t option to -u (ignore LD_ vars)

Requested by: arichardson
Sponsored by: The FreeBSD Foundation
MFC after: 3 days


# d81f999a 28-May-2021 Konstantin Belousov <kib@FreeBSD.org>

rtld direct exec: add option to ignore LD_ variables

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 630caa95 10-May-2021 Konstantin Belousov <kib@FreeBSD.org>

rtld: preserve the 'seen' state of the dlerror message in errmsg_save()

rtld preserves its current error message around calls to user init/fini
lists, to not override original error with potential secondary errors
caused by user code recursing into rtld. After 4d9128da54f8f8e2a29190,
the preservation of the string itself is not enough, the 'seen'
indicator must be preserved as well. Otherwise, since new code does not
clear string (it cannot), call to _rtld_error() from errmsg_restore()
revived whatever message was consumed last.

Change errmsg_save() to return structure recording both 'seen' indicator
and the message, if any.

PR: 255698
Reported by: Eugene M. Kim <astralblue@gmail.com>
Sponsored by: The FreeBSD Foundation
MFC after: 3 days


# 4d9128da 07-Apr-2021 Konstantin Belousov <kib@FreeBSD.org>

rtld: make dlerror() thread-local

PR: 95339
Discussed with: arichardson
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D29633


# 4d7f08c8 10-Apr-2021 Konstantin Belousov <kib@FreeBSD.org>

rtld: unstaticise lockinfo and obj_from_addr()

Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D29633


# 7cb32a0d 06-Apr-2021 Konstantin Belousov <kib@FreeBSD.org>

rtld: avoid recursing on rtld_bind_lock for write

This fixes a regression in d36d6816151705907393889, where the call to
__tls_get_address() was performed under rtld_bind_lock write-locked.
Instead use tls_get_addr_slow() directly, with locked = true.

Reported by: jkim, many others
Tested by: jkim, bdragon (powerpc), mhorne (riscv)
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D29623


# 89508048 06-Apr-2021 Konstantin Belousov <kib@FreeBSD.org>

rtld: allow to use tls_get_addr_slow() from context where rtld_bind_lock is locked

Explicit locked parameter is added

Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D29623


# 85d846b3 06-Apr-2021 Konstantin Belousov <kib@FreeBSD.org>

rtld: style tls_get_addr_slow

Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D29623


# d36d6816 04-Apr-2021 Konstantin Belousov <kib@FreeBSD.org>

rtld dl_iterate_phdr(): dlpi_tls_data is wrong

dl_iterate_phdr() dlpi_tls_data should provide the TLS module segment
address, and not the TLS init segment address as it does now.

Reported by: emacsray@gmail.com
PR: 254774
Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# f9021888 24-Mar-2021 Mariusz Zaborski <oshogbo@FreeBSD.org>

rtld: introduce PRELOAD_FDS

The new PRELOAD_FDS variable accepts a list of file descriptors
that should be loaded into the process.

This may be used to optimize a loading process - in the case when
we already have a file descriptor to the library; we don't have
to look into multiple PATH to find it.

It may also be used in capability mode to load a single additional
library without the need to open a directory that contains it.

The last use of this functionality t may be a race-free method
of loading libraries.

Reviewed by: kib, markj
Differential Revision: https://reviews.freebsd.org/D29334


# 852a88a1 24-Mar-2021 Mariusz Zaborski <oshogbo@FreeBSD.org>

rtld: style nits

No functional change intended.

Requested by: kib


# 43d44842 02-Feb-2021 David Chisnall <theraven@FreeBSD.org>

rtld: Fix null-pointer dereference

When a library is opened via fdlopen, it has a null pointer for its path
and so _rtld_bind can crash as a result of passing the null pointer to
basename() (which passes it to strrchr(), which doesn't do a null check).

PR: 253081
Submitted by: theraven
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D28442


# 613a08cf 04-Jan-2021 Ed Maste <emaste@FreeBSD.org>

rtld: map without PROT_EXEC for relocation

This makes text segment relocation work under W^X.

Submitted by: Greg V <greg@unrelenting.technology> (original version)
Reviewed by: kib
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D27953


# b58c853e 24-Dec-2020 Marius Strobl <marius@FreeBSD.org>

rtld-elf(1): remove obsolete pre_init() hook

It's no longer used since 600ee699ed2805894f5972c6ac2c3d17dca7f6ce
and r358358 respectively.


# 71df6a15 01-Dec-2020 Konstantin Belousov <kib@FreeBSD.org>

rtld: bump r_debug.r_version to 1 from current 0.

Add r_ldbase.

Requested and reviewed by: emaste
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D27429


# 1db23efb 07-Sep-2020 Konstantin Belousov <kib@FreeBSD.org>

rtld: pass argc/argv/env to dso inits.

This is consistent with how array inits are called, and also makes us
more compatible with glibc environment.

Requested by: Alex S <iwtcex@gmail.com>
PR: 249162
Reviewed by: dim, emaste
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D26351


# 50043305 05-Sep-2020 Konstantin Belousov <kib@FreeBSD.org>

rtld: do not refuse to relocate objects without dynamic symtabs.

Such objects can still have valid relocations not requiring symbolic
references.

PR: 249121
Reported by: wsh@riski.sh
Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 2b49b95c 05-Sep-2020 Konstantin Belousov <kib@FreeBSD.org>

rtld: do not process absent dynamic.

If object has no dynamic phdr, do not try to dereference NULL. This
means that we cannot process any relocation, and that there cannot be
symbols defined, but it is up to static linker to produce meaningful
objects.

PR: 249121
Reported by: wsh@riski.sh
Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# e9751a84 16-Jul-2020 John Baldwin <jhb@FreeBSD.org>

Include FreeBSD ABI tag note in the ELF runtime loader.

Reviewed by: kib
Sponsored by: DARPA
Differential Revision: https://reviews.freebsd.org/D25306


# a5467d6c 06-Jul-2020 Leandro Lupori <luporl@FreeBSD.org>

Handle non-PLT GNU IFUNC relocations in rtld

In the last IFUNC related changes to rtld, the code that handled non-PLT
GNU IFUNC relocations ended up getting lost. This could leave some
relocations unhandled, causing crashes or misbehavior. This change restores
the handling of these relocations, but now together with the other IFUNC
relocations, allowing resolvers to reference external symbols.

Reviewed by: kib
MFC after: 2 weeks
Sponsored by: Eldorado Research Institute (eldorado.org.br)
Differential Revision: https://reviews.freebsd.org/D25550


# 7e400f1a 18-Jun-2020 Konstantin Belousov <kib@FreeBSD.org>

rtld: Apply relro to itself.

Reviewed by: emaste
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D25319


# e0b322ae 18-Jun-2020 Konstantin Belousov <kib@FreeBSD.org>

rtld: Parse own phdr and notes.

Reviewed by: emaste
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D25319


# 512baba6 16-Jun-2020 Konstantin Belousov <kib@FreeBSD.org>

rtld: Allow to load ET_DYN && DF_1_PIE when tracing.

This makes old ldd to still work on newer tagged PIE binaries.

Also move debug line for hashes before both decisions to not load are
done, so that the end of digest_dynamic() processing and reason to not
load or load is seen in debug trace.

Noted by: jhb
Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 53b1c320 16-Jun-2020 Konstantin Belousov <kib@FreeBSD.org>

rtld: Add debug line for dlopen_object().

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# de344015 16-Jun-2020 Konstantin Belousov <kib@FreeBSD.org>

Systematically pass RTLD_LO_TRACE to load_needed_objects().

Which makes all calls to load_object() to observe the flag, except the
calls for preloaded DSOs.

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 510b525f 12-Jun-2020 Konstantin Belousov <kib@FreeBSD.org>

rtld: set osrel when in the direct exec mode.

Rtld itself is a shared object which does not have vendor note, so
after the direct exec of ld-elf.so.1 process has p_osrel set to zero.
This affects the ABI of syscalls.

Set osrel to the __FreeBSD_version value at compile time right after
rtld identified direct exec mode. Then, switch to the osrel read from
the binary note or zero if no note, right before starting calling
ifunc resolvers, which is the first byte of the user code.

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# daf5a897 02-Jun-2020 Konstantin Belousov <kib@FreeBSD.org>

Uppercase 'dso' to indicate that it is abbreviation.

Suggested by: arichardson
Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# c1a81320 02-Jun-2020 Konstantin Belousov <kib@FreeBSD.org>

Do not allow to load ET_DYN object with DF_1_PIE flag set.

Linkers are supposed to mark PIE binaries with DF_1_PIE, such binary
cannot be correctly and usefully loaded neither by dlopen(3) nor as a
dependency of other object. For instance, we cannot do anything
useful with COPY relocations, among other things.

Glibc already added similar restriction.

Requested and reviewed by: emaste
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D25086


# e82d1982 31-May-2020 Konstantin Belousov <kib@FreeBSD.org>

rtld: Add -b option to allow to specify image name different from arg0.

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 72bef4d8 31-May-2020 Konstantin Belousov <kib@FreeBSD.org>

rtld: Fix indent in print_usage().

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# c8dd6c05 31-May-2020 Konstantin Belousov <kib@FreeBSD.org>

rtld: Add -v switch to print some useful information about the rtld binary.

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# f393ade7 31-May-2020 Konstantin Belousov <kib@FreeBSD.org>

rtld: Add -p switch to direct exec mode summary line.

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# d89d5508 26-May-2020 Konstantin Belousov <kib@FreeBSD.org>

Add version indicators to rtld.

It is wrong to relate on __FreeBSD_version, either from
include/param.h, kernel, or libc, to check for rtld features.
Rtld might be from newer world than the running userspace.

Add special private symbols exported by rtld itself, to indicate the
changes in runtime behavior, and features that cannot be otherwise
detected or deduced at runtime.

Note that the symbols are not exported from libc, so they intentionally
cannot be linked against, and exported from the private namespace from rtld.
Consumers are required to use dlsym(3). For instance, for
_rtld_version_laddr_offset, user should do
ptr = dlsym(RTLD_DEFAULT, "_rtld_version_laddr_offset")
or even
ptr = dlvsym(RTLD_DEFAULT, "_rtld_version_laddr_offset",
"FBSDprivate_1.0");
Non-null ptr means that the change is present.

Also add _rtld_version__FreeBSD_version indicator to report the
headers version used at time of the rtld build.

Reviewed by: jhb
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D24982


# c8ad15b6 22-May-2020 Konstantin Belousov <kib@FreeBSD.org>

Implement Solaris-like link_map l_refname member.

The implementation is based on the public documentation, in particular
dlinfo(3) from Solaris.

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 24ea64de 22-May-2020 Konstantin Belousov <kib@FreeBSD.org>

Convert linkmap_add() and linkmap_delete() to style(8).

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# d0ca9a7f 21-May-2020 Konstantin Belousov <kib@FreeBSD.org>

Restore the binary compatibility for link_map l_addr.

Keep link_map l_addr binary layout compatible, rename l_addr to l_base
where rtld returns map base. Provide relocbase in newly added l_addr.

This effectively reverts the patch to the initial version of D24918.

Reported by: antoine (portmgr)
Reviewed by: jhb, markj
Tested by: markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D24946


# 2c6d9dc0 20-May-2020 Konstantin Belousov <kib@FreeBSD.org>

Change the samantic of struct link_map l_addr member.

It previously returned the object map base address, while all other
ELF operating systems return load offset, i.e. the difference between
map base and the link base.

Explain the meaning of the field in the man page.

Stop filling the mips-only l_offs member, which is apparently unused.

PR: 246561
Requested by: Damjan Jovanovic <damjan.jov@gmail.com>
Reviewed by: emaste, jhb, cem (previous version)
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D24918


# 1659238a 15-May-2020 Konstantin Belousov <kib@FreeBSD.org>

Implement RTLD_DEEPBIND.

PR: 246462
Tested by: Martin Birgmeier <d8zNeCFG@aon.at>
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D24841


# 62af2dc3 22-Apr-2020 Konstantin Belousov <kib@FreeBSD.org>

rtld: ignore static TLS segments when tracing.

For PIE binaries, ldd(1) performs dlopen(RTLD_TRACE) on the binary.
It is legal for binary to use initial exec TLS mode, but when such
binary (actually dso) is dlopened, we might not have enough free space
in the finalized static TLS segment. Make ldd operational by skipping
TLS space allocation, we are not going to execute any code from the
dso anyway.

Reported by: tobik
PR: 245677
Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# e5c3405c 19-Apr-2020 Konstantin Belousov <kib@FreeBSD.org>

Align initial-exec TLS segments to the p_vaddr % align.

This is continuation of D21163/r359634, which handled the alignment
for global mode.

Non-x86 arches are not handled, maintainers are welcomed.

Tested by: emaste
Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks
Differential revision: https://reviews.freebsd.org/D24366


# 2f06c66a 04-Apr-2020 Konstantin Belousov <kib@FreeBSD.org>

Make p_vaddr % p_align == p_offset % p_align for (some) TLS segments.

See https://sourceware.org/bugzilla/show_bug.cgi?id=24606 for the test case.
See https://reviews.llvm.org/D64930 for the background and more discussion.

Also this fixes another bug in malloc_aligned() where total size of
the allocated memory might be not enough to fit the aligned requested
block after the initial pointer is incremented by the pointer size.

Reviewed by: bdragon
Tested by: antoine (exp-run PR 244866), bdragon, emaste
Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks
Differential revision: https://reviews.freebsd.org/D21163


# 8e0ff10d 26-Feb-2020 Warner Losh <imp@FreeBSD.org>

Remove sparc64 specific parts of rtld-elf.


# c5ca0d11 13-Feb-2020 Konstantin Belousov <kib@FreeBSD.org>

Handle non-plt IRELATIVE relocations, at least for x86.

lld 10.0 seems to generate this relocation for rdtsc_mb() ifunc in our libc.

Reported, reviewed, and tested by: dim (amd64, previous version)
Discussed with: emaste
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D23652


# c626c88e 11-Feb-2020 Konstantin Belousov <kib@FreeBSD.org>

Fix indent.

Sponsored by: The FreeBSD Foundation
MFC after: 3 days


# aef199e5 08-Feb-2020 Konstantin Belousov <kib@FreeBSD.org>

Use sigfastblock(2) in rtld.

This allows for rtld to not issue two sigprocmask(2) syscalls for each
symbol binding operation in single-threaded processes. Rtld needs to
block signals as part of locking to ensure signal safety of the bind
process, because signal handlers might need to lazily resolve symbol
references.

As result, number of syscalls issued on startup by simple programs not
using libthr, is typically reduced 2x. For instance, for hello world,
I see:
non-sigfastblock
# (truss ./hello > /dev/null) |& wc -l
63
sigfastblock
# (truss ./hello > /dev/null) |& wc -l
37

Tested by: pho
Disscussed with: cem, emaste, jilles
Sponsored by: The FreeBSD Foundation
Differential revision: https://reviews.freebsd.org/D12773


# da8e950a 14-Jan-2020 Mateusz Guzik <mjg@FreeBSD.org>

rtld: remove hand rolled memset and bzero

They were introduced to take care of ifunc, but right now no architecture
provides ifunc'ed variants. Since rtld uses memset extensively this results in
a pessmization. Should someone want to use ifunc here they should provide a
mandatory symbol (e.g., rtld_memset).

See the review for profiling data.

Reviewed by: kib
Differential Revision: https://reviews.freebsd.org/D23176


# 1021c8d7 11-Jan-2020 Konstantin Belousov <kib@FreeBSD.org>

Stop prepending prefix to the result of realpath(3).

The path is already absolute.

Noted and reviewed by: rstone
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D23121


# 87073343 09-Jan-2020 Konstantin Belousov <kib@FreeBSD.org>

rtld: Return error if $ORIGIN for a dlopen-ed library cannot be resolved ...

instead of killing the process. The same behaviour of terminating
image activation if the $ORIGIN cannot be resolved for the main
object, is kept.

Reported by: Greg V <greg@unrelenting.technology>
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D23053


# f1605963 09-Jan-2020 Konstantin Belousov <kib@FreeBSD.org>

Resolve relative argv0 for direct exec mode to absolute path for AT_EXECPATH.

We know the binary relative name and can reliably calculate cwd path.
Because realpath(3) was already linked into ld-elf.so.1, reuse it
there to resolve dots and dotdots making the path more canonical.

Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D23014


# f26c30a5 08-Jan-2020 Konstantin Belousov <kib@FreeBSD.org>

rtld: fix after r356300

binpath local was changed from char array to a char pointer, update
strlcpy/strlcat uses.

Reported by: Coverity through vangyzen
CID: 1412239 and 1412240
Reviewed by: emaste, imp, vangyzen
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D23090


# 68faee11 07-Jan-2020 Ryan Stone <rstone@FreeBSD.org>

rtld: Fix segfault in direct exec mode

When rtld is directly executed with arguments, it has to move the
program arguments, environment and elf aux data up a few slots to
remove its own arguments before the process being executed sees
them. When copying the environment, rtld was incorrectly testing
whether the location about to be written to currently contained
NULL, when was supposed to check whether it had just copied the
NULL terminator of the environment string. This had the result
that the ELF aux data was mostly treated as environment variables,
and rtld would quickly crash when it tried to access required
ELF aux data that it didn't think was present.

Differential Revision: https://reviews.freebsd.org/D23008
Reviewed by: kib
MFC after: 1 month


# 137aed91 02-Jan-2020 Konstantin Belousov <kib@FreeBSD.org>

Fix AT_EXECPATH for direct exec mode.

When activated in direct exec mode, kernel-provided AT_EXECPATH points
to the interpreter. We need to recalculate auxv to point to the
string with the path to the executable which is actually executed.

The somewhat problematic case is when the executable path is relative
and either $PATH use is not enabled or it contains '/' so $PATH search
is not performed. In this case resulting AT_EXECPATH is relative, I
might fix this later.

Reported and reviewed by: rstone
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D22894


# adea0d63 26-Dec-2019 Justin Hibbits <jhibbits@FreeBSD.org>

Eliminate the last MI difference in AT_* definitions (for powerpc).

Summary:
As a transition aide, implement an alternative elfN_freebsd_fixup which
is called for old powerpc binaries. Similarly, add a translation to rtld to
convert old values to new ones (as expected by a new rtld).

Translation of old<->new values is incomplete, but sufficient to allow an
installworld of a new userspace from an old one when a new kernel is running.

Test Plan:
Someone needs to see how a new kernel/rtld/libc works with an old
binary. If if works we can probalby ship this. If not we probalby need
some more compat bits.

Submitted by: brooks
Reviewed by: jhibbits
Differential Revision: https://reviews.freebsd.org/D20799


# d020b3eb 14-Sep-2019 Brandon Bergren <bdragon@FreeBSD.org>

Fix aux_info corruption in rtld direct execution mode.

After the aux vector is moved, it is necessary to re-digest aux_info so the
pointers are updated to the new locations.

This was causing thread creation to fail on powerpc64 when using direct
execution due to a nonsense value being read for aux_info[AT_STACKPROT].

Approved by: jhibbits (mentor)
Differential Revision: https://reviews.freebsd.org/D21656


# b54a59f3 30-Jun-2019 Alex Richardson <arichardson@FreeBSD.org>

Reduce size of rtld by 22% by pulling in less code from libc

Currently RTLD is linked against libc_nossp_pic which means that any libc
symbol used in rtld can pull in a lot of depedencies. This was causing
symbol such as __libc_interposing and all the pthread stubs to be included
in RTLD even though they are not required. It turns out most of these
dependencies can easily be avoided by providing overrides inside of rtld.

This change is motivated by CHERI, where we have an experimental ABI that
requires additional relocation processing to allow the use of function
pointers inside of rtld. Instead of adding this self-relocation code to
RTLD I attempted to remove most function pointers from RTLD and discovered
that most of them came from the libc dependencies instead of being actually
used inside rtld.

A nice side-effect of this change is that rtld is now 22% smaller on amd64.

text data bss dec hex filename
0x21eb6 0xce0 0xe60 145910 239f6 /home/alr48/ld-elf-x86.before.so.1
0x1a6ed 0x728 0xdd8 113645 1bbed /home/alr48/ld-elf-x86.after.so.1

The number of R_X86_64_RELATIVE relocations that need to be processed on
startup has also gone down from 368 to 187 (almost 50% less).

Reviewed By: kib
Differential Revision: https://reviews.freebsd.org/D20663


# f62da49b 24-Jun-2019 Justin Hibbits <jhibbits@FreeBSD.org>

powerpc: Transition to Secure-PLT, like most other OSs

Summary:
PowerPC has two PLT models: BSS-PLT and Secure-PLT. BSS-PLT uses runtime
code generation to generate the PLT stubs. Secure-PLT was introduced with
GCC 4.1 and Binutils 2.17 (base has GCC 4.2.1 and Binutils 2.17), and is a
more secure PLT format, using a read-only linkage table, with the dynamic
linker populating a non-executable index table.

This is the libc, rtld, and kernel support only. The toolchain and build
parts will be updated separately.

Reviewed By: nwhitehorn, bdragon, pfg
Differential Revision: https://reviews.freebsd.org/D20598
MFC after: 1 month


# 78022527 05-May-2019 Konstantin Belousov <kib@FreeBSD.org>

Switch to use shared vnode locks for text files during image activation.

kern_execve() locks text vnode exclusive to be able to set and clear
VV_TEXT flag. VV_TEXT is mutually exclusive with the v_writecount > 0
condition.

The change removes VV_TEXT, replacing it with the condition
v_writecount <= -1, and puts v_writecount under the vnode interlock.
Each text reference decrements v_writecount. To clear the text
reference when the segment is unmapped, it is recorded in the
vm_map_entry backed by the text file as MAP_ENTRY_VN_TEXT flag, and
v_writecount is incremented on the map entry removal

The operations like VOP_ADD_WRITECOUNT() and VOP_SET_TEXT() check that
v_writecount does not contradict the desired change. vn_writecheck()
is now racy and its use was eliminated everywhere except access.
Atomic check for writeability and increment of v_writecount is
performed by the VOP. vn_truncate() now increments v_writecount
around VOP_SETATTR() call, lack of which is arguably a bug on its own.

nullfs bypasses v_writecount to the lower vnode always, so nullfs
vnode has its own v_writecount correct, and lower vnode gets all
references, since object->handle is always lower vnode.

On the text vnode' vm object dealloc, the v_writecount value is reset
to zero, and deadfs vop_unset_text short-circuit the operation.
Reclamation of lowervp always reclaims all nullfs vnodes referencing
lowervp first, so no stray references are left.

Reviewed by: markj, trasz
Tested by: mjg, pho
Sponsored by: The FreeBSD Foundation
MFC after: 1 month
Differential revision: https://reviews.freebsd.org/D19923


# 760e3477 15-Apr-2019 Konstantin Belousov <kib@FreeBSD.org>

Fix order of destructors between main binary and libraries.

Since inits for the main binary are run from rtld (for some time), the
rtld_exit atexit(3) handler, which is passed from rtld to the program
entry and installed by csu, is installed after any atexit(3) handlers
installed by main binary constructors. This means that rtld_exit() is
fired before main binary handlers.

Typical C++ static constructors are executed from init (either binary
or libs) but use atexit(3) to ensure that destructors are called in
the right order, independent of the linking order. Also, C++
libraries finalizers call __cxa_finalize(3) to flush library'
atexit(3) entries. Since atexit(3) entry is cleared after being run,
this would be mostly innocent, except that, atexit(rtld_exit) done
after main binary constructors, makes destructors from libraries
executed before destructors for main.

Fix by reordering atexit(rtld_exit) before inits for main binary, same
as it happened when inits were called by csu. Do it using new private
libc symbol with pre-defined ABI.

Reported. tested, and reviewed by: kan
Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 5d00c5a6 29-Mar-2019 Konstantin Belousov <kib@FreeBSD.org>

Fix initial exec TLS mode for dynamically loaded shared objects.

If dso uses initial exec TLS mode, rtld tries to allocate TLS in
static space. If there is no space left, the dlopen(3) fails. If space
if allocated, initial content from PT_TLS segment is distributed to
all threads' pcbs, which was missed and caused un-initialized TLS
segment for such dso after dlopen(3).

The mode is auto-detected either due to the relocation used, or if the
DF_STATIC_TLS dynamic flag is set. In the later case, the TLS segment
is tried to allocate earlier, which increases chance of the dlopen(3)
to succeed. LLD was recently fixed to properly emit the flag, ld.bdf
did it always.

Initial test by: dumbbell
Tested by: emaste (amd64), ian (arm)
Tested by: Gerald Aryeetey <aryeeteygerald_rogers.com> (arm64)
Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks
Differential revision: https://reviews.freebsd.org/D19072


# ad484b8c 27-Mar-2019 Konstantin Belousov <kib@FreeBSD.org>

rtld: disable relro enforcement for irelative relocation processing.

This fixes yet another breakage for relro + bind now.

Reported by: emaste
Sponsored by: The FreeBSD Foundation
MFC after: 3 days


# 1a3b2ebf 29-Jan-2019 Konstantin Belousov <kib@FreeBSD.org>

Adjust posix symbols from rtld-elf/malloc.c with the __crt_ prefix.

This allows to reuse the allocator in other environments that get
malloc(3) and related functions from libc or interposer.

MFC after: 2 weeks
Sponsored by: The FreeBSD Foundation
Differential revision: https://reviews.freebsd.org/D18988


# 8b40aab1 26-Jan-2019 Konstantin Belousov <kib@FreeBSD.org>

Remove now redundand ifunc relocation code which should have been
removed as part of r341441.

This call to reloc_non_plt() may crash if ifunc resolvers use the
needed libraries symbols since the pass over the needed libs
relocation is not yet done. The change in r341441 ensures the right
relocation order otherwise.

Submitted by: theraven
MFC after: 1 week
Discussed in: https://reviews.freebsd.org/D17529


# c9cf7cb8 17-Jan-2019 Dag-Erling Smørgrav <des@FreeBSD.org>

Revert r343093 until I can address the issues raised by kib@.


# 9b35e902 15-Jan-2019 Dag-Erling Smørgrav <des@FreeBSD.org>

Implement dlopenat(3).

MFC after: 3 weeks


# 4849c3a5 15-Dec-2018 Michal Meloun <mmel@FreeBSD.org>

Improve R_AARCH64_TLSDESC relocation.
The original code did not support dynamically loaded libraries and used
suboptimal access to TLS variables.
New implementation removes lazy resolving of TLS relocation - due to flaw
in TLSDESC design is impossible to switch resolver function at runtime
without expensive locking.

Due to this, 3 specialized resolvers are implemented:
- load time resolver for TLS relocation from libraries loaded with main
executable (thus with known TLS offset).
- resolver for undefined thread weak symbols.
- slower lazy resolver for dynamically loaded libraries with fast path for
already resolved symbols.

PR: 228892, 232149, 233204, 232311
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D18417


# 4903c73f 03-Dec-2018 Konstantin Belousov <kib@FreeBSD.org>

Some fixes for LD_BIND_NOW + ifuncs.

- Do not perform ifunc relocations together with other PLT relocations
in PLT. Instead, do it during an additional pass over the init
list, so that ifuncs are resolved in the order of dso
dependencies. This allows the ifuncs resolvers to call into depended
libs. Init list now includes all objects instead of only objects
with init/fini callables.
- Disable relro protection around bind_now ifunc relocations.

I considered calling ifunc resolvers of dso after initializers of all
dependencies are processed, and decided that this is wrong/should not
be supported. The order now is normal relocations for all
objects->ifunc resolution in init order->initializers, where each step
does complete pass over all loaded objects before moving to the next
step.

Reported, tested and reviewed by: emaste
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D18400


# 5962a71e 03-Dec-2018 Konstantin Belousov <kib@FreeBSD.org>

Provide naive but self-contained implementations of memset(3) and
bzero(3) for rtld.

This again reduces rtld dependency on libc, and in future, avoid ifunc
relocations when the functions are converted to ifuncs in libc.

Reported by: mjg
Reviewed by: emaste
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D18400


# e8927aa6 23-Nov-2018 Konstantin Belousov <kib@FreeBSD.org>

rtld: parse FreeBSD Feature Control note on the object load.

Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks


# abfc3b2f 20-Nov-2018 Konstantin Belousov <kib@FreeBSD.org>

rtld: when immediate bind mode is requested, process irelocs in PLT
immediately after other PLT relocs.

Otherwise, if the object has relro page, we write to readonly page,
and we would need to use mprotect(2) two more times to fix it. Note
that resolve_object_ifunc() does nothing when called second time, so
there is no need to avoid existing call.

Reported and tested by: emaste
PR: 233333
Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 57fe7128 07-Nov-2018 Alex Richardson <arichardson@FreeBSD.org>

Handle the DT_MIPS_RLD_MAP_REL dynamic tag in RTLD

This dynamic tag contains the location of the .rld_map section relative to
the location of the dynamic tag. For PIE MIPS binaries DT_MIPS_RLD_MAP can
not be used since it contains an absolute address. Without this change
GDB can not find the function program counters in other libraries and once
I apply this change I can successfully run info sharedlibraries again.

Reviewed By: kib
Differential Revision: https://reviews.freebsd.org/D17867


# eda66948 04-Nov-2018 Ed Maste <emaste@FreeBSD.org>

rtld: move relro enforcement after ifunc processing

Previously the combination of relro (implicit), -z now and ifunc use
resulted in a segfault when applying ifuncs after relro (test binary
here just calls amd64_get_fsbase()):

| % env LD_DEBUG=1 libexec/rtld-elf/obj/ld-elf.so.1 a.out
| ...
| enforcing main obj relro
| ...
| resolving ifuncs
| reloc_jmpslot: *0x203198 = 0x189368ea4570
| zsh: bus error (core dumped) LD_DEBUG=1 obj/ld-elf.so.1 ~/a.out

Reported by: Shawn Webb
Reviewed by: kib
Sponsored by: The FreeBSD Foundation


# 56199114 03-Nov-2018 Konstantin Belousov <kib@FreeBSD.org>

Remove Obj_Entry textsize member.

It is unused after r340102, and more important, I do not see how to
define textsize in both practically useful and correct way, for binaries
with more that one executable segments.

Sponsored by: The FreeBSD Foundation


# 29ea8142 29-Oct-2018 Konstantin Belousov <kib@FreeBSD.org>

Initialize ifunc calling machinery earlier.

In particular, do it before the first call to allocate_initial_tls(),
which contains MD parts to set the initial thread' TLS pointer.

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 3ab5b6bd 29-Oct-2018 Alex Richardson <arichardson@FreeBSD.org>

rtld-elf: fix more warnings to allow compiling with WARNS=6

Reviewed By: kib
Approved By: brooks (mentor)
Differential Revision: https://reviews.freebsd.org/D17154


# 903e0ffd 29-Oct-2018 Alex Richardson <arichardson@FreeBSD.org>

rtld-elf: compile with WANRS=4 warnings other than -Wcast-align

Reviewed By: kib
Approved By: brooks (mentor)
Differential Revision: https://reviews.freebsd.org/D17153


# 78b64846 29-Oct-2018 Alex Richardson <arichardson@FreeBSD.org>

rtld-elf: make it compile with WARNS=3

Reviewed By: kib
Approved By: brooks (mentor)
Differential Revision: https://reviews.freebsd.org/D17150


# ca7e27bb 29-Oct-2018 Alex Richardson <arichardson@FreeBSD.org>

rtld: set obj->textsize correctly

With lld-generated binaries the first PT_LOAD will usually be a read-only
segment unless you pass --no-rosegment. For those binaries the textsize is
determined by the next PT_LOAD. To allow both LLD and bfd 2.17 binaries to
be parsed correctly use the end of the last PT_LOAD that is marked as
executable instead.

I noticed that the value was wrong while adding some debug prints for some rtld
changes for CHERI binaries. `obj->textsize` only seems to be used by PPC so the
effect is untested. However, the value before was definitely wrong and the new
result matches the phdrs.

Reviewed By: kib
Approved By: brooks (mentor)
Differential Revision: https://reviews.freebsd.org/D17117


# d2f2e4c0 26-Sep-2018 Konstantin Belousov <kib@FreeBSD.org>

Provide refobj context when doing libmap substitution inside
search_library_path().

This corrects the scope of libmap matches.

Reported and tested by: Andreas Longwitz <longwitz@incore.de>
Sponsored by: The FreeBSD Foundation
Approved by: re (gjb)
MFC after: 1 week


# 17fb2856 05-Sep-2018 Brooks Davis <brooks@FreeBSD.org>

Rework rtld's TLS Variant I implementation to match r326794

The above commit fixed handling overaligned TLS segments in libc's
TLS Variant I implementation, but rtld provides its own implementation
for dynamically-linked executables which lacks these fixes. Thus,
port these changes to rtld.

This was previously commited as r337978 and reverted in r338149 due to
exposing a bug the ARM rtld. This bug was fixed in r338317 by mmel.

Submitted by: James Clarke
Approved by: re (kib)
Reviewed by: kbowling
Testing by: kbowling (powerpc64), br (riscv), kevans (armv7)
Obtained from: CheriBSD
Sponsored by: DARPA, AFRL
Differential Revision: https://reviews.freebsd.org/D16510


# a5207d3e 21-Aug-2018 Brooks Davis <brooks@FreeBSD.org>

Revert r337978: Rework rtld's TLS Variant I implementation to match r326794

Michal Meloun reports that it breaks ctype (isspace()..) related
functions on armv7 so back out while we diagnose the issue.

Reported by: Michal Meloun <melounmichal@gmail.com>


# 9b50d816 17-Aug-2018 Brooks Davis <brooks@FreeBSD.org>

Rework rtld's TLS Variant I implementation to match r326794

The above commit fixed handling overaligned TLS segments in libc's
TLS Variant I implementation, but rtld provides its own implementation
for dynamically-linked executables which lacks these fixes. Thus,
port these changes to rtld.

Submitted by: James Clarke
Reviewed by: kbowling
Testing byL kbowling (powerpc64), br (riscv), kevans (armv7)
Obtained from: CheriBSD
Sponsored by: DARPA, AFRL
Differential Revision: https://reviews.freebsd.org/D16510


# 711a4538 02-Aug-2018 Edward Tomasz Napierala <trasz@FreeBSD.org>

Make sure the rtld(1) error messages go to stderr, not stdout.
While here fix capitalization of a few nearby strings, add the
rtld's file name prefix so it's obvious where the message come
from, and return zero when "-h" is used.

Reviewed by: kib
MFC after: 2 weeks
Sponsored by: DARPA, AFRL
Differential Revision: https://reviews.freebsd.org/D16530


# 0725fca5 09-May-2018 Konstantin Belousov <kib@FreeBSD.org>

Make rtld use libc_nossp_pic.a. Remove SSP shims.

Submitted by: Luis Pires
Reviewed by: brooks
Differential revision: https://reviews.freebsd.org/D15341


# 41fc6f68 03-Feb-2018 Marius Strobl <marius@FreeBSD.org>

o Let rtld(1) set up psABI user trap handlers prior to executing the
objects' init functions instead of doing the setup via a constructor
in libc as the init functions may already depend on these handlers
to be in place. This gets us rid of:
- the undefined order in which libc constructors as __guard_setup()
and jemalloc_constructor() are executed WRT __sparc_utrap_setup(),
- the requirement to link libc last so __sparc_utrap_setup() gets
called prior to constructors in other libraries (see r122883).
For static binaries, crt1.o still sets up the user trap handlers.
o Move misplaced prototypes for MD functions in to the MD prototype
section of rtld.h.
o Sprinkle nitems().


# e6209940 27-Nov-2017 Pedro F. Giffuni <pfg@FreeBSD.org>

libexec: adoption of SPDX licensing ID tags.

Mainly focus on files that use BSD 2-Clause license, however the tool I
was using misidentified many licenses so this was mostly a manual - error
prone - task.

The Software Package Data Exchange (SPDX) group provides a specification
to make it easier for automated tools to detect and summarize well known
opensource licenses. We are gradually adopting the specification, noting
that the tags are considered only advisory and do not, in any way,
superceed or replace the license texts.

No functional change intended.


# b4ed9a87 23-Oct-2017 Edward Tomasz Napierala <trasz@FreeBSD.org>

Remove unneeded calls to access(2) from rtld(1); just call open(2) instead.
The result looks like this:

--- przed 2017-10-21 23:19:21.445034000 +0100
+++ po 2017-10-21 23:18:50.031865000 +0100
@@ -11,7 +11,6 @@ mmap(0x0,102,PROT_READ,MAP_PRIVATE,3,0x0) = 343665418
close(3) = 0 (0x0)
open("/usr/local/etc/libmap.d",O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC,0165) ERR#2 'No such file or directory'
munmap(0x80067d000,102) = 0 (0x0)
-access("/usr/local/lib/libintl.so.8",F_OK) = 0 (0x0)
openat(AT_FDCWD,"/usr/local/lib/libintl.so.8",O_RDONLY|O_CLOEXEC|O_VERIFY,00) = 3 (0x3)
fstat(3,{ mode=-rw-r--r-- ,inode=642560,size=55188,blksize=32768 }) = 0 (0x0)
mmap(0x0,4096,PROT_READ,MAP_PRIVATE|MAP_PREFAULT_READ,3,0x0) = 34366541824 (0x80067d000)
@@ -20,14 +19,13 @@ mmap(0x800877000,40960,PROT_READ|PROT_EXEC,MAP_PRIVATE
mmap(0x800a81000,4096,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_FIXED|MAP_PREFAULT_READ,3,0xa000) = 34370752512 (0x800a81000)
munmap(0x80067d000,4096) = 0 (0x0)
close(3) = 0 (0x0)
-access("/usr/local/lib/libc.so.7",F_OK) ERR#2 'No such file or directory'
+openat(AT_FDCWD,"/usr/local/lib/libc.so.7",O_RDONLY|O_CLOEXEC|O_VERIFY,00) ERR#2 'No such file or directory'
openat(AT_FDCWD,"/var/run/ld-elf.so.hints",O_RDONLY|O_CLOEXEC,00) = 3 (0x3)
read(3,"Ehnt\^A\0\0\0\M^@\0\0\0\M-2\0\0"...,128) = 128 (0x80)
fstat(3,{ mode=-r--r--r-- ,inode=970684,size=306,blksize=32768 }) = 0 (0x0)
lseek(3,0x80,SEEK_SET) = 128 (0x80)
read(3,"/lib:/usr/lib:/usr/lib/compat:/u"...,178) = 178 (0xb2)
close(3) = 0 (0x0)
-access("/lib/libc.so.7",F_OK) = 0 (0x0)
openat(AT_FDCWD,"/lib/libc.so.7",O_RDONLY|O_CLOEXEC|O_VERIFY,00) = 3 (0x3)
fstat(3,{ mode=-r--r--r-- ,inode=1605239,size=1910320,blksize=32768 }) = 0 (0x0)
mmap(0x0,4096,PROT_READ,MAP_PRIVATE|MAP_PREFAULT_READ,3,0x0) = 34366541824 (0x80067d000)

Reviewed by: kib
MFC after: 2 weeks
Sponsored by: DARPA, AFRL
Differential Revision: https://reviews.freebsd.org/D12766


# 2fe071d9 23-Oct-2017 Edward Tomasz Napierala <trasz@FreeBSD.org>

Replace lseek(2)/read(2) pair with pread(2), removing yet another syscall
from the binary startup code.

MFC after: 2 weeks
Sponsored by: DARPA, AFRL


# 1689a3c4 24-Oct-2017 Edward Tomasz Napierala <trasz@FreeBSD.org>

Make find_library() conform to style(9). No functional changes.

Suggested by: kib
MFC after: 2 weeks
Sponsored by: DARPA, AFRL


# e65ad973 24-Oct-2017 Edward Tomasz Napierala <trasz@FreeBSD.org>

Reword the conditional; it was ugly, and adding another parameter,
which I'm going to do in a subsequent commit, would make it even uglier.
No functional changes.

MFC after: 2 weeks
Sponsored by: DARPA, AFRL


# b4e9a36b 12-Sep-2017 John Baldwin <jhb@FreeBSD.org>

Handle relocations for newer non-PIC MIPS ABI.

Newer binutils supports extensions to the MIPS ABI for non-PIC code
that is used when compiling O32 binaries with clang 5 (but not used
for N64 oddly enough). These extensions require support for
R_MIPS_COPY relocations as well as a second PLT GOT using
R_MIPS_JUMP_SLOT relocations.

For R_MIPS_COPY, use the same approach as on other architectures where
fixups are deferred to the MD do_copy_relocations.

The additional PLT GOT for jump slots is located in a .got.plt section
which is identified by a DT_MIPS_PLTGOT dynamic entry. This GOT also
requires fixups for the first two GOT entries just as the normal GOT.
However, the entry point for this second GOT uses a different calling
convention. Rather than passing an offset into the GOT, it passes an
offset into the .rel.plt section. This requires a second entry point
(_rtld_pltbind_start) which calls the normal _rtld_bind() rather than
_mips_rtld_bind(). This also means providing a real version of
reloc_jmpslot() which is used by _rtld_bind().

In addition, add real implementions of reloc_plt() and
reloc_jmpslots() which walk .rel.plt handling R_MIPS_JUMP_SLOT
relocations.

Reviewed by: kib
Sponsored by: DARPA / AFRL
Differential Revision: https://reviews.freebsd.org/D12326


# 83d33b2b 30-Aug-2017 John Baldwin <jhb@FreeBSD.org>

Read max_stack_flags from correct object.

'obj' is not initialized here.

Reviewed by: kib
MFC after: 1 week
Sponsored by: DARPA / AFRL


# ca20f8ec 07-Aug-2017 Ruslan Bukin <br@FreeBSD.org>

o Replace __riscv__ with __riscv
o Replace __riscv64 with (__riscv && __riscv_xlen == 64)

This is required to support new GCC 7.1 compiler.
This is compatible with current GCC 6.1 compiler.

RISC-V is extensible ISA and the idea here is to have built-in define
per each extension, so together with __riscv we will have some subset
of these as well (depending on -march string passed to compiler):

__riscv_compressed
__riscv_atomic
__riscv_mul
__riscv_div
__riscv_muldiv
__riscv_fdiv
__riscv_fsqrt
__riscv_float_abi_soft
__riscv_float_abi_single
__riscv_float_abi_double
__riscv_cmodel_medlow
__riscv_cmodel_medany
__riscv_cmodel_pic
__riscv_xlen

Reviewed by: ngie
Sponsored by: DARPA, AFRL
Differential Revision: https://reviews.freebsd.org/D11901


# dd269a0b 27-Jul-2017 Konstantin Belousov <kib@FreeBSD.org>

Allow to specify targets by absolute paths in libmap.conf.

Submitted by: Tatu Kilappa <tatu.kilappa@iki.fi>
PR: 221032
MFC after: 2 weeks


# 2bbd226f 05-Jul-2017 Xin LI <delphij@FreeBSD.org>

In open_binary_fd: when using buffer size for strl* and snprintf,
always use >= instead of > to avoid truncation.

Reviewed by: kib
Differential Revision: https://reviews.freebsd.org/D11474
MFC after: 3 days


# 84de44d3 04-Jul-2017 Konstantin Belousov <kib@FreeBSD.org>

When reporting undefined symbol, note the version, if specified.

Use the standard syntax of name@version, I do not expect a confusion
due to unlikely possibility of the name containing the '@' character.

Requested by: emaste
Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 9e5e0e88 23-May-2017 Konstantin Belousov <kib@FreeBSD.org>

For ld.so direct execution mode, implement -p option: search for the
binary in $PATH.

Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks
Differential revision: https://reviews.freebsd.org/D10790


# ce9600b1 18-May-2017 Konstantin Belousov <kib@FreeBSD.org>

Update my copyright, note The FreeBSD Foundation involvement.
While tweaking copyright block, switch to use __FBSDID for tag.

Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks


# 591986a8 18-May-2017 Konstantin Belousov <kib@FreeBSD.org>

Fix style [1], add static keyword before static function definition.

Noted by: bapt [1]
Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks


# d5a5e50d 17-May-2017 Jonathan Anderson <jonathan@FreeBSD.org>

Allow rtld direct-exec to take a file descriptor.

When executing rtld directly, allow a file descriptor to be explicitly
specified rather than opened from the given path. This, together with the
LD_LIBRARY_PATH_FDS environment variable, allows dynamically-linked
applications to be executed from within capability mode.

Also add some rudimentary argument parsing (without pulling in getopt or
the like) to accept this file descriptor, a help (-h) option and a basic
usage string.

Reviewed by: kib
Sponsored by: NSERC, RDC
Differential Revision: https://reviews.freebsd.org/D10751


# da403aea 16-May-2017 Konstantin Belousov <kib@FreeBSD.org>

Pretend that there is some security when executing in direct mode.

Do not allow direct exec if we the process is suid. Try to follow Unix
permission checks for DACs, ignore ACLs.

Reviewed by: emaste
Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks
Differential revision: https://reviews.freebsd.org/D10750


# 7a36bd9f 16-May-2017 Jonathan Anderson <jonathan@FreeBSD.org>

Rename rtld's parse_libdir to parse_integer.

This is a more accurate name, as the integer doesn't have to be a library
directory descriptor. It is also a prerequisite for more argument parsing
coming in the near future (e.g., parsing explicit binary descriptors).

Reviewed by: kib
MFC after: 2 weeks
Sponsored by: NSERC


# 0fc65b0a 15-May-2017 Konstantin Belousov <kib@FreeBSD.org>

Make ld-elf.so.1 directly executable.

Check if passed phdr is actually phdr of the interpreter itself, and
decide that this is the case of direct execution. In this case, the
binary to activate is specified in the argv[1]. After opening it,
shift down on-stack structure with argv, env and aux vectors to
emulate execution of the binary and not of the interpreter.

Reviewed by: emaste
Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks
Differential revision: https://reviews.freebsd.org/D10701


# c4f7cccb 13-May-2017 Konstantin Belousov <kib@FreeBSD.org>

In _rtld(), reorder local declarations to compact the block and
partially sort them by style(9). Move locals declarations from nested
blocks into the block at function start.

Discussed with: emaste
MFC after: 1 week


# 018865f8 15-Mar-2017 Konstantin Belousov <kib@FreeBSD.org>

Disable LD_BIND_NOT for setugid processes.

Requested by: jilles
Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks


# e35ddbe4 15-Mar-2017 Konstantin Belousov <kib@FreeBSD.org>

Implement LD_BIND_NOT knob for rtld.

From the manpage:
When set to a nonempty string, prevents modifications of the PLT slots
when doing bindings. As result, each call of the PLT-resolved
function is resolved. In combination with debug output, this provides
complete account of all bind actions at runtime.

Same feature exists on Linux and Solaris.

Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks


# 12c81769 09-Mar-2017 Konstantin Belousov <kib@FreeBSD.org>

Avoid bind lock recursion.

When dlclose(3) unloads an object with filtees, it recursively calls
dlclose(3) on each filtee in free_needed_filtees(). Introduce
dlclose_locked() helper, called from free_needed_filtees() instead of
dlclose(), and pass the bind lockstate down to avoid recursing.

Reported and tested by: jhibbits
Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 6d20836a 09-Feb-2017 Konstantin Belousov <kib@FreeBSD.org>

Handle protected symbols in rtld.

Protected symbol reference in GOT of the defining object must be
resolved to itself, same as -Bsymbolic globally.

Discussed with: emaste
Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks
Differential revision: https://reviews.freebsd.org/D9317


# 87879285 30-Jan-2017 Peter Jeremy <peterj@FreeBSD.org>

Extend LD_UTRACE by also generating utrace(2) log events for runtime linker
errors.

Reviewed by: kib, jhb
Approved by: jhb(mentor)
MFC after: 1 week
Differential Revision: D9347


# f8adf1a7 12-Jan-2017 Konstantin Belousov <kib@FreeBSD.org>

For the main binary, postpone enforcing relro read-only protection
until copy relocations are done.

Newer binutils and lld seems to output copy into relro-protected range.

Reported by: Rafael Espц╜ndola via emaste
Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 57a9273f 22-Dec-2016 Mark Johnston <markj@FreeBSD.org>

rtld: Fix a couple of bugs around the unloading of ELF filters.

- Pass the correct object to unload_filtees().
- Use a marker to restart iteration after unload_filtees() has returned.
It calls dlclose() and may recursively remove entries from the global
object list, so TAILQ_FOREACH_SAFE is not sufficient.

Reviewed by: kib
MFC after: 2 weeks
Sponsored by: Dell EMC Isilon


# 510fe58c 22-Dec-2016 Mark Johnston <markj@FreeBSD.org>

rtld: Ensure that dlopen() cannot obtain a reference on a doomed object.

rtld drops the bind lock to call fini functions in an object prior to
unmapping it. The new "doomed" state flag prevents the acquisition of new
references for an object while the lock is dropped.

Reviewed by: kib
MFC after: 2 weeks
Sponsored by: Dell EMC Isilon


# c0274175 22-Dec-2016 Mark Johnston <markj@FreeBSD.org>

rtld: Fix a race between dl_iterate_phdr() and dlclose().

Add a transient reference count to ensure that the phdr argument to the
callback remains valid while the bind lock is dropped.

Reviewed by: kib
MFC after: 2 weeks
Sponsored by: Dell EMC Isilon


# 3931b59f 16-Dec-2016 Konstantin Belousov <kib@FreeBSD.org>

Fix typo.

MFC after: 3 days


# 9d9b69b3 13-Dec-2016 Bryan Drewery <bdrewery@FreeBSD.org>

Take write lock for rtld_bind before modifying obj_list in dl_iterate_phdr().

This avoids a race with readers such as dladdr(3)/dlinfo(3)/dlsym(3) and
the atexit(3) handler. This race was introduced in r294373.

Reviewed by: markj, kib, kan
MFC after: 2 weeks
Sponsored by: Dell EMC Isilon


# eeef1833 02-Dec-2016 Ed Maste <emaste@FreeBSD.org>

Retire long-broken/unused static rtld support

rtld-elf has some vestigial support for building as a static executable.
r45501 introduced a partial implementation with a prescient note that it
"might never be enabled." r153515 introduced ELF symbol versioning
support, and removed part of the unused build infrastructure for static
rtld.

GNU ld populates rela relocation addends and GOT entries with the same
values, and rtld's run-time dynamic executable check relied on this.
Alternate toolchains may not populate the GOT entries, which caused
RTLD_IS_DYNAMIC to return false. Simplify rtld by just removing the
unused check.

If we want to restore static rtld support later on we ought to introduce
a build-time #ifdef flag.

PR: 214972
Reviewed by: kan
MFC after: 1 month
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D8687


# 6a368d16 23-Nov-2016 John Baldwin <jhb@FreeBSD.org>

Fix _mips_rtld_bind() to handle ELF filters.

MIPS does not use the common _rtld_bind() to handle runtime binding.
Instead, it uses a private _mips_rtld_bind(). Update _mips_rtld_bind()
to include the changes made to _rtld_bind() in r216695 and r218476 to
support upgrading the read-locked rtld_bind_lock to a write lock when
an object with a filter is encountered.

While here, add a 'where' variable to track the location of the fixup
in the GOT to make the code flow more closely match _rtld_bind().

Reviewed by: kib
Obtained from: CheriBSD
Sponsored by: DARPA / AFRL
Differential Revision: https://reviews.freebsd.org/D8625


# 4352999e 15-Nov-2016 Konstantin Belousov <kib@FreeBSD.org>

Pass CPUID[1] %edx (cpu_feature), %ecx (cpu_feature2) and
CPUID[7].%ebx (cpu_stdext_feature), %ecx (cpu_stdext_feature2) to the
ifunc resolvers on x86.

It is much more clean to use CPUID instruction in usermode to retrieve
this information than to pass AT_HWCAP aux vector from kernel, on
x86. Still, the change does allow for use of AT_HWCAP on arches where it is
needed, by passing aux array to ifunc_init() initializer which should
prepare arguments for ifunc resolvers.

Current signature for resolvers on x86 is
func_t iresolve(uint32_t cpu_feature, uint32_t cpu_feature2,
uint32_t cpu_stdext_feature, uint32_t cpu_stdext_feature2);
where arguments have identical meaning as the kernel variables of the
same name. The ABIs allow to use resolvers with the void or shortened
list of arguments.

Reviewed by: jhb
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D8448


# b5b4f379 08-Nov-2016 John Baldwin <jhb@FreeBSD.org>

Pass the correct flag to find_symdef() from _rtld_bind().

When symbol versioning was added to rtld, the boolean 'in_plt' argument
to find_symdef() was converted to a bitmask of flags. The first flag
added was 'SYMLOOK_IN_PLT' which replaced the 'in_plt' bool. This
happened to still work by accident as SYMLOOK_IN_PLT had the value of 1
which is the same as 'true', so there should be no functional change.

Tested on: amd64
Reviewed by: kan
MFC after: 2 weeks
Sponsored by: DARPA / AFRL


# f214036e 12-Aug-2016 Konstantin Belousov <kib@FreeBSD.org>

Move defines common between rtld and libsysdecode into the header,
instead of copying inline into sources.

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 09944776 12-Aug-2016 Konstantin Belousov <kib@FreeBSD.org>

Fill phdr and phsize for rtld object. It is needed for
dl_iterate_phdr() reporting the correct values.

PR: 211367
Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 20ee0f71 12-Aug-2016 Konstantin Belousov <kib@FreeBSD.org>

Remove all remaining uses of TAILQ_FOREACH_FROM() from rtld-elf.

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 1c1093d6 15-Jul-2016 Bryan Drewery <bdrewery@FreeBSD.org>

Fix dlsym(RTLD_NEXT) handling to only return the next library in last library cases.

The root of the problem here is that TAILQ_FOREACH_FROM will default to
the head of the list if passed NULL, which will be the case if there are
no libraries loaded after this one. Thus all libraries, including the
current, were iterated in that case rather than none.

This was broken in r294373.

Reviewed by: markj (earlier version), cem, kib, ngie
MFC after: 1 week
Sponsored by: EMC / Isilon Storage Division
Differential Revision: https://reviews.freebsd.org/D7216


# 360ba6bc 25-May-2016 Konstantin Belousov <kib@FreeBSD.org>

Fix issues found by Coverity in the rtld-elf.c:gethints().

Check that the dirlist path string specification does not cause
overflow and is fully contained in the hints file.
Check that the dirlist string is nul-terminated.
Make 'hdr' static variable, so that hdr.dirlistlen is available when
hints cached value is used on next function calls. Reset hdr.dirlistlen
to zero if error was detected, so that allocations use reasonable size.
Use 'hints', and not 'p' in the body, since p is only initialized on the
first call.

Reported and reviewed by: truckman (previous version)
Sponsored by: The FreeBSD Foundation
CIDs: 1006503, 1006504, 1006676, 1008488, 1007263
MFC after: 2 weeks


# ec489d64 01-May-2016 Pedro F. Giffuni <pfg@FreeBSD.org>

libexec: minor spelling fixes in comments.

No functional change.


# a5d5e8dd 19-Apr-2016 Pedro F. Giffuni <pfg@FreeBSD.org>

rtld-elf: use NULL instead of zero for pointers.


# ca8c8dc3 02-Mar-2016 Konstantin Belousov <kib@FreeBSD.org>

Fix handling of DT_TEXTREL for an object with more than one read-only
segment. According to gABI spec, presence of the tag indicates that
dynamic linker must be prepared to handle relocations against any
read-only segment, not only the segment which we, somewhat arbitrary,
declared the text.

For each read-only segment, add write permission before relocs are
processed, and return to the mapping mode requested by the phdr, after
relocs are done.

Reported, tested, and reviewed by: emaste
PR: 207631
Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks


# ef2c2a69 27-Jan-2016 Alexander Kabaev <kan@FreeBSD.org>

Do not unlock rtld_phdr_lock over callback invocations.

The dl_iterate_phdr consumer code in libgcc does not expect multiple
callbacks running concurrently. This was fixed once already in r178807,
but accidentally got reverted in r294373.


# 832b9473 20-Jan-2016 Alexander Kabaev <kan@FreeBSD.org>

Fix initlist_add_object invocation parameters.

The tail parameter should point to the last object for
which dependencies should be processed. In most cases,
this is the object itself.


# 9fee0541 20-Jan-2016 Konstantin Belousov <kib@FreeBSD.org>

Do not call callbacks for dl_iterate_phdr(3) with the rtld bind and
phdr locks locked. This allows to call rtld services from the
callback, which is only reasonable for dlopen(path, RTLD_NOLOAD) to
test existence of the library in the image, and for dlsym(). The
later might still be not quite safe, due to the lazy resolution of
filters.

To allow dropping the locks around iteration in dl_iterate_phdr(3), we
insert markers to track current position between relocks. The global
objects list is converted to tailq and all iterators skip markers,
globallist_next() and globallist_curr() helpers are added.

Reported and tested by: davide
Reviewed by: kan
Sponsored by: The FreeBSD Foundation
MFC after: 3 weeks


# 3dda93b9 18-Jan-2016 Warner Losh <imp@FreeBSD.org>

Restore ABI variants now that ldconfig groks -soft. In addition, as a
transition mechanism, if we don't have /usr/libsoft, assume that soft
float ABI binaries are the default, so treat them as default binaries.
When we've fully transitioned, it will make no sense to do this stat,
and it will be removed.


# b873436a 07-Jan-2016 Ed Maste <emaste@FreeBSD.org>

Revert r293201, r293202 (rtld: populate DT_DEBUG iff DYNAMIC segment is writable)

It turns out MIPS binaries may have other oddities that can trigger a
fault at startup.

PR: 206017
Reported by: ray


# 11cf751d 05-Jan-2016 Warner Losh <imp@FreeBSD.org>

Disable abi variant hook until strangeness with packages can be sorted
out.


# 7a2ff73d 05-Jan-2016 Ed Maste <emaste@FreeBSD.org>

rtld: populate DT_DEBUG iff DYNAMIC segment is writable

MIPS has/had a read-only DYNAMIC segment, and uses an extra level of
indirection (through MIPS_RLD_MAP) to locate the debugger rendezvous
data.

Some linkers (e.g. LLVM's lld) may produce MIPS binaries with a writable
DYNAMIC segment, which would allow us to eventually drop a special case.

Therefore, instead of hardcoding knowledge that DYNAMIC is not writable
on MIPS just check the permissions on the segment.

Reviewed by: kib
MFC after: 2 weeks
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D4791


# c333c74a 02-Jan-2016 Warner Losh <imp@FreeBSD.org>

If md_exec_hook is defined, provide a way to create the strings
for the environment variables we look up at runtime. Otherwise,
there's no way they will change, optimize it at compile time.

Differential Review: https://reviews.freebsd.org/D2718


# 8fd53f45 02-Jan-2016 Warner Losh <imp@FreeBSD.org>

Create a generalized exec hook that different architectures can hook
into if they need to, but default to no action.

Differential Review: https://reviews.freebsd.org/D2718


# 95b56c0e 27-Dec-2015 Warner Losh <imp@FreeBSD.org>

Use a macro to create the names for the library path names. This will
allow later substitution at run time instead of compile time of the
environment variable name prefix.

Differential Review: https://reviews.freebsd.org/D2718


# 18010b98 24-Dec-2015 Ed Maste <emaste@FreeBSD.org>

rtld: remove old XXX comment missed in r35529

Sponsored by: The FreeBSD Foundation


# 4b1859c0 24-Dec-2015 Ruslan Bukin <br@FreeBSD.org>

Add support for RISC-V architecture.

Reviewed by: andrew, kib
Sponsored by: DARPA, AFRL
Sponsored by: HEIF5
Differential Revision: https://reviews.freebsd.org/D4679


# 66963b3c 21-Dec-2015 Ed Maste <emaste@FreeBSD.org>

rtld: Use common NT_FREEBSD_* note types introduced in r291909

Sponsored by: The FreeBSD Foundation


# d1e1c4de 17-Dec-2015 Warner Losh <imp@FreeBSD.org>

Use variable names that aren't as prone to dyslexic confusion.

Suggested by: jmallet@


# 29ba9b61 02-Dec-2015 Nathan Whitehorn <nwhitehorn@FreeBSD.org>

Provide support for ELFv2 userland if using a newer compiler (recent clang
or gcc) and binutils >= 2.24. Not enabled by default.


# 3deca56f 30-Oct-2015 Warner Losh <imp@FreeBSD.org>

Rather than using the #define for path names, indirect through a char *
variable that could change for different executable types detected.


# b2a4014c 30-Oct-2015 Warner Losh <imp@FreeBSD.org>

Move all the paths into a new path.h to centralize them.


# 878165d2 01-Sep-2015 Andrew Turner <andrew@FreeBSD.org>

Ensure we use calculate_first_tls_offset, even if the main program doesn't
have TLS program header. This is needed on architectures with Variant I
tls, that is arm, arm64, mips, and powerpc. These place the thread control
block at the start of the buffer and, without this, this data may be
trashed.

This appears to not be an issue on mips or powerpc as they include a second
adjustment to move the thread local data, however this is on arm64 (with a
future change to fix placing this data), and should be on arm. I am unable
to trigger this on arm, even after changing the code to move the data
around to make it more likely to be hit. This is most likely because my
tests didn't use the variable in offset 0.

Reviewed by: kib
MFC after: 1 week
Sponsored by: ABT Systems Ltd


# 244f6b3e 06-May-2015 Ed Maste <emaste@FreeBSD.org>

Remove historical GNUC test

The requirement is for a GCC-compatible compiler and not necessarily
GCC itself. However, we currently expect any compiler used for building
the whole of FreeBSD to be GCC-compatible and many things will break if
not; there's no longer a need to have an explicit test for this in rtld.

Reviewed by: imp, kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D2422


# b3ff02bf 27-Apr-2015 Konstantin Belousov <kib@FreeBSD.org>

Change interpretation of the DF_ORIGIN and DF_1_ORIGIN flags.
According to standard, the presence of the flags only means that the
object path must be resolved at the time object loading, instead of my
reading that the flag is required to enable token substitution at all.

The consequence is that -z origin linker flag is no longer required
for the token substitution in the run/rpath or the needed library
soname. It is only recommended if token substition is needed at
dlopen(3) time, since namecache might drop the required entries at the
time of resolution.

Found, reviewed and tested by: emaste
Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# d5fec489 21-Apr-2015 Craig Rodrigues <rodrigc@FreeBSD.org>

Support file verification in MAC.

* Add VCREAT flag to indicate when a new file is being created
* Add VVERIFY to indicate verification is required
* Both VCREAT and VVERIFY are only passed on the MAC method vnode_check_open
and are removed from the accmode after
* Add O_VERIFY flag to rtld open of objects
* Add 'v' flag to __sflags to set O_VERIFY flag.

Submitted by: Steve Kiernan <stevek@juniper.net>
Obtained from: Juniper Networks, Inc.
GitHub Pull Request: https://github.com/freebsd/freebsd/pull/27
Relnotes: yes


# 3de38154 15-Apr-2015 Konstantin Belousov <kib@FreeBSD.org>

Implement support -z global linker option. It marks the shared object
as always participating in the global symbols namespace, regardless of
the way the object was brought into the process address space.

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 29f36d0b 02-Apr-2015 Ed Maste <emaste@FreeBSD.org>

Make die available as rtld_die for use by MD relocation code

Reviewed by: kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D2213


# 047c6e3a 31-Mar-2015 Andrew Turner <andrew@FreeBSD.org>

Add the arm64 code to the runtime linker. It's not able to be built as we
still need libc_pic for a few things, but this is expected to be ready
soon.

Differential Revision: https://reviews.freebsd.org/D2136
Reviewed by: kib
Sponsored by: The FreeBSD Foundation


# 0c4f9ecd 29-Mar-2015 Konstantin Belousov <kib@FreeBSD.org>

Change compiler setting to make default visibility of the symbols for
rtld on x86 to be hidden. This is a micro-optimization, which allows
intrinsic references inside rtld to be handled without indirection
through PLT. The visibility of rtld symbols for other objects in the
symbol namespace is controlled by a version script.

Reviewed by: kan, jilles
Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks


# 0461326c 27-Feb-2015 Jung-uk Kim <jkim@FreeBSD.org>

When a file is executed and the path starts with `/', AT_EXECPATH is set
without any translation. If the file is a symbolic link, $ORIGIN may not be
expanded to the actual origin. Use realpath(3) to properly expand $ORIGIN
to its absolute path.

Reviewed by: kib
MFC after: 1 week


# 803fc2ca 30-Jan-2015 Konstantin Belousov <kib@FreeBSD.org>

Use powerof2(). Remove single-use variable.

Submitted by: Conrad Meyer
Differential Revision: https://reviews.freebsd.org/D1724
MFC after: 1 week


# 4ac1e0a9 24-Jan-2015 Dag-Erling Smørgrav <des@FreeBSD.org>

Allow tracing dlfunc() / dlsym() events.

MFC after: 1 week


# 0c5cba54 03-Jan-2015 Konstantin Belousov <kib@FreeBSD.org>

Do not erronously export 'openat' symbol from rtld.

The symbol leaked after r276630 since lib/libc/sys/openat.c defines
versions for openat using .symver (version script cannot assign two
versions to one symbol), and rtld uses openat. Instead, directly use
__sys_openat().

Reported and tested by: antoine
Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 0e521992 03-Jan-2015 Konstantin Belousov <kib@FreeBSD.org>

Add rtld private interface for dso to detect dynamic loading
vs. static linking.

Tested by: pho, antoine (exp-run)
Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 9abeb029 02-Dec-2014 John Baldwin <jhb@FreeBSD.org>

The runtime linker needs to include a path to itself in the link map
it exports to the debugger. It currently has two choices: it can use
a compiled-in path (/libexec/ld-elf.so.1) or it can use the path stored
in the interpreter path in the binary being executed. The runtime linker
currently prefers the second. However, this is usually wrong for compat32
binaries since the binary specifies the path of rtld on a 32-bit system
(/libexec/ld-elf.so.1) instead of the actual path (/libexec/ld-elf32.so.1).
For now, always assume the compiled in path (/libexec/ld-elf32.so.1) as
the rtld path and ignore the path in the binary for the 32-bit runtime
linker.

Differential Revision: https://reviews.freebsd.org/D1236
Reviewed by: kib


# 294246bb 24-Nov-2014 Ed Maste <emaste@FreeBSD.org>

Revert r274772: it is not valid on MIPS

Reported by: sbruno


# 688fd61a 20-Nov-2014 Ed Maste <emaste@FreeBSD.org>

Use canonical __PIC__ flag

It is automatically set when -fPIC is passed to the compiler.

Reviewed by: dim, kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D1179


# 54ac1078 09-Oct-2014 Ed Maste <emaste@FreeBSD.org>

Always return pathname in dl_iterate_phdr's dlpi_name, as Linux does

Linux LD_ITERATE_PHDR(3):
The dlpi_name field is a null-terminated string giving the
pathname from which the shared object was loaded.

That functionality is much more useful than returning just the short
name.

Approved by: kan
Sponsored by: The FreeBSD Foundation


# 74b0daf4 29-Aug-2014 Konstantin Belousov <kib@FreeBSD.org>

Optimize r270798, only do the second pass over non-plt relocations
when the first pass found IFUNCs.

Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks


# 14c35647 29-Aug-2014 Konstantin Belousov <kib@FreeBSD.org>

IFUNC symbol type shall be processed for non-PLT relocations,
e.g. when a global variable is initialized with a pointer to ifunc.
Add symbol type check and call resolver for STT_GNU_IFUNC symbol types
when processing non-PLT relocations, but only after non-IFUNC
relocations are done. The two-phase proceessing is required since
resolvers may reference other symbols, which must be ready to use when
resolver calls are done.

Restructure reloc_non_plt() on x86 to call find_symdef() and handle
IFUNC in single place.

For non-x86 reloc_non_plt(), check for call for IFUNC relocation and
do nothing, to avoid processing relocs twice.

PR: 193048
Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks


# e404dc33 26-Aug-2014 Konstantin Belousov <kib@FreeBSD.org>

Remove stray newline.


# e7d939bd 06-Jul-2014 Marcel Moolenaar <marcel@FreeBSD.org>

Remove ia64.

This includes:
o All directories named *ia64*
o All files named *ia64*
o All ia64-specific code guarded by __ia64__
o All ia64-specific makefile logic
o Mention of ia64 in comments and documentation

This excludes:
o Everything under contrib/
o Everything under crypto/
o sys/xen/interface
o sys/sys/elf_common.h

Discussed at: BSDcan


# 97ef7689 02-Jul-2014 Marcel Moolenaar <marcel@FreeBSD.org>

Fix r264346 for ia64. We need to allocate memory for the function
descriptors in order to relocate RTLD itself. To allocate memory,
we need the pagesizes array initialized, but that happens after
RTLD is relocated. This ordering is important for amd64, but it's
opposite of what ia64 needs. Handle this conflict with the define
called RTLD_INIT_PAGESIZES_EARLY. When defined, obtain the page
sizes before relocating rtld, otherwise do it after.


# 02d3b38e 20-Jun-2014 Jonathan Anderson <jonathan@FreeBSD.org>

Add the LD_LIBRARY_PATH_FDS environmental variable.

This variable allows the loading of shared libraries via directory descriptors
rather than via library paths. If LD_LIBRARY_PATH_FDS=3:4:12, the directories
represented by file descriptors 3, 4 and 12 will searched for shared libraries
before the normal path-based mechanisms are used. This allows us to execute
unprivileged binaries from within a Capsicum sandbox even if they require
shared libraries.

Approved by: rwatson (mentor)
Reviewed by: kib
MFC after: 3 weeks
Sponsored by: DARPA/AFRL


# 7a61fc5a 07-May-2014 Mark Johnston <markj@FreeBSD.org>

- Export the function added in r265456 rather than the non-existent
_rtld_debug_postinit(). [1]
- Use __compiler_membar() instead of inline asm in _r_debug_state() and
_r_debug_postinit(). [2]

Pointy hat to: markj [1]
Reported by: attilio [2]
Discussed with: kib
X-MFC-With: r265456


# a8509eb2 06-May-2014 Mark Johnston <markj@FreeBSD.org>

Add a postinit debugger hook to rtld. This will be used by dtrace(1) to halt
the victim process before its entry point is called, at which point probes
and DOF data are registered with the kernel. The r_debug_state hook cannot
be used for this purpose, as it is called before the program's init routines
are invoked and in particular before DOF data is registered (via drti.o).

Reviewed by: kib
MFC after: 2 weeks


# ea8577c7 11-Apr-2014 Alan Cox <alc@FreeBSD.org>

Before calling mmap() on a shared library's text and data sections, rtld
first calls mmap() with the arguments PROT_NONE and MAP_ANON to reserve a
single, contiguous range of virtual addresses for the entire shared library.
Later, rtld calls mmap() with the the shared library's file descriptor
and the argument MAP_FIXED to place the text and data sections within the
reserved range. The rationale for mapping shared libraries in this way is
explained in the commit message for Revision 190885. However, this approach
does have an unintended, negative consequence. Since the first call to
mmap() specifies MAP_ANON and not the shared library's file descriptor, the
kernel has no idea what alignment the vm object backing the file prefers.
As a result, the reserved range's alignment is unlikely to be the same as
the vm object's, and so mapping with superpages becomes impossible. To
address this problem, this revision adds the argument MAP_ALIGNED_SUPER to
the first call to mmap() if the text section is larger than the smallest
superpage size.

To determine if the text section is larger than the smallest superpage
size, rtld must always fetch the page size information. As a result, the
private code for fetching the base page size in rtld's builtin malloc is
redundant. Eliminate it. Requested by: kib

Tested by: zbb (on arm)
Reviewed by: kib (an earlier version)
Discussed with: jhb


# 6cd2b1dc 07-Dec-2013 Konstantin Belousov <kib@FreeBSD.org>

Cast Elf_Addr to void * to match the free_aligned() argument type.

Found by: gcc
Sponsored by: The FreeBSD Foundation
MFC after: 6 days


# 16a93df7 06-Dec-2013 Konstantin Belousov <kib@FreeBSD.org>

For variant II static TLS, properly align tls segments. Pre-calculate
the max required alignment for the static tls segments, and honor it
when carving the pieces for next module, from the static space. Use
aligned allocator to get properly-aligned dynamic blocks.

Reported by: dt71@gmx.com
Reviewed by: kan
Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 7a89ddd4 07-Nov-2013 Mark Johnston <markj@FreeBSD.org>

Include rtld itself when iterating over loaded ELF objects in
dl_iterate_phdr(3).

Reviewed by: kib


# 3cf98c19 07-Oct-2013 Konstantin Belousov <kib@FreeBSD.org>

Implement support for the interpose dso flag.

Requested by: bf
Reviewed by: kan
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Approved by: re (glebius)


# d24aca1b 01-Oct-2013 Ed Maste <emaste@FreeBSD.org>

Populate .rld_map on MIPS for debuggers

On MIPS the .dynamic section is read-only, so the pointer to rtld
information for debuggers cannot be stored there (in DT_DEBUG).
Instead, a special section .rld_map is used.

Sponsored by: DARPA, AFRL
Approved by: re (delphij)


# 8182b3be 21-Sep-2013 Dag-Erling Smørgrav <des@FreeBSD.org>

Make the directory mapping functionality, which was previously only
available in 32-bit compatibility mode, unconditional.

Overhaul the man page, which had evolved more by accretion than by design.

Approved by: re (gjb)
MFC after: 3 weeks


# 3c9cb0c6 29-Apr-2013 Konstantin Belousov <kib@FreeBSD.org>

Properly terminate the result string for intermediate results, to
allow the final strcpy() to start at the intended place.

Reported and tested by: pgj
Pointy hat to: kib
MFC after: 3 days


# 32e1d801 15-Apr-2013 Konstantin Belousov <kib@FreeBSD.org>

The origin_subst_one() function limits the length of the string to
PATH_MAX after the token substitution. This is wrong, because
origin_subst_one() performs the substitution on the whole rpath and
similar strings, which contain several pathes separated by colon. As
result, long (but correct) rpath consisting of many path elements is
rejected by the function.

Correct the problem by rewriting the origin_subst_one() to perform two
passes, first pass to calculate the number of substitutions to be
performed, and second pass to generate the resulting string. Second
pass allocates the memory for the result based on the count from the
first pass, without enforcing a limit.

Reported and tested by: pgj
Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks


# e1942829 04-Nov-2012 Jilles Tjoelker <jilles@FreeBSD.org>

rtld: Fix fd leak with parallel dlopen and fork/exec.

Rtld did not set FD_CLOEXEC on its internal file descriptors; therefore,
such a file descriptor may be passed to a process created by another thread
running in parallel to dlopen() or fdlopen().

No other threads are expected to be running during parsing of the hints
and libmap files but the file descriptors need not be passed to child
processes so add O_CLOEXEC there as well.

This change will break fdlopen() (as used by OpenPAM) on kernels without
F_DUPFD_CLOEXEC (added in July). Note that running new userland on old
kernels is not supported.

Reviewed by: kib


# 1a4f1f69 18-Sep-2012 Konstantin Belousov <kib@FreeBSD.org>

Do not reference z_nodeflib for !objgiven case, thus fixing LD_PRELOAD
for a non-absolute path.

PR: bin/171604
MFC after: 3 days


# 5763679b 20-Aug-2012 Alexander Kabaev <kan@FreeBSD.org>

Do not call process_nodelete with NULL object pointer.

The place where the function is called can be reached if object loading
and relocation fails too, in which case obj pointer will be NULL. Do not
call process_nodelete then, or crash will follow.

Pointy hat to: kan


# 207eee57 14-Aug-2012 Alexander Kabaev <kan@FreeBSD.org>

Pospone the DF_1_NODELETE processing until object DAG is fully loaded.

Trying to up the reference from the load loop risks missing dependencies
that have not been loaded yet.

MFC afer: 1 week
Reported by: nox
Reviewd by: kib


# bca2f623 15-Jul-2012 Konstantin Belousov <kib@FreeBSD.org>

Import the DragonFly BSD commit 4f0bc915b65fcf5a23214f6d221d65c80be68ad4
by John Marino <draco@marino.st>, with the following (edited) commit
message
Date: Sat, 24 Mar 2012 06:40:50 +0100
Subject: [PATCH 1/1] rtld: Implement DT_RUNPATH and -z nodefaultlib

DT_RUNPATH is incorrectly being considered as an alias of DT_RPATH. The
purpose of DT_RUNPATH is to have two different types of rpath: one that
can be overridden by the environment variable LD_LIBRARY_PATH and one that
can't. With the currently implementation, LD_LIBRARY_PATH will always
trump any embedded rpath or runpath tags.

Current path search order by rtld:
==================================
LD_LIBRARY_PATH
DT_RPATH / DT_RUNPATH (always the same)
ldconfig hints file (default: /var/run/ld-elf.so.hints)
/usr/lib

New path search order by rtld:
==============================
DT_RPATH of the calling object if no DT_RUNPATH
DT_RPATH of the main binary if no DT_RUNPATH and binary isn't calling obj
LD_LIBRARY_PATH
DT_RUNPATH
ldconfig hints file
/usr/lib

The new path search matches how the linux runtime loader works. The other
major added feature is support for linker flag "-z nodefaultlib". When
this flag is passed to the linker, rtld will skip all references to the
standard library search path ("/usr/lib" in this case but it could handle
more color delimited paths) except in DT_RPATH and DT_RUNPATH.

New path search order by rtld with -z nodefaultlib flag set:
============================================================
DT_RPATH of the calling object if no DT_RUNPATH
DT_RPATH of the main binary if no DT_RUNPATH and binary isn't calling obj
LD_LIBRARY_PATH
DT_RUNPATH
ldconfig hints file (skips all references to /usr/lib)

FreeBSD notes:
- we fixed some bugs which were submitted to DragonFly and merged there
as commit 1ff8a2bd3eb6e5587174c6a983303ea3a79e0002;
- we added LD_LIBRARY_PATH_RPATH environment variable to switch to
the previous behaviour of considering DT_RPATH a synonym for DT_RUNPATH;
- the FreeBSD default search path is /lib:/usr/lib and not /usr/lib.

Reviewed by: kan
MFC after: 1 month
MFC note: flip the ld_library_path_rpath default value for stable/9


# a33cb5fe 27-Jun-2012 Konstantin Belousov <kib@FreeBSD.org>

Ensure that for the object which is a dependency for some filtee,
relocations are performed before the object's initializer is called.
When dlopen()ing an object, relocate the whole DAG rooted in the
object instead of only relocating the object itself and list of newly
loaded dependencies.

Reversed sequence currently can occur if the same object is a
dependency for both filtee and filter, since filtees are loaded
typically during the relocation processing, when some filter
dependencies might be already loaded but not relocated yet.

Reported and tested by: swills
Reviewed by: kan
MFC after: 1 week


# eb6910cc 05-May-2012 Konstantin Belousov <kib@FreeBSD.org>

Work around a situation where symlook_obj() could be called for the
object for which digest_dynamic1() was not done yet. Just return
EINVAL and do not try to dereference NULL buckets hash array.

This seems to happen on ia64 for rtld object itself, where the
R_IA_64_FPTR64LSB relocations require symbol lookup. The dynamic
linker itself does not rely on identity of the C-level function
pointers (i.e. function descriptors).

Reported and reviewed by: marcel
MFC after: 8 days


# f6265192 30-Apr-2012 Konstantin Belousov <kib@FreeBSD.org>

Add GNU hash support for rtld.

Based on dragonflybsd support for GNU hash by John Marino <draco marino st>
Reviewed by: kan
Tested by: bapt
MFC after: 2 weeks


# 34cb87ba 30-Apr-2012 Konstantin Belousov <kib@FreeBSD.org>

Split the symlook_obj1 into a loop iterating over the ELF object symbol
hash elements, and a helper matched_symbol() which match the given hash
entry and request, performing needed type and version checks.

Based on dragonflybsd support for GNU hash by John Marino <draco marino st>
Reviewed by: kan
Tested by: bapt
MFC after: 2 weeks


# fdfc035b 12-Apr-2012 Konstantin Belousov <kib@FreeBSD.org>

Propagate the current state of rtld_bind_lock to dlopen_object() calls
through the filter loading call chain. This fixes attempts to
write-lock the already locked rtld_bind_lock when filter loading is
initiated by relocation of dlopening dso.

Reported and tested by: Taku YAMAMOTO <taku tackymt homeip net>
MFC after: 1 week


# 3f4e35f7 05-Apr-2012 Konstantin Belousov <kib@FreeBSD.org>

Properly handle absent AT_CANARY aux entry.

Submitted by: Andrey Zonov <andrey zonov org>
MFC after: 3 days


# 4aed2ce8 02-Apr-2012 Alexander Kabaev <kan@FreeBSD.org>

Remove extra blank line from revious commit.

Submitted by: trema


# 7605b428 02-Apr-2012 Alexander Kabaev <kan@FreeBSD.org>

Do not try to adjust stacks if dlopen_object is called too early.

This is a follow-up to r233231, which fixed similar issue with
object initialization code.

Reviewed by: kib
MFC after: 1 week (with 233231)


# 5b7a7b02 29-Mar-2012 Konstantin Belousov <kib@FreeBSD.org>

Fix ia64 build after r233655.

MFC after: 1 week


# 5ceeeba9 29-Mar-2012 Konstantin Belousov <kib@FreeBSD.org>

Import DragonFly BSD commit

From: Sascha Wildner <saw@online.de>
Date: Fri, 2 Mar 2012 09:15:56 +0000 (+0100)
Subject: rtld: Add a special case in do_dlsym() for TLS stored symbols.
X-Git-Url: http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/1388aaafe730c85693936aaf9bc6d83fc2d981be?hp=bca4412595a8979ab9f1bf36068c806ce88a667a

rtld: Add a special case in do_dlsym() for TLS stored symbols.

Submitted-by: Markus Pfeiffer <markus.pfeiffer@morphism.de>

Discussed with: kan
MFC after: 1 week


# ff17bc61 27-Mar-2012 Konstantin Belousov <kib@FreeBSD.org>

Prevent rtld_verify_object_versions() from being called several times
for the same object. This can happen when object is a dependency of the
dlopen()ed dso. When called several times, we waste time due to unneeded
processing, and memory, because obj->vertab is allocated anew on each
iteration.

Reviewed by: kan
MFC after: 2 weeks


# 2aa3a467 24-Mar-2012 Konstantin Belousov <kib@FreeBSD.org>

Remove libssp_nonshared from the rtld linking set. The only use for the
library was definition for the weak alias of __stack_chk_fail.

No objections from: kan
MFC after: 2 weeks


# 83dd1777 24-Mar-2012 Konstantin Belousov <kib@FreeBSD.org>

Provide short-circuit exit(3) implementation for rtld.
There is no atexit finalizers in rtld to call on rtld exiting (due to errors).

Submitted by: bde
No objections from: kan
MFC after: 2 weeks


# 758ffbfa 22-Mar-2012 Konstantin Belousov <kib@FreeBSD.org>

Use xmalloc() instead of malloc() in the places where malloc() calls
are assumed to not fail.

Make the xcalloc() calling conventions follow the calloc(3) calling
conventions and replace unchecked calls to calloc() with calls to
xcalloc().

Remove redundand declarations from xmalloc.c, which are already
present in rtld.h.

Reviewed by: kan
Discussed with: bde
MFC after: 2 weeks


# 082f959a 20-Mar-2012 Konstantin Belousov <kib@FreeBSD.org>

Fix several problems with our ELF filters implementation.

Do not relocate twice an object which happens to be needed by loaded
binary (or dso) and some filtee opened due to symbol resolution when
relocating need objects. Record the state of the relocation
processing in Obj_Entry and short-circuit relocate_objects() if
current object already processed.

Do not call constructors for filtees loaded during the early
relocation processing before image is initialized enough to run
user-provided code. Filtees are loaded using dlopen_object(), which
normally performs relocation and initialization. If filtee is
lazy-loaded during the relocation of dso needed by the main object,
dlopen_object() runs too earlier, when most runtime services are not
yet ready.

Postpone the constructors call to the time when main binary and
depended libraries constructors are run, passing the new flag
RTLD_LO_EARLY to dlopen_object(). Symbol lookups callers inform
symlook_* functions about early stage of initialization with
SYMLOOK_EARLY. Pass flags through all functions participating in
object relocation.

Use the opportunity and fix flags argument to find_symdef() in
arch-specific reloc.c to use proper name SYMLOOK_IN_PLT instead of
true, which happen to have the same numeric value.

Reported and tested by: theraven
Reviewed by: kan
MFC after: 2 weeks


# 6fea10fb 14-Mar-2012 Konstantin Belousov <kib@FreeBSD.org>

Rtld on diet 3.

Stop using strerror(3) in rtld, which brings in msgcat and stdio.
Directly access sys_errlist array of errno messages with private
rtld_strerror() function.

Now,
$ size /libexec/ld-elf.so.1
text data bss dec hex filename
96983 2480 8744 108207 1a6af /libexec/ld-elf.so.1

Reviewed by: dim, kan
MFC after: 2 weeks


# ef5cdcbd 11-Mar-2012 Konstantin Belousov <kib@FreeBSD.org>

Rtld on diet part 1:

Provide rtld-private implementations of __stack_chk_guard,
__stack_chk_fail() and __chk_fail() symbols, to be used by functions
linked from libc_pic.a. This avoids use of libc stack_protector.c,
which pulls in syslog(3) and stdio as dependency.

Also, do initialize rtld-private copy __stack_chk_guard, previously
libc-provided one was not initialized, since we do not call rtld
object _init() methods.

Reviewed by: kan
MFC after: 3 weeks


# 3c5b7c6f 12-Mar-2012 Dimitry Andric <dim@FreeBSD.org>

Amend r232857, now dropping the casts entirely, as they were not
necessary at all.

Submitted by: stefanf


# addfbd03 12-Mar-2012 Dimitry Andric <dim@FreeBSD.org>

Fix the following warning/error with clang:

libexec/rtld-elf/rtld.c:1898:22: error: comparison between pointer and integer ('Elf_Addr *' (aka 'unsigned int *') and 'Elf_Addr' (aka 'unsigned int')) [-Werror]
if (preinit_addr == (Elf_Addr)NULL)
~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~
libexec/rtld-elf/rtld.c:2039:16: error: comparison between pointer and integer ('Elf_Addr *' (aka 'unsigned int *') and 'Elf_Addr' (aka 'unsigned int')) [-Werror]
if (init_addr != (Elf_Addr)NULL) {
~~~~~~~~~ ^ ~~~~~~~~~~~~~~

Reviewed by: kib


# 83aa9cc0 11-Mar-2012 Konstantin Belousov <kib@FreeBSD.org>

Add support for preinit, init and fini arrays. Some ABIs, in
particular on ARM, do require working init arrays.

Traditional FreeBSD crt1 calls _init and _fini of the binary, instead
of allowing runtime linker to arrange the calls. This was probably
done to have the same crt code serve both statically and dynamically
linked binaries. Since ABI mandates that first is called preinit
array functions, then init, and then init array functions, the init
have to be called from rtld now.

To provide binary compatibility to old FreeBSD crt1, which calls _init
itself, rtld only calls intializers and finalizers for main binary if
binary has a note indicating that new crt was used for linking. Add
parsing of ELF notes to rtld, and cache p_osrel value since we parsed
it anyway.

The patch is inspired by init_array support for DragonflyBSD, written
by John Marino.

Reviewed by: kan
Tested by: andrew (arm, previous version), flo (sparc64, previous version)
MFC after: 3 weeks


# 6bfe9e8c 10-Mar-2012 Konstantin Belousov <kib@FreeBSD.org>

Optimize tls_get_addr_common(). The change provides around 30% speedup
for TLS microbenchmark using global-dynamic TLS model on amd64 (which is
default for PIC dso objects).

Split the slow path into tls_get_addr_slow(), for which inlining is
disabled. This prevents the registers spill on tls_get_addr_common()
entry.

Provide static branch hint to the compiler, indicating that slow path
is not likely to be taken.

While there, do some minimal style adjustments.

Reported and tested by: davidxu
MFC after: 1 week


# dc3b6c3a 13-Feb-2012 Oleksandr Tymoshenko <gonzo@FreeBSD.org>

Add thread-local storage support for ARM to rtld-elf

Reviewed by: cognet
Obtained from: NetBSD


# 0eddfb06 13-Feb-2012 Konstantin Belousov <kib@FreeBSD.org>

Add missed EOL when die() was converted to use rtld_fdputstr() instead
of errx().

Reported by: amdmi3
PR: bin/165075
MFC after: 3 days


# 20c390af 09-Feb-2012 Oleksandr Tymoshenko <gonzo@FreeBSD.org>

Switch MIPS TLS implementation to Variant I


# 6d7610d7 30-Jan-2012 Konstantin Belousov <kib@FreeBSD.org>

Add support for GNU RELRO.

Submitted by: John Marino <draco marino st>
MFC after: 2 weeks


# 5d8aec9c 07-Jan-2012 Konstantin Belousov <kib@FreeBSD.org>

Implement fdlopen(3), an rtld interface to load shared object by file
descriptor.

Requested and tested by: des (previous version)
Reviewed by: des, kan (previous version)
MFC after: 2 weeks


# 68266d5a 04-Jan-2012 Konstantin Belousov <kib@FreeBSD.org>

Postpone the resolution of IRELATIVE relocations and IFUNC-targeted
relocations until tls is initialized and stacks permissions correctly
set. This allows the ifunc to call malloc(3) and some other heavy
services.

Add debug banner.

MFC after: 3 days


# 5734c46c 14-Dec-2011 Konstantin Belousov <kib@FreeBSD.org>

_rtld_bind() read-locks the bind lock, and possible plt resolution
from the dispatcher would also acquire bind lock in read mode, which
is the supported operation. plt is explicitely designed to allow safe
multithreaded updates, so the shared lock do not cause problems.

The error in r228435 is that it allows read lock acquisition after the
write lock for the bind block. If we dlopened the shared object that
contains IRELATIVE or jump slot which target is STT_GNU_IFUNC, then
possible recursive plt resolve from the dispatcher would cause it.

Postpone the resolution for irelative/ifunc right before initializers
are called, and drop bind lock around calls to dispatcher. Use
initlist to iterate over the objects instead of the ->next, due to
drop of the bind lock in iteration.

For i386/reloc.c:reloc_iresolve(), fix calculation of the dispatch
function address for dso, by taking into account possible non-zero
relocbase.

MFC after: 3 weeks


# 6be4b697 12-Dec-2011 Konstantin Belousov <kib@FreeBSD.org>

Add support for STT_GNU_IFUNC and R_MACHINE_IRELATIVE GNU extensions to
rtld on 386 and amd64. This adds runtime bits neccessary for the use
of the dispatch functions from the dynamically-linked executables and
shared libraries.

To allow use of external references from the dispatch function, resolution
of the R_MACHINE_IRESOLVE relocations in PLT is postponed until GOT entries
for PLT are prepared, and normal resolution of the GOT entries is finished.
Similar to how it is done by GNU, IRELATIVE relocations are resolved in
advance, instead of normal lazy handling for PLT.

Move the init_pltgot() call before the relocations for the object are
processed.

MFC after: 3 weeks


# 953cc854 18-Nov-2011 Konstantin Belousov <kib@FreeBSD.org>

Fix fd leak.

Reported by: slonoman2011 yandex ru
MFC after: 1 week


# 4e63ea73 07-Oct-2011 Konstantin Belousov <kib@FreeBSD.org>

Setting up TLS block for the main thread must be done after the
relocations are processed, since tls initialization section might be
itself subject for relocations. Only set up of the block is postponed,
the tls block offsets are allocated before relocation processing, since
TLS-related relocations may need offsets ready.

Reported by: ale
PR: threads/161344
Reviewed by: kan
MFC after: 1 week


# f7855887 15-Sep-2011 Konstantin Belousov <kib@FreeBSD.org>

Use the proper dynamic tls block to calculate the tls variable address
in case tls data generation was updated.

PR: misc/160721
Submitted by: "Thinker K.F. Li" <thinker codemud net>
Tested by: flo
Approved by: re (bz)
MFC after: 1 week


# cce0f33c 03-Sep-2011 Dimitry Andric <dim@FreeBSD.org>

When libexec/rtld-elf/rtld.c is compiled with clang, the r_debug_state()
function (a hook necessary for gdb support), is inlined, but since the
function contains no code, no calls to it are generated. When gdb is
debugging a dynamically linked program, this causes backtraces to be
corrupted.

Fix it by marking the function __noinline, and inserting an empty asm
statement, that pretends to clobber memory. This forces the compiler to
emit calls to r_debug_state() throughout rtld.c.

Approved by: re (kib)


# 0e9a2605 24-Aug-2011 Konstantin Belousov <kib@FreeBSD.org>

Rtld links with the specially built pic static libc library to get some
C runtime services, like printf(). Unfortunately, the multithread-safeness
measures in the libc do not work in rtld environment.

Rip the kernel printf() implementation and use it in the rtld instead of
libc version. This printf does not require any shared global data and thus
is mt-safe. Systematically use rtld_printf() and related functions, remove
the calls to err(3).

Note that stdio is still pulled from libc due to libmap implementaion using
fopen(). This is safe but unoptimal, and can be changed later.

Reported and tested by: pgj
Diagnosed and reviewed by: kan (previous version)
Approved by: re (bz)


# 5f301949 18-Jun-2011 Ben Laurie <benl@FreeBSD.org>

Fix clang warnings.

Approved by: philip (mentor)


# 6014c8de 25-Mar-2011 Andriy Gapon <avg@FreeBSD.org>

rtld: eliminate double call to close(2) that may occur in load_object

The second close(2) call resulted in heisenbugs in some multi-threaded
applications where e.g. dlopen(3) call in one thread could close a file
descriptor for a file having been opened in other thread concurrently.

My litmus test for this issue was an openoffice.org build.

Reviewed by: jhb
MFC after: 2 weeks


# a7bc470a 09-Feb-2011 Konstantin Belousov <kib@FreeBSD.org>

Use sigsetjmp/siglongjmp with disabled signal mask access for
lock upgrade in rtld. There is no need to care about the mask,
which causes a lot of unneeded sigprocmask(2) calls during each
symbol lookup.


# 54a6cb4e 30-Jan-2011 Konstantin Belousov <kib@FreeBSD.org>

Fix grammar in comment.

Pointy hat to: kib
MFC after: 1 week


# 2c953288 30-Jan-2011 Konstantin Belousov <kib@FreeBSD.org>

Make ldd(1) work when versioned dependency file is cannot be loaded.
Instead of aborting in locate_dependency(), propagate the error to
caller. The rtld startup function does the right thing with an error
from rtld_verify_versions(), depending on the mode of operation.

Reported by: maho
In collaboration with: kan
MFC after: 1 week


# 20a86d1f 28-Jan-2011 Alexander Kabaev <kan@FreeBSD.org>

Eliminate the use of symlook_needed function in favor of DAGS.

Place elements on DAG lists in breadth-first order. This allows us to
walk pre-built list in all cases where breadth-first dependency chain
enumeration is required.

Fix dlsym on special handle obtained by dlopen(NULL, ...) to do what
comment claims it does. Take advantage of recently added symlook_global
function to iterate over main objects and global DAGs lists properly in
search of a symbol. Since rtld itself provides part of the global
namespace, search rtld_obj too.

Remove recursion from init_dag and symlook_needed functions. Use
symlook_needed for ELF filtee processing only and change lookup order
used in the function to match the order used by Solaris runtime linker
under same circumstances. While there, fix weak symbol handling in the
loop so that we return the first weak symbol definition if no strong one
was found, instead of the last one.

Reviewed by: kib
MFC after: 1 month


# 3fce3875 28-Jan-2011 Sergey Kandaurov <pluknet@FreeBSD.org>

Remove SuperH architecture from a comment as we do not support it.
Presumably it was leaked from NetBSD together with rtld-elf mips support.

Approved by: kib (mentor)
MFC after: 3 days


# cb38d494 25-Jan-2011 Konstantin Belousov <kib@FreeBSD.org>

When loading dso without PT_GNU_STACK phdr, only call
__pthread_map_stacks_exec() on architectures that allow executable
stacks.

Reported and tested by: marcel (ia64)


# 4503c8f7 25-Jan-2011 Konstantin Belousov <kib@FreeBSD.org>

Fix get_program_var_addr() when type of the resolved symbol is functional.
Use make_function_pointer then, otherwise ia64 is broken.

Reported and tested by: marcel


# cb48d320 22-Jan-2011 Konstantin Belousov <kib@FreeBSD.org>

Add my copyright.

Discussed with: kan


# bf390c1f 10-Jan-2011 Konstantin Belousov <kib@FreeBSD.org>

get_program_var_addr() must prefer the strong symbol to the weak
one. Search global objects, together with main object and
dependencies, for the requested symbol.

Move the common code from symlook_default() into new helper
symlook_global(), and use it both in symlook_global() and
get_program_var_addr().

Supply lock state to get_program_var_addr().

Reviewed by: kan
Tested by: Mykola Dzham <i levsha me>


# 212f264c 08-Jan-2011 Konstantin Belousov <kib@FreeBSD.org>

In rtld, read the initial stack access mode from AT_STACKPROT as set
by kernel, and parse PT_GNU_STACK phdr from linked and loaded dsos.

If the loaded dso requires executable stack, as specified by PF_X bit
of p_flags of PT_GNU_STACK phdr, but current stack protection does not
permit execution, the __pthread_map_stacks_exec symbol is looked up
and called. It should be implemented in libc or threading library and
change the protection mode of all thread stacks to be executable.

Provide a private interface _rtld_get_stack_prot() to export the stack
access mode as calculated by rtld.

Reviewed by: kan


# 43c9be3d 26-Dec-2010 Alexander Kabaev <kan@FreeBSD.org>

Fix an apparent cop-and-paste mistake in previous commit.

This makes dlsym(RTLD_DEFAULT) work properly again.


# 8569deaf 25-Dec-2010 Konstantin Belousov <kib@FreeBSD.org>

Implement support for ELF filters in rtld. Both normal and auxillary
filters are implemented.

Filtees are loaded on demand, unless LD_LOADFLTR environment variable
is set or -z loadfltr was specified during the linking. This forces
rtld to upgrade read-locked rtld_bind_lock to write lock when it
encounters an object with filter during symbol lookup.

Consolidate common arguments of the symbol lookup functions in the
SymLook structure. Track the state of the rtld locks in the
RtldLockState structure. Pass local RtldLockState through the rtld
symbol lookup calls to allow lock upgrades.

Reviewed by: kan
Tested by: Mykola Dzham <i levsha me>, nwhitehorn (powerpc)


# 4ef75f14 16-Dec-2010 Jaakko Heinonen <jh@FreeBSD.org>

If dlclose() is called recursively from a _fini() function, the inner
dlclose() call may unload the object of the outer call prematurely
because objects are unreferenced before _fini() calls.

Fix this by unreferencing objects after calling objlist_call_fini() in
dlclose(). Therefore objlist_call_fini() now calls the fini function if
the reference count of an object is 1. In addition we must restart the
list_fini traversal after every _fini() call because another dlclose()
call might have modified the reference counts.

Add an XXX comment to objlist_call_fini() about possible race with
dlopen().

PR: 133246, 149464
Reviewed by: kan, kib


# 4495a80b 04-Nov-2010 Konstantin Belousov <kib@FreeBSD.org>

In r214728, if dlopen() is called for the object that has been already
loaded as a dependency and marked -z nodlopen, object' DAG is already
initialized by load_needed_objects(). Due to this, the init_dag() call
from dlopen() does not increment refcount for the object [1].

Change init_dag() to not increment DAG refcount. Require explicit calls
to ref_dag() to increment, and assert that ref_dag() and unref_dag()
are called for root that has dag initialized. To fix the noted issue,
unconditionally call both init_dag() and ref_dag() in dlopen() for the
case when the object was already loaded, making it similar to the case
of newly loaded object.

Noted by: jh [1]
Reviewed by: jh, kan
MFC after: 6 days


# 5dc7bbaf 04-Nov-2010 Konstantin Belousov <kib@FreeBSD.org>

Fix style.

MFC after: 6 days


# b8fc1b23 03-Nov-2010 Konstantin Belousov <kib@FreeBSD.org>

If dlopen() is called for the dso that has been already loaded as a
dependency, then the dso never has its DAG initialized. Empty DAG
makes ref_dag() call in dlopen() a nop, and the dso refcount is off
by one.

Initialize the DAG on the first dlopen() call, using a boolean flag
to prevent double initialization.

From the PR (edited):
Assume we have a library liba.so, containing a function a(), and a
library libb.so, containing function b(). liba.so needs functionality
from libb.so, so liba.so links in libb.so.

An application doesn't know about the relation between these libraries,
but needs to call a() and b(). It dlopen()s liba.so and obtains a
pointer to a(), then it dlopen()s libb.so and obtains a pointer to b().

As soon as the application doesn't need a() anymore, it dlclose()s liba.so.

Expected result: the pointer to b() is still valid and can be called
Actual result: the pointer to b() has become invalid, even though the
application did not dlclose() the handle to libb.so. On calling b(), the
application crashes with a segmentation fault.

PR: misc/151861
Based on patch by: jh
Reviewed by: kan
Tested by: Arjan van Leeuwen <freebsd-maintainer opera com>
MFC after: 1 week


# a7d5f7eb 19-Oct-2010 Jamie Gritton <jamie@FreeBSD.org>

A new jail(8) with a configuration file, to replace the work currently done
by /etc/rc.d/jail.


# d48dde6f 12-Sep-2010 Nathan Whitehorn <nwhitehorn@FreeBSD.org>

Check for undefined weak symbols during PLT binding on powerpc64, and do
not attempt to copy NULL function descriptors. This fixes LD_BIND_NOW on
powerpc64 after r211706.

Reviewed by: kib


# d4ba3a56 24-Aug-2010 Konstantin Belousov <kib@FreeBSD.org>

Remove exports table. Export control by the version script is enough.

Reviewed by: kan
MFC after: 3 weeks


# ea246b63 23-Aug-2010 Konstantin Belousov <kib@FreeBSD.org>

On shared object unload, in __cxa_finalize, call and clear all installed
atexit and __cxa_atexit handlers that are either installed by unloaded
dso, or points to the functions provided by the dso.

Use _rtld_addr_phdr to locate segment information from the address of
private variable belonging to the dso, supplied by crtstuff.c. Provide
utility function __elf_phdr_match_addr to do the match of address against
dso executable segment.

Call back into libthr from __cxa_finalize using weak
__pthread_cxa_finalize symbol to remove any atfork handler which
function points into unloaded object.

The rtld needs private __pthread_cxa_finalize symbol to not require
resolution of the weak undefined symbol at initialization time. This
cannot work, since rtld is relocated before sym_zero is set up.

Idea by: kan
Reviewed by: kan (previous version)
MFC after: 3 weeks


# e048186a 23-Aug-2010 Konstantin Belousov <kib@FreeBSD.org>

Introduce implementation-private rtld interface _rtld_addr_phdr, which
fills struct dl_phdr_info for the shared object that contains the
specified address, if any.

Idea and reviewed by: kan
MFC after: 3 weeks


# 8fc48522 17-Aug-2010 Konstantin Belousov <kib@FreeBSD.org>

Provide the starting image with the pointer to ELF aux vector. It is
written into the __elf_aux_vector variable, if the symbol is present.

Idea from: kan
Tested by: marius (sparc64)
MFC after: 1 month


# d59a6353 17-Aug-2010 Konstantin Belousov <kib@FreeBSD.org>

Use the newly provided aux vectors to get pagesize and osreldate information.
Use local version of getpagesize(), rtld_getpagesize() in private allocator.
Override the __getosreldate() previously fetched from libc_pic.a with
local version that uses aux value if present. Note that __getosreldate()
is used by rtld indirectly, by mmap(2) libc wrapper.

To be able to utilize aux, split digest_dynamic() for use by init_rtld()
into two parts, where the first one does not call malloc(), and the
second part uses it. init_rtld() is able to initialize global variables
before digest_dynamic2() calls. In particular, pagesize and osreldate are
set up from the aux values.

Now, rtld avoids (two) sysctl calls in startup.

Tested by: marius (sparc64)
MFC after: 1 month


# 153d788f 27-Jun-2010 Nathan Whitehorn <nwhitehorn@FreeBSD.org>

Revert r209544. It papers over a binutils bug, and is not even a reliable
fix for it.

The bug occurs when using the --as-needed flag to ld in the presence of
synthetic linker-generated symbols that reference symbols defined in
linked-to shared libraries with versioned symbols. When the only symbols
used from a library fall into this category, ld will drop the DT_NEEDED
entry for it, but retain the versioning information. This bug is best
fixed/hacked around in binutils, not in rtld.

Discussed with: kan


# 5540acc1 26-Jun-2010 Nathan Whitehorn <nwhitehorn@FreeBSD.org>

Ignore versioned dependencies on shared objects to which we do not link.
This fixes an error with files like this created by GNU ld under certain
circumstances.


# f28c411c 02-Jun-2010 Alexander Kabaev <kan@FreeBSD.org>

Plug possible memory leak.

Found by: Coverity
MFC after: 2 weeks


# 1dfdc15b 18-May-2010 Roman Divacky <rdivacky@FreeBSD.org>

Only use the cache after the early stage of loading. This is
because calling mmap() etc. may use GOT which is not set up
yet. Use calloc() instead of mmap() in cases where this
was the case before (sparc64, powerpc, arm).

Submitted by: Dimitry Andric (dimitry andric com)
Reviewed by: kan
Approved by: ed (mentor)


# 28f91736 31-Mar-2010 Pietro Cerutti <gahr@FreeBSD.org>

MFC r205606
Remove const'ness from dlerror(3) prototype, for consistency with POSIX.

Approved by: cognet


# 071ab531 24-Mar-2010 Pietro Cerutti <gahr@FreeBSD.org>

- Remove const'ness from dlerror(3) prototype, for consistency with POSIX.

Approved by: cognet
MFC after: 1 week


# fe0506d7 09-Mar-2010 Marcel Moolenaar <marcel@FreeBSD.org>

Create the altix project branch. The altix project will add support
for the SGI Altix 350 to FreeBSD/ia64. The hardware used for porting
is a two-module system, consisting of a base compute module and a
CPU expansion module. SGI's NUMAFlex architecture can be an excellent
platform to test CPU affinity and NUMA-aware features in FreeBSD.


# e45051c3 15-Feb-2010 Marcel Moolenaar <marcel@FreeBSD.org>

Improve TLS variant I:
o Use obj->tlsinitsize to determine whether there's initialized data.
o If obj->tlssize > obj->tlsinitsize, then bzero uninitialized data.
o Don't exclude variant I from the work-around in free_tls_offset().


# 1eea4693 17-Dec-2009 Konstantin Belousov <kib@FreeBSD.org>

MFC r199829:
Implement rtld part of the support for -z nodlopen (see ld(1)).

MFC r199877:
Allow to load not-openable dso when tracing. This fixes ldd on such dso or
dso linked to non-openable object.
Remove '\n' at the end of error message.
End comments with dot.


# 38420804 14-Dec-2009 Robert Watson <rwatson@FreeBSD.org>

Merge r199270 from head to stable/8:

Fix white space in rtld runtime error printf.


# 0b1a7fea 30-Nov-2009 Colin Percival <cperciva@FreeBSD.org>

MFC r199979: Fix local root vulnerability.


# f349fbc4 30-Nov-2009 Colin Percival <cperciva@FreeBSD.org>

Fix local root vulnerability.

Security: Advisory will be coming soon.
X-MFC-After: 30 seconds


# 66b3ab74 29-Nov-2009 Konstantin Belousov <kib@FreeBSD.org>

MFC r199828:
Flag controlling origin expansion in DT_FLAGS is DF_ORIGIN, not DF_1_ORIGIN.


# abf48e83 28-Nov-2009 Konstantin Belousov <kib@FreeBSD.org>

Allow to load not-openable dso when tracing. This fixes ldd on such dso or
dso linked to non-openable object.
Remove '\n' at the end of error message.
End comments with dot.

MFC after: 3 weeks (together with r199829)


# 0d3bc8a9 26-Nov-2009 Konstantin Belousov <kib@FreeBSD.org>

Implement rtld part of the support for -z nodlopen (see ld(1)).

Reviewed by: kan
MFC after: 3 weeks


# 45d276ce 26-Nov-2009 Konstantin Belousov <kib@FreeBSD.org>

Flag controlling origin expansion in DT_FLAGS is DF_ORIGIN, not DF_1_ORIGIN.

Reviewed by: kan
MFC after: 3 days


# de8b11d8 14-Nov-2009 Robert Watson <rwatson@FreeBSD.org>

Fix white space in rtld runtime error printf.

MFC after: 3 days


# b6124fac 20-Oct-2009 Konstantin Belousov <kib@FreeBSD.org>

MFC r197931:
Apply relocations for PIE binary ELF data structures pointers in rtld.

Approved by: re (kensmith)


# dec4912e 10-Oct-2009 Konstantin Belousov <kib@FreeBSD.org>

Calculate relocation base for the main object, and apply the relocation
adjustment for all virtual addresses encoded into the ELF structures of
it. PIE binary could and should be loaded at non-zero mapbase.

For sym_zero pseudosymbol used as a return value from find_symdef()
for undefined weak symbols, st_value also should be adjusted, since
_rtld_bind corrects symbol values by relocbase.

Discussed with: bz
Reviewed by: kan
Tested by: bz (i386, amd64), bsam (linux)
MFC after: some time


# 49e8c06b 17-Jul-2009 Konstantin Belousov <kib@FreeBSD.org>

Implement RTLD_NOLOAD flag for dlopen(3).

Requested and tested by: jkim
Reviewed by: kan
Approved by: re (kensmith)


# 26d0788e 23-Jun-2009 Ed Schouten <ed@FreeBSD.org>

Fix a typo in the same comment, one line below.

Submitted by: bf1783 googlemail com


# 75b872ee 23-Jun-2009 Ed Schouten <ed@FreeBSD.org>

Fix typo in comment.

Submitted by: Christoph Mallon


# 6c3154f6 20-Jun-2009 Alexander Kabaev <kan@FreeBSD.org>

Allow order of initialization of loaded shared objects to be
altered through their .init code. This might happen if init
vector calls dlopen on its own and that dlopen causes some not
yet initialized object to be initialized earlier as part of that
dlopened DAG.

Do not reset module reference counts to zero on final fini vector
run when process is exiting. Just add an additional parameter to
force fini vector invocation regardless of current reference count
value if object was not destructed yet. This allows dlclose called
from fini vector to proceed normally instead of failing with handle
validation error.

Reviewed by: kib
Reported by: venki kaps


# 1310f237 16-Jun-2009 Alexander Kabaev <kan@FreeBSD.org>

FreeBSD returns main object handle from dlopen(NULL, ...) calls.
dlsym seaches using this handle are expected to look for symbol
definitions in all objects loaded at the program start time along
with all objects currently in RTLD_GLOBAL scope.

Discussed with: kib
Reported by: Maho NAKATA
MFC after: 2 weeks


# c8da4f07 03-Apr-2009 Konstantin Belousov <kib@FreeBSD.org>

Allow the NULL, RTLD_SELF and RTLD_NEXT handles to work with dlfunc(3).
dlfunc() called dlsym() to do the work, and dlsym() determines the dso
that originating the call by the return address. Due to this, dlfunc()
operated as if the caller is always the libc.

To fix this, move the dlfunc() to rtld, where it can call the internal
implementation of dlsym, and still correctly fetch return address.
Provide usual weak stub for the symbol from libc for static binaries.
dlfunc is put to FBSD_1.0 symver namespace in the ld.so export to
override dlfunc@FBSD_1.0 weak symbol, exported by libc.

Reported, analyzed and tested by: Tijl Coosemans <tijl ulyssis org>
PR: standards/133339
Reviewed by: kan


# 2b0b4ee3 30-Mar-2009 Konstantin Belousov <kib@FreeBSD.org>

Implement support for RTLD_NODELETE flag for dlopen() and -z nodelete
static linker option. Do it by incrementing reference count on the loaded
object and its dependencies.

Reviewed by: davidxu, kan


# 4d59cc85e 28-Mar-2009 Konstantin Belousov <kib@FreeBSD.org>

Do not dereference NULL pointer. refobj is NULL for the objects that are
preloaded.

Reported and tested by: ed


# 569e2ef6 23-Mar-2009 Xin LI <delphij@FreeBSD.org>

Support for a new environment variable, LD_ELF_HINTS_PATH for overriding
the rtld hints file. This environment variable would be unset if the
process is considered as tainted with setuid/setgid. This feature gives
a convenient way of using a custom set of shared library that is not
located in the default location and switch back.

Feature requested by: iXsystems
Original patch by: John Hixson
MFC after: 2 weeks


# 28551690 18-Mar-2009 Konstantin Belousov <kib@FreeBSD.org>

Implement the dynamic string token substitution in the rpath and
soneeded pathes. The $ORIGIN, $OSNAME, $OSREL and $PLATFORM tokens
are supported. Enabling the substitution requires DF_ORIGIN flag in
DT_FLAGS or DF_1_ORIGIN if DF_FLAGS_1, that may be set with -z origin
gnu ld flag. Translation is unconditionally disabled for setuid/setgid
processes.

The $ORIGIN translation relies on the AT_EXECPATH auxinfo supplied
by kernel.

Requested by: maho
Tested by: maho, pho
Reviewed by: kan


# cb5c4b10 27-Nov-2008 Konstantin Belousov <kib@FreeBSD.org>

Add two rtld exported symbols, _rtld_atfork_pre and _rtld_atfork_post.
Threading library calls _pre before the fork, allowing the rtld to
lock itself to ensure that other threads of the process are out of
dynamic linker. _post releases the locks.

This allows the rtld to have consistent state in the child. Although
child may legitimately call only async-safe functions, the call may
need plt relocation resolution, and this requires working rtld.

Reported and debugging help by: rink
Reviewed by: kan, davidxu
MFC after: 1 month (anyway, not before 7.1 is out)


# d7f03759 19-Oct-2008 Ulf Lilleengen <lulf@FreeBSD.org>

- Import the HEAD csup code which is the basis for the cvsmode work.


# 657d9f9a 09-Oct-2008 Alexander Kabaev <kan@FreeBSD.org>

Allow strong symbols to override weak ones for lookups done through
dlsym with RTLD_NEXT/RTLD_SELF handles.

Allow symbols from ld-elf.so to be located this way too.

Based on report and original patch from sobomax@.


# 61adda84 02-Sep-2008 Alexander Kabaev <kan@FreeBSD.org>

Make sure internal rtld malloc routines are not called from unlocked
contexts as rtld's malloc is not thread safe and is only supposed to be
called with exclusive bind lock already held.

The originating PR submitted a patch on top of different pre-requisite
workaroud for unsafe dlopen calls, and the patch was midief slighlty to apply
to stock sources for the purpose of this commit. Running rtld malloc from
unlocked contexts is a bug on its own.

PR: 126950
Submited by: Oleg Dolgov


# e91ff25c 06-May-2008 Konstantin Belousov <kib@FreeBSD.org>

Fix the problem with the C++ exception handling for the multithreaded
programs.

From the PR description:
The gcc runtime's _Unwind_Find_FDE function, invoked during exception
handling's stack unwinding, is not safe to execute from within multiple
threads. FreeBSD' s dl_iterate_phdr() however permits multiple threads
to pass through it though. The result is surprisingly reliable infinite
looping of one or more threads if they just happen to be unwinding at
the same time.

Introduce the new lock that is write locked around the dl_iterate_pdr,
thus providing required exclusion for the stack unwinders.

PR: threads/123062
Submitted by: Andy Newman <an at atrn org>
Reviewed by: kan
MFC after: 2 weeks


# 652d402e 04-Apr-2008 Warner Losh <imp@FreeBSD.org>

MFp4: Add mips support for dynamic linking.

This code came from the merged mips2 and Juniper mips repositories.
Warner Losh, Randall Seager, Oleksandr Tymoshenko and Olivier Houchard
worked to merge, debug and integrate this code. This code may also
contain code derived from NetBSD.


# d61e5aa4 17-May-2007 Christian S.J. Peron <csjp@FreeBSD.org>

In the event a process is tainted (setuid/setgid binaries), un-set any
potentially dangerous environment variables all together. It should be
noted that the run-time linker will not honnor these environment variables
if the process is tainted currently. However, once a child of the tainted
process calls setuid(2), it's status as being tainted (as defined by
issetugid(2)) will be removed. This could be problematic because
subsequent activations of the run-time linker could honnor these
dangerous variables.

This is more of an anti foot-shot mechanism, there is nothing I am
aware of in base that does this, however there may be third party
utilities which do, and there is no real negative impact of clearing
these environment variables.

Discussed on: secteam
Reviewed by: cperciva
PR: kern/109836
MFC after: 2 weeks


# 25785f91 05-May-2007 David Xu <davidxu@FreeBSD.org>

Fix a TLS memory leak.

PR: threads/112297
MFC: 1 week


# ac34654d 07-Apr-2007 Alexander Kabaev <kan@FreeBSD.org>

Catch up on rtld's special status. Since it does not appear on
main object list, its versioning information needs to be examined
separately.

This hopefully fixes problems that people running with SYMVER_ENABLED
are experiencing.


# 49f90ad2 03-Apr-2007 Alexander Kabaev <kan@FreeBSD.org>

Implement dl_iterate_phdr function.
Convert boolean flags in internal Obj_Entry structure into bitfields.
Properly check for loaded segment alignment in map_object.


# 1f4b63f8 09-Jan-2007 John Baldwin <jhb@FreeBSD.org>

Add various utrace's for use with ktrace to the ELF runtime linker. To
activate the traces, set the LD_UTRACE (or LD_32_UTRACE) environment
variable. This also includes code in kdump(8) to parse the traces.

Reviewed by: kan, jdp
MFC after: 2 weeks


# da7bf2bb 19-Sep-2006 Jung-uk Kim <jkim@FreeBSD.org>

Clean up white spaces and fix style(9).


# 5fd885b0 18-Sep-2006 Konstantin Belousov <kib@FreeBSD.org>

Fix the buggy rev. 1.117. dagmembers are only initialized for dlopen'ed
dso that are actually loading. If dso a.so depends on b.so, then dlsym
with handle from dlopen("b.so") will fail unconditionally.

Correct implementation shall use the Obj_Entry.needed list to walk
dependencies DAG.

Test provided by: jkim
Tested (prev. version) by: jkim, Nicolas Blais <nb_root at videotron ca>, h.blanke at chello nl
Pointy hat to: kib
Approved by: kan (mentor)


# d0cb0064 08-Sep-2006 Konstantin Belousov <kib@FreeBSD.org>

When looking up the symbol by dlsym, look it not only in the object
given as dso handle, but also in the implicit dependencies of that dso.

Also, const-ify the read-only parameter objlist of symlook_list.

Reported by: "Simon 'corecode' Schubert" <corecode at fs ei tum de>
Approved by: kan (mentor)
X-MFC-After: 6.2


# 3614156c 01-Sep-2006 Marcel Moolenaar <marcel@FreeBSD.org>

Fix the variant I allocation for KSE: Allow a larger TCB and assume
that the documented TCB is at the tail of the extended TCB. In other
words, the base of the TCB has a negative offset from the TLS.


# c93b8edf 04-Aug-2006 Xin LI <delphij@FreeBSD.org>

In symlook_obj(): fix _rtld_error output.

MFC After: 2 weeks


# c7717871 27-Mar-2006 David Xu <davidxu@FreeBSD.org>

Er, forgot to clear tls space to zero for Variant II.


# c0d2338c 27-Mar-2006 David Xu <davidxu@FreeBSD.org>

Allocate space for thread pointer, this allows thread library to access
its pointer from begin, and simplifies _get_curthread() in libthr.


# 96ff9a2b 24-Dec-2005 Alexander Kabaev <kan@FreeBSD.org>

Make lookups for relocations from old unversioned binaries return
oldest versioned symbol available. Do not accept hidden symbols for
all other versions.

Use "<obj->path>: <error message>" for all error messages in new
functions to make them more consistent.


# b80d39d0 23-Dec-2005 Alexander Kabaev <kan@FreeBSD.org>

Remove debugging statement that slipped into lone of the previous commits
unintentionally.


# f6e5db22 22-Dec-2005 Alexander Kabaev <kan@FreeBSD.org>

Initialize object dagmembers list before checking version dependencies.


# 0eb88f20 18-Dec-2005 Alexander Kabaev <kan@FreeBSD.org>

Implement ELF symbol versioning using GNU semantics. This code aims
to be compatible with symbol versioning support as implemented by
GNU libc and documented by http://people.redhat.com/~drepper/symbol-versioning
and LSB 3.0.

Implement dlvsym() function to allow lookups for a specific version of
a given symbol.


# 757686b1 17-Dec-2005 Marcel Moolenaar <marcel@FreeBSD.org>

Make our ELF64 type definitions match standards. In particular this
means:
o Remove Elf64_Quarter,
o Redefine Elf64_Half to be 16-bit,
o Redefine Elf64_Word to be 32-bit,
o Add Elf64_Xword and Elf64_Sxword for 64-bit entities,
o Use Elf_Size in MI code to abstract the difference between
Elf32_Word and Elf64_Word.
o Add Elf_Ssize as the signed counterpart of Elf_Size.

MFC after: 2 weeks


# 4d5fe96d 11-Nov-2005 John Baldwin <jhb@FreeBSD.org>

Fix a bug in dlinfo(RTLD_DI_SERINFOSIZE) requests. For each search path
we included the length of the path in the returned size but not the length
of the associated Dl_serpath structure. Without this fix, programs
attempting to allocate a structure to hold the search path information
would allocate too small of a buffer and rtld would overrun the buffer
while filling it via a subsequent RTLD_DI_SERINFO request.

Submitted by: "William K. Josephson" wkj at morphisms dot net
Reviewed by: jdp
MFC after: 2 weeks


# 3709906a 30-Mar-2005 Doug Rabson <dfr@FreeBSD.org>

When allocating TLS and DTV, make sure that any unused slots in the DTV
are initialised to zero. When freeing TLS, don't attempt to free DTV
slots which were not used.

Pointed out by: Joerg Sonnenberger
X-MFC-After: After the branch, probably


# 8fe7df9b 24-Mar-2005 Colin Percival <cperciva@FreeBSD.org>

If "dangerous" environment variables (LD_PRELOAD, LD_LIBMAP,
LD_LIBMAP_DISABLE, LD_LIBRARY_PATH) are used, then make sure the
libraries being loaded aren't on a noexec-mounted filesystem.

This is a compromise position: I'm assuming that nobody will be silly
enough to set the noexec mount flag on part of the default library
path, in order to avoid adding extra overhead into the common case
(where those environment variables aren't used).

Discussed with: csjp, secteam
MFC after: 1 week


# c5fa3778 20-Mar-2005 David Xu <davidxu@FreeBSD.org>

Add locking code for tls routines.


# ddab7ee8 26-Feb-2005 Doug Rabson <dfr@FreeBSD.org>

Attempt to free any static TLS space used by a shared library when it
is unloaded. This allows applications which load and unload libraries
like libGL.so.1 several times to work properly.

MFC after: 2 days


# 5b08cb04 03-Feb-2005 Matthew N. Dodd <mdodd@FreeBSD.org>

Description from Dan:

Another handy libmap patch. Lets you do stuff like this:

LD_LIBMAP="libpthread.so.1=libthr.so.1" mythreadedapp

If you already have a program-specific override in libmap.conf, note
that you must use a program-specific override in LD_LIBMAP:

LD_LIBMAP="[mythreadedapp],libpthread.so.1=libthr.so.1" mythreadedapp

PR: bin/74471
Submitted by: Dan Nelson <dnelson AT allantgroup.com>
MFC after: 2 weeks


# 5bbd22ee 02-Nov-2004 Suleiman Souhlal <ssouhlal@FreeBSD.org>

Do the TLS offset allocations before relocations, as otherwise there
can be overlap in the TLS offsets, if the relocations are done in a
certain order.

Approved by: dfr, grehan (mentor)


# 9ac88d19 23-Sep-2004 Olivier Houchard <cognet@FreeBSD.org>

Add stubs for TLS.
Arbitraly choose the 2nd variant until I figure out which one I should use.


# fca32c74 04-Aug-2004 Doug Rabson <dfr@FreeBSD.org>

Add stubs for powerpc TLS.

Submitted by: ssouhlal


# 017246d0 03-Aug-2004 Doug Rabson <dfr@FreeBSD.org>

Add support for Thread Local Storage.


# d05bb9a2 17-Jun-2004 Thomas Moestl <tmm@FreeBSD.org>

Fix the problem that surfaced with the new binutils import on sparc64
(and that is for now being worked around by a binutils patch).

The rtld code tested &_DYNAMIC against 0 to see whether rtld itself
was built as PIC or not. While the sparc64 MD code did not rely
on the preset value of the GOT slot for _DYNAMIC any more due
to previous binutils changes, it still used to not be 0, so
that this check did work. The new binutils do however initialize
this slot with 0. As a consequence, rtld would not properly initialize
itself and crash.
Fix that by introducing a new macro, RTLD_IS_DYNAMIC, to take the role
of this test. For sparc64, it is implemented using the rtld_dynamic()
code that was already there. If an architecture does not provide its
own implementation, we default to the old check.

While being there, mark _DYNAMIC as a weak symbol in the sparc64
rtld_start.S. This is needed in the LDSCRIPT case, which is however
not currently supported for want of an actual ldscript.

Sanity checked with md5 on alpha, amd64, i386 and ia64.


# 0a16eb83 27-May-2004 Oliver Eikemeier <eik@FreeBSD.org>

give out a little more information in case of a missing dependency

PR: 56549
Submitted by: edwin
Reviewed by: joerg, ru
Approved by: joerg
MFC after: 2 weeks


# f88e6cac 29-Mar-2004 Doug Rabson <dfr@FreeBSD.org>

If we change obj_rtld.path after initialising __progname, make sure we
change __progname to point at the new storage otherwise it ends up
pointing at freed memory which leads to confusing garbled error messages.


# c905e45d 20-Mar-2004 Peter Wemm <peter@FreeBSD.org>

Add initial support for compiling a special 32 bit version of
ld-elf.so.1 on 64 bit systems. Most of this involves using alternate
paths, environment variables and diagnostic messages.

The build glue is seperate.


# 16fc3635 05-Mar-2004 Mark Murray <markm@FreeBSD.org>

Make NULL a (void*)0 whereever possible, and fix the warnings(-Werror)
that this provokes. "Wherever possible" means "In the kernel OR NOT
C++" (implying C).

There are places where (void *) pointers are not valid, such as for
function pointers, but in the special case of (void *)0, agreement
settles on it being OK.

Most of the fixes were NULL where an integer zero was needed; many
of the fixes were NULL where ascii <nul> ('\0') was needed, and a
few were just "other".

Tested on: i386 sparc64


# 2627f357 25-Feb-2004 Alexander Kabaev <kan@FreeBSD.org>

Do not depend on existence of _end symbol in obj_from_addr, use
obj->mapbase and obj->mapsize instead.

Prompted by: OpenOffice debugging session at last BSDCon.


# ae59481b 31-Dec-2003 Doug Rabson <dfr@FreeBSD.org>

Initialise some uninitialised variables.

Thanks to: valgrind


# 4893027a 13-Nov-2003 Anton Berezin <tobez@FreeBSD.org>

Sync comment with code's reality.

MFC after: 1 week


# 5515f48c 13-Sep-2003 Matthew N. Dodd <mdodd@FreeBSD.org>

Retire the WITH_LIBMAP compile knob; libmap is now a standard feature.


# 4402996d 13-Sep-2003 Matthew N. Dodd <mdodd@FreeBSD.org>

Change libmap.c:lm_init() to return a status value; 0 for success
(libmap available) and 1 for failure. Assign this return to the
global 'libmap_disable' variable in rtld.c.

This totally prevents any libmap functions from being called after
lm_init() if no config file is present.


# df7c0368 17-Aug-2003 Gordon Tetlow <gordon@FreeBSD.org>

As long threatened, stage 2 of making a dynamically-linked root a reality.
Install rtld into /libexec.


# 7b73593a 17-Aug-2003 Gordon Tetlow <gordon@FreeBSD.org>

Prepend /lib to the builtin library search path in rtld.


# c5d061c1 18-Jun-2003 Matthew N. Dodd <mdodd@FreeBSD.org>

Provide a mechanism for dumping relocation information.

Setting the LD_DUMP_REL_PRE or LD_DUMP_REL_POST environment variables
cause rtld-elf to output a table of all relocations.

This is useful for debugging.


# 5952de4b 18-Jun-2003 Matthew N. Dodd <mdodd@FreeBSD.org>

Avoid a NULL pointer dereference.


# da9f2454 17-Jun-2003 Matthew N. Dodd <mdodd@FreeBSD.org>

- Add support for DT_FLAGS.
- Define various things from the most recent ELF spec.


# c930fec7 31-May-2003 Matthew N. Dodd <mdodd@FreeBSD.org>

- use issetugid()
- be paranoid about honoring LD_LIBMAP_DISABLE.

Suggested by: rwatson


# 4df60d1c 31-May-2003 Matthew N. Dodd <mdodd@FreeBSD.org>

Use the environment variable LD_LIBMAP_DISABLE to disable
libmap.conf(5) functionality.


# 6d5d786f 29-May-2003 Alexander Kabaev <kan@FreeBSD.org>

Allow threading libraries to register their own locking
implementation in case default one provided by rtld is
not suitable.

Consolidate various identical MD lock implementation into
a single file using appropriate machine/atomic.h.

Approved by: re (scottl)


# 3ddc66d8 07-May-2003 Alexander Kabaev <kan@FreeBSD.org>

Rethink the way we count module references. Simply following
DT_NEEDED links is not flexible enough for cases where dynamically
loaded modules form a dependency cycle.

This should fix an infinite recursion problem encountered by Yahoo.

Approved by: re (jhb)


# 78af18bd 03-May-2003 David E. O'Brien <obrien@FreeBSD.org>

Fix signed/unsigned comparison warnings.


# 29ade362 07-Apr-2003 Matthew N. Dodd <mdodd@FreeBSD.org>

Dynamic object dependency mapping: libmap.

This is an optional feature, disabled by default.

This will be useful to people testing the various POSIX threading
libraries under -CURRENT but can easily serve other needs.


# fa4a502e 17-Feb-2003 Alexander Kabaev <kan@FreeBSD.org>

Do not remove object from the lists at the unref_dag() stage.
Introduce a new unlink_object() function and call it in
unload_object() instead. Removing the object in unref_dag() is
too early, rtld calls _fini() function after that and shared
objects might fail resolve their own symbols.


# 2542b742 13-Feb-2003 Alexander Kabaev <kan@FreeBSD.org>

Fix a typo in rtld_dirname.


# 42d206e9 13-Feb-2003 Alexander Kabaev <kan@FreeBSD.org>

Implement dlinfo() function.

Introdice RTLD_SELF special handle and properly process it within
dlsym() and dlinfo() functions.

The intention is to improve our compatibility with Solaris and
to make a Java port easier.

Partially submitted by: phantom


# d38a104b 13-Feb-2003 Alexander Kabaev <kan@FreeBSD.org>

Remove /usr/lib/elf from a default search path.
Move xprintf to malloc.c, it is only used there. Make static.

Submitted by: phantom


# f8d7256a 10-Feb-2003 Alexander Kabaev <kan@FreeBSD.org>

When unloading dependencies make sure they are removed from all the
associated lists:
remove RTLD_GLOBAL objects from global objects list;
remove the parent object from dldags list of its children.

Previosly we were doing that only to the top-level object OF the DAG
being unloaded and all its dependencies were ignored, leading to
mysterious crashes later.

Submitted by: peter (partially)


# 999d9d2b 29-Nov-2002 Alexander Kabaev <kan@FreeBSD.org>

Put back a test for binaries with no PT_LOAD entries I over-jealosly
removed in r1.69.

Apploved by: re (rwatson)


# a42a42e9 18-Nov-2002 Thomas Moestl <tmm@FreeBSD.org>

Fix the handling of high PLT entries (> 32764) on sparc64. This requires
additional arguments to reloc_jmpslot(), which is why MI code and MD code
of other platforms had to be changed.

Reviewed by: jake
Approved by: re


# 8b7f25d4 22-Oct-2002 Alexander Kabaev <kan@FreeBSD.org>

Add support for binaries with arbitrary number of PT_LOAD sections.

Reviewed by: peter


# b2ce5132 19-Oct-2002 Alexander Kabaev <kan@FreeBSD.org>

Change the symbol lookup order to search RTLD_GLOBAL objects
before referencing object's DAG. This makes it possible for
C++ exceptions to work across shared libraries and brings
us closer to the search order used by Solaris/Linux.

Reviewed by: jdp
Approved by: obrien
MFC after: 1 month


# d1cf9ea2 19-Oct-2002 Maxim Sobolev <sobomax@FreeBSD.org>

Fix a problem with RTLD_TRACE flag to dlopen(3), which sometimes can return
even if there was no error occured (when trying to dlopen(3) object that
already linked into executable which does dlopen(3) call). This is more
proper fix for `ldd /usr/lib/libc.so' problem, because the new behaviour
conforms to documentation.

Remove workaround from ldd.c (rev.1.32).

PR: 35099
Submitted by: Nathan Hawkins <utsl@quic.net>
MFC after: 1 week


# 0df23e4b 08-Aug-2002 John Polstra <jdp@FreeBSD.org>

Don't acquire the writer lock in rtld_exit when clearing the shared
objects' reference counts. This function is called by the atexit
mechanism at program shutdown. I don't think the locking is necessary
here. It caused OpenOffice builds to hang more often than not.
Credit to Martin Blapp and Matt Dillon for helping to diagnose this
problem and for testing the fix.


# 2aba0238 26-Apr-2002 Marcel Moolenaar <marcel@FreeBSD.org>

Fix handling of weak references to undefined symbols on ia64:
o Set st_shndx for sym_zero to SHN_UNDEF instead of SHN_ABS.
This gives us something to reliably test against.
o For weak references to undefined sysmbols (as indicated by
having st_shndx equals SHN_UNDEF) in the context of OPDs,
the address of the OPD is to be zero, not the address of
the function it contains.
o For weak references to undefined symbols in all other cases
(only DIR64LSB at this time), the actual relocated value is
to be zero, not the value prior to relocating.

Roughly speaking, weak references to undefined symbols are no-ops.

Tested on: i386, ia64


# 9d4f2714 26-Apr-2002 Marcel Moolenaar <marcel@FreeBSD.org>

Don't do symbol lookups for local symbols. The symbol index in the
relocation identifies the symbol to which we need to bind. This
solves a problem seen on ia64 where the symbol hash table does not
contain local symbols and thus resulted in unresolved symbols.

Tested on: alpha, i386, ia64


# 2da08e79 01-Apr-2002 Jake Burkholder <jake@FreeBSD.org>

Minor changes to make this work on sparc64.

Approved by: jdp
Tested on: alpha, i386, sparc64


# e211585c 27-Feb-2002 Dag-Erling Smørgrav <des@FreeBSD.org>

When searching an object that was opened with RTLD_GLOBAL, search its DAG too.

PR: bin/25059
Approved by: jdp
MFC after: 3 weeks


# 20249943 17-Feb-2002 David E. O'Brien <obrien@FreeBSD.org>

Add support such that if LD_TRACE_LOADED_OBJECTS_ALL is defined to a
non-empty string in the environment; we indicate which objects caused
each object to be loaded.

PR: 30908
Submitted-by: Mike Meyer <mwm@mired.org>


# c6de4ce7 04-Feb-2002 Maxim Sobolev <sobomax@FreeBSD.org>

Allow ldd(1) be used on shared libraries in addition to executables.


# 8f23d506 03-Feb-2002 Kris Kennaway <kris@FreeBSD.org>

Mark a function as __printflike()

MFC after: 1 week


# a7dcaa34 25-Jan-2002 John Polstra <jdp@FreeBSD.org>

Change the library search order so that LD_LIBRARY_PATH overrides
all others.

PR: bin/28191
MFC after: 2 weeks


# 14a55adf 29-Oct-2001 Peter Wemm <peter@FreeBSD.org>

Update rtld for the "new" ia64 ABI. In the old toolchain, the
DT_INIT and DT_FINI tags pointed to fptr records. In 2.11.2, it points
to the actuall address of the function. On IA64 you cannot just take
an address of a function, store it in a function pointer variable and
call it.. the function pointers point to a fptr data block that has the
target gp and address in it. This is absolutely necessary for using
the in-tree binutils toolchain, but (unfortunately) will not work with
old shared libraries. Save your old ld-elf.so.1 if you want to use
old ones still. Do not mix-and-match.

This is a no-op change for i386 and alpha.

Reviewed by: dfr


# b5393d9f 15-Oct-2001 Doug Rabson <dfr@FreeBSD.org>

Add ia64 support. Various adjustments were made to existing targets to
cope with a few interface changes required by the ia64. In particular,
function pointers on ia64 need special treatment in rtld.


# e1b4d8d0 26-Jul-2001 Sheldon Hearn <sheldonh@FreeBSD.org>

Use STD{ERR,IN,OUT}_FILENO instead of their numeric values. The
definitions are more readable, and it's possible that they're
more portable to pathalogical platforms.

Submitted by: David Hill <david@phobia.ms>


# c15e7faa 05-May-2001 John Polstra <jdp@FreeBSD.org>

Performance improvements for the ELF dynamic linker. These
particularly help programs which load many shared libraries with
a lot of relocations. Large C++ programs such as are found in KDE
are a prime example.

While relocating a shared object, maintain a vector of symbols
which have already been looked up, directly indexed by symbol
number. Typically, symbols which are referenced by a relocation
entry are referenced by many of them. This is the same optimization
I made to the a.out dynamic linker in 1995 (rtld.c revision 1.30).

Also, compare the first character of a sought-after symbol with its
symbol table entry before calling strcmp().

On a PII/400 these changes reduce the start-up time of a typical
KDE program from 833 msec (elapsed) to 370 msec.

MFC after: 5 days


# 27e2c035 04-Jan-2001 John Polstra <jdp@FreeBSD.org>

Fix a bug in which a program called dlclose from a destructor and
got an assert failure in the dynamic linker.


# c1ff193d 07-Nov-2000 John Polstra <jdp@FreeBSD.org>

Remove the superfluous call to _rtld_error() in symlook_default().
The function's callers generate the error message when appropriate.

This eliminates the message ``Undefined symbol "__register_frame_info"''
which was bogusly returned by dlerror() in some cases.


# 185db83c 18-Sep-2000 John Polstra <jdp@FreeBSD.org>

Add support for dlsym(RTLD_DEFAULT, ...).


# bde08d00 25-Aug-2000 John W. De Boskey <jwd@FreeBSD.org>

Pass two pointer parameters to the r_debug_state() hook
function, thus allowing a debugger or other trace tool
to easily grab the addresses of the needed structures
off the stack.

This change is transparent to gdb, which locates the
link_map list and transfers it to debugger memory
for comparison purposes.

A sample program will be committed showing how this can
be used.

Reviewed by: John Polstra <jdp@FreeBSD.org>


# 44a028c3 25-Jul-2000 John Polstra <jdp@FreeBSD.org>

Revamp the code that calls shared libraries' init and fini functions.
Formerly the init functions were called in the opposite of the
order in which libraries were loaded, and libraries were loaded
according to a breadth-first traversal of the dependency graph.
That ordering came from SVR4.0, and it was easy to implement but
not always sensible.

Now we do a depth-first walk over the dependency graph and call
the init functions in an order such that each shared object's needed
objects are initialized before the shared object itself. At the
same time we build a list of finalization (fini) functions in the
opposite order, to guarantee correct C++ destructor ordering whenever
possible. (It may not be possible if dlopen and dlclose are used
in strange ways, but we come as close as one can come.)

The need for this renovation has become apparent as more programs
have started using multithreading. The multithreaded C library
libc_r requires initialization, whereas the standard libc does not.
Since virtually every other object depends on the C library, it is
important that it get initialized first.


# 630df077 07-Jul-2000 John Polstra <jdp@FreeBSD.org>

Solve the dynamic linker's problems with multithreaded programs once
and for all (I hope). Packages such as wine, JDK, and linuxthreads
should no longer have any problems with re-entering the dynamic
linker.

This commit replaces the locking used in the dynamic linker with a
new spinlock-based reader/writer lock implementation. Brian
Fundakowski Feldman <green> argued for this from the very beginning,
but it took me a long time to come around to his point of view.
Spinlocks are the only kinds of locks that work with all thread
packages. But on uniprocessor systems they can be inefficient,
because while a contender for the lock is spinning the holder of the
lock cannot make any progress toward releasing it. To alleviate
this disadvantage I have borrowed a trick from Sleepycat's Berkeley
DB implementation. When spinning for a lock, the requester does a
nanosleep() call for 1 usec. each time around the loop. This will
generally yield the CPU to other threads, allowing the lock holder
to finish its business and release the lock. I chose 1 usec. as the
minimum sleep which would with reasonable certainty not be rounded
down to 0.

The formerly machine-independent file "lockdflt.c" has been moved
into the architecture-specific subdirectories by repository copy.
It now contains the machine-dependent spinlocking code. For the
spinlocks I used the very nifty "simple, non-scalable reader-preference
lock" which I found at

<http://www.cs.rochester.edu/u/scott/synchronization/pseudocode/rw.html>

on all CPUs except the 80386 (the specific CPU model, not the
architecture). The 80386 CPU doesn't support the necessary "cmpxchg"
instruction, so on that CPU a simple exclusive test-and-set lock
is used instead. 80386 CPUs are detected at initialization time by
trying to execute "cmpxchg" and catching the resulting SIGILL
signal.

To reduce contention for the locks, I have revamped a couple of
key data structures, permitting all common operations to be done
under non-exclusive (reader) locking. The only operations that
require exclusive locking now are the rare intrusive operations
such as dlopen() and dlclose().

The dllockinit() interface is now deprecated. It still exists,
but only as a do-nothing stub. I plan to remove it as soon as is
reasonably possible. (From the very beginning it was clearly
labeled as experimental and subject to change.) As far as I know,
only the linuxthreads port uses dllockinit(). This interface turned
out to have several problems. As one example, when the dynamic
linker called a client-supplied locking function, that function
sometimes needed lazy binding, causing re-entry into the dynamic
linker and a big looping mess. And in any case, it turned out to be
too burdensome to require threads packages to register themselves
with the dynamic linker.


# e3975643 25-May-2000 Jake Burkholder <jake@FreeBSD.org>

Back out the previous change to the queue(3) interface.
It was not discussed and should probably not happen.

Requested by: msmith and others


# 740a1973 23-May-2000 Jake Burkholder <jake@FreeBSD.org>

Change the way that the queue(3) structures are declared; don't assume that
the type argument to *_HEAD and *_ENTRY is a struct.

Suggested by: phk
Reviewed by: phk
Approved by: mdodd


# 7dbe16fb 28-Jan-2000 John Polstra <jdp@FreeBSD.org>

When a threads package registers locking methods with dllockinit(),
figure out which shared object(s) contain the the locking methods
and fully bind those objects as if they had been loaded with
LD_BIND_NOW=1. The goal is to keep the locking methods from
requiring any lazy binding. Otherwise infinite recursion occurs
in _rtld_bind.

This fixes the infinite recursion problem in the linuxthreads port.


# 924d965b 22-Jan-2000 John Polstra <jdp@FreeBSD.org>

Allow files in LD_PRELOAD to be separated by white space, like Solaris
and Linux.


# 9bfb1dfc 09-Jan-2000 John Polstra <jdp@FreeBSD.org>

Revamp the mechanism for enumerating and calling shared objects'
init and fini functions. Now the code is very careful to hold no
locks when calling these functions. Thus the dynamic linker cannot
be re-entered with a lock already held.

Remove the tolerance for recursive locking that I added in revision
1.2 of dllockinit.c. Recursive locking shouldn't happen any more.

Mozilla and JDK users: I'd appreciate confirmation that things still
work right (or at least the same) with these changes.


# d3980376 26-Dec-1999 John Polstra <jdp@FreeBSD.org>

Add a new function dllockinit() for registering thread locking
functions to be used by the dynamic linker. This can be called by
threads packages at start-up time. I will add the call to libc_r
soon.

Also add a default locking method that is used up until dllockinit()
is called. The default method works by blocking SIGVTALRM, SIGPROF,
and SIGALRM in critical sections. It is based on the observation
that most user-space threads packages implement thread preemption
with one of these signals (usually SIGVTALRM).

The dynamic linker has never been reentrant, but it became less
reentrant in revision 1.34 of "src/libexec/rtld-elf/rtld.c".
Starting with that revision, multiple threads each doing lazy
binding could interfere with each other. The usual symptom was
that a symbol was falsely reported as undefined at start-up time.
It was rare but not unseen. This commit fixes it.


# df618d03 18-Nov-1999 John Polstra <jdp@FreeBSD.org>

In revision 1.21 I changed the search order for shared libraries,
but I forgot to make the corresponding fix to the comment. Rectify
that.

Submitted by: Tony Finch <fanf@demon.net>


# ed5e1b55 04-Sep-1999 John Polstra <jdp@FreeBSD.org>

Change the warning about unrecognized entries in the dynamic table
to a debug message which is disabled in production builds of the
dynamic linker. The condition warned about is normally harmless.

PR: bin/12849


# 476015a3 03-Sep-1999 John Polstra <jdp@FreeBSD.org>

When looking up symbols, search the objects loaded at program start
up first -- before the dlopened DAGs containing the referencing
object.

This makes dynamically loaded perl modules work properly again.


# a607e5d7 29-Aug-1999 John Polstra <jdp@FreeBSD.org>

Get the actual pathname of the dynamic linker from the executable's
PT_INTERP program header entry, to ensure that gdb always finds
the right dynamic linker.

Use obj->relocbase to simplify a few calculations where appropriate.


# 7360ae0f 29-Aug-1999 John Polstra <jdp@FreeBSD.org>

When checking to see if a shared object is already loaded, look for
a device/inode match if no pathname match is found.


# 926ea445 29-Aug-1999 John Polstra <jdp@FreeBSD.org>

Revamp the symbol lookup algorithm to cope better with objects
loaded separately by dlopen that have global symbols with identical
names. Viewing each dlopened object as a DAG which is linked by its
DT_NEEDED entries in the dynamic table, the search order is as
follows:

* If the referencing object was linked with -Bsymbolic, search it
internally.
* Search all dlopened DAGs containing the referencing object.
* Search all objects loaded at program start up.
* Search all objects which were dlopened() using the RTLD_GLOBAL
flag (which is now supported too).

The search terminates as soon as a strong definition is found.
Lacking that, the first weak definition is used.

These rules match those of Solaris, as best I could determine them
from its vague manual pages and the results of experiments I performed.

PR: misc/12438


# 7326e0b6 29-Aug-1999 John Polstra <jdp@FreeBSD.org>

When honoring -Bsymbolic, still keep searching if only a weak
definition was found in the referencing object.


# 6bd93745 29-Aug-1999 John Polstra <jdp@FreeBSD.org>

Simplify the logic in find_symdef().


# 7f3dea24 27-Aug-1999 Peter Wemm <peter@FreeBSD.org>

$Id$ -> $FreeBSD$


# 41f83b07 20-Aug-1999 John Polstra <jdp@FreeBSD.org>

Add a NULL pointer check whose absence could cause segmentation
violations in certain obscure cases involving failed dlopens. Many
thanks to Archie Cobbs for providing me with a good test case.

Eliminate a block that existed only to localize a declaration.


# bfb1ef60 17-Jul-1999 John Polstra <jdp@FreeBSD.org>

Change many asserts into normal errors. They were all for conditions
caused by invalid shared objects rather than by internal errors.

Enable format string mismatch checking for _rtld_error().


# cb435fa9 13-Jul-1999 John Polstra <jdp@FreeBSD.org>

Change the symbol used to find the end of an object's address space
from "end" to "_end". The former does not exist in most shared
libraries. This fixes problems in dladdr() and dlsym(RTLD_NEXT, ...).


# 8d05e8c4 09-Jul-1999 John Polstra <jdp@FreeBSD.org>

Fix bug: if a dlopen() failed (e.g., because of undefined symbols),
the dynamic linker didn't clean up properly. A subsequent dlopen()
of the same object would appear to succeed.

Another excellent fix from Max Khon.

PR: bin/12471
Submitted by: Max Khon <fjoe@iclub.nsu.ru>


# 5bf3700d 03-Jul-1999 John Polstra <jdp@FreeBSD.org>

Shake hands with GDB a little bit earlier so that it is possible to
debug the init functions.

Submitted by: dfr


# d16ad2d0 24-Jun-1999 John Polstra <jdp@FreeBSD.org>

Fix a reference counting problem when using dlopen(NULL, ...).

PR: bin/12129


# 962fdc46 24-Jun-1999 John Polstra <jdp@FreeBSD.org>

Fix a serious performance bug for large programs on the Alpha,
discovered by Hidetoshi Shimokawa. 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.

Tested by Hidetoshi Shimokawa and Steve Price.

Reviewed by: Doug Rabson <dfr@freebsd.org>


# 6d30b167 21-Apr-1999 John Polstra <jdp@FreeBSD.org>

Back out my change from 6 April PDT that added a new dlversion()
function. It was an ill-considered feature. It didn't solve the
problem I wanted it to solve. And it added Yet Another Version
Number that would have to be maintained at every release point.
I'm nuking it now before anybody grows too fond of it.


# 5353bfc3 20-Apr-1999 John Polstra <jdp@FreeBSD.org>

After relocating the main program, but before calling any of the
_init() functions, initialize the global variables "__progname" and
"environ". This makes it possible for the _init() functions to call
things like getenv() and err().


# a18cde53 09-Apr-1999 John Polstra <jdp@FreeBSD.org>

The ELF specification says that the RPATH in the executable or
shared object takes precedence over LD_LIBRARY_PATH. Make the
dynamic linker do it that way.


# d5b537d0 08-Apr-1999 John Polstra <jdp@FreeBSD.org>

Eliminate all machine-dependent code from the main source body and
the Makefile, and move it down into the architecture-specific
subdirectories.

Eliminate an asm() statement for the i386.

Make the dynamic linker work if it is built as an executable instead
of as a shared library. See i386/Makefile.inc to find out how to
do it. Note, this change is not enabled and it might never be
enabled. But it might be useful in the future. Building the
dynamic linker as an executable should make it start up faster,
because it won't have any relocations. But in practice I suspect
the difference is negligible.


# a16ed197 06-Apr-1999 John Polstra <jdp@FreeBSD.org>

Fix a couple of typos in comments.


# 14f5fa05 06-Apr-1999 John Polstra <jdp@FreeBSD.org>

Add a new function dlversion() which returns the version number of
the dynamic linker in the same form as __FreeBSD_version. This is
mainly intended for checking the dynamic linker version during a make
world.


# 5e4636f2 04-Apr-1999 John Polstra <jdp@FreeBSD.org>

Resolve undefined weak references to a value of 0. This solves the
"__deregister_frame_info" problem that was seen when combining a
program linked using the old gcc with shared libraries that were
built using egcs.


# faba5e74 03-Apr-1999 Peter Wemm <peter@FreeBSD.org>

If somebody does an execv("foo", NULL) (which theoretically is an error),
avoid crashing inside rtld (since it's easy) since everything else handles
it. Of course, if the target program checks argv[], it'll fall over.

Reviewed by: jdp


# 38ccb4c2 24-Mar-1999 Nate Williams <nate@FreeBSD.org>

- Commit the correct dladdr() implementation.

Reviewed by: jdp@FreeBSD.org <This is the version he reviewed!>


# e818e307 24-Mar-1999 Nate Williams <nate@FreeBSD.org>

- Added dladdr(3) support.

Reviewed by: jdp@FreeBSD.org


# eace1a8a 27-Nov-1998 Doug Rabson <dfr@FreeBSD.org>

Use the runpath of the main program for locating libraries loaded by
dlopen().

Reviewed by: jdp


# 1280c211 12-Oct-1998 John Polstra <jdp@FreeBSD.org>

Fix a bug in dlclose that broke the apache13 port. The list of
loaded objects wasn't being maintained properly.


# b19042b5 21-Sep-1998 John Polstra <jdp@FreeBSD.org>

Make LD_PRELOAD work for ELF.


# 29218d94 15-Sep-1998 John Polstra <jdp@FreeBSD.org>

Fix a bug that showed up when debugging dynamically linked programs.
References from GDB to "printf" and various other functions would
find the versions in the dynamic linker itself, rather than the
versions in the program's libc. This fix moves the GDB link map
entry for the dynamic linker to the end of the search list, where
its symbols will be found only if they are not found anywhere else.
It was suggested by Doug Rabson, though I implemented it a little
differently.

I personally would prefer to leave the dynamic linker's entry out
of the GDB search list altogether. But Doug argues that it is
handy there for such things as setting breakpoints on dlopen().
So it stays for now, at least.

Note, if we ever integrate the dynamic linker with libc (which has
several important benefits to recommend it), this whole problem
goes away.


# 4e25d42a 15-Sep-1998 John Polstra <jdp@FreeBSD.org>

Make the pathname pointed to by the Obj_Entry structure for the
dynamic linker itself dynamically allocated. All of them are
supposed to be dynamically allocated, but we cheated before. It
made gdb unhappy under some circumstances.


# a565ca59 04-Sep-1998 John Polstra <jdp@FreeBSD.org>

Implement ldconfig functionality for ELF. The hints are stored in
a different file than the a.out hints, namely, "/var/run/ld-elf.so.hints".
These hints consist only of the directory search path. There is
no hash table as in the a.out hints, because ELF doesn't have to
search for the file with the highest minor version number. (It
doesn't have minor version numbers at all.)

A single run of ldconfig updates either the a.out hints or the ELF
hints, but not both. The set of hints to process is selected in
the usual way, via /etc/objformat, or ${OBJFORMAT}, or the "-aout"
or "-elf" command line option. The rationale is that you probably
want to search different directories for ELF than for a.out.

"ldconfig -r" is faked up to produce output like we are used to,
except that for ELF there are no minor version numbers. This should
enable "ldconfig -r" to be used for checking LIB_DEPENDS in ports
even for ELF.

I implemented the ELF functionality in a new source file, with an
eye toward eliminating the a.out code entirely at some point in
the future.


# 13575fc4 04-Sep-1998 Doug Rabson <dfr@FreeBSD.org>

Add alpha support.

Submitted by: John Birrell <jb@cimlogic.com.au> (with extra hacks by me)
Obtained from: Probably NetBSD


# 63fac2b9 01-Sep-1998 John Polstra <jdp@FreeBSD.org>

Suppress duplicate entries in ldd output.


# 93df8d68 01-Sep-1998 John Polstra <jdp@FreeBSD.org>

Style fixes. If it seems like a lot of lines of changes, it's
because I moved some functions. Mr. Tidy likes them to be in
alphabetical order.


# cefbc496 01-Sep-1998 John Polstra <jdp@FreeBSD.org>

Handle dlsym(NULL, ...) properly, by searching in the caller's
shared object. Note, this searches _only_ that object, and not its
needed objects, in accordance with the documentation.

Also fix dlopen(NULL, ...) so that the executable's needed objects
are searched as well as the executable itself.


# 46066cf1 01-May-1998 Doug Rabson <dfr@FreeBSD.org>

Add support for ldd.


# 2001f720 30-Apr-1998 Doug Rabson <dfr@FreeBSD.org>

Add GDB support. The method and some of the code came from NetBSD's elf
runtime linker.


# 3124c3e0 07-Mar-1998 John Polstra <jdp@FreeBSD.org>

Import the ELF dynamic linker. This is the ElfKit version with
quite a few enhancements and bug fixes. There are still some known
deficiencies, but it should be adequate to get us started with ELF.

Submitted by: John Polstra <jdp@polstra.com>