History log of /freebsd-current/libexec/rtld-elf/rtld.h
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


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

rtld: Add MD_OBJ_ENTRY to extend Struct_Obj_Entry

Add a macro the architectures can use to add per-arch fields to
Struct_Obj_Entry.

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


# 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


# 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


# 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


# 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


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

Remove $FreeBSD$: two-line .h pattern

Remove /^\s*\*\n \*\s+\$FreeBSD\$$\n/


# cf6dbdd1 21-Jul-2023 Konstantin Belousov <kib@FreeBSD.org>

rtld: remove dup __crt_malloc prototypes

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


# 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


# 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


# 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


# 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


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

rtld: extract header validation into new helper check_elf_headers()

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


# 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


# 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


# 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.


# 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


# 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


# 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


# 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


# 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


# 168bbfa7 30-Dec-2019 Conrad Meyer <cem@FreeBSD.org>

rtld(1): Do booleans like C99

Reviewed by: kib, rlibby
Differential Revision: https://reviews.freebsd.org/D22964


# 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


# 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


# 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


# 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


# 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


# 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


# 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


# 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.


# 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


# 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


# 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


# d27078f9 21-Nov-2016 Konstantin Belousov <kib@FreeBSD.org>

Adjust r308689 to make rtld compilable with either in-tree or
(hopefully) stock gcc 4.2.1 on i386 and other arches.

In particular:
- Do not use %ebx in the asm constraints on i386, since rtld is
compiled with -fPIC and gcc cannot handle GOT-base register reload
(clang and newer gcc can).
- Avoid direct use of [static N] construct in the function
declaration/definion. In-tree gcc was patched to support this, but
stock 4.2.1 cannot handle the feature.

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


# 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


# 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


# 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


# 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


# 16ef2e1a 05-Jan-2016 Ed Maste <emaste@FreeBSD.org>

rtld: populate DT_DEBUG iff DYNAMIC segment is writable

rtld.h was accidentally missed in r293201


# 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.


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

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


# 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


# 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


# 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


# 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


# 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


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

Build an allocator for the aligned memory on top of the rtld-private
malloc.

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


# 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)


# 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


# 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


# 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


# e24348df 22-Mar-2012 Konstantin Belousov <kib@FreeBSD.org>

Remove superfluous extern keywords.

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


# 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


# 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


# 1acf0dba 07-Jan-2012 Ulrich Spörlein <uqs@FreeBSD.org>

Spelling fixes for libexec/


# 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


# 5b646fa1 09-Dec-2011 Konstantin Belousov <kib@FreeBSD.org>

Typo.

MFC after: 3 days


# 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)


# 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.


# 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


# 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)


# 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


# 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.


# 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.


# 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


# 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


# 22a91927 27-May-2009 Doug Rabson <dfr@FreeBSD.org>

Increase the size of the static TLS area slightly (required for the NVidia's
OpenGL driver on amd64).


# 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


# 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


# d7f03759 19-Oct-2008 Ulf Lilleengen <lulf@FreeBSD.org>

- Import the HEAD csup code which is the basis for the cvsmode work.


# 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.


# 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.


# 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


# 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


# 017246d0 03-Aug-2004 Doug Rabson <dfr@FreeBSD.org>

Add support for Thread Local Storage.


# 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.


# 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.


# 94040887 18-Jun-2003 Matthew N. Dodd <mdodd@FreeBSD.org>

Move MD function prototypes together.


# 2c297acb 18-Jun-2003 Matthew N. Dodd <mdodd@FreeBSD.org>

Fix warnings; no parameters in function prototypes.


# da9f2454 17-Jun-2003 Matthew N. Dodd <mdodd@FreeBSD.org>

- Add support for DT_FLAGS.
- Define various things from the most recent ELF spec.


# 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)


# 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


# 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.


# 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


# 5e6220d9 02-May-2001 David E. O'Brien <obrien@FreeBSD.org>

* include/elf.h has been repo copied to include/elf-hints.h, and it no
longer includes machine/elf.h.
* consumers of elf.h now use the minimalist elf header possible.

This change is motivated by Binutils 2.11.0 and too much clashing over
our base elf headers and the Binutils elf headers.


# 185db83c 18-Sep-2000 John Polstra <jdp@FreeBSD.org>

Add support for dlsym(RTLD_DEFAULT, ...).


# 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.


# 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.


# 82531605 05-Sep-1999 John Polstra <jdp@FreeBSD.org>

Make jdk-1.1.8 work again. It turns out that some code inside
libjava peeks into the dynamic linker's private Obj_Entry structures.
My recent changes introduced some new members near the front of
the structures, causing libjava to get the wrong fields. This commit
moves the new members toward the end of the structure so that the
layout of the portion that is relevant to JDK remains the same as
before.

I will work with the JDK porting team to see if we can come up with
a less fragile way for them to do what they need to do. I understand
the current approach was necessary in order to work around some
limitations of the dynamic linker. Maybe it's not necessary any
more.


# 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


# 7f3dea24 27-Aug-1999 Peter Wemm <peter@FreeBSD.org>

$Id$ -> $FreeBSD$


# 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().


# 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.


# 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.


# 1eab1be0 20-Aug-1998 John Birrell <jb@FreeBSD.org>

Update this header to use the revamped elf headers which select Elf32
or Elf64 based on the inclusion of the machine dependent header.

I've left the addition of the extra fields to handle the relocation
structures with addend for a separate commit after jdp has had a chance
to review what I've done. The current change is needed to compile
csu/alpha/crt1.c


# 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>