When neither DT_HASH nor DT_GNU_HASH is present, the code scans
[DT_SYMTAB, DT_STRTAB). However, there is no guarantee that .dynstr
immediately follows .dynsym (e.g. lld typically places .gnu.version
after .dynsym).
In the absence of a hash table, symbol lookup will always fail
(map->l_nbuckets == 0 in dl-lookup.c) as if the object has no symbol, so
it seems fair for dladdr to do the same.
Reviewed-by: Florian Weimer <fweimer@redhat.com>
I used these shell commands:
../glibc/scripts/update-copyrights $PWD/../gnulib/build-aux/update-copyright
(cd ../glibc && git commit -am"[this commit message]")
and then ignored the output, which consisted lines saying "FOO: warning:
copyright statement not found" for each of 7061 files FOO.
I then removed trailing white space from math/tgmath.h,
support/tst-support-open-dev-null-range.c, and
sysdeps/x86_64/multiarch/strlen-vec.S, to work around the following
obscure pre-commit check failure diagnostics from Savannah. I don't
know why I run into these diagnostics whereas others evidently do not.
remote: *** 912-#endif
remote: *** 913:
remote: *** 914-
remote: *** error: lines with trailing whitespace found
...
remote: *** error: sysdeps/unix/sysv/linux/statx_cp.c: trailing lines
They are no longer needed after everything has been moved into
libc. The _dl_vsym test has to be removed because the symbol
cannot be used outside libc anymore.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
I used these shell commands:
../glibc/scripts/update-copyrights $PWD/../gnulib/build-aux/update-copyright
(cd ../glibc && git commit -am"[this commit message]")
and then ignored the output, which consisted lines saying "FOO: warning:
copyright statement not found" for each of 6694 files FOO.
I then removed trailing white space from benchtests/bench-pthread-locks.c
and iconvdata/tst-iconv-big5-hkscs-to-2ucs4.c, to work around this
diagnostic from Savannah:
remote: *** pre-commit check failed ...
remote: *** error: lines with trailing whitespace found
remote: error: hook declined to update refs/heads/master
This patch is a reimplementation of [1], which was submitted back in
2015. Copyright issue has been sorted [2] last year. It proposed a new
section (.gnu.xhash) and related dynamic tag (GT_GNU_XHASH). The new
section would be virtually identical to the existing .gnu.hash except
for the translation table (xlat) which would contain correct MIPS
.dynsym indexes corresponding to the hashvals in chains. This is because
MIPS ABI imposes a different ordering of the dynsyms than the one
expected by the .gnu.hash section. Another addition would be a leading
word at the beggining of the section, which would contain the number of
entries in the translation table.
In this patch, the new section name and dynamic tag are changed to
reflect the fact that the section should be treated as MIPS specific
(.MIPS.xhash and DT_MIPS_XHASH).
This patch addresses the alignment issue reported in [3] which is caused
by the leading word of the .MIPS.xhash section. Leading word is now
removed in the corresponding binutils patch, and the number of entries
in the translation table is computed using DT_MIPS_SYMTABNO dynamic tag.
Since the MIPS specific dl-lookup.c file was removed following the
initial patch submission, I opted for the definition of three new macros
in the generic ldsodefs.h. ELF_MACHINE_GNU_HASH_ADDRIDX defines the
index of the dynamic tag in the l_info array. ELF_MACHINE_HASH_SYMIDX is
used to calculate the index of a symbol in GNU hash. On MIPS, it is
defined to look up the symbol index in the translation table.
ELF_MACHINE_XHASH_SETUP is defined for MIPS only. It initializes the
.MIPS.xhash pointer in the link_map_machine struct.
The other major change is bumping the highest EI_ABIVERSION value for
MIPS to suggest that the dynamic linker now supports GNU hash.
The patch was tested by running the glibc testsuite for the three MIPS
ABIs (o32, n32 and n64) and for x86_64-linux-gnu.
[1] https://sourceware.org/ml/binutils/2015-10/msg00057.html
[2] https://sourceware.org/ml/binutils/2018-03/msg00025.html
[3] https://sourceware.org/ml/binutils/2016-01/msg00006.html
* elf/dl-addr.c (determine_info): Calculate the symbol index
using the newly defined ELF_MACHINE_HASH_SYMIDX macro.
* elf/dl-lookup.c (do_lookup_x): Ditto.
(_dl_setup_hash): Initialize MIPS xhash translation table.
* elf/elf.h (SHT_MIPS_XHASH): New define.
(DT_MIPS_XHASH): New define.
* sysdeps/generic/ldsodefs.h (ELF_MACHINE_GNU_HASH_ADDRIDX): New
define.
(ELF_MACHINE_HASH_SYMIDX): Ditto.
(ELF_MACHINE_XHASH_SETUP): Ditto.
* sysdeps/mips/ldsodefs.h (ELF_MACHINE_GNU_HASH_ADDRIDX): New
define.
(ELF_MACHINE_HASH_SYMIDX): Ditto.
(ELF_MACHINE_XHASH_SETUP): Ditto.
* sysdeps/mips/linkmap.h (struct link_map_machine): New member.
* sysdeps/unix/sysv/linux/mips/ldsodefs.h: Increment valid ABI
version.
* sysdeps/unix/sysv/linux/mips/libc-abis: New ABI version.
Do not relocate absolute symbols by the base address. Such symbols have
SHN_ABS as the section index and their value is not supposed to be
affected by relocation as per the ELF gABI[1]:
"SHN_ABS
The symbol has an absolute value that will not change because of
relocation."
The reason for our non-conformance here seems to be an old SysV linker
bug causing symbols like _DYNAMIC to be incorrectly emitted as absolute
symbols[2]. However in a previous discussion it was pointed that this
is seriously flawed by preventing the lone purpose of the existence of
absolute symbols from being used[3]:
"On the contrary, the only interpretation that makes sense to me is that
it will not change because of relocation at link time or at load time.
Absolute symbols, from the days of the earliest linking loaders, have
been used to represent addresses that are outside the address space of
the module (e.g., memory-mapped addresses or kernel gateway pages).
They've even been used to represent true symbolic constants (e.g.,
system entry point numbers, sizes, version numbers). There's no other
way to represent a true absolute symbol, while the meaning you seek is
easily represented by giving the symbol a non-negative st_shndx value."
and we ought to stop supporting our current broken interpretation.
Update processing for dladdr(3) and dladdr1(3) so that SHN_ABS symbols
are ignored, because under the corrected interpretation they do not
represent addresses within a mapped file and therefore are not supposed
to be considered.
References:
[1] "System V Application Binary Interface - DRAFT - 19 October 2010",
The SCO Group, Section "Symbol Table",
<http://www.sco.com/developers/gabi/2012-12-31/ch4.symtab.html>
[2] Alan Modra, "Absolute symbols"
<https://sourceware.org/ml/binutils/2012-05/msg00019.html>
[3] Cary Coutant, "Re: Absolute symbols"
<https://sourceware.org/ml/binutils/2012-05/msg00020.html>
[BZ #19818]
* sysdeps/generic/ldsodefs.h (SYMBOL_ADDRESS): Handle SHN_ABS
symbols.
* elf/dl-addr.c (determine_info): Ignore SHN_ABS symbols.
* elf/tst-absolute-sym.c: New file.
* elf/tst-absolute-sym-lib.c: New file.
* elf/tst-absolute-sym-lib.lds: New file.
* elf/Makefile (tests): Add `tst-absolute-sym'.
(modules-names): Add `tst-absolute-sym-lib'.
(LDLIBS-tst-absolute-sym-lib.so): New variable.
($(objpfx)tst-absolute-sym-lib.so): New dependency.
($(objpfx)tst-absolute-sym): New dependency.
The only differences in ld.so are line numbers for asserts.
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
* elf/dl-addr.c (determine_info): Use ADDRIDX with DT_GNU_HASH.
* elf/dl-lookup.c (_dl_setup_hash): Likewise.
* elf/get-dynamic-info.h (elf_get_dynamic_info): Likewise.
The function _dl_addr_inside_object is simplified by removing
the conditional 'reladdr - l->l_phdr[n].p_vaddr >= 0' which is
always true. The function is refactored into it's own object file
and a unit test added to verify the correct behaviour of the
function.
In a reference to PR ld/19908 make ld.so respect symbol export classes
aka visibility and treat STV_HIDDEN and STV_INTERNAL symbols as local,
preventing such symbols from preempting exported symbols.
According to the ELF gABI[1] neither STV_HIDDEN nor STV_INTERNAL symbols
are supposed to be present in linked binaries:
"A hidden symbol contained in a relocatable object must be either
removed or converted to STB_LOCAL binding by the link-editor when the
relocatable object is included in an executable file or shared object."
"An internal symbol contained in a relocatable object must be either
removed or converted to STB_LOCAL binding by the link-editor when the
relocatable object is included in an executable file or shared object."
however some GNU binutils versions produce such symbols in some cases.
PR ld/19908 is one and we also have this note in scripts/abilist.awk:
so clearly there is linked code out there which contains such symbols
which is prone to symbol table misinterpretation, and it'll be more
productive if we handle this gracefully, under the Robustness Principle:
"be liberal in what you accept, and conservative in what you produce",
especially as this is a simple (STV_HIDDEN|STV_INTERNAL) => STB_LOCAL
mapping.
References:
[1] "System V Application Binary Interface - DRAFT - 24 April 2001",
The Santa Cruz Operation, Inc., "Symbol Table",
<http://www.sco.com/developers/gabi/2001-04-24/ch4.symtab.html>
* sysdeps/generic/ldsodefs.h
(dl_symbol_visibility_binds_local_p): New inline function.
* elf/dl-addr.c (determine_info): Treat hidden and internal
symbols as local.
* elf/dl-lookup.c (do_lookup_x): Likewise.
* elf/dl-reloc.c (RESOLVE_MAP): Likewise.
to fill in holes
(rtld_global_ro): Likewise.
2007-06-18 Jakub Jelinek <jakub@redhat.com>
* elf/dl-addr.c (_dl_addr): Skip PT_LOAD checking if l_contiguous.
Move PT_LOAD checking to...
(_dl_addr_inside_object): ... here, new function.
* elf/dl-sym.c (do_sym): If not l_contiguous,
call _dl_addr_inside_object.
* elf/dl-iteratephdr.c (__dl_iterate_phdr): Likewise.
* dlfcn/dlinfo.c (dlinfo_doit): Likewise.
* elf/dl-open.c (dl_open_worker): Likewise.
(_dl_addr_inside_object): New function if IS_IN_rtld.
* elf/dl-load.c (_dl_map_object_from_fd): Set l_contiguous if no
holes are present or are PROT_NONE protected.
* include/link.h (struct link_map): Add l_contiguous field.
* sysdeps/generic/ldsodefs.h (_dl_addr_inside_object): New prototype.
2007-05-06 Ulrich Drepper <drepper@redhat.com>
[BZ #4131]
* elf/dl-addr.c (_dl_addr): Compare address with actual segment
boundaries to work around systems with overlapping binary loading.
Based on a patch by Suzuki <suzuki@in.ibm.com>.
2006-08-24 Ulrich Drepper <drepper@redhat.com>
[BZ #2683]
* elf/dl-addr.c (_dl_addr): Don't ignore all undefined symbols.
If symbol has a value use it.
* elf/tst-dladdr1.c: New file.
* elf/Makefile: Add rules to build and run tst-addr1.
2006-06-23 Joseph Myers <joseph@codesourcery.com>
[BZ #2980]
* posix/Makefile (CFLAGS-waitid.c): Add
-fasynchronous-unwind-tables.
2006-08-02 Ulrich Drepper <drepper@redhat.com>
* elf/dl-addr.c (_dl_addr): If GNU-style hash tables are present,
walk them instead of the symbol table.
2005-08-01 Bob Wilson <bob.wilson@acm.org>
Richard Sandiford <richard@codesourcery.com>
* sysdeps/ieee754/flt-32/e_hypotf.c (__ieee754_hypotf): Add missing
exponent bias to the value for 2^126.
2005-08-30 Jakub Jelinek <jakub@redhat.com>
Alan Modra <amodra@bigpond.net.au>
* elf/dl-addr.c (_dl_addr): Use DL_ADDR_SYM_MATCH macro.
* sysdeps/generic/ldsodefs.h (DL_ADDR_SYM_MATCH): Define.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h: New file.
(_dl_out_of_memory): Use rtld_hidden_proto.
* elf/dl-error.c (_dl_out_of_memory): Use rtld_hidden_data_def.
(_dl_signal_error): Don't use INTUSE on _dl_out_of_memory.
* elf/dl-open.c (_dl_open): Likewise.
* elf/dl-deps.c (_dl_map_object_deps): Likewise.
* sunrpc/des_impl.c (des_set_key): Make first argument unsigned char *.
* elf/dl-addr.c (_dl_addr): Add a cast.
* elf/unload3mod4.c: Declare foo.
* elf/testobj2.c: Include <stdio.h>.
* sysdeps/gnu/errlist.awk: Emit NERR macro for _sys_nerr_internal
value constant, and use it in the defn.
* sysdeps/gnu/errlist-compat.awk: Use NERR in array decl.
Use actual size for compat array decls.
* config.make.in (cc-mtune): New substituted variable.
* configure.in (libc_cv_cc_mtune): New test for -mtune= switch,
done only if libc_mtune_example is defined.
* configure: Regenerated.
* sysdeps/i386/configure.in (libc_mtune_example): Set it.
* sysdeps/i386/configure: Regenerated.
* sysdeps/i386/Makefile (CFLAGS-initfini.s): Use $(cc-mtune).
Update.
Add support for namespaces in the dynamic linker.
* dlfcn/Makefile (libdl-routines): Add dlmopen.
* dlfcn/Versions [libdl, GLIBC_2.3.4]: Add dlmopen.
* dlfcn/dlfcn.h: Define Lmid_t, LM_ID_BASE, and LM_ID_NEWLM.
Declare dlmopen. Document RTLD_DI_LMID.
* dlfcn/dlinfo.c: Handle RTLD_DI_LMID.
* dlfcn/dlmopen.c: New file.
* dlfcn/dlopen.c: Pass new parameter to _dl_open.
* dlfcn/dlopenold.c: Likewise.
* elf/dl-addr.c: Adjust for removal of GL(dl_loaded).
* elf/dl-caller.c: Likewise.
* elf/dl-close.c: Likewise.
* elf/dl-conflict.c: Likewise.
* elf/dl-debug.c: Likewise.
* elf/dl-lookup.c: Likewise.
* elf/dl-sym.c: Likewise.
* elf/dl-version.c: Likewise.
* elf/do-lookup.h: Likewise.
* elf/rtld.c: Likewise.
* sysdeps/unix/sysv/linux/i386/dl-librecon.h: Likewise.
* elf/dl-depsc: Likewise. Add new parameter to _dl_map_object.
* elf/dl-fini.c: Call destructors in all namespaces.
* elf/dl-iteratephdr.c: Compute total nloaded. Adjust for removal of
GL(dl_loaded).
* elf/dl-libc.c: Pass new parameter to _dl_open. Adjust for removal
of GL(dl_loaded).
* elf/dl-load.c (_dl_map_object_from_fd): Don't load ld.so a second
time. Reuse the one from the main namespace in all others.
Pass new parameter to _dl_new_object.
Adjust for removal of GL(dl_loaded).
* elf/dl-object.c: Take new parameter. Use it to initialize l_ns.
Adjust for removal of GL(dl_loaded).
* elf/dl-open.c (_dl_open): Take new parameter.
Adjust for removal of GL(dl_loaded).
* elf/dl-support.c: Replace global _dl_loaded etc variables with
_dl_ns variable.
* include/dlfcn.h: Adjust prototype of _dl_open.
Define __LM_ID_CALLER.
* include/link.h: Add l_real, l_ns, and l_direct_opencount elements.
* sysdeps/generic/dl-tls.c: Bump TLS_STATIC_SURPLUS. Since libc is
using TLS we need memory appropriate to the number of namespaces.
* sysdeps/generic/ldsodefs.h (struct rtld_global): Replace _dl_loaded,
_dl_nloaded, _dl_global_scope, _dl_main_searchlist, and
_dl_global_scope_alloc with _dl_ns element. Define DL_NNS.
Adjust prototypes of _dl_map_object and member in rtld_global_ro.
* malloc/malloc.c: Include <dlfcn.h>.
* malloc/arena.c (ptmalloc_init): If libc is not in primary namespace,
never use brk.
* elf/Makefile: Add rules to build and run tst-dlmopen1 and
tst-dlmopen2.
* elf/tst-dlmopen1.c: New file.
* elf/tst-dlmopen1mod.c: New file.
* elf/tst-dlmopen2.c: New file.
* elf/dl-close.c: Improve reference counting by tracking direct loads.
* elf/dl-lookup.c (add_dependency): Likewise.
* elf/dl-open.c (dl_open_worker): Likewise.
* elf/rtld.c (dl_main): Likewise.
2004-09-09 GOTO Masanori <gotom@debian.or.jp>
[BZ #77]
* elf/dl-close.c: Count down l_opencount to check not only for
l_reldeps, but also l_initfini.
2004-10-13 Ulrich Drepper <drepper@redhat.com>
2004-02-20 Ulrich Drepper <drepper@redhat.com>
* dlfcn/dlsym.c: Get ld.so loading lock before the call into ld.so.
* dlfcn/dlvsym.c: Likewise.
* elf/dl-addr.c: Get loading lock while using _dl_loaded data.
* elf/dl-fini.c: Likewise.
Patch by Shunichi Sagawa <s-sagawa@jp.fujitsu.com>.
unconditionally. Set dli_fname to _dl_argv[0] only for main program.
2002-09-27 Roland McGrath <roland@redhat.com>
* elf/dl-addr.c (_dl_addr): Add a cast.
* sysdeps/x86_64/dl-machine.h (elf_machine_rela) [USE_TLS]: Handle new
TLS relocs R_X86_64_DTPMOD64, R_X86_64_DTPOFF64, and R_X86_64_TPOFF64.
* elf/elf.h (R_X86_64_DTPMOD64, R_X86_64_DTPOFF64, R_X86_64_TPOFF64,
R_X86_64_TLSGD, R_X86_64_TLSLD, R_X86_64_DTPOFF32,
R_x86_64_GOTTPOFF, R_X86_64_TPOFF32): New macros.
(R_X86_64_NUM): Update the value.
2002-09-26 Ulrich Drepper <drepper@redhat.com>
* elf/dynamic-link.h (elf_get_dynamic_info): Relocate DT_HASH entry
if necessary.
* elf/dl-lookup.c (_dl_setup_hash): DT_HASH entry is already relocated.
* elf/dl-addr.c (_dl_addr): Use .hash[1] entry to determine end of the
symbol table if necessary.
2001-08-22 Ulrich Drepper <drepper@redhat.com>
* elf/dl-addr.c (_dl_addr): Fix tests to determine dli_sname.
* malloc/mtrace.c (tr_where): dli_sname always points to a
non-empty string is != NULL.
Reported by Tim Janik <timj@gtk.org>.