[PATCH] D33251: [lld][ELF]Add option to make .dynamic read only

Roland McGrath via llvm-commits llvm-commits at lists.llvm.org
Tue May 23 18:49:57 PDT 2017


I would not say that is correct.

I think everyone would say that if we were starting over today, we would
not have writable .dynamic.  The only reason from an ELF ABI perspective
that it has ever been writable is DT_DEBUG.

Different dynamic linker implementations differ in whether they adjust
ElfNN_Dyn.d_un.d_ptr fields in .dynamic sections at runtime, thus
gratuitously writing into .dynamic for a purpose nothing really requires.
glibc's dynamic linker does this (except on MIPS).  The musl dynamic
linker (and Fuchsia's, which is derived from musl) never writes into
.dynamic, except for DT_DEBUG.  I don't know what other dynamic linkers
do.  The conservative assumption is that others might also behave as
glibc does.

Because glibc has always done this, it's part of all the existing ABIs
for Linux that .dynamic must be writable (except on MIPS).  For Fuchsia,
the ABI we want is that .dynamic is always read-only.  Hence we propose
the new switch -z rodynamic, which will always be passed by the compiler
for Fuchsia targets.

I don't claim to characterize any general consensus of opinion about
DT_DEBUG, except that it alone is a poor reason for .dynamic to be
writable.  It's not a mechanism we consider important for Fuchsia.

The need that DT_DEBUG meets is to have some way for a debugger to find
the address of the in-memory r_debug data structure that's the de facto
standard for discovering the dynamic linker's list of loaded modules and
for the before/after loading breakpoint protocol.  A mechanism that
stores this address somewhere in the process's own memory that can be
found via traversing various forms of ELF headers has some advantages:
    * reading it works the same way in live processes and in ELF core files
    * debugger support to use it is mostly OS-independent
    * no new support is required to get it written into ELF core files

DT_DEBUG has that property.  So does DT_MIPS_RLD_MAP, and so would a
DT_DEBUG_INDIRECT (i.e. a generic ELF ABI number assignment for exactly
what DT_MIPS_RLD_MAP does on MIPS).

It's my personal view that for Unix-like systems, DT_DEBUG_INDIRECT is a
pretty good mechanism because of the advantages listed above.  I also
think that DT_DEBUG is fine enough for existing ABIs where writable
.dynamic is already a compatibility requirement, though I would certainly
advocate using read-only .dynamic and DT_DEBUG_INDIRECT instead in the
ABI for any new OS or in the GNU/Linux ABI for any new machine.

Rafael mentioned "something with aux vectors", but I don't know what he
had in mind.  The ElfNN_auxv_t kind of auxiliary vector in many Unix-like
systems' ELF ABIs is a one-way channel of information at program loading
time, not a way that the dynamic linker can record something to be seen
later.  (For example, on Linux, /proc/$pid/auxv and NT_AUXV notes in core
files are a snapshot of the bits given the program on startup, not a dump
gleaned from the program's memory where it could have modified them.)

For Fuchsia, we're set on having read-only .dynamic in our ABI.  We'd be
happy to have DT_DEBUG_INDIRECT and would make our runtime support it if
it got added to the tools.  But we don't actually care about it enough to
make the effort to get consensus on a generic ELF ABI number assignment
and formalization of the ABI for our own sake.

Fuchsia is not so Unix-like.  We already have an OS-specific mechanism by
which our dynamic linker registers its r_debug address with the system
and our debuggers can fetch that data for a process they're debugging.
We don't currently produce ELF core files at all.  If we ever do, they
will use new OS-specific note formats to record all our OS-specific data
about a process (including the r_debug address)--and they will *not*
include NT_AUXV, which is part of how debuggers find everything they need
(in the PIE case) to look for DT_DEBUG on Linux and similar systems, but
is not something that has any reason to exist on Fuchsia.

If other people are interested enough in read-only .dynamic ABIs that
they want to pursue DT_DEBUG_INDIRECT as a generic ELF feature, then we'd
be glad to assist them with that.  But it's not a priority for us, so
we've proposed a -z rodynamic switch that just omits DT_DEBUG entirely as
the first step because that is simpler (the implementation is already
done and ready to commit, and there is nothing new to standardize) and is
sufficient for our needs.


More information about the llvm-commits mailing list