Bumping manifests a=b2g-bump
[gecko.git] / mozglue / linker / ElfLoader.cpp
blob7fe28efbddb210640144afa9cacf21e75b1547e7
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 <unistd.h>
11 #include <algorithm>
12 #include <fcntl.h>
13 #include "ElfLoader.h"
14 #include "CustomElf.h"
15 #include "Mappable.h"
16 #include "Logging.h"
17 #include <inttypes.h>
19 #if defined(ANDROID)
20 #include <sys/syscall.h>
22 #include <android/api-level.h>
23 #if __ANDROID_API__ < 8
24 /* Android API < 8 doesn't provide sigaltstack */
26 extern "C" {
28 inline int sigaltstack(const stack_t *ss, stack_t *oss) {
29 return syscall(__NR_sigaltstack, ss, oss);
32 } /* extern "C" */
33 #endif /* __ANDROID_API__ */
34 #endif /* ANDROID */
36 #ifdef __ARM_EABI__
37 extern "C" MOZ_EXPORT const void *
38 __gnu_Unwind_Find_exidx(void *pc, int *pcount) __attribute__((weak));
39 #endif
41 using namespace mozilla;
43 /**
44 * dlfcn.h replacements functions
47 void *
48 __wrap_dlopen(const char *path, int flags)
50 RefPtr<LibHandle> handle = ElfLoader::Singleton.Load(path, flags);
51 if (handle)
52 handle->AddDirectRef();
53 return handle;
56 const char *
57 __wrap_dlerror(void)
59 const char *error = ElfLoader::Singleton.lastError;
60 ElfLoader::Singleton.lastError = nullptr;
61 return error;
64 void *
65 __wrap_dlsym(void *handle, const char *symbol)
67 if (!handle) {
68 ElfLoader::Singleton.lastError = "dlsym(NULL, sym) unsupported";
69 return nullptr;
71 if (handle != RTLD_DEFAULT && handle != RTLD_NEXT) {
72 LibHandle *h = reinterpret_cast<LibHandle *>(handle);
73 return h->GetSymbolPtr(symbol);
75 return dlsym(handle, symbol);
78 int
79 __wrap_dlclose(void *handle)
81 if (!handle) {
82 ElfLoader::Singleton.lastError = "No handle given to dlclose()";
83 return -1;
85 reinterpret_cast<LibHandle *>(handle)->ReleaseDirectRef();
86 return 0;
89 int
90 __wrap_dladdr(void *addr, Dl_info *info)
92 RefPtr<LibHandle> handle = ElfLoader::Singleton.GetHandleByPtr(addr);
93 if (!handle)
94 return 0;
95 info->dli_fname = handle->GetPath();
96 return 1;
99 int
100 __wrap_dl_iterate_phdr(dl_phdr_cb callback, void *data)
102 if (!ElfLoader::Singleton.dbg)
103 return -1;
105 for (ElfLoader::DebuggerHelper::iterator it = ElfLoader::Singleton.dbg.begin();
106 it < ElfLoader::Singleton.dbg.end(); ++it) {
107 dl_phdr_info info;
108 info.dlpi_addr = reinterpret_cast<Elf::Addr>(it->l_addr);
109 info.dlpi_name = it->l_name;
110 info.dlpi_phdr = nullptr;
111 info.dlpi_phnum = 0;
113 // Assuming l_addr points to Elf headers (in most cases, this is true),
114 // get the Phdr location from there.
115 uint8_t mapped;
116 // If the page is not mapped, mincore returns an error.
117 if (!mincore(const_cast<void*>(it->l_addr), PageSize(), &mapped)) {
118 const Elf::Ehdr *ehdr = Elf::Ehdr::validate(it->l_addr);
119 if (ehdr) {
120 info.dlpi_phdr = reinterpret_cast<const Elf::Phdr *>(
121 reinterpret_cast<const char *>(ehdr) + ehdr->e_phoff);
122 info.dlpi_phnum = ehdr->e_phnum;
126 int ret = callback(&info, sizeof(dl_phdr_info), data);
127 if (ret)
128 return ret;
130 return 0;
133 #ifdef __ARM_EABI__
134 const void *
135 __wrap___gnu_Unwind_Find_exidx(void *pc, int *pcount)
137 RefPtr<LibHandle> handle = ElfLoader::Singleton.GetHandleByPtr(pc);
138 if (handle)
139 return handle->FindExidx(pcount);
140 if (__gnu_Unwind_Find_exidx)
141 return __gnu_Unwind_Find_exidx(pc, pcount);
142 *pcount = 0;
143 return nullptr;
145 #endif
148 * faulty.lib public API
151 MFBT_API size_t
152 __dl_get_mappable_length(void *handle) {
153 if (!handle)
154 return 0;
155 return reinterpret_cast<LibHandle *>(handle)->GetMappableLength();
158 MFBT_API void *
159 __dl_mmap(void *handle, void *addr, size_t length, off_t offset)
161 if (!handle)
162 return nullptr;
163 return reinterpret_cast<LibHandle *>(handle)->MappableMMap(addr, length,
164 offset);
167 MFBT_API void
168 __dl_munmap(void *handle, void *addr, size_t length)
170 if (!handle)
171 return;
172 return reinterpret_cast<LibHandle *>(handle)->MappableMUnmap(addr, length);
175 MFBT_API bool
176 IsSignalHandlingBroken()
178 return ElfLoader::Singleton.isSignalHandlingBroken();
181 namespace {
184 * Returns the part after the last '/' for the given path
186 const char *
187 LeafName(const char *path)
189 const char *lastSlash = strrchr(path, '/');
190 if (lastSlash)
191 return lastSlash + 1;
192 return path;
195 } /* Anonymous namespace */
198 * LibHandle
200 LibHandle::~LibHandle()
202 free(path);
205 const char *
206 LibHandle::GetName() const
208 return path ? LeafName(path) : nullptr;
211 size_t
212 LibHandle::GetMappableLength() const
214 if (!mappable)
215 mappable = GetMappable();
216 if (!mappable)
217 return 0;
218 return mappable->GetLength();
221 void *
222 LibHandle::MappableMMap(void *addr, size_t length, off_t offset) const
224 if (!mappable)
225 mappable = GetMappable();
226 if (!mappable)
227 return MAP_FAILED;
228 void* mapped = mappable->mmap(addr, length, PROT_READ, MAP_PRIVATE, offset);
229 if (mapped != MAP_FAILED) {
230 /* Ensure the availability of all pages within the mapping */
231 for (size_t off = 0; off < length; off += PageSize()) {
232 mappable->ensure(reinterpret_cast<char *>(mapped) + off);
235 return mapped;
238 void
239 LibHandle::MappableMUnmap(void *addr, size_t length) const
241 if (mappable)
242 mappable->munmap(addr, length);
246 * SystemElf
248 TemporaryRef<LibHandle>
249 SystemElf::Load(const char *path, int flags)
251 /* The Android linker returns a handle when the file name matches an
252 * already loaded library, even when the full path doesn't exist */
253 if (path && path[0] == '/' && (access(path, F_OK) == -1)){
254 DEBUG_LOG("dlopen(\"%s\", 0x%x) = %p", path, flags, (void *)nullptr);
255 return nullptr;
258 void *handle = dlopen(path, flags);
259 DEBUG_LOG("dlopen(\"%s\", 0x%x) = %p", path, flags, handle);
260 ElfLoader::Singleton.lastError = dlerror();
261 if (handle) {
262 SystemElf *elf = new SystemElf(path, handle);
263 ElfLoader::Singleton.Register(elf);
264 return elf;
266 return nullptr;
269 SystemElf::~SystemElf()
271 if (!dlhandle)
272 return;
273 DEBUG_LOG("dlclose(%p [\"%s\"])", dlhandle, GetPath());
274 dlclose(dlhandle);
275 ElfLoader::Singleton.lastError = dlerror();
276 ElfLoader::Singleton.Forget(this);
279 void *
280 SystemElf::GetSymbolPtr(const char *symbol) const
282 void *sym = dlsym(dlhandle, symbol);
283 DEBUG_LOG("dlsym(%p [\"%s\"], \"%s\") = %p", dlhandle, GetPath(), symbol, sym);
284 ElfLoader::Singleton.lastError = dlerror();
285 return sym;
288 Mappable *
289 SystemElf::GetMappable() const
291 const char *path = GetPath();
292 if (!path)
293 return nullptr;
294 #ifdef ANDROID
295 /* On Android, if we don't have the full path, try in /system/lib */
296 const char *name = LeafName(path);
297 std::string systemPath;
298 if (name == path) {
299 systemPath = "/system/lib/";
300 systemPath += path;
301 path = systemPath.c_str();
303 #endif
305 return MappableFile::Create(path);
308 #ifdef __ARM_EABI__
309 const void *
310 SystemElf::FindExidx(int *pcount) const
312 /* TODO: properly implement when ElfLoader::GetHandleByPtr
313 does return SystemElf handles */
314 *pcount = 0;
315 return nullptr;
317 #endif
320 * ElfLoader
323 /* Unique ElfLoader instance */
324 ElfLoader ElfLoader::Singleton;
326 TemporaryRef<LibHandle>
327 ElfLoader::Load(const char *path, int flags, LibHandle *parent)
329 /* Ensure logging is initialized or refresh if environment changed. */
330 Logging::Init();
332 RefPtr<LibHandle> handle;
334 /* Handle dlopen(nullptr) directly. */
335 if (!path) {
336 handle = SystemElf::Load(nullptr, flags);
337 return handle;
340 /* TODO: Handle relative paths correctly */
341 const char *name = LeafName(path);
343 /* Search the list of handles we already have for a match. When the given
344 * path is not absolute, compare file names, otherwise compare full paths. */
345 if (name == path) {
346 for (LibHandleList::iterator it = handles.begin(); it < handles.end(); ++it)
347 if ((*it)->GetName() && (strcmp((*it)->GetName(), name) == 0))
348 return *it;
349 } else {
350 for (LibHandleList::iterator it = handles.begin(); it < handles.end(); ++it)
351 if ((*it)->GetPath() && (strcmp((*it)->GetPath(), path) == 0))
352 return *it;
355 char *abs_path = nullptr;
356 const char *requested_path = path;
358 /* When the path is not absolute and the library is being loaded for
359 * another, first try to load the library from the directory containing
360 * that parent library. */
361 if ((name == path) && parent) {
362 const char *parentPath = parent->GetPath();
363 abs_path = new char[strlen(parentPath) + strlen(path)];
364 strcpy(abs_path, parentPath);
365 char *slash = strrchr(abs_path, '/');
366 strcpy(slash + 1, path);
367 path = abs_path;
370 Mappable *mappable = GetMappableFromPath(path);
372 /* Try loading with the custom linker if we have a Mappable */
373 if (mappable)
374 handle = CustomElf::Load(mappable, path, flags);
376 /* Try loading with the system linker if everything above failed */
377 if (!handle)
378 handle = SystemElf::Load(path, flags);
380 /* If we didn't have an absolute path and haven't been able to load
381 * a library yet, try in the system search path */
382 if (!handle && abs_path)
383 handle = SystemElf::Load(name, flags);
385 delete [] abs_path;
386 DEBUG_LOG("ElfLoader::Load(\"%s\", 0x%x, %p [\"%s\"]) = %p", requested_path, flags,
387 reinterpret_cast<void *>(parent), parent ? parent->GetPath() : "",
388 static_cast<void *>(handle));
390 return handle;
393 mozilla::TemporaryRef<LibHandle>
394 ElfLoader::GetHandleByPtr(void *addr)
396 /* Scan the list of handles we already have for a match */
397 for (LibHandleList::iterator it = handles.begin(); it < handles.end(); ++it) {
398 if ((*it)->Contains(addr))
399 return *it;
401 return nullptr;
404 Mappable *
405 ElfLoader::GetMappableFromPath(const char *path)
407 const char *name = LeafName(path);
408 Mappable *mappable = nullptr;
409 RefPtr<Zip> zip;
410 const char *subpath;
411 if ((subpath = strchr(path, '!'))) {
412 char *zip_path = strndup(path, subpath - path);
413 while (*(++subpath) == '/') { }
414 zip = ZipCollection::GetZip(zip_path);
415 Zip::Stream s;
416 if (zip && zip->GetStream(subpath, &s)) {
417 /* When the MOZ_LINKER_EXTRACT environment variable is set to "1",
418 * compressed libraries are going to be (temporarily) extracted as
419 * files, in the directory pointed by the MOZ_LINKER_CACHE
420 * environment variable. */
421 const char *extract = getenv("MOZ_LINKER_EXTRACT");
422 if (extract && !strncmp(extract, "1", 2 /* Including '\0' */))
423 mappable = MappableExtractFile::Create(name, zip, &s);
424 if (!mappable) {
425 if (s.GetType() == Zip::Stream::DEFLATE) {
426 mappable = MappableDeflate::Create(name, zip, &s);
427 } else if (s.GetType() == Zip::Stream::STORE) {
428 mappable = MappableSeekableZStream::Create(name, zip, &s);
433 /* If we couldn't load above, try with a MappableFile */
434 if (!mappable && !zip)
435 mappable = MappableFile::Create(path);
437 return mappable;
440 void
441 ElfLoader::Register(LibHandle *handle)
443 handles.push_back(handle);
444 if (dbg && !handle->IsSystemElf())
445 dbg.Add(static_cast<CustomElf *>(handle));
448 void
449 ElfLoader::Forget(LibHandle *handle)
451 /* Ensure logging is initialized or refresh if environment changed. */
452 Logging::Init();
454 LibHandleList::iterator it = std::find(handles.begin(), handles.end(), handle);
455 if (it != handles.end()) {
456 DEBUG_LOG("ElfLoader::Forget(%p [\"%s\"])", reinterpret_cast<void *>(handle),
457 handle->GetPath());
458 if (dbg && !handle->IsSystemElf())
459 dbg.Remove(static_cast<CustomElf *>(handle));
460 handles.erase(it);
461 } else {
462 DEBUG_LOG("ElfLoader::Forget(%p [\"%s\"]): Handle not found",
463 reinterpret_cast<void *>(handle), handle->GetPath());
467 ElfLoader::~ElfLoader()
469 LibHandleList list;
470 /* Build up a list of all library handles with direct (external) references.
471 * We actually skip system library handles because we want to keep at least
472 * some of these open. Most notably, Mozilla codebase keeps a few libgnome
473 * libraries deliberately open because of the mess that libORBit destruction
474 * is. dlclose()ing these libraries actually leads to problems. */
475 for (LibHandleList::reverse_iterator it = handles.rbegin();
476 it < handles.rend(); ++it) {
477 if ((*it)->DirectRefCount()) {
478 if ((*it)->IsSystemElf()) {
479 static_cast<SystemElf *>(*it)->Forget();
480 } else {
481 list.push_back(*it);
485 /* Force release all external references to the handles collected above */
486 for (LibHandleList::iterator it = list.begin(); it < list.end(); ++it) {
487 while ((*it)->ReleaseDirectRef()) { }
489 /* Remove the remaining system handles. */
490 if (handles.size()) {
491 list = handles;
492 for (LibHandleList::reverse_iterator it = list.rbegin();
493 it < list.rend(); ++it) {
494 if ((*it)->IsSystemElf()) {
495 DEBUG_LOG("ElfLoader::~ElfLoader(): Remaining handle for \"%s\" "
496 "[%d direct refs, %d refs total]", (*it)->GetPath(),
497 (*it)->DirectRefCount(), (*it)->refCount());
498 } else {
499 DEBUG_LOG("ElfLoader::~ElfLoader(): Unexpected remaining handle for \"%s\" "
500 "[%d direct refs, %d refs total]", (*it)->GetPath(),
501 (*it)->DirectRefCount(), (*it)->refCount());
502 /* Not removing, since it could have references to other libraries,
503 * destroying them as a side effect, and possibly leaving dangling
504 * pointers in the handle list we're scanning */
510 void
511 ElfLoader::stats(const char *when)
513 for (LibHandleList::iterator it = Singleton.handles.begin();
514 it < Singleton.handles.end(); ++it)
515 if (!(*it)->IsSystemElf())
516 static_cast<CustomElf *>(*it)->stats(when);
519 #ifdef __ARM_EABI__
521 ElfLoader::__wrap_aeabi_atexit(void *that, ElfLoader::Destructor destructor,
522 void *dso_handle)
524 Singleton.destructors.push_back(
525 DestructorCaller(destructor, that, dso_handle));
526 return 0;
528 #else
530 ElfLoader::__wrap_cxa_atexit(ElfLoader::Destructor destructor, void *that,
531 void *dso_handle)
533 Singleton.destructors.push_back(
534 DestructorCaller(destructor, that, dso_handle));
535 return 0;
537 #endif
539 void
540 ElfLoader::__wrap_cxa_finalize(void *dso_handle)
542 /* Call all destructors for the given DSO handle in reverse order they were
543 * registered. */
544 std::vector<DestructorCaller>::reverse_iterator it;
545 for (it = Singleton.destructors.rbegin();
546 it < Singleton.destructors.rend(); ++it) {
547 if (it->IsForHandle(dso_handle)) {
548 it->Call();
553 void
554 ElfLoader::DestructorCaller::Call()
556 if (destructor) {
557 DEBUG_LOG("ElfLoader::DestructorCaller::Call(%p, %p, %p)",
558 FunctionPtr(destructor), object, dso_handle);
559 destructor(object);
560 destructor = nullptr;
564 ElfLoader::DebuggerHelper::DebuggerHelper(): dbg(nullptr)
566 /* Find ELF auxiliary vectors.
568 * The kernel stores the following data on the stack when starting a
569 * program:
570 * argc
571 * argv[0] (pointer into argv strings defined below)
572 * argv[1] (likewise)
573 * ...
574 * argv[argc - 1] (likewise)
575 * nullptr
576 * envp[0] (pointer into environment strings defined below)
577 * envp[1] (likewise)
578 * ...
579 * envp[n] (likewise)
580 * nullptr
581 * ... (more NULLs on some platforms such as Android 4.3)
582 * auxv[0] (first ELF auxiliary vector)
583 * auxv[1] (second ELF auxiliary vector)
584 * ...
585 * auxv[p] (last ELF auxiliary vector)
586 * (AT_NULL, nullptr)
587 * padding
588 * argv strings, separated with '\0'
589 * environment strings, separated with '\0'
590 * nullptr
592 * What we are after are the auxv values defined by the following struct.
594 struct AuxVector {
595 Elf::Addr type;
596 Elf::Addr value;
599 /* Pointer to the environment variables list */
600 extern char **environ;
602 /* The environment may have changed since the program started, in which
603 * case the environ variables list isn't the list the kernel put on stack
604 * anymore. But in this new list, variables that didn't change still point
605 * to the strings the kernel put on stack. It is quite unlikely that two
606 * modified environment variables point to two consecutive strings in memory,
607 * so we assume that if two consecutive environment variables point to two
608 * consecutive strings, we found strings the kernel put on stack. */
609 char **env;
610 for (env = environ; *env; env++)
611 if (*env + strlen(*env) + 1 == env[1])
612 break;
613 if (!*env)
614 return;
616 /* Next, we scan the stack backwards to find a pointer to one of those
617 * strings we found above, which will give us the location of the original
618 * envp list. As we are looking for pointers, we need to look at 32-bits or
619 * 64-bits aligned values, depening on the architecture. */
620 char **scan = reinterpret_cast<char **>(
621 reinterpret_cast<uintptr_t>(*env) & ~(sizeof(void *) - 1));
622 while (*env != *scan)
623 scan--;
625 /* Finally, scan forward to find the last environment variable pointer and
626 * thus the first auxiliary vector. */
627 while (*scan++);
629 /* Some platforms have more NULLs here, so skip them if we encounter them */
630 while (!*scan)
631 scan++;
633 AuxVector *auxv = reinterpret_cast<AuxVector *>(scan);
635 /* The two values of interest in the auxiliary vectors are AT_PHDR and
636 * AT_PHNUM, which gives us the the location and size of the ELF program
637 * headers. */
638 Array<Elf::Phdr> phdrs;
639 char *base = nullptr;
640 while (auxv->type) {
641 if (auxv->type == AT_PHDR) {
642 phdrs.Init(reinterpret_cast<Elf::Phdr*>(auxv->value));
643 /* Assume the base address is the first byte of the same page */
644 base = reinterpret_cast<char *>(PageAlignedPtr(auxv->value));
646 if (auxv->type == AT_PHNUM)
647 phdrs.Init(auxv->value);
648 auxv++;
651 if (!phdrs) {
652 DEBUG_LOG("Couldn't find program headers");
653 return;
656 /* In some cases, the address for the program headers we get from the
657 * auxiliary vectors is not mapped, because of the PT_LOAD segments
658 * definitions in the program executable. Trying to map anonymous memory
659 * with a hint giving the base address will return a different address
660 * if something is mapped there, and the base address otherwise. */
661 MappedPtr mem(MemoryRange::mmap(base, PageSize(), PROT_NONE,
662 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
663 if (mem == base) {
664 /* If program headers aren't mapped, try to map them */
665 int fd = open("/proc/self/exe", O_RDONLY);
666 if (fd == -1) {
667 DEBUG_LOG("Failed to open /proc/self/exe");
668 return;
670 mem.Assign(MemoryRange::mmap(base, PageSize(), PROT_READ, MAP_PRIVATE,
671 fd, 0));
672 /* If we don't manage to map at the right address, just give up. */
673 if (mem != base) {
674 DEBUG_LOG("Couldn't read program headers");
675 return;
678 /* Sanity check: the first bytes at the base address should be an ELF
679 * header. */
680 if (!Elf::Ehdr::validate(base)) {
681 DEBUG_LOG("Couldn't find program base");
682 return;
685 /* Search for the program PT_DYNAMIC segment */
686 Array<Elf::Dyn> dyns;
687 for (Array<Elf::Phdr>::iterator phdr = phdrs.begin(); phdr < phdrs.end();
688 ++phdr) {
689 /* While the program headers are expected within the first mapped page of
690 * the program executable, the executable PT_LOADs may actually make them
691 * loaded at an address that is not the wanted base address of the
692 * library. We thus need to adjust the base address, compensating for the
693 * virtual address of the PT_LOAD segment corresponding to offset 0. */
694 if (phdr->p_type == PT_LOAD && phdr->p_offset == 0)
695 base -= phdr->p_vaddr;
696 if (phdr->p_type == PT_DYNAMIC)
697 dyns.Init(base + phdr->p_vaddr, phdr->p_filesz);
699 if (!dyns) {
700 DEBUG_LOG("Failed to find PT_DYNAMIC section in program");
701 return;
704 /* Search for the DT_DEBUG information */
705 for (Array<Elf::Dyn>::iterator dyn = dyns.begin(); dyn < dyns.end(); ++dyn) {
706 if (dyn->d_tag == DT_DEBUG) {
707 dbg = reinterpret_cast<r_debug *>(dyn->d_un.d_ptr);
708 break;
711 DEBUG_LOG("DT_DEBUG points at %p", static_cast<void *>(dbg));
715 * Helper class to ensure the given pointer is writable within the scope of
716 * an instance. Permissions to the memory page where the pointer lies are
717 * restored to their original value when the instance is destroyed.
719 class EnsureWritable
721 public:
722 template <typename T>
723 EnsureWritable(T *ptr, size_t length_ = sizeof(T))
725 MOZ_ASSERT(length_ < PageSize());
726 prot = -1;
727 page = MAP_FAILED;
729 char *firstPage = PageAlignedPtr(reinterpret_cast<char *>(ptr));
730 char *lastPageEnd = PageAlignedEndPtr(reinterpret_cast<char *>(ptr) + length_);
731 length = lastPageEnd - firstPage;
732 uintptr_t start = reinterpret_cast<uintptr_t>(firstPage);
733 uintptr_t end;
735 prot = getProt(start, &end);
736 if (prot == -1 || (start + length) > end)
737 MOZ_CRASH();
739 if (prot & PROT_WRITE)
740 return;
742 page = firstPage;
743 mprotect(page, length, prot | PROT_WRITE);
746 ~EnsureWritable()
748 if (page != MAP_FAILED) {
749 mprotect(page, length, prot);
753 private:
754 int getProt(uintptr_t addr, uintptr_t *end)
756 /* The interesting part of the /proc/self/maps format looks like:
757 * startAddr-endAddr rwxp */
758 int result = 0;
759 AutoCloseFILE f(fopen("/proc/self/maps", "r"));
760 while (f) {
761 unsigned long long startAddr, endAddr;
762 char perms[5];
763 if (fscanf(f, "%llx-%llx %4s %*1024[^\n] ", &startAddr, &endAddr, perms) != 3)
764 return -1;
765 if (addr < startAddr || addr >= endAddr)
766 continue;
767 if (perms[0] == 'r')
768 result |= PROT_READ;
769 else if (perms[0] != '-')
770 return -1;
771 if (perms[1] == 'w')
772 result |= PROT_WRITE;
773 else if (perms[1] != '-')
774 return -1;
775 if (perms[2] == 'x')
776 result |= PROT_EXEC;
777 else if (perms[2] != '-')
778 return -1;
779 *end = endAddr;
780 return result;
782 return -1;
785 int prot;
786 void *page;
787 size_t length;
791 * The system linker maintains a doubly linked list of library it loads
792 * for use by the debugger. Unfortunately, it also uses the list pointers
793 * in a lot of operations and adding our data in the list is likely to
794 * trigger crashes when the linker tries to use data we don't provide or
795 * that fall off the amount data we allocated. Fortunately, the linker only
796 * traverses the list forward and accesses the head of the list from a
797 * private pointer instead of using the value in the r_debug structure.
798 * This means we can safely add members at the beginning of the list.
799 * Unfortunately, gdb checks the coherency of l_prev values, so we have
800 * to adjust the l_prev value for the first element the system linker
801 * knows about. Fortunately, it doesn't use l_prev, and the first element
802 * is not ever going to be released before our elements, since it is the
803 * program executable, so the system linker should not be changing
804 * r_debug::r_map.
806 void
807 ElfLoader::DebuggerHelper::Add(ElfLoader::link_map *map)
809 if (!dbg->r_brk)
810 return;
811 dbg->r_state = r_debug::RT_ADD;
812 dbg->r_brk();
813 map->l_prev = nullptr;
814 map->l_next = dbg->r_map;
815 if (!firstAdded) {
816 firstAdded = map;
817 /* When adding a library for the first time, r_map points to data
818 * handled by the system linker, and that data may be read-only */
819 EnsureWritable w(&dbg->r_map->l_prev);
820 dbg->r_map->l_prev = map;
821 } else
822 dbg->r_map->l_prev = map;
823 dbg->r_map = map;
824 dbg->r_state = r_debug::RT_CONSISTENT;
825 dbg->r_brk();
828 void
829 ElfLoader::DebuggerHelper::Remove(ElfLoader::link_map *map)
831 if (!dbg->r_brk)
832 return;
833 dbg->r_state = r_debug::RT_DELETE;
834 dbg->r_brk();
835 if (dbg->r_map == map)
836 dbg->r_map = map->l_next;
837 else
838 map->l_prev->l_next = map->l_next;
839 if (map == firstAdded) {
840 firstAdded = map->l_prev;
841 /* When removing the first added library, its l_next is going to be
842 * data handled by the system linker, and that data may be read-only */
843 EnsureWritable w(&map->l_next->l_prev);
844 map->l_next->l_prev = map->l_prev;
845 } else
846 map->l_next->l_prev = map->l_prev;
847 dbg->r_state = r_debug::RT_CONSISTENT;
848 dbg->r_brk();
851 #if defined(ANDROID)
852 /* As some system libraries may be calling signal() or sigaction() to
853 * set a SIGSEGV handler, effectively breaking MappableSeekableZStream,
854 * or worse, restore our SIGSEGV handler with wrong flags (which using
855 * signal() will do), we want to hook into the system's sigaction() to
856 * replace it with our own wrapper instead, so that our handler is never
857 * replaced. We used to only do that with libraries this linker loads,
858 * but it turns out at least one system library does call signal() and
859 * breaks us (libsc-a3xx.so on the Samsung Galaxy S4).
860 * As libc's signal (bsd_signal/sysv_signal, really) calls sigaction
861 * under the hood, instead of calling the signal system call directly,
862 * we only need to hook sigaction. This is true for both bionic and
863 * glibc.
866 /* libc's sigaction */
867 extern "C" int
868 sigaction(int signum, const struct sigaction *act,
869 struct sigaction *oldact);
871 /* Simple reimplementation of sigaction. This is roughly equivalent
872 * to the assembly that comes in bionic, but not quite equivalent to
873 * glibc's implementation, so we only use this on Android. */
875 sys_sigaction(int signum, const struct sigaction *act,
876 struct sigaction *oldact)
878 return syscall(__NR_sigaction, signum, act, oldact);
881 /* Replace the first instructions of the given function with a jump
882 * to the given new function. */
883 template <typename T>
884 static bool
885 Divert(T func, T new_func)
887 void *ptr = FunctionPtr(func);
888 uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
890 #if defined(__i386__)
891 // A 32-bit jump is a 5 bytes instruction.
892 EnsureWritable w(ptr, 5);
893 *reinterpret_cast<unsigned char *>(addr) = 0xe9; // jmp
894 *reinterpret_cast<intptr_t *>(addr + 1) =
895 reinterpret_cast<uintptr_t>(new_func) - addr - 5; // target displacement
896 return true;
897 #elif defined(__arm__)
898 const unsigned char trampoline[] = {
899 // .thumb
900 0x46, 0x04, // nop
901 0x78, 0x47, // bx pc
902 0x46, 0x04, // nop
903 // .arm
904 0x04, 0xf0, 0x1f, 0xe5, // ldr pc, [pc, #-4]
905 // .word <new_func>
907 const unsigned char *start;
908 if (addr & 0x01) {
909 /* Function is thumb, the actual address of the code is without the
910 * least significant bit. */
911 addr--;
912 /* The arm part of the trampoline needs to be 32-bit aligned */
913 if (addr & 0x02)
914 start = trampoline;
915 else
916 start = trampoline + 2;
917 } else {
918 /* Function is arm, we only need the arm part of the trampoline */
919 start = trampoline + 6;
922 size_t len = sizeof(trampoline) - (start - trampoline);
923 EnsureWritable w(reinterpret_cast<void *>(addr), len + sizeof(void *));
924 memcpy(reinterpret_cast<void *>(addr), start, len);
925 *reinterpret_cast<void **>(addr + len) = FunctionPtr(new_func);
926 cacheflush(addr, addr + len + sizeof(void *), 0);
927 return true;
928 #else
929 return false;
930 #endif
932 #else
933 #define sys_sigaction sigaction
934 template <typename T>
935 static bool
936 Divert(T func, T new_func)
938 return false;
940 #endif
942 namespace {
944 /* Clock that only accounts for time spent in the current process. */
945 static uint64_t ProcessTimeStamp_Now()
947 struct timespec ts;
948 int rv = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
950 if (rv != 0) {
951 return 0;
954 uint64_t baseNs = (uint64_t)ts.tv_sec * 1000000000;
955 return baseNs + (uint64_t)ts.tv_nsec;
960 /* Data structure used to pass data to the temporary signal handler,
961 * as well as triggering a test crash. */
962 struct TmpData {
963 volatile int crash_int;
964 volatile uint64_t crash_timestamp;
967 SEGVHandler::SEGVHandler()
968 : initialized(false), registeredHandler(false), signalHandlingBroken(true)
969 , signalHandlingSlow(true)
971 /* Initialize oldStack.ss_flags to an invalid value when used to set
972 * an alternative stack, meaning we haven't got information about the
973 * original alternative stack and thus don't mean to restore it in
974 * the destructor. */
975 oldStack.ss_flags = SS_ONSTACK;
977 /* Get the current segfault signal handler. */
978 struct sigaction old_action;
979 sys_sigaction(SIGSEGV, nullptr, &old_action);
981 /* Some devices don't provide useful information to their SIGSEGV handlers,
982 * making it impossible for on-demand decompression to work. To check if
983 * we're on such a device, setup a temporary handler and deliberately
984 * trigger a segfault. The handler will set signalHandlingBroken if the
985 * provided information is bogus.
986 * Some other devices have a kernel option enabled that makes SIGSEGV handler
987 * have an overhead so high that it affects how on-demand decompression
988 * performs. The handler will also set signalHandlingSlow if the triggered
989 * SIGSEGV took too much time. */
990 struct sigaction action;
991 action.sa_sigaction = &SEGVHandler::test_handler;
992 sigemptyset(&action.sa_mask);
993 action.sa_flags = SA_SIGINFO | SA_NODEFER;
994 action.sa_restorer = nullptr;
995 stackPtr.Assign(MemoryRange::mmap(nullptr, PageSize(),
996 PROT_READ | PROT_WRITE,
997 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
998 if (stackPtr.get() == MAP_FAILED)
999 return;
1000 if (sys_sigaction(SIGSEGV, &action, nullptr))
1001 return;
1003 TmpData *data = reinterpret_cast<TmpData*>(stackPtr.get());
1004 data->crash_timestamp = ProcessTimeStamp_Now();
1005 mprotect(stackPtr, stackPtr.GetLength(), PROT_NONE);
1006 data->crash_int = 123;
1007 /* Restore the original segfault signal handler. */
1008 sys_sigaction(SIGSEGV, &old_action, nullptr);
1009 stackPtr.Assign(MAP_FAILED, 0);
1012 void
1013 SEGVHandler::FinishInitialization()
1015 /* Ideally, we'd need some locking here, but in practice, we're not
1016 * going to race with another thread. */
1017 initialized = true;
1019 if (signalHandlingBroken || signalHandlingSlow)
1020 return;
1022 typedef int (*sigaction_func)(int, const struct sigaction *,
1023 struct sigaction *);
1025 sigaction_func libc_sigaction;
1027 #if defined(ANDROID)
1028 /* Android > 4.4 comes with a sigaction wrapper in a LD_PRELOADed library
1029 * (libsigchain) for ART. That wrapper kind of does the same trick as we
1030 * do, so we need extra care in handling it.
1031 * - Divert the libc's sigaction, assuming the LD_PRELOADed library uses
1032 * it under the hood (which is more or less true according to the source
1033 * of that library, since it's doing a lookup in RTLD_NEXT)
1034 * - With the LD_PRELOADed library in place, all calls to sigaction from
1035 * from system libraries will go to the LD_PRELOADed library.
1036 * - The LD_PRELOADed library calls to sigaction go to our __wrap_sigaction.
1037 * - The calls to sigaction from libraries faulty.lib loads are sent to
1038 * the LD_PRELOADed library.
1039 * In practice, for signal handling, this means:
1040 * - The signal handler registered to the kernel is ours.
1041 * - Our handler redispatches to the LD_PRELOADed library's if there's a
1042 * segfault we don't handle.
1043 * - The LD_PRELOADed library redispatches according to whatever system
1044 * library or faulty.lib-loaded library set with sigaction.
1046 * When there is no sigaction wrapper in place:
1047 * - Divert the libc's sigaction.
1048 * - Calls to sigaction from system library and faulty.lib-loaded libraries
1049 * all go to the libc's sigaction, which end up in our __wrap_sigaction.
1050 * - The signal handler registered to the kernel is ours.
1051 * - Our handler redispatches according to whatever system library or
1052 * faulty.lib-loaded library set with sigaction.
1054 void *libc = dlopen("libc.so", RTLD_GLOBAL | RTLD_LAZY);
1055 if (libc) {
1056 libc_sigaction =
1057 reinterpret_cast<sigaction_func>(dlsym(libc, "sigaction"));
1058 } else
1059 #endif
1061 libc_sigaction = sigaction;
1064 if (!Divert(libc_sigaction, __wrap_sigaction))
1065 return;
1067 /* Setup an alternative stack if the already existing one is not big
1068 * enough, or if there is none. */
1069 if (sigaltstack(nullptr, &oldStack) == 0) {
1070 if (oldStack.ss_flags == SS_ONSTACK)
1071 oldStack.ss_flags = 0;
1072 if (!oldStack.ss_sp || oldStack.ss_size < stackSize) {
1073 stackPtr.Assign(MemoryRange::mmap(nullptr, stackSize,
1074 PROT_READ | PROT_WRITE,
1075 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
1076 if (stackPtr.get() == MAP_FAILED)
1077 return;
1078 stack_t stack;
1079 stack.ss_sp = stackPtr;
1080 stack.ss_size = stackSize;
1081 stack.ss_flags = 0;
1082 if (sigaltstack(&stack, nullptr) != 0)
1083 return;
1086 /* Register our own handler, and store the already registered one in
1087 * SEGVHandler's struct sigaction member */
1088 action.sa_sigaction = &SEGVHandler::handler;
1089 action.sa_flags = SA_SIGINFO | SA_NODEFER | SA_ONSTACK;
1090 registeredHandler = !sys_sigaction(SIGSEGV, &action, &this->action);
1093 SEGVHandler::~SEGVHandler()
1095 /* Restore alternative stack for signals */
1096 if (oldStack.ss_flags != SS_ONSTACK)
1097 sigaltstack(&oldStack, nullptr);
1098 /* Restore original signal handler */
1099 if (registeredHandler)
1100 sys_sigaction(SIGSEGV, &this->action, nullptr);
1103 /* Test handler for a deliberately triggered SIGSEGV that determines whether
1104 * useful information is provided to signal handlers, particularly whether
1105 * si_addr is filled in properly, and whether the segfault handler is called
1106 * quickly enough. */
1107 void SEGVHandler::test_handler(int signum, siginfo_t *info, void *context)
1109 SEGVHandler &that = ElfLoader::Singleton;
1110 if (signum == SIGSEGV && info &&
1111 info->si_addr == that.stackPtr.get())
1112 that.signalHandlingBroken = false;
1113 mprotect(that.stackPtr, that.stackPtr.GetLength(), PROT_READ | PROT_WRITE);
1114 TmpData *data = reinterpret_cast<TmpData*>(that.stackPtr.get());
1115 uint64_t latency = ProcessTimeStamp_Now() - data->crash_timestamp;
1116 DEBUG_LOG("SEGVHandler latency: %" PRIu64, latency);
1117 /* See bug 886736 for timings on different devices, 150 µs is reasonably above
1118 * the latency on "working" devices and seems to be short enough to not incur
1119 * a huge overhead to on-demand decompression. */
1120 if (latency <= 150000)
1121 that.signalHandlingSlow = false;
1124 /* TODO: "properly" handle signal masks and flags */
1125 void SEGVHandler::handler(int signum, siginfo_t *info, void *context)
1127 //ASSERT(signum == SIGSEGV);
1128 DEBUG_LOG("Caught segmentation fault @%p", info->si_addr);
1130 /* Check whether we segfaulted in the address space of a CustomElf. We're
1131 * only expecting that to happen as an access error. */
1132 if (info->si_code == SEGV_ACCERR) {
1133 mozilla::RefPtr<LibHandle> handle =
1134 ElfLoader::Singleton.GetHandleByPtr(info->si_addr);
1135 if (handle && !handle->IsSystemElf()) {
1136 DEBUG_LOG("Within the address space of a CustomElf");
1137 CustomElf *elf = static_cast<CustomElf *>(static_cast<LibHandle *>(handle));
1138 if (elf->mappable->ensure(info->si_addr))
1139 return;
1143 /* Redispatch to the registered handler */
1144 SEGVHandler &that = ElfLoader::Singleton;
1145 if (that.action.sa_flags & SA_SIGINFO) {
1146 DEBUG_LOG("Redispatching to registered handler @%p",
1147 FunctionPtr(that.action.sa_sigaction));
1148 that.action.sa_sigaction(signum, info, context);
1149 } else if (that.action.sa_handler == SIG_DFL) {
1150 DEBUG_LOG("Redispatching to default handler");
1151 /* Reset the handler to the default one, and trigger it. */
1152 sys_sigaction(signum, &that.action, nullptr);
1153 raise(signum);
1154 } else if (that.action.sa_handler != SIG_IGN) {
1155 DEBUG_LOG("Redispatching to registered handler @%p",
1156 FunctionPtr(that.action.sa_handler));
1157 that.action.sa_handler(signum);
1158 } else {
1159 DEBUG_LOG("Ignoring");
1164 SEGVHandler::__wrap_sigaction(int signum, const struct sigaction *act,
1165 struct sigaction *oldact)
1167 SEGVHandler &that = ElfLoader::Singleton;
1169 /* Use system sigaction() function for all but SIGSEGV signals. */
1170 if (!that.registeredHandler || (signum != SIGSEGV))
1171 return sys_sigaction(signum, act, oldact);
1173 if (oldact)
1174 *oldact = that.action;
1175 if (act)
1176 that.action = *act;
1177 return 0;
1180 Logging Logging::Singleton;