Backed out changeset 870b68c06bd7 (bug 1914438) for causing bc failures on browser_ne...
[gecko.git] / mozglue / linker / ElfLoader.cpp
blob88efbf58b8bbffaec942084beb673f4afee4f3c3
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include <string>
6 #include <cstring>
7 #include <cstdlib>
8 #include <cstdio>
9 #include <dlfcn.h>
10 #include <link.h>
11 #include <optional>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <algorithm>
15 #include <fcntl.h>
16 #include "ElfLoader.h"
17 #include "BaseElf.h"
18 #include "CustomElf.h"
19 #include "Mappable.h"
20 #include "Logging.h"
21 #include "Utils.h"
22 #include <inttypes.h>
23 #include "mozilla/ScopeExit.h"
25 // From Utils.h
26 mozilla::Atomic<size_t, mozilla::ReleaseAcquire> gPageSize;
28 #if defined(ANDROID)
29 # include <sys/syscall.h>
30 # include <sys/system_properties.h>
31 # include <math.h>
33 # include <android/api-level.h>
35 /**
36 * Return the current Android version, or 0 on failure.
38 static int GetAndroidSDKVersion() {
39 static int version = 0;
40 if (version) {
41 return version;
44 char version_string[PROP_VALUE_MAX] = {'\0'};
45 int len = __system_property_get("ro.build.version.sdk", version_string);
46 if (len) {
47 version = static_cast<int>(strtol(version_string, nullptr, 10));
49 return version;
52 #endif /* ANDROID */
54 #ifdef __ARM_EABI__
55 extern "C" MOZ_EXPORT const void* __gnu_Unwind_Find_exidx(void* pc, int* pcount)
56 __attribute__((weak));
57 #endif
59 /* Pointer to the PT_DYNAMIC section of the executable or library
60 * containing this code. */
61 extern "C" Elf::Dyn _DYNAMIC[];
63 /**
64 * dlfcn.h replacements functions
67 void* __wrap_dlopen(const char* path, int flags) {
68 #if defined(ANDROID)
69 if (GetAndroidSDKVersion() >= 23) {
70 return dlopen(path, flags);
72 #endif
74 RefPtr<LibHandle> handle = ElfLoader::Singleton.Load(path, flags);
75 if (handle) handle->AddDirectRef();
76 return handle;
79 const char* __wrap_dlerror(void) {
80 #if defined(ANDROID)
81 if (GetAndroidSDKVersion() >= 23) {
82 return dlerror();
84 #endif
86 const char* error = ElfLoader::Singleton.lastError.exchange(nullptr);
87 if (error) {
88 // Return a custom error if available.
89 return error;
91 // Or fallback to the system error.
92 return dlerror();
95 void* __wrap_dlsym(void* handle, const char* symbol) {
96 #if defined(ANDROID)
97 if (GetAndroidSDKVersion() >= 23) {
98 return dlsym(handle, symbol);
100 #endif
102 if (!handle) {
103 ElfLoader::Singleton.lastError = "dlsym(NULL, sym) unsupported";
104 return nullptr;
106 if (handle != RTLD_DEFAULT && handle != RTLD_NEXT) {
107 LibHandle* h = reinterpret_cast<LibHandle*>(handle);
108 return h->GetSymbolPtr(symbol);
111 ElfLoader::Singleton.lastError = nullptr; // Use system dlerror.
112 return dlsym(handle, symbol);
115 int __wrap_dlclose(void* handle) {
116 #if defined(ANDROID)
117 if (GetAndroidSDKVersion() >= 23) {
118 return dlclose(handle);
120 #endif
122 if (!handle) {
123 ElfLoader::Singleton.lastError = "No handle given to dlclose()";
124 return -1;
126 reinterpret_cast<LibHandle*>(handle)->ReleaseDirectRef();
127 return 0;
130 int __wrap_dladdr(const void* addr, Dl_info* info) {
131 #if defined(ANDROID)
132 if (GetAndroidSDKVersion() >= 23) {
133 return dladdr(addr, info);
135 #endif
137 RefPtr<LibHandle> handle =
138 ElfLoader::Singleton.GetHandleByPtr(const_cast<void*>(addr));
139 if (!handle) {
140 return dladdr(addr, info);
142 info->dli_fname = handle->GetPath();
143 info->dli_fbase = handle->GetBase();
144 return 1;
147 class DlIteratePhdrHelper {
148 public:
149 DlIteratePhdrHelper() {
150 int pipefd[2];
151 valid_pipe = (pipe(pipefd) == 0);
152 read_fd.emplace(pipefd[0]);
153 write_fd.emplace(pipefd[1]);
156 int fill_and_call(dl_phdr_cb callback, const void* l_addr, const char* l_name,
157 void* data);
159 private:
160 bool valid_pipe;
161 std::optional<AutoCloseFD> read_fd;
162 std::optional<AutoCloseFD> write_fd;
165 // This function is called for each shared library iterated over by
166 // dl_iterate_phdr, and is used to fill a dl_phdr_info which is then
167 // sent through to the dl_iterate_phdr callback.
168 int DlIteratePhdrHelper::fill_and_call(dl_phdr_cb callback, const void* l_addr,
169 const char* l_name, void* data) {
170 dl_phdr_info info;
171 info.dlpi_addr = reinterpret_cast<Elf::Addr>(l_addr);
172 info.dlpi_name = l_name;
173 info.dlpi_phdr = nullptr;
174 info.dlpi_phnum = 0;
176 // Assuming l_addr points to Elf headers (in most cases, this is true),
177 // get the Phdr location from there.
178 // Unfortunately, when l_addr doesn't point to Elf headers, it may point
179 // to unmapped memory, or worse, unreadable memory. The only way to detect
180 // the latter without causing a SIGSEGV is to use the pointer in a system
181 // call that will try to read from there, and return an EFAULT error if
182 // it can't. One such system call is write(). It used to be possible to
183 // use a file descriptor on /dev/null for these kind of things, but recent
184 // Linux kernels never return an EFAULT error when using /dev/null.
185 // So instead, we use a self pipe. We do however need to read() from the
186 // read end of the pipe as well so as to not fill up the pipe buffer and
187 // block on subsequent writes.
188 // In the unlikely event reads from or write to the pipe fail for some
189 // other reason than EFAULT, we don't try any further and just skip setting
190 // the Phdr location for all subsequent libraries, rather than trying to
191 // start over with a new pipe.
192 int can_read = true;
193 if (valid_pipe) {
194 int ret;
195 char raw_ehdr[sizeof(Elf::Ehdr)];
196 static_assert(sizeof(raw_ehdr) < PIPE_BUF, "PIPE_BUF is too small");
197 do {
198 // writes are atomic when smaller than PIPE_BUF, per POSIX.1-2008.
199 ret = write(*write_fd, l_addr, sizeof(raw_ehdr));
200 } while (ret == -1 && errno == EINTR);
201 if (ret != sizeof(raw_ehdr)) {
202 if (ret == -1 && errno == EFAULT) {
203 can_read = false;
204 } else {
205 valid_pipe = false;
207 } else {
208 size_t nbytes = 0;
209 do {
210 // Per POSIX.1-2008, interrupted reads can return a length smaller
211 // than the given one instead of failing with errno EINTR.
212 ret = read(*read_fd, raw_ehdr + nbytes, sizeof(raw_ehdr) - nbytes);
213 if (ret > 0) nbytes += ret;
214 } while ((nbytes != sizeof(raw_ehdr) && ret > 0) ||
215 (ret == -1 && errno == EINTR));
216 if (nbytes != sizeof(raw_ehdr)) {
217 valid_pipe = false;
222 if (valid_pipe && can_read) {
223 const Elf::Ehdr* ehdr = Elf::Ehdr::validate(l_addr);
224 if (ehdr) {
225 info.dlpi_phdr = reinterpret_cast<const Elf::Phdr*>(
226 reinterpret_cast<const char*>(ehdr) + ehdr->e_phoff);
227 info.dlpi_phnum = ehdr->e_phnum;
231 return callback(&info, sizeof(dl_phdr_info), data);
234 int __wrap_dl_iterate_phdr(dl_phdr_cb callback, void* data) {
235 #if defined(ANDROID)
236 if (GetAndroidSDKVersion() >= 23) {
237 return dl_iterate_phdr(callback, data);
239 #endif
241 DlIteratePhdrHelper helper;
242 AutoLock lock(&ElfLoader::Singleton.handlesMutex);
244 for (ElfLoader::LibHandleList::reverse_iterator it =
245 ElfLoader::Singleton.handles.rbegin();
246 it < ElfLoader::Singleton.handles.rend(); ++it) {
247 BaseElf* elf = (*it)->AsBaseElf();
248 if (!elf) {
249 continue;
251 int ret = helper.fill_and_call(callback, (*it)->GetBase(), (*it)->GetPath(),
252 data);
253 if (ret) return ret;
255 return dl_iterate_phdr(callback, data);
258 #ifdef __ARM_EABI__
259 const void* __wrap___gnu_Unwind_Find_exidx(void* pc, int* pcount) {
260 RefPtr<LibHandle> handle = ElfLoader::Singleton.GetHandleByPtr(pc);
261 if (handle) return handle->FindExidx(pcount);
262 if (__gnu_Unwind_Find_exidx) return __gnu_Unwind_Find_exidx(pc, pcount);
263 *pcount = 0;
264 return nullptr;
266 #endif
268 namespace {
271 * Returns the part after the last '/' for the given path
273 const char* LeafName(const char* path) {
274 const char* lastSlash = strrchr(path, '/');
275 if (lastSlash) return lastSlash + 1;
276 return path;
280 * Run the given lambda while holding the internal lock of the system linker.
281 * To take the lock, we call the system dl_iterate_phdr and invoke the lambda
282 * from the callback, which is called while the lock is held. Return true on
283 * success.
285 template <class Lambda>
286 static bool RunWithSystemLinkerLock(Lambda&& aLambda) {
287 #if defined(ANDROID)
288 if (GetAndroidSDKVersion() < 23) {
289 // dl_iterate_phdr is _not_ protected by a lock on Android < 23.
290 // Also return false here if we failed to get the version.
291 return false;
293 #endif
295 dl_iterate_phdr(
296 [](dl_phdr_info*, size_t, void* lambda) -> int {
297 (*static_cast<Lambda*>(lambda))();
298 // Return 1 to stop iterating.
299 return 1;
301 &aLambda);
302 return true;
305 } /* Anonymous namespace */
308 * LibHandle
310 LibHandle::~LibHandle() { free(path); }
312 const char* LibHandle::GetName() const {
313 return path ? LeafName(path) : nullptr;
317 * SystemElf
319 already_AddRefed<LibHandle> SystemElf::Load(const char* path, int flags) {
320 /* The Android linker returns a handle when the file name matches an
321 * already loaded library, even when the full path doesn't exist */
322 if (path && path[0] == '/' && (access(path, F_OK) == -1)) {
323 DEBUG_LOG("dlopen(\"%s\", 0x%x) = %p", path, flags, (void*)nullptr);
324 ElfLoader::Singleton.lastError = "Specified file does not exist";
325 return nullptr;
328 ElfLoader::Singleton.lastError = nullptr; // Use system dlerror.
329 void* handle = dlopen(path, flags);
330 DEBUG_LOG("dlopen(\"%s\", 0x%x) = %p", path, flags, handle);
331 if (handle) {
332 SystemElf* elf = new SystemElf(path, handle);
333 ElfLoader::Singleton.Register(elf);
334 RefPtr<LibHandle> lib(elf);
335 return lib.forget();
337 return nullptr;
340 SystemElf::~SystemElf() {
341 if (!dlhandle) return;
342 DEBUG_LOG("dlclose(%p [\"%s\"])", dlhandle, GetPath());
343 ElfLoader::Singleton.lastError = nullptr; // Use system dlerror.
344 dlclose(dlhandle);
345 ElfLoader::Singleton.Forget(this);
348 void* SystemElf::GetSymbolPtr(const char* symbol) const {
349 ElfLoader::Singleton.lastError = nullptr; // Use system dlerror.
350 void* sym = dlsym(dlhandle, symbol);
351 DEBUG_LOG("dlsym(%p [\"%s\"], \"%s\") = %p", dlhandle, GetPath(), symbol,
352 sym);
353 return sym;
356 #ifdef __ARM_EABI__
357 const void* SystemElf::FindExidx(int* pcount) const {
358 /* TODO: properly implement when ElfLoader::GetHandleByPtr
359 does return SystemElf handles */
360 *pcount = 0;
361 return nullptr;
363 #endif
366 * ElfLoader
369 /* Unique ElfLoader instance */
370 ElfLoader ElfLoader::Singleton;
372 already_AddRefed<LibHandle> ElfLoader::Load(const char* path, int flags,
373 LibHandle* parent) {
374 /* Ensure logging is initialized or refresh if environment changed. */
375 Logging::Init();
377 /* Ensure self_elf initialization. */
378 if (!self_elf) Init();
380 RefPtr<LibHandle> handle;
382 /* Handle dlopen(nullptr) directly. */
383 if (!path) {
384 handle = SystemElf::Load(nullptr, flags);
385 return handle.forget();
388 /* TODO: Handle relative paths correctly */
389 const char* name = LeafName(path);
391 /* Search the list of handles we already have for a match. When the given
392 * path is not absolute, compare file names, otherwise compare full paths. */
393 if (name == path) {
394 AutoLock lock(&handlesMutex);
395 for (LibHandleList::iterator it = handles.begin(); it < handles.end(); ++it)
396 if ((*it)->GetName() && (strcmp((*it)->GetName(), name) == 0)) {
397 handle = *it;
398 return handle.forget();
400 } else {
401 AutoLock lock(&handlesMutex);
402 for (LibHandleList::iterator it = handles.begin(); it < handles.end(); ++it)
403 if ((*it)->GetPath() && (strcmp((*it)->GetPath(), path) == 0)) {
404 handle = *it;
405 return handle.forget();
409 char* abs_path = nullptr;
410 const char* requested_path = path;
412 /* When the path is not absolute and the library is being loaded for
413 * another, first try to load the library from the directory containing
414 * that parent library. */
415 if ((name == path) && parent) {
416 const char* parentPath = parent->GetPath();
417 abs_path = new char[strlen(parentPath) + strlen(path)];
418 strcpy(abs_path, parentPath);
419 char* slash = strrchr(abs_path, '/');
420 strcpy(slash + 1, path);
421 path = abs_path;
424 Mappable* mappable = GetMappableFromPath(path);
426 /* Try loading with the custom linker if we have a Mappable */
427 if (mappable) handle = CustomElf::Load(mappable, path, flags);
429 /* Try loading with the system linker if everything above failed */
430 if (!handle) handle = SystemElf::Load(path, flags);
432 /* If we didn't have an absolute path and haven't been able to load
433 * a library yet, try in the system search path */
434 if (!handle && abs_path) handle = SystemElf::Load(name, flags);
436 delete[] abs_path;
437 DEBUG_LOG("ElfLoader::Load(\"%s\", 0x%x, %p [\"%s\"]) = %p", requested_path,
438 flags, reinterpret_cast<void*>(parent),
439 parent ? parent->GetPath() : "", static_cast<void*>(handle));
441 return handle.forget();
444 already_AddRefed<LibHandle> ElfLoader::GetHandleByPtr(void* addr) {
445 AutoLock lock(&handlesMutex);
446 /* Scan the list of handles we already have for a match */
447 for (LibHandleList::iterator it = handles.begin(); it < handles.end(); ++it) {
448 if ((*it)->Contains(addr)) {
449 RefPtr<LibHandle> lib = *it;
450 return lib.forget();
453 return nullptr;
456 Mappable* ElfLoader::GetMappableFromPath(const char* path) {
457 return Mappable::Create(path);
460 void ElfLoader::Register(LibHandle* handle) {
461 AutoLock lock(&handlesMutex);
462 handles.push_back(handle);
465 void ElfLoader::Register(CustomElf* handle) {
466 Register(static_cast<LibHandle*>(handle));
467 if (dbg) {
468 // We could race with the system linker when modifying the debug map, so
469 // only do so while holding the system linker's internal lock.
470 RunWithSystemLinkerLock([this, handle] { dbg.Add(handle); });
474 void ElfLoader::Forget(LibHandle* handle) {
475 /* Ensure logging is initialized or refresh if environment changed. */
476 Logging::Init();
478 AutoLock lock(&handlesMutex);
479 LibHandleList::iterator it =
480 std::find(handles.begin(), handles.end(), handle);
481 if (it != handles.end()) {
482 DEBUG_LOG("ElfLoader::Forget(%p [\"%s\"])", reinterpret_cast<void*>(handle),
483 handle->GetPath());
484 handles.erase(it);
485 } else {
486 DEBUG_LOG("ElfLoader::Forget(%p [\"%s\"]): Handle not found",
487 reinterpret_cast<void*>(handle), handle->GetPath());
491 void ElfLoader::Forget(CustomElf* handle) {
492 Forget(static_cast<LibHandle*>(handle));
493 if (dbg) {
494 // We could race with the system linker when modifying the debug map, so
495 // only do so while holding the system linker's internal lock.
496 RunWithSystemLinkerLock([this, handle] { dbg.Remove(handle); });
500 void ElfLoader::Init() {
501 Dl_info info;
502 /* On Android < 4.1 can't reenter dl* functions. So when the library
503 * containing this code is dlopen()ed, it can't call dladdr from a
504 * static initializer. */
505 if (dladdr(_DYNAMIC, &info) != 0) {
506 self_elf = LoadedElf::Create(info.dli_fname, info.dli_fbase);
510 ElfLoader::~ElfLoader() {
511 LibHandleList list;
513 if (!Singleton.IsShutdownExpected()) {
514 MOZ_CRASH("Unexpected shutdown");
517 /* Release self_elf and libc */
518 self_elf = nullptr;
520 AutoLock lock(&handlesMutex);
521 /* Build up a list of all library handles with direct (external) references.
522 * We actually skip system library handles because we want to keep at least
523 * some of these open. Most notably, Mozilla codebase keeps a few libgnome
524 * libraries deliberately open because of the mess that libORBit destruction
525 * is. dlclose()ing these libraries actually leads to problems. */
526 for (LibHandleList::reverse_iterator it = handles.rbegin();
527 it < handles.rend(); ++it) {
528 if ((*it)->DirectRefCount()) {
529 if (SystemElf* se = (*it)->AsSystemElf()) {
530 se->Forget();
531 } else {
532 list.push_back(*it);
536 /* Force release all external references to the handles collected above */
537 for (LibHandleList::iterator it = list.begin(); it < list.end(); ++it) {
538 while ((*it)->ReleaseDirectRef()) {
541 /* Remove the remaining system handles. */
542 if (handles.size()) {
543 list = handles;
544 for (LibHandleList::reverse_iterator it = list.rbegin(); it < list.rend();
545 ++it) {
546 if ((*it)->AsSystemElf()) {
547 DEBUG_LOG(
548 "ElfLoader::~ElfLoader(): Remaining handle for \"%s\" "
549 "[%" PRIdPTR " direct refs, %" PRIdPTR " refs total]",
550 (*it)->GetPath(), (*it)->DirectRefCount(), (*it)->refCount());
551 } else {
552 DEBUG_LOG(
553 "ElfLoader::~ElfLoader(): Unexpected remaining handle for \"%s\" "
554 "[%" PRIdPTR " direct refs, %" PRIdPTR " refs total]",
555 (*it)->GetPath(), (*it)->DirectRefCount(), (*it)->refCount());
556 /* Not removing, since it could have references to other libraries,
557 * destroying them as a side effect, and possibly leaving dangling
558 * pointers in the handle list we're scanning */
562 pthread_mutex_destroy(&handlesMutex);
565 #ifdef __ARM_EABI__
566 int ElfLoader::__wrap_aeabi_atexit(void* that, ElfLoader::Destructor destructor,
567 void* dso_handle) {
568 Singleton.destructors.push_back(
569 DestructorCaller(destructor, that, dso_handle));
570 return 0;
572 #else
573 int ElfLoader::__wrap_cxa_atexit(ElfLoader::Destructor destructor, void* that,
574 void* dso_handle) {
575 Singleton.destructors.push_back(
576 DestructorCaller(destructor, that, dso_handle));
577 return 0;
579 #endif
581 void ElfLoader::__wrap_cxa_finalize(void* dso_handle) {
582 /* Call all destructors for the given DSO handle in reverse order they were
583 * registered. */
584 std::vector<DestructorCaller>::reverse_iterator it;
585 for (it = Singleton.destructors.rbegin(); it < Singleton.destructors.rend();
586 ++it) {
587 if (it->IsForHandle(dso_handle)) {
588 it->Call();
593 void ElfLoader::DestructorCaller::Call() {
594 if (destructor) {
595 DEBUG_LOG("ElfLoader::DestructorCaller::Call(%p, %p, %p)",
596 FunctionPtr(destructor), object, dso_handle);
597 destructor(object);
598 destructor = nullptr;
602 ElfLoader::DebuggerHelper::DebuggerHelper()
603 : dbg(nullptr), firstAdded(nullptr) {
604 /* Find ELF auxiliary vectors.
606 * The kernel stores the following data on the stack when starting a
607 * program:
608 * argc
609 * argv[0] (pointer into argv strings defined below)
610 * argv[1] (likewise)
611 * ...
612 * argv[argc - 1] (likewise)
613 * nullptr
614 * envp[0] (pointer into environment strings defined below)
615 * envp[1] (likewise)
616 * ...
617 * envp[n] (likewise)
618 * nullptr
619 * ... (more NULLs on some platforms such as Android 4.3)
620 * auxv[0] (first ELF auxiliary vector)
621 * auxv[1] (second ELF auxiliary vector)
622 * ...
623 * auxv[p] (last ELF auxiliary vector)
624 * (AT_NULL, nullptr)
625 * padding
626 * argv strings, separated with '\0'
627 * environment strings, separated with '\0'
628 * nullptr
630 * What we are after are the auxv values defined by the following struct.
632 struct AuxVector {
633 Elf::Addr type;
634 Elf::Addr value;
637 /* Pointer to the environment variables list */
638 extern char** environ;
640 /* The environment may have changed since the program started, in which
641 * case the environ variables list isn't the list the kernel put on stack
642 * anymore. But in this new list, variables that didn't change still point
643 * to the strings the kernel put on stack. It is quite unlikely that two
644 * modified environment variables point to two consecutive strings in memory,
645 * so we assume that if two consecutive environment variables point to two
646 * consecutive strings, we found strings the kernel put on stack. */
647 char** env;
648 for (env = environ; *env; env++)
649 if (*env + strlen(*env) + 1 == env[1]) break;
650 if (!*env) return;
652 /* Next, we scan the stack backwards to find a pointer to one of those
653 * strings we found above, which will give us the location of the original
654 * envp list. As we are looking for pointers, we need to look at 32-bits or
655 * 64-bits aligned values, depening on the architecture. */
656 char** scan = reinterpret_cast<char**>(reinterpret_cast<uintptr_t>(*env) &
657 ~(sizeof(void*) - 1));
658 while (*env != *scan) scan--;
660 /* Finally, scan forward to find the last environment variable pointer and
661 * thus the first auxiliary vector. */
662 while (*scan++);
664 /* Some platforms have more NULLs here, so skip them if we encounter them */
665 while (!*scan) scan++;
667 AuxVector* auxv = reinterpret_cast<AuxVector*>(scan);
669 /* The two values of interest in the auxiliary vectors are AT_PHDR and
670 * AT_PHNUM, which gives us the the location and size of the ELF program
671 * headers. */
672 Array<Elf::Phdr> phdrs;
673 char* base = nullptr;
674 while (auxv->type) {
675 if (auxv->type == AT_PHDR) {
676 phdrs.Init(reinterpret_cast<Elf::Phdr*>(auxv->value));
677 /* Assume the base address is the first byte of the same page */
678 base = reinterpret_cast<char*>(PageAlignedPtr(auxv->value));
680 if (auxv->type == AT_PHNUM) phdrs.Init(auxv->value);
681 auxv++;
684 if (!phdrs) {
685 DEBUG_LOG("Couldn't find program headers");
686 return;
689 /* In some cases, the address for the program headers we get from the
690 * auxiliary vectors is not mapped, because of the PT_LOAD segments
691 * definitions in the program executable. Trying to map anonymous memory
692 * with a hint giving the base address will return a different address
693 * if something is mapped there, and the base address otherwise. */
694 MappedPtr mem(MemoryRange::mmap(base, PageSize(), PROT_NONE,
695 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
696 if (mem == base) {
697 /* If program headers aren't mapped, try to map them */
698 int fd = open("/proc/self/exe", O_RDONLY);
699 if (fd == -1) {
700 DEBUG_LOG("Failed to open /proc/self/exe");
701 return;
703 mem.Assign(
704 MemoryRange::mmap(base, PageSize(), PROT_READ, MAP_PRIVATE, fd, 0));
705 /* If we don't manage to map at the right address, just give up. */
706 if (mem != base) {
707 DEBUG_LOG("Couldn't read program headers");
708 return;
711 /* Sanity check: the first bytes at the base address should be an ELF
712 * header. */
713 if (!Elf::Ehdr::validate(base)) {
714 DEBUG_LOG("Couldn't find program base");
715 return;
718 /* Search for the program PT_DYNAMIC segment */
719 Array<Elf::Dyn> dyns;
720 for (Array<Elf::Phdr>::iterator phdr = phdrs.begin(); phdr < phdrs.end();
721 ++phdr) {
722 /* While the program headers are expected within the first mapped page of
723 * the program executable, the executable PT_LOADs may actually make them
724 * loaded at an address that is not the wanted base address of the
725 * library. We thus need to adjust the base address, compensating for the
726 * virtual address of the PT_LOAD segment corresponding to offset 0. */
727 if (phdr->p_type == PT_LOAD && phdr->p_offset == 0) base -= phdr->p_vaddr;
728 if (phdr->p_type == PT_DYNAMIC)
729 dyns.Init(base + phdr->p_vaddr, phdr->p_filesz);
731 if (!dyns) {
732 DEBUG_LOG("Failed to find PT_DYNAMIC section in program");
733 return;
736 /* Search for the DT_DEBUG information */
737 for (Array<Elf::Dyn>::iterator dyn = dyns.begin(); dyn < dyns.end(); ++dyn) {
738 if (dyn->d_tag == DT_DEBUG) {
739 dbg = reinterpret_cast<r_debug*>(dyn->d_un.d_ptr);
740 break;
743 DEBUG_LOG("DT_DEBUG points at %p", static_cast<void*>(dbg));
747 * Helper class to ensure the given pointer is writable within the scope of
748 * an instance. Permissions to the memory page where the pointer lies are
749 * restored to their original value when the instance is destroyed.
751 class EnsureWritable {
752 public:
753 template <typename T>
754 explicit EnsureWritable(T* ptr, size_t length_ = sizeof(T)) {
755 MOZ_ASSERT(length_ < PageSize());
756 prot = -1;
757 page = MAP_FAILED;
759 char* firstPage = PageAlignedPtr(reinterpret_cast<char*>(ptr));
760 char* lastPageEnd =
761 PageAlignedEndPtr(reinterpret_cast<char*>(ptr) + length_);
762 length = lastPageEnd - firstPage;
763 uintptr_t start = reinterpret_cast<uintptr_t>(firstPage);
764 uintptr_t end;
766 prot = getProt(start, &end);
767 if (prot == -1 || (start + length) > end) MOZ_CRASH();
769 if (prot & PROT_WRITE) {
770 success = true;
771 return;
774 page = firstPage;
775 int ret = mprotect(page, length, prot | PROT_WRITE);
776 success = ret == 0;
777 if (!success) {
778 ERROR("mprotect(%p, %zu, %d) = %d (errno=%d; %s)", page, length,
779 prot | PROT_WRITE, ret, errno, strerror(errno));
783 bool IsWritable() const { return success; }
785 ~EnsureWritable() {
786 if (success && page != MAP_FAILED) {
787 mprotect(page, length, prot);
791 private:
792 int getProt(uintptr_t addr, uintptr_t* end) {
793 /* The interesting part of the /proc/self/maps format looks like:
794 * startAddr-endAddr rwxp */
795 int result = 0;
796 FILE* const f = fopen("/proc/self/maps", "r");
797 const auto cleanup = mozilla::MakeScopeExit([&]() {
798 if (f) fclose(f);
800 while (f) {
801 unsigned long long startAddr, endAddr;
802 char perms[5];
803 if (fscanf(f, "%llx-%llx %4s %*1024[^\n] ", &startAddr, &endAddr,
804 perms) != 3)
805 return -1;
806 if (addr < startAddr || addr >= endAddr) continue;
807 if (perms[0] == 'r')
808 result |= PROT_READ;
809 else if (perms[0] != '-')
810 return -1;
811 if (perms[1] == 'w')
812 result |= PROT_WRITE;
813 else if (perms[1] != '-')
814 return -1;
815 if (perms[2] == 'x')
816 result |= PROT_EXEC;
817 else if (perms[2] != '-')
818 return -1;
819 *end = endAddr;
820 return result;
822 return -1;
825 int prot;
826 void* page;
827 size_t length;
828 bool success;
832 * The system linker maintains a doubly linked list of library it loads
833 * for use by the debugger. Unfortunately, it also uses the list pointers
834 * in a lot of operations and adding our data in the list is likely to
835 * trigger crashes when the linker tries to use data we don't provide or
836 * that fall off the amount data we allocated. Fortunately, the linker only
837 * traverses the list forward and accesses the head of the list from a
838 * private pointer instead of using the value in the r_debug structure.
839 * This means we can safely add members at the beginning of the list.
840 * Unfortunately, gdb checks the coherency of l_prev values, so we have
841 * to adjust the l_prev value for the first element the system linker
842 * knows about. Fortunately, it doesn't use l_prev, and the first element
843 * is not ever going to be released before our elements, since it is the
844 * program executable, so the system linker should not be changing
845 * r_debug::r_map.
847 void ElfLoader::DebuggerHelper::Add(ElfLoader::link_map* map) {
848 if (!dbg->r_brk) return;
850 dbg->r_state = r_debug::RT_ADD;
851 dbg->r_brk();
853 if (!firstAdded) {
854 /* When adding a library for the first time, r_map points to data
855 * handled by the system linker, and that data may be read-only */
856 EnsureWritable w(&dbg->r_map->l_prev);
857 if (!w.IsWritable()) {
858 dbg->r_state = r_debug::RT_CONSISTENT;
859 dbg->r_brk();
860 return;
863 firstAdded = map;
864 dbg->r_map->l_prev = map;
865 } else
866 dbg->r_map->l_prev = map;
868 map->l_prev = nullptr;
869 map->l_next = dbg->r_map;
871 dbg->r_map = map;
872 dbg->r_state = r_debug::RT_CONSISTENT;
873 dbg->r_brk();
876 void ElfLoader::DebuggerHelper::Remove(ElfLoader::link_map* map) {
877 if (!dbg->r_brk) return;
879 dbg->r_state = r_debug::RT_DELETE;
880 dbg->r_brk();
882 if (map == firstAdded) {
883 /* When removing the first added library, its l_next is going to be
884 * data handled by the system linker, and that data may be read-only */
885 EnsureWritable w(&map->l_next->l_prev);
886 if (!w.IsWritable()) {
887 dbg->r_state = r_debug::RT_CONSISTENT;
888 dbg->r_brk();
889 return;
892 firstAdded = map->l_prev;
893 map->l_next->l_prev = map->l_prev;
894 } else if (map->l_next) {
895 map->l_next->l_prev = map->l_prev;
898 if (dbg->r_map == map)
899 dbg->r_map = map->l_next;
900 else if (map->l_prev) {
901 map->l_prev->l_next = map->l_next;
903 dbg->r_state = r_debug::RT_CONSISTENT;
904 dbg->r_brk();
907 #if defined(ANDROID) && defined(__NR_sigaction)
908 /* As some system libraries may be calling signal() or sigaction() to
909 * set a SIGSEGV handler, effectively breaking MappableSeekableZStream,
910 * or worse, restore our SIGSEGV handler with wrong flags (which using
911 * signal() will do), we want to hook into the system's sigaction() to
912 * replace it with our own wrapper instead, so that our handler is never
913 * replaced. We used to only do that with libraries this linker loads,
914 * but it turns out at least one system library does call signal() and
915 * breaks us (libsc-a3xx.so on the Samsung Galaxy S4).
916 * As libc's signal (bsd_signal/sysv_signal, really) calls sigaction
917 * under the hood, instead of calling the signal system call directly,
918 * we only need to hook sigaction. This is true for both bionic and
919 * glibc.
922 /* libc's sigaction */
923 extern "C" int sigaction(int signum, const struct sigaction* act,
924 struct sigaction* oldact);
926 /* Simple reimplementation of sigaction. This is roughly equivalent
927 * to the assembly that comes in bionic, but not quite equivalent to
928 * glibc's implementation, so we only use this on Android. */
929 int sys_sigaction(int signum, const struct sigaction* act,
930 struct sigaction* oldact) {
931 return syscall(__NR_sigaction, signum, act, oldact);
934 /* Replace the first instructions of the given function with a jump
935 * to the given new function. */
936 template <typename T>
937 static bool Divert(T func, T new_func) {
938 void* ptr = FunctionPtr(func);
939 uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
941 # if defined(__i386__)
942 // A 32-bit jump is a 5 bytes instruction.
943 EnsureWritable w(ptr, 5);
944 *reinterpret_cast<unsigned char*>(addr) = 0xe9; // jmp
945 *reinterpret_cast<intptr_t*>(addr + 1) =
946 reinterpret_cast<uintptr_t>(new_func) - addr - 5; // target displacement
947 return true;
948 # elif defined(__arm__) || defined(__aarch64__)
949 const unsigned char trampoline[] = {
950 # ifdef __arm__
951 // .thumb
952 0x46, 0x04, // nop
953 0x78, 0x47, // bx pc
954 0x46, 0x04, // nop
955 // .arm
956 0x04, 0xf0, 0x1f, 0xe5, // ldr pc, [pc, #-4]
957 // .word <new_func>
958 # else // __aarch64__
959 0x50, 0x00,
960 0x00, 0x58, // ldr x16, [pc, #8] ; x16 (aka ip0) is the first
961 0x00, 0x02,
962 0x1f, 0xd6, // br x16 ; intra-procedure-call
963 // .word <new_func.lo> ; scratch register.
964 // .word <new_func.hi>
965 # endif
967 const unsigned char* start;
968 # ifdef __arm__
969 if (addr & 0x01) {
970 /* Function is thumb, the actual address of the code is without the
971 * least significant bit. */
972 addr--;
973 /* The arm part of the trampoline needs to be 32-bit aligned */
974 if (addr & 0x02)
975 start = trampoline;
976 else
977 start = trampoline + 2;
978 } else {
979 /* Function is arm, we only need the arm part of the trampoline */
980 start = trampoline + 6;
982 # else // __aarch64__
983 start = trampoline;
984 # endif
986 size_t len = sizeof(trampoline) - (start - trampoline);
987 EnsureWritable w(reinterpret_cast<void*>(addr), len + sizeof(void*));
988 memcpy(reinterpret_cast<void*>(addr), start, len);
989 *reinterpret_cast<void**>(addr + len) = FunctionPtr(new_func);
990 __builtin___clear_cache(reinterpret_cast<char*>(addr),
991 reinterpret_cast<char*>(addr + len + sizeof(void*)));
992 return true;
993 # else
994 return false;
995 # endif
997 #else
998 # define sys_sigaction sigaction
999 template <typename T>
1000 static bool Divert(T func, T new_func) {
1001 return false;
1003 #endif
1005 namespace {
1007 /* Clock that only accounts for time spent in the current process. */
1008 static uint64_t ProcessTimeStamp_Now() {
1009 struct timespec ts;
1010 int rv = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
1012 if (rv != 0) {
1013 return 0;
1016 uint64_t baseNs = (uint64_t)ts.tv_sec * 1000000000;
1017 return baseNs + (uint64_t)ts.tv_nsec;
1020 } // namespace
1022 /* Data structure used to pass data to the temporary signal handler,
1023 * as well as triggering a test crash. */
1024 struct TmpData {
1025 volatile int crash_int;
1026 volatile uint64_t crash_timestamp;
1029 SEGVHandler::SEGVHandler()
1030 : initialized(false), registeredHandler(false), signalHandlingSlow(true) {
1031 /* Ensure logging is initialized before the DEBUG_LOG in the test_handler.
1032 * As this constructor runs before the ElfLoader constructor (by effect
1033 * of ElfLoader inheriting from this class), this also initializes on behalf
1034 * of ElfLoader and DebuggerHelper. */
1035 Logging::Init();
1037 /* Initialize oldStack.ss_flags to an invalid value when used to set
1038 * an alternative stack, meaning we haven't got information about the
1039 * original alternative stack and thus don't mean to restore it in
1040 * the destructor. */
1041 oldStack.ss_flags = SS_ONSTACK;
1043 /* Get the current segfault signal handler. */
1044 struct sigaction old_action;
1045 sys_sigaction(SIGSEGV, nullptr, &old_action);
1047 /* Some devices have a kernel option enabled that makes SIGSEGV handler
1048 * have an overhead so high that it affects how on-demand decompression
1049 * performs. The handler will set signalHandlingSlow if the triggered
1050 * SIGSEGV took too much time. */
1051 struct sigaction action;
1052 action.sa_sigaction = &SEGVHandler::test_handler;
1053 sigemptyset(&action.sa_mask);
1054 action.sa_flags = SA_SIGINFO | SA_NODEFER;
1055 action.sa_restorer = nullptr;
1056 stackPtr.Assign(MemoryRange::mmap(nullptr, PageSize(), PROT_READ | PROT_WRITE,
1057 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
1058 if (stackPtr.get() == MAP_FAILED) return;
1059 if (sys_sigaction(SIGSEGV, &action, nullptr)) return;
1061 TmpData* data = reinterpret_cast<TmpData*>(stackPtr.get());
1062 data->crash_timestamp = ProcessTimeStamp_Now();
1063 mprotect(stackPtr, stackPtr.GetLength(), PROT_NONE);
1064 data->crash_int = 123;
1065 /* Restore the original segfault signal handler. */
1066 sys_sigaction(SIGSEGV, &old_action, nullptr);
1067 stackPtr.Assign(MAP_FAILED, 0);
1070 void SEGVHandler::FinishInitialization() {
1071 /* Ideally, we'd need some locking here, but in practice, we're not
1072 * going to race with another thread. */
1073 initialized = true;
1075 if (signalHandlingSlow) {
1076 return;
1079 typedef int (*sigaction_func)(int, const struct sigaction*,
1080 struct sigaction*);
1082 sigaction_func libc_sigaction;
1084 #if defined(ANDROID)
1085 /* Android > 4.4 comes with a sigaction wrapper in a LD_PRELOADed library
1086 * (libsigchain) for ART. That wrapper kind of does the same trick as we
1087 * do, so we need extra care in handling it.
1088 * - Divert the libc's sigaction, assuming the LD_PRELOADed library uses
1089 * it under the hood (which is more or less true according to the source
1090 * of that library, since it's doing a lookup in RTLD_NEXT)
1091 * - With the LD_PRELOADed library in place, all calls to sigaction from
1092 * from system libraries will go to the LD_PRELOADed library.
1093 * - The LD_PRELOADed library calls to sigaction go to our __wrap_sigaction.
1094 * - The calls to sigaction from libraries faulty.lib loads are sent to
1095 * the LD_PRELOADed library.
1096 * In practice, for signal handling, this means:
1097 * - The signal handler registered to the kernel is ours.
1098 * - Our handler redispatches to the LD_PRELOADed library's if there's a
1099 * segfault we don't handle.
1100 * - The LD_PRELOADed library redispatches according to whatever system
1101 * library or faulty.lib-loaded library set with sigaction.
1103 * When there is no sigaction wrapper in place:
1104 * - Divert the libc's sigaction.
1105 * - Calls to sigaction from system library and faulty.lib-loaded libraries
1106 * all go to the libc's sigaction, which end up in our __wrap_sigaction.
1107 * - The signal handler registered to the kernel is ours.
1108 * - Our handler redispatches according to whatever system library or
1109 * faulty.lib-loaded library set with sigaction.
1111 void* libc = dlopen("libc.so", RTLD_GLOBAL | RTLD_LAZY);
1112 if (libc) {
1114 * Lollipop bionic only has a small trampoline in sigaction, with the real
1115 * work happening in __sigaction. Divert there instead of sigaction if it
1116 * exists. Bug 1154803
1118 libc_sigaction =
1119 reinterpret_cast<sigaction_func>(dlsym(libc, "__sigaction"));
1121 if (!libc_sigaction) {
1122 libc_sigaction =
1123 reinterpret_cast<sigaction_func>(dlsym(libc, "sigaction"));
1125 } else
1126 #endif
1128 libc_sigaction = sigaction;
1131 if (!Divert(libc_sigaction, __wrap_sigaction)) return;
1133 /* Setup an alternative stack if the already existing one is not big
1134 * enough, or if there is none. */
1135 if (sigaltstack(nullptr, &oldStack) == 0) {
1136 if (oldStack.ss_flags == SS_ONSTACK) oldStack.ss_flags = 0;
1137 if (!oldStack.ss_sp || oldStack.ss_size < stackSize) {
1138 stackPtr.Assign(MemoryRange::mmap(nullptr, stackSize,
1139 PROT_READ | PROT_WRITE,
1140 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
1141 if (stackPtr.get() == MAP_FAILED) return;
1142 stack_t stack;
1143 stack.ss_sp = stackPtr;
1144 stack.ss_size = stackSize;
1145 stack.ss_flags = 0;
1146 if (sigaltstack(&stack, nullptr) != 0) return;
1149 /* Register our own handler, and store the already registered one in
1150 * SEGVHandler's struct sigaction member */
1151 action.sa_sigaction = &SEGVHandler::handler;
1152 action.sa_flags = SA_SIGINFO | SA_NODEFER | SA_ONSTACK;
1153 registeredHandler = !sys_sigaction(SIGSEGV, &action, &this->action);
1156 SEGVHandler::~SEGVHandler() {
1157 /* Restore alternative stack for signals */
1158 if (oldStack.ss_flags != SS_ONSTACK) sigaltstack(&oldStack, nullptr);
1159 /* Restore original signal handler */
1160 if (registeredHandler) sys_sigaction(SIGSEGV, &this->action, nullptr);
1163 /* Test handler for a deliberately triggered SIGSEGV that determines whether
1164 * the segfault handler is called quickly enough. */
1165 void SEGVHandler::test_handler(int signum, siginfo_t* info, void* context) {
1166 SEGVHandler& that = ElfLoader::Singleton;
1167 mprotect(that.stackPtr, that.stackPtr.GetLength(), PROT_READ | PROT_WRITE);
1168 TmpData* data = reinterpret_cast<TmpData*>(that.stackPtr.get());
1169 uint64_t latency = ProcessTimeStamp_Now() - data->crash_timestamp;
1170 DEBUG_LOG("SEGVHandler latency: %" PRIu64, latency);
1171 /* See bug 886736 for timings on different devices, 150 µs is reasonably above
1172 * the latency on "working" devices and seems to be short enough to not incur
1173 * a huge overhead to on-demand decompression. */
1174 if (latency <= 150000) that.signalHandlingSlow = false;
1177 /* TODO: "properly" handle signal masks and flags */
1178 void SEGVHandler::handler(int signum, siginfo_t* info, void* context) {
1179 // ASSERT(signum == SIGSEGV);
1180 DEBUG_LOG("Caught segmentation fault @%p", info->si_addr);
1182 /* Redispatch to the registered handler */
1183 SEGVHandler& that = ElfLoader::Singleton;
1184 if (that.action.sa_flags & SA_SIGINFO) {
1185 DEBUG_LOG("Redispatching to registered handler @%p",
1186 FunctionPtr(that.action.sa_sigaction));
1187 that.action.sa_sigaction(signum, info, context);
1188 } else if (that.action.sa_handler == SIG_DFL) {
1189 DEBUG_LOG("Redispatching to default handler");
1190 /* Reset the handler to the default one, and trigger it. */
1191 sys_sigaction(signum, &that.action, nullptr);
1192 raise(signum);
1193 } else if (that.action.sa_handler != SIG_IGN) {
1194 DEBUG_LOG("Redispatching to registered handler @%p",
1195 FunctionPtr(that.action.sa_handler));
1196 that.action.sa_handler(signum);
1197 } else {
1198 DEBUG_LOG("Ignoring");
1202 int SEGVHandler::__wrap_sigaction(int signum, const struct sigaction* act,
1203 struct sigaction* oldact) {
1204 SEGVHandler& that = ElfLoader::Singleton;
1206 /* Use system sigaction() function for all but SIGSEGV signals. */
1207 if (!that.registeredHandler || (signum != SIGSEGV))
1208 return sys_sigaction(signum, act, oldact);
1210 if (oldact) *oldact = that.action;
1211 if (act) that.action = *act;
1212 return 0;