mozglue/linker/ElfLoader.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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);
    30 }
    32 } /* extern "C" */
    33 #endif /* __ANDROID_API__ */
    34 #endif /* ANDROID */
    36 #ifdef __ARM_EABI__
    37 extern "C" 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
    45  */
    47 void *
    48 __wrap_dlopen(const char *path, int flags)
    49 {
    50   RefPtr<LibHandle> handle = ElfLoader::Singleton.Load(path, flags);
    51   if (handle)
    52     handle->AddDirectRef();
    53   return handle;
    54 }
    56 const char *
    57 __wrap_dlerror(void)
    58 {
    59   const char *error = ElfLoader::Singleton.lastError;
    60   ElfLoader::Singleton.lastError = nullptr;
    61   return error;
    62 }
    64 void *
    65 __wrap_dlsym(void *handle, const char *symbol)
    66 {
    67   if (!handle) {
    68     ElfLoader::Singleton.lastError = "dlsym(NULL, sym) unsupported";
    69     return nullptr;
    70   }
    71   if (handle != RTLD_DEFAULT && handle != RTLD_NEXT) {
    72     LibHandle *h = reinterpret_cast<LibHandle *>(handle);
    73     return h->GetSymbolPtr(symbol);
    74   }
    75   return dlsym(handle, symbol);
    76 }
    78 int
    79 __wrap_dlclose(void *handle)
    80 {
    81   if (!handle) {
    82     ElfLoader::Singleton.lastError = "No handle given to dlclose()";
    83     return -1;
    84   }
    85   reinterpret_cast<LibHandle *>(handle)->ReleaseDirectRef();
    86   return 0;
    87 }
    89 int
    90 __wrap_dladdr(void *addr, Dl_info *info)
    91 {
    92   RefPtr<LibHandle> handle = ElfLoader::Singleton.GetHandleByPtr(addr);
    93   if (!handle)
    94     return 0;
    95   info->dli_fname = handle->GetPath();
    96   return 1;
    97 }
    99 int
   100 __wrap_dl_iterate_phdr(dl_phdr_cb callback, void *data)
   101 {
   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;
   123       }
   124     }
   126     int ret = callback(&info, sizeof(dl_phdr_info), data);
   127     if (ret)
   128       return ret;
   129   }
   130   return 0;
   131 }
   133 #ifdef __ARM_EABI__
   134 const void *
   135 __wrap___gnu_Unwind_Find_exidx(void *pc, int *pcount)
   136 {
   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;
   144 }
   145 #endif
   147 /**
   148  * faulty.lib public API
   149  */
   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();
   156 }
   158 MFBT_API void *
   159 __dl_mmap(void *handle, void *addr, size_t length, off_t offset)
   160 {
   161   if (!handle)
   162     return nullptr;
   163   return reinterpret_cast<LibHandle *>(handle)->MappableMMap(addr, length,
   164                                                              offset);
   165 }
   167 MFBT_API void
   168 __dl_munmap(void *handle, void *addr, size_t length)
   169 {
   170   if (!handle)
   171     return;
   172   return reinterpret_cast<LibHandle *>(handle)->MappableMUnmap(addr, length);
   173 }
   175 MFBT_API bool
   176 IsSignalHandlingBroken()
   177 {
   178   return ElfLoader::Singleton.isSignalHandlingBroken();
   179 }
   181 namespace {
   183 /**
   184  * Returns the part after the last '/' for the given path
   185  */
   186 const char *
   187 LeafName(const char *path)
   188 {
   189   const char *lastSlash = strrchr(path, '/');
   190   if (lastSlash)
   191     return lastSlash + 1;
   192   return path;
   193 }
   195 } /* Anonymous namespace */
   197 /**
   198  * LibHandle
   199  */
   200 LibHandle::~LibHandle()
   201 {
   202   free(path);
   203 }
   205 const char *
   206 LibHandle::GetName() const
   207 {
   208   return path ? LeafName(path) : nullptr;
   209 }
   211 size_t
   212 LibHandle::GetMappableLength() const
   213 {
   214   if (!mappable)
   215     mappable = GetMappable();
   216   if (!mappable)
   217     return 0;
   218   return mappable->GetLength();
   219 }
   221 void *
   222 LibHandle::MappableMMap(void *addr, size_t length, off_t offset) const
   223 {
   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);
   233     }
   234   }
   235   return mapped;
   236 }
   238 void
   239 LibHandle::MappableMUnmap(void *addr, size_t length) const
   240 {
   241   if (mappable)
   242     mappable->munmap(addr, length);
   243 }
   245 /**
   246  * SystemElf
   247  */
   248 TemporaryRef<LibHandle>
   249 SystemElf::Load(const char *path, int flags)
   250 {
   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;
   256   }
   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;
   265   }
   266   return nullptr;
   267 }
   269 SystemElf::~SystemElf()
   270 {
   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);
   277 }
   279 void *
   280 SystemElf::GetSymbolPtr(const char *symbol) const
   281 {
   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;
   286 }
   288 Mappable *
   289 SystemElf::GetMappable() const
   290 {
   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();
   302   }
   303 #endif
   305   return MappableFile::Create(path);
   306 }
   308 #ifdef __ARM_EABI__
   309 const void *
   310 SystemElf::FindExidx(int *pcount) const
   311 {
   312   /* TODO: properly implement when ElfLoader::GetHandleByPtr
   313      does return SystemElf handles */
   314   *pcount = 0;
   315   return nullptr;
   316 }
   317 #endif
   319 /**
   320  * ElfLoader
   321  */
   323 /* Unique ElfLoader instance */
   324 ElfLoader ElfLoader::Singleton;
   326 TemporaryRef<LibHandle>
   327 ElfLoader::Load(const char *path, int flags, LibHandle *parent)
   328 {
   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;
   338   }
   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;
   353   }
   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;
   368   }
   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;
   391 }
   393 mozilla::TemporaryRef<LibHandle>
   394 ElfLoader::GetHandleByPtr(void *addr)
   395 {
   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;
   400   }
   401   return nullptr;
   402 }
   404 Mappable *
   405 ElfLoader::GetMappableFromPath(const char *path)
   406 {
   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);
   429         }
   430       }
   431     }
   432   }
   433   /* If we couldn't load above, try with a MappableFile */
   434   if (!mappable && !zip)
   435     mappable = MappableFile::Create(path);
   437   return mappable;
   438 }
   440 void
   441 ElfLoader::Register(LibHandle *handle)
   442 {
   443   handles.push_back(handle);
   444   if (dbg && !handle->IsSystemElf())
   445     dbg.Add(static_cast<CustomElf *>(handle));
   446 }
   448 void
   449 ElfLoader::Forget(LibHandle *handle)
   450 {
   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());
   464   }
   465 }
   467 ElfLoader::~ElfLoader()
   468 {
   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);
   482       }
   483     }
   484   }
   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()) { }
   488   }
   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 */
   505       }
   506     }
   507   }
   508 }
   510 void
   511 ElfLoader::stats(const char *when)
   512 {
   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);
   517 }
   519 #ifdef __ARM_EABI__
   520 int
   521 ElfLoader::__wrap_aeabi_atexit(void *that, ElfLoader::Destructor destructor,
   522                                void *dso_handle)
   523 {
   524   Singleton.destructors.push_back(
   525     DestructorCaller(destructor, that, dso_handle));
   526   return 0;
   527 }
   528 #else
   529 int
   530 ElfLoader::__wrap_cxa_atexit(ElfLoader::Destructor destructor, void *that,
   531                              void *dso_handle)
   532 {
   533   Singleton.destructors.push_back(
   534     DestructorCaller(destructor, that, dso_handle));
   535   return 0;
   536 }
   537 #endif
   539 void
   540 ElfLoader::__wrap_cxa_finalize(void *dso_handle)
   541 {
   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();
   549     }
   550   }
   551 }
   553 void
   554 ElfLoader::DestructorCaller::Call()
   555 {
   556   if (destructor) {
   557     DEBUG_LOG("ElfLoader::DestructorCaller::Call(%p, %p, %p)",
   558               FunctionPtr(destructor), object, dso_handle);
   559     destructor(object);
   560     destructor = nullptr;
   561   }
   562 }
   564 ElfLoader::DebuggerHelper::DebuggerHelper(): dbg(nullptr)
   565 {
   566   /* Find ELF auxiliary vectors.
   567    *
   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
   591    *
   592    * What we are after are the auxv values defined by the following struct.
   593    */
   594   struct AuxVector {
   595     Elf::Addr type;
   596     Elf::Addr value;
   597   };
   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));
   645     }
   646     if (auxv->type == AT_PHNUM)
   647       phdrs.Init(auxv->value);
   648     auxv++;
   649   }
   651   if (!phdrs) {
   652     DEBUG_LOG("Couldn't find program headers");
   653     return;
   654   }
   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;
   669     }
   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;
   676     }
   677   }
   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;
   683   }
   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);
   698   }
   699   if (!dyns) {
   700     DEBUG_LOG("Failed to find PT_DYNAMIC section in program");
   701     return;
   702   }
   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;
   709     }
   710   }
   711   DEBUG_LOG("DT_DEBUG points at %p", static_cast<void *>(dbg));
   712 }
   714 /**
   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.
   718  */
   719 class EnsureWritable
   720 {
   721 public:
   722   template <typename T>
   723   EnsureWritable(T *ptr, size_t length_ = sizeof(T))
   724   {
   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);
   744   }
   746   ~EnsureWritable()
   747   {
   748     if (page != MAP_FAILED) {
   749       mprotect(page, length, prot);
   750 }
   751   }
   753 private:
   754   int getProt(uintptr_t addr, uintptr_t *end)
   755   {
   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;
   781     }
   782     return -1;
   783   }
   785   int prot;
   786   void *page;
   787   size_t length;
   788 };
   790 /**
   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.
   805  */
   806 void
   807 ElfLoader::DebuggerHelper::Add(ElfLoader::link_map *map)
   808 {
   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();
   826 }
   828 void
   829 ElfLoader::DebuggerHelper::Remove(ElfLoader::link_map *map)
   830 {
   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();
   849 }
   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.
   864  */
   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. */
   874 int
   875 sys_sigaction(int signum, const struct sigaction *act,
   876               struct sigaction *oldact)
   877 {
   878   return syscall(__NR_sigaction, signum, act, oldact);
   879 }
   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)
   886 {
   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>
   906   };
   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;
   920   }
   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
   931 }
   932 #else
   933 #define sys_sigaction sigaction
   934 template <typename T>
   935 static bool
   936 Divert(T func, T new_func)
   937 {
   938   return false;
   939 }
   940 #endif
   942 namespace {
   944 /* Clock that only accounts for time spent in the current process. */
   945 static uint64_t ProcessTimeStamp_Now()
   946 {
   947   struct timespec ts;
   948   int rv = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
   950   if (rv != 0) {
   951     return 0;
   952   }
   954   uint64_t baseNs = (uint64_t)ts.tv_sec * 1000000000;
   955   return baseNs + (uint64_t)ts.tv_nsec;
   956 }
   958 }
   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;
   965 };
   967 SEGVHandler::SEGVHandler()
   968 : registeredHandler(false), signalHandlingBroken(false)
   969 , signalHandlingSlow(false)
   970 {
   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 */
   974   oldStack.ss_flags = SS_ONSTACK;
   975   if (!Divert(sigaction, __wrap_sigaction))
   976     return;
   978   /* Get the current segfault signal handler. */
   979   sys_sigaction(SIGSEGV, nullptr, &this->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, &this->action, nullptr);
  1009   stackPtr.Assign(MAP_FAILED, 0);
  1010   if (signalHandlingBroken || signalHandlingSlow)
  1011     return;
  1013   /* Setup an alternative stack if the already existing one is not big
  1014    * enough, or if there is none. */
  1015   if (sigaltstack(nullptr, &oldStack) == 0) {
  1016     if (oldStack.ss_flags == SS_ONSTACK)
  1017       oldStack.ss_flags = 0;
  1018     if (!oldStack.ss_sp || oldStack.ss_size < stackSize) {
  1019       stackPtr.Assign(MemoryRange::mmap(nullptr, stackSize,
  1020                                         PROT_READ | PROT_WRITE,
  1021                                         MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
  1022       if (stackPtr.get() == MAP_FAILED)
  1023         return;
  1024       stack_t stack;
  1025       stack.ss_sp = stackPtr;
  1026       stack.ss_size = stackSize;
  1027       stack.ss_flags = 0;
  1028       if (sigaltstack(&stack, nullptr) != 0)
  1029         return;
  1032   /* Register our own handler, and store the already registered one in
  1033    * SEGVHandler's struct sigaction member */
  1034   action.sa_sigaction = &SEGVHandler::handler;
  1035   action.sa_flags = SA_SIGINFO | SA_NODEFER | SA_ONSTACK;
  1036   registeredHandler = !sys_sigaction(SIGSEGV, &action, nullptr);
  1039 SEGVHandler::~SEGVHandler()
  1041   /* Restore alternative stack for signals */
  1042   if (oldStack.ss_flags != SS_ONSTACK)
  1043     sigaltstack(&oldStack, nullptr);
  1044   /* Restore original signal handler */
  1045   if (registeredHandler)
  1046     sys_sigaction(SIGSEGV, &this->action, nullptr);
  1049 /* Test handler for a deliberately triggered SIGSEGV that determines whether
  1050  * useful information is provided to signal handlers, particularly whether
  1051  * si_addr is filled in properly, and whether the segfault handler is called
  1052  * quickly enough. */
  1053 void SEGVHandler::test_handler(int signum, siginfo_t *info, void *context)
  1055   SEGVHandler &that = ElfLoader::Singleton;
  1056   if (signum != SIGSEGV ||
  1057       info == nullptr || info->si_addr != that.stackPtr.get())
  1058     that.signalHandlingBroken = true;
  1059   mprotect(that.stackPtr, that.stackPtr.GetLength(), PROT_READ | PROT_WRITE);
  1060   TmpData *data = reinterpret_cast<TmpData*>(that.stackPtr.get());
  1061   uint64_t latency = ProcessTimeStamp_Now() - data->crash_timestamp;
  1062   DEBUG_LOG("SEGVHandler latency: %" PRIu64, latency);
  1063   /* See bug 886736 for timings on different devices, 150 µs is reasonably above
  1064    * the latency on "working" devices and seems to be reasonably fast to incur
  1065    * a huge overhead to on-demand decompression. */
  1066   if (latency > 150000)
  1067     that.signalHandlingSlow = true;
  1070 /* TODO: "properly" handle signal masks and flags */
  1071 void SEGVHandler::handler(int signum, siginfo_t *info, void *context)
  1073   //ASSERT(signum == SIGSEGV);
  1074   DEBUG_LOG("Caught segmentation fault @%p", info->si_addr);
  1076   /* Check whether we segfaulted in the address space of a CustomElf. We're
  1077    * only expecting that to happen as an access error. */
  1078   if (info->si_code == SEGV_ACCERR) {
  1079     mozilla::RefPtr<LibHandle> handle =
  1080       ElfLoader::Singleton.GetHandleByPtr(info->si_addr);
  1081     if (handle && !handle->IsSystemElf()) {
  1082       DEBUG_LOG("Within the address space of a CustomElf");
  1083       CustomElf *elf = static_cast<CustomElf *>(static_cast<LibHandle *>(handle));
  1084       if (elf->mappable->ensure(info->si_addr))
  1085         return;
  1089   /* Redispatch to the registered handler */
  1090   SEGVHandler &that = ElfLoader::Singleton;
  1091   if (that.action.sa_flags & SA_SIGINFO) {
  1092     DEBUG_LOG("Redispatching to registered handler @%p",
  1093               FunctionPtr(that.action.sa_sigaction));
  1094     that.action.sa_sigaction(signum, info, context);
  1095   } else if (that.action.sa_handler == SIG_DFL) {
  1096     DEBUG_LOG("Redispatching to default handler");
  1097     /* Reset the handler to the default one, and trigger it. */
  1098     sys_sigaction(signum, &that.action, nullptr);
  1099     raise(signum);
  1100   } else if (that.action.sa_handler != SIG_IGN) {
  1101     DEBUG_LOG("Redispatching to registered handler @%p",
  1102               FunctionPtr(that.action.sa_handler));
  1103     that.action.sa_handler(signum);
  1104   } else {
  1105     DEBUG_LOG("Ignoring");
  1109 int
  1110 SEGVHandler::__wrap_sigaction(int signum, const struct sigaction *act,
  1111                               struct sigaction *oldact)
  1113   SEGVHandler &that = ElfLoader::Singleton;
  1115   /* Use system sigaction() function for all but SIGSEGV signals. */
  1116   if (!that.registeredHandler || (signum != SIGSEGV))
  1117     return sys_sigaction(signum, act, oldact);
  1119   if (oldact)
  1120     *oldact = that.action;
  1121   if (act)
  1122     that.action = *act;
  1123   return 0;
  1126 Logging Logging::Singleton;

mercurial