mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-14 15:37:55 +00:00
3fe1d51986
Note that we don't want this extra check on regular Android, because there's Dalvik jitcode in ashmem, and any mappings that aren't that special ashmem file will already be excluded (because everything else is handled through dl_iterate_phdr).
125 lines
3.2 KiB
C++
125 lines
3.2 KiB
C++
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "shared-libraries.h"
|
|
|
|
#define PATH_MAX_TOSTRING(x) #x
|
|
#define PATH_MAX_STRING(x) PATH_MAX_TOSTRING(x)
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <limits.h>
|
|
#include <unistd.h>
|
|
#include <fstream>
|
|
#include "platform.h"
|
|
#include "shared-libraries.h"
|
|
|
|
#if !defined(MOZ_WIDGET_GONK)
|
|
// TODO fix me with proper include
|
|
#include "nsDebug.h"
|
|
#ifdef ANDROID
|
|
#include "ElfLoader.h" // dl_phdr_info
|
|
#else
|
|
#include <link.h> // dl_phdr_info
|
|
#endif
|
|
#include <features.h>
|
|
#include <dlfcn.h>
|
|
#include <sys/types.h>
|
|
|
|
#ifdef ANDROID
|
|
extern "C" __attribute__((weak))
|
|
int dl_iterate_phdr(
|
|
int (*callback) (struct dl_phdr_info *info,
|
|
size_t size, void *data),
|
|
void *data);
|
|
#endif
|
|
|
|
int dl_iterate_callback(struct dl_phdr_info *dl_info, size_t size, void *data)
|
|
{
|
|
SharedLibraryInfo& info = *reinterpret_cast<SharedLibraryInfo*>(data);
|
|
|
|
if (dl_info->dlpi_phnum <= 0)
|
|
return 0;
|
|
|
|
unsigned long libStart = -1;
|
|
unsigned long libEnd = 0;
|
|
|
|
for (size_t i = 0; i < dl_info->dlpi_phnum; i++) {
|
|
if (dl_info->dlpi_phdr[i].p_type != PT_LOAD) {
|
|
continue;
|
|
}
|
|
unsigned long start = dl_info->dlpi_addr + dl_info->dlpi_phdr[i].p_vaddr;
|
|
unsigned long end = start + dl_info->dlpi_phdr[i].p_memsz;
|
|
if (start < libStart)
|
|
libStart = start;
|
|
if (end > libEnd)
|
|
libEnd = end;
|
|
}
|
|
SharedLibrary shlib(libStart, libEnd, 0, "", dl_info->dlpi_name);
|
|
info.AddSharedLibrary(shlib);
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf()
|
|
{
|
|
SharedLibraryInfo info;
|
|
|
|
#if !defined(MOZ_WIDGET_GONK)
|
|
dl_iterate_phdr(dl_iterate_callback, &info);
|
|
#ifndef ANDROID
|
|
return info;
|
|
#endif
|
|
#endif
|
|
|
|
pid_t pid = getpid();
|
|
char path[PATH_MAX];
|
|
snprintf(path, PATH_MAX, "/proc/%d/maps", pid);
|
|
std::ifstream maps(path);
|
|
std::string line;
|
|
int count = 0;
|
|
while (std::getline(maps, line)) {
|
|
int ret;
|
|
//XXX: needs input sanitizing
|
|
unsigned long start;
|
|
unsigned long end;
|
|
char perm[6] = "";
|
|
unsigned long offset;
|
|
char name[PATH_MAX] = "";
|
|
ret = sscanf(line.c_str(),
|
|
"%lx-%lx %6s %lx %*s %*x %" PATH_MAX_STRING(PATH_MAX) "s\n",
|
|
&start, &end, perm, &offset, name);
|
|
if (!strchr(perm, 'x')) {
|
|
// Ignore non executable entries
|
|
continue;
|
|
}
|
|
if (ret != 5 && ret != 4) {
|
|
LOG("Get maps line failed");
|
|
continue;
|
|
}
|
|
#if defined(ANDROID) && !defined(MOZ_WIDGET_GONK)
|
|
// Use proc/pid/maps to get the dalvik-jit section since it has
|
|
// no associated phdrs
|
|
if (strcmp(name, "/dev/ashmem/dalvik-jit-code-cache") != 0)
|
|
continue;
|
|
#else
|
|
if (strcmp(perm, "r-xp") != 0) {
|
|
// Ignore entries that are writable and/or shared.
|
|
// At least one graphics driver uses short-lived "rwxs" mappings
|
|
// (see bug 926734 comment 5), so just checking for 'x' isn't enough.
|
|
continue;
|
|
}
|
|
#endif
|
|
SharedLibrary shlib(start, end, offset, "", name);
|
|
info.AddSharedLibrary(shlib);
|
|
if (count > 10000) {
|
|
LOG("Get maps failed");
|
|
break;
|
|
}
|
|
count++;
|
|
}
|
|
return info;
|
|
}
|