This patch changes the load_library() function in the
dynamic linker to avoid reserving a huge read-only
address-space range just to read the ELF header and
program header (which are typically very small and easily
fit in the first page).
Instead, we use the functions in linker_phdr.c to only
load the data that we need in a temporary mmap-allocated
page of memory, which we release when the function exits.
This avoids issues when loading very large libraries, or
simply debug versions that only need to load a tiny percentage
of their overall file content in RAM.
Change-Id: Id3a189fad2119a870a1b3d43dd81380c54ea6044
This patch introduces two new source files containing a set of functions
to manage the program header table in an ELF binary, including the ability
to load PT_LOAD segments, and apply PT_GNU_RELRO protection.
Note: the files are not used currently, this will appear in a series
of future patches that will gradually modify linker.c to use
the phdr_table_xxx functions properly.
Change-Id: Ia3d4c1ff5fc3e265d8258b64b492f4e643f51bdc
With -fstack-protector, x86 -m32 needs __stack_chk_fail_local
defined in crtbegin_*.o.
Include __stack_chk_fail_local.S in begin.S otherwise linker
(which is built w/o crt*) may not link.
Change-Id: Id242fcf3eff157264afe3b04f27288ab7991220a
This patch adds a trivial implementation of snprintf() that calls
our internal vsnprintf().
Inspection of the generated machine code showed that the linker
contained a full implementation of stdio's vfprintf. It was pulled
in because the pthread implementation uses snprintf() somewhere.
ProTip: It's possible to see why specific objects files are included
in a final binary by adding the following to your Android.mk, then
looking at the content of /tmp/MAP.TXT:
LOCAL_LDFLAGS += -Wl,-Map=/tmp/MAP.TXT
Change-Id: I325e71b0cad1d01116a2e00c09e30a80cb716aa3
This patch adds to make the linker a little bit easier to understand
by making all functions that acts on a sofino object with a soinfo_
prefix.
This is to more easily distinguish functions that operate on global
state, and those that operate on individual libraries.
This should be purely stylistic, i.e. no feature/behaviour change.
Change-Id: Ie510d13d743aa4317644caefa9910b8af7e84f44
Before changing mmap() permission to PROT_NONE in alloc_mem_region(),
such libraries once worked with a bug that uses mmap'ed region outside of
memory region allocated by alloc_mem_region(). This possibly incurs
SIGSEGV because it can overwrite memory region of previously loaded
library, but it sometimes worked, depending on loading order.
After PROT_NONE, this caused SIGSEGV earlier during calculation of
si->phdr in load_library(), but this was fixed by:
75917c84d1 Use mmap to read an ...
Now the behaviour is the same as before applying PROT_NONE in
alloc_mem_region().
This CL fixed the original issue, supporting shared libraries that have
non-zero p_vaddr in first (= with lowest p_vaddr) PT_LOAD segment.
Bug: 6561258
Change-Id: Ib6176dd3e44c4d99a340eb1cbd16fb037586b0bc
Also, fixes SIGSEV during calculation of si->phdr in load_library(),
which is caused by accessing PHDR area, which is not guaranteed to be
loaded.
Note that this usually does not happen because program header area is
covered by immediately following PT_LOAD entry. But it does not hold
always.
Bug: 6561258
Change-Id: Ie376253c773b5420279ca89044e81b1aad5a5736
Previously, the linker always loaded itself into the same
location in memory, which inhibited the effectiveness of Android's
ASLR implementation. Modify the linker code so it can be relocatable
and link itself at runtime.
Change-Id: Ia80273d7a00ff648b4da545f4b69debee6343968
Use LOCAL_NO_CRT to prevent linking against crtbegin.o, rather than
messing with build rules. This also prevents linking against crtend.o,
which isn't needed for the linker.
Change-Id: I0c5b9999be7e8676560fe145c1c033ffce8db4d1
The computation of si->base assumed that the first entry in the
program header table is a PT_PHDR. This results in the dynamic
linker crashing with a SIGSEGV/MAPERR when trying to load some
of the NDK unit test programs, which happen to have an EXIDX
header first, followed byu a PHDR one.
This patch fixes the computation by parsing the program header
table, looking explicitely for the PHDR entry. This fixes the
load of the NDK unit test programs, and doesn't affect system
libraries.
Change-Id: Id18ea6037dbe950b5abbbce816c2960321f0b81d
Modify the dynamic linker so that executables can be loaded
at locations other than 0x00000000.
Modify crtbegin* so that non-PIC compilant "thumb interwork
veneers" are not created by the linker.
Bug: 5323301
Change-Id: Iece0272e2b708c79034f302c20160e1fe9029588
The ARM static linker wasn't properly handling __exidx_start
and __exidx_end symbols. Now that the static linker has been fixed,
we don't need the dynamic linker to work around this problem.
Change-Id: I041b94903609fafab33663a7d441a5e70b7ffcdd
Since e19d702b8e, dlsym and friends use recursive mutexes that
require the current thread id, which is not available before the libc
constructor. This prevents us from using dlsym() in .preinit_array.
This change moves TLS initialization from libc constructor to the earliest
possible point - immediately after linker itself is relocated. As a result,
pthread_internal_t for the initial thread is available from the start.
As a bonus, values stored in TLS in .preinit_array are not lost when libc is
initialized.
Change-Id: Iee5a710ee000173bff63e924adeb4a4c600c1e2d
This reverts commit 61ff83475c.
This code is harmless, and only applies to the linker, so
there's no harm in keeping it in the tree a little bit longer.
Let's roll this back while we try to figure out the root cause
of bug 6314858.
Bug: 6314858
Change-Id: I9f5ed81d23a7abe273baf792aa8a0a2839ef094c
The ARM static linker wasn't properly handling __exidx_start
and __exidx_end symbols. Now that the static linker has been fixed,
we don't need the dynamic linker to work around this problem.
Change-Id: Ic567122b6c7746cc016795e2befba2c6bd7c0478
Compile the linker with -fvisibility=hidden. This reduces the number
of symbols that show up in the .dynsym section of the linker.
These symbols are never exported to other applications.
In particular, this fixes a problem with setting -DLINKER_DEBUG=1
introduced in 468319ce4f.
Because the symbols "debug_verbosity" and "format_log" have not been
resolved before the linker links itself, any attempt to call
PRINT / INFO / TRACE / WARN / ERROR will result in a segfault.
This change allows the static linker to produce a relative reference
to these symbols rather than relying on relocation.
This also has a nice side effect of making the linker slightly smaller
and slightly more optimized.
The following symbols no longer in the .dynsym section of the linker
after this change:
-addr_to_name
-call_constructors_recursi
-calloc
-debugger_init
-debugger_signal_handler
-debug_verbosity
-dladdr
-dlclose
-dlerror
-dl_lock
-dlopen
-dlsym
-dl_unwind_find_exidx
-find_containing_library
-find_containing_symbol
-find_library
-format_buffer
-free
-libdl_info
-linker_env_get
-linker_env_init
-linker_env_secure
-linker_env_unset
-linker_get_error
-__linker_init
-lookup
-lookup_in_library
-malloc
-notify_gdb_of_libraries
-notify_gdb_of_load
-notify_gdb_of_unload
-realloc
-rtld_db_dlactivity
-unload_library
-vsnprintf
Bug: 5827809
Change-Id: I5e8cd7dcf48c1d6831a970a67f63f24916c5e437
When the dynamic linker loads a shared library into memory, it
initially allocates a chunk of memory. The memory is then carved
into smaller chunks for each LOAD region, and appropriate memory
protections applied.
Modify the initial memory allocation so that the pages are mapped
as PROT_NONE, rather than PROT_READ / PROT_EXEC. This ensures that
gaps between LOAD regions are not inadvertantly readable / executable.
(Long term, we should munmap() these gaps entirely)
Change-Id: If128a203ccc6fe12dcbbd2bfe0cf13a2045675af
If we catch a fatal signal that won't automatically re-throw when
the thread resumes, re-throw it manually. (Common examples are
SIGPIPE and the SIGFPE from integer division by zero.)
Change-Id: I329e6d4db907047c555957b42cbd09c50fc808e7
This adds the thread id and name to the "Fatal signal" logging,
making it easier to track down where in process it actually crashed.
Change-Id: I17a365042b2f10b161debe98bc2e7070af055dfb
Add support for PT_GNU_RELRO. This allows the static linker to
indicate that certain regions of memory should be marked as
"read-only" after dynamic linking is complete.
See:
* http://www.akkadia.org/drepper/nonselsec.pdf (section 6)
* http://tk-blog.blogspot.com/2009/02/relro-not-so-well-known-memory.html
Note that this change has no effect on Android right now, because
we don't compile our code with relro enabled.
Change-Id: I6541f8775367e8558b4388f7d105b1ae6e8f046b
That is to fix the bug:
dlxxx functions can't be called recursively.
For example, if we use dlopen() to use open one library whose constructor
also calls dlopen() in order to open another library, then the thread is
dead-blocked.
By changing the dl_lock from a non-recursive lock to a recursive lock, we can
prevent the thread from dead-blocked by recursive dlxxx calls in the same
thread context.
Change-Id: I1018b41c82f4641cc009c0a2eda31f5a47a534f9
Signed-off-by: Pavel Chupin <pavel.v.chupin@intel.com>
Signed-off-by: Jack Ren <jack.ren@intel.com>
Signed-off-by: Bruce Beare <bruce.j.beare@intel.com>
We don't have a toolchain anymore, we don't have working original
kernel headers, and nobody is maintaining this so there is really
no point in keeping this here. Details of the patch:
- removed code paths from Android.mk files related to the SuperH
architecture ("sh")
- removed libc/arch-sh, linker/arch-sh, libc/kernel/arch-sh
- simplified libc/SYSCALLS.TXT
- simplified the scripts in libc/tools/ and libc/kernel/tools
Change-Id: I26b0e1422bdc347489e4573e2fbec0e402f75560
Signed-off-by: David 'Digit' Turner <digit@android.com>
The flag to avoid calling ELF constructors recursively (in the case
of recursive .so dependencies) was being set after the dangerous
recursive constructor call had already been made.
This fixes the libc's debug malloc implementation.
Change-Id: I5e601f0ea19ab1df81b8b1ad4df25c3eab0ccda4
Write a message to the log file if the signal handler is not able
to connect to debuggerd. This is especially handy if the failure
was caused by running out of file descriptors, since there's some
chance that the lack of fds relates to the crash.
Sample:
F libc : Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1)
F libc : Unable to open connection to debuggerd: Too many open files
Bug 5926330
Change-Id: I0ff210d82ab1db39b08f328bae5e08f67a69e5d7
The Linux kernel provides an AT_SECURE auxv flag to inform userspace
whether or not a security transition has occurred. This is more reliable
than directly checking the uid/gid against the euid/egid, because it covers
not only setuid/setgid but also file capabilities, SELinux, and AppArmor
security transitions. It is also a more efficient test since it does
not require any additional system calls.
Change-Id: I9752a4f6da452273258d2876d13b05e402fb0409
This change makes linker handling of .preinit_array compliant with the
System V ABI:
"These [pre-initialization] functions are executed after the dynamic linker has
built the process image and performed relocations but before any shared object
initialization functions."
http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#init_fini
Change-Id: Iebfee22bb1ebe1d7c7e69cb4686e4ebae0dfc4bb
android linker doesn't check machine type, it may load some
libraries which it doesn't support sometimes.
Author: Zhenghua Wang <zhenghua.wang@intel.com>
Signed-off-by: Bruce Beare <bruce.j.beare@intel.com>
The computation of si->base assumed that the first entry in the
program header table is a PT_PHDR. This results in the dynamic
linker crashing with a SIGSEGV/MAPERR when trying to load some
of the NDK unit test programs, which happen to have an EXIDX
header first, followed byu a PHDR one.
This patch fixes the computation by parsing the program header
table, looking explicitely for the PHDR entry. This fixes the
load of the NDK unit test programs, and doesn't affect system
libraries.
Change-Id: Id18ea6037dbe950b5abbbce816c2960321f0b81d
Previously, the linker always loaded itself into the same
location in memory, which inhibited the effectiveness of Android's
ASLR implementation. Modify the linker code so it can be relocatable
and link itself at runtime.
Change-Id: Ia80273d7a00ff648b4da545f4b69debee6343968
Use LOCAL_NO_CRT to prevent linking against crtbegin.o, rather than
messing with build rules. This also prevents linking against crtend.o,
which isn't needed for the linker.
Change-Id: I0c5b9999be7e8676560fe145c1c033ffce8db4d1
Previously, the linker always loaded itself into the same
location in memory, which inhibited the effectiveness of Android's
ASLR implementation. Modify the linker code so it can be relocatable
and link itself at runtime.
Change-Id: I90d064743abdd29450ac0482ed28752b2196286c
Modify the dynamic linker so that executables can be loaded
at locations other than 0x00000000.
Modify crtbegin* so that non-PIC compilant "thumb interwork
veneers" are not created by the linker.
Bug: 5323301
Change-Id: Iece0272e2b708c79034f302c20160e1fe9029588
In 48527c3f74, we modified the soinfo
structure to remove an unnecessary variable. However, third party
programs seem to be relying on the structure not changing.
Add a dummy variable back into place to preserve structure.
Bug: 5064106
Change-Id: I3014dda1a46e624644b09e156c3e9381ba3729bd
This patch allows the debugging of constructors in shared
libraries and executables. It does so by ensuring that the
corresponding binary is visible to gdb before running the
constructors.
Change-Id: I0a3df726a04ad109944c834dcbba672b85d3991e
When a fatal signal is received, we now write a message to the log
that looks like this:
F/libc ( 1540): Fatal signal 11 (SIGSEGV) at 0xdeadd00d (code=1)
This is useful for debugging fatal signals that turn out not to be
fatal. This also changes the signal reset from SIG_IGN to SIG_DFL,
so that future non-fatal fatal signals are fatal.
The code that blocked SIGUSR1 to avoid being interrupted by the GC
has been removed.
Also, fix minor issues in format_buffer().
Bug 5035703
Change-Id: I8940af47297b5dcf3cf33537e3483ca5334ed565
Currently, the Android linker is placing shared libraries into
a well-known spot in memory. This is interfering with the kernel's
ASLR support.
This change stops forcing non-prelinked libraries into a particular
address space.
Also, get rid of FLAG_PRELINKED. As best I can tell, this flag
is never used.
Change-Id: I527af12fb54f821c2b5ca7693dbf63d022f8f4ae
Prelinked libraries must be mapped to a fixed address. MAP_FIXED is ignored
for non-prelinked libraries (si->base==0)
Signed-off-by: Raghu Gandham <raghu@mips.com>
* commit '962dcb22218a1a6d4ebd05e4fc4a69875d037234':
libc: Fix PTHREAD_RWLOCK_INITIALIZER
Proxy getnameinfo through netd
Updated gcc 4.4.3 IA toolchain doesn't require the .ctors list
Convert cname lenght before use
system_server loads up 87 shared libraries upon start. Running under
valgrind pushes this just over the edge of 96. Increase SO_MAX to 128 to
give us some more headroom.
Change-Id: Iadceb14ab6d9621bdccd292570d50867828057d9
The linker_env_get() method that is used to match an environment
variable was failing due to an incorrect equality check.
This was introduced in git change
be5755969d.
The bug was causing the linker to ignore environment variables such
as LD_LIBRARY_PATH. This issue also affects the linker_env_secure()
path that removes unsafe environment variables, since it would
not match any in the unsecure variable list.
Change-Id: I14228df9252010e9fb4c1862bed5735f23e97aec
The linker_env_get() method that is used to match an environment
variable was failing due to an incorrect equality check.
This was introduced in git change
be5755969d.
The bug was causing the linker to ignore environment variables such
as LD_LIBRARY_PATH. This issue also affects the linker_env_secure()
path that removes unsafe environment variables, since it would
not match any in the unsecure variable list.
Change-Id: I169024de4a005321e768accd38246fc1d717271b
This removes several unsecure environment variables from the
environment block when the program being loaded is setuid. The
list of env. variables is the same than what GLibc uses at this
point.
Change-Id: I456d3ea0880fe0d4de0d3c5dd51871dd36e87fd6
The LD_PRELOAD environment variable allows the user to specify a list of
libraries which should be unconditionally loaded before any others. This
makes possible some useful tricks, such as library interposers.
Change-Id: I433d775ab08ef63a5fbe7b21f87a5642954fc32f
The previous implementation of this flag was broken--it behaved identically
to RTLD_DEFAULT. This adds a proper implementation, which examines the address
of the calling function, and uses it to determine which library to use to begin
the symbol search process.
Change-Id: I2ad2b46363f68932af63a3828a22f9c7987eea67
dladdr() is a GNU extension function, which allows the caller to retrieve
symbol information for a specified memory address. It is useful for things
like generating backtrace information at runtime.
Change-Id: I3a1def1a6c9c666d93e1e97b7d260dfa5b9b79a9
This provides a mini-printf implementation that reduces the
size of the dynamic linker by 25 KB, by preventing the drag of
formatting-related routines from the C library.
Also allow traces to be sent to the log, instead of stdout.
NOTE: You now need to modify Android.mk to enable/disable debug
output.
-- fixes b/2432550
-- ba_prelink is used to manage non-prelinked libraries, hence ba_nonprelink is
a more appropriate name for it
Signed-off-by: Iliyan Malchev <malchev@google.com>
Replicate ARM libc build's HAVE_ARM_TLS_REGISTER preprocessor definition
logic, to ensure that the runtime linker uses the correct codepath for
accessing the TLS address
Merge commit 'fe62de1ad036a1417df44b7b1a7c65cc79dc7091' into eclair-plus-aosp
* commit 'fe62de1ad036a1417df44b7b1a7c65cc79dc7091':
Add support for R_ARM_REL32 to the dynamic linker.
Merge commit 'ebf3ea006e5367fff93d2491eec24c4b1a633805'
* commit 'ebf3ea006e5367fff93d2491eec24c4b1a633805':
Add support for R_ARM_REL32 to the dynamic linker.
Merge commit '34ea5117dbeba41ae5dfdfb2c2ec8cae23388b66' into eclair-mr2-plus-aosp
* commit '34ea5117dbeba41ae5dfdfb2c2ec8cae23388b66':
Add support for R_ARM_REL32 to the dynamic linker.
Merge commit '83362689f5b1f6393d376d242fe29541b63ead2d'
* commit '83362689f5b1f6393d376d242fe29541b63ead2d':
added and modified linker to support SuperH architecture
Add the BSD sys_signame array.
added and modified bionic code to support SuperH architecture
Merge commit '9e78de3e3c90ec3c2970431d8eae7378fdc0dac6'
* commit '9e78de3e3c90ec3c2970431d8eae7378fdc0dac6':
bionic/linker: make the buddy allocator compute max_order on its own
bionic/linker: change the buddy allocator to take a handle to the managed area
Merge commit '70bba5160f83ecd6251c4539f747ae39e9ed469c' into eclair-mr2-plus-aosp
* commit '70bba5160f83ecd6251c4539f747ae39e9ed469c':
bionic/linker: make the buddy allocator compute max_order on its own
bionic/linker: change the buddy allocator to take a handle to the managed area
Merge commit '763ac28357f604e0e4196e0a7ad5b0f5cdcf274a' into eclair-plus-aosp
* commit '763ac28357f604e0e4196e0a7ad5b0f5cdcf274a':
bionic/linker: make the buddy allocator compute max_order on its own
bionic/linker: change the buddy allocator to take a handle to the managed area
Merge commit '763ac28357f604e0e4196e0a7ad5b0f5cdcf274a' into eclair-mr2
* commit '763ac28357f604e0e4196e0a7ad5b0f5cdcf274a':
bionic/linker: make the buddy allocator compute max_order on its own
bionic/linker: change the buddy allocator to take a handle to the managed area
-- rename struct ba_info to struct ba
-- move the static ba descriptor from ba.c to linker.c and rename it ba_prelink
-- ba_init, ba_allocate, ba_free, ba_start_addr, and ba_len all take a pointer
to struct ba
Signed-off-by: Iliyan Malchev <malchev@google.com>
Merge commit 'eeaf6544b676f68ccdd70a3fa78f44789a1bf69c' into eclair-mr2-plus-aosp
* commit 'eeaf6544b676f68ccdd70a3fa78f44789a1bf69c':
Prevent spurious EINTR to freeze process debugging
Merge commit '8213d5c3c072b23f5cc1922d232efe7338091d9b' into eclair-mr2-plus-aosp
* commit '8213d5c3c072b23f5cc1922d232efe7338091d9b':
Allow the dynamic linker to relocate references to thumb symbols in NDK libraries.
Merge commit 'ff7b46b87c4d85881d88c2105a94be6c6accb628' into eclair-plus-aosp
* commit 'ff7b46b87c4d85881d88c2105a94be6c6accb628':
Allow the dynamic linker to relocate references to thumb symbols in NDK libraries.
When resolving relocations while loading a library, the linker used to find
symbols by looking them up in the list of all linked libraries for the current
process, as opposed to following just the library's DT_NEEDED entries. This
can cause a problem where the symbol is picked up from the wrong library.
Signed-off-by: Iliyan Malchev <malchev@google.com>
GDB will try to read l_ld of linkmaps and compare the value to vma of
.dynamic sections from shared objects. Since linker does not assign l_ld,
GDB will complain about and re-compute l_addr from l_ld. And, GDB will get a
wrong value.
Prior to this change, the dynamic loader kept track of opened libraries
either by their base name (i.e., libfoo.so instead of /system/lib/libfoo.so)
when the shared library was loaded through the DT_NEEDED tag in an ELF header,
or by whatever name was passed to dlopen(). This created a number of problems,
among which:
1. dlopen("libfoo.so") and dlopen("/path/to/libfoo.so") would open the same
library twice;
2. dlopen("/path/to/libfoo.so") and then dlopen("libbar.so"), where libbar.so
depends on libfoo.so, would open libfoo.so twice.
This patch makes the dynamic loader keep track of each loaded library by
basename, which resolves the above ambiguity. The patch also enforces
library lookup by base name, which means that it will refuse to load another
library that has the same name.
Thanks for the inspiration Iliyan.
Signed-off-by: Erik Gilling <konkers@android.com>
Cc: Iliyan Malchev <malchev@google.com>
This is needed to properly initialize the C runtime when libc.so
is loaded by the dynamic linker.
Move the temporary TLS setup before the first system call, just
in case something really horrible happens, we won't crash when
trying to write an error code in 'errno'
Remove the broken TLS_SLOT_THREAD_ID setup. First, this slot
should normally receive the address of a pthread_internal_t,
not a kernel thread identifier. Second, it is never used by
the linker anyway.
Also remove an obsolete comment.
Changed it so that when the linker generates error messages, they are
scribbled away into a buffer that dlfcn and friends can read from.
Since the error messages are generetad with snprintf, and snprintf
MAY call malloc during some code paths, we now link against a version
of libc that does not contain malloc/free/realloc/calloc. We then define
malloc and friends in the dynamic loader, and make them abort() if they
are ever called.
Signed-off-by: Dima Zavin <dima@android.com>