Wed, 31 Dec 2014 06:09:35 +0100
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
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "shared-libraries.h"
7 #define PATH_MAX_TOSTRING(x) #x
8 #define PATH_MAX_STRING(x) PATH_MAX_TOSTRING(x)
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <limits.h>
13 #include <unistd.h>
14 #include <fstream>
15 #include "platform.h"
16 #include "shared-libraries.h"
18 #if !defined(MOZ_WIDGET_GONK)
19 // TODO fix me with proper include
20 #include "nsDebug.h"
21 #ifdef ANDROID
22 #include "ElfLoader.h" // dl_phdr_info
23 #else
24 #include <link.h> // dl_phdr_info
25 #endif
26 #include <features.h>
27 #include <dlfcn.h>
28 #include <sys/types.h>
30 #ifdef ANDROID
31 extern "C" __attribute__((weak))
32 int dl_iterate_phdr(
33 int (*callback) (struct dl_phdr_info *info,
34 size_t size, void *data),
35 void *data);
36 #endif
38 int dl_iterate_callback(struct dl_phdr_info *dl_info, size_t size, void *data)
39 {
40 SharedLibraryInfo& info = *reinterpret_cast<SharedLibraryInfo*>(data);
42 if (dl_info->dlpi_phnum <= 0)
43 return 0;
45 unsigned long libStart = -1;
46 unsigned long libEnd = 0;
48 for (size_t i = 0; i < dl_info->dlpi_phnum; i++) {
49 if (dl_info->dlpi_phdr[i].p_type != PT_LOAD) {
50 continue;
51 }
52 unsigned long start = dl_info->dlpi_addr + dl_info->dlpi_phdr[i].p_vaddr;
53 unsigned long end = start + dl_info->dlpi_phdr[i].p_memsz;
54 if (start < libStart)
55 libStart = start;
56 if (end > libEnd)
57 libEnd = end;
58 }
59 SharedLibrary shlib(libStart, libEnd, 0, "", dl_info->dlpi_name);
60 info.AddSharedLibrary(shlib);
62 return 0;
63 }
64 #endif
66 SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf()
67 {
68 SharedLibraryInfo info;
70 #if !defined(MOZ_WIDGET_GONK)
71 dl_iterate_phdr(dl_iterate_callback, &info);
72 #ifndef ANDROID
73 return info;
74 #endif
75 #endif
77 pid_t pid = getpid();
78 char path[PATH_MAX];
79 snprintf(path, PATH_MAX, "/proc/%d/maps", pid);
80 std::ifstream maps(path);
81 std::string line;
82 int count = 0;
83 while (std::getline(maps, line)) {
84 int ret;
85 //XXX: needs input sanitizing
86 unsigned long start;
87 unsigned long end;
88 char perm[6] = "";
89 unsigned long offset;
90 char name[PATH_MAX] = "";
91 ret = sscanf(line.c_str(),
92 "%lx-%lx %6s %lx %*s %*x %" PATH_MAX_STRING(PATH_MAX) "s\n",
93 &start, &end, perm, &offset, name);
94 if (!strchr(perm, 'x')) {
95 // Ignore non executable entries
96 continue;
97 }
98 if (ret != 5 && ret != 4) {
99 LOG("Get maps line failed");
100 continue;
101 }
102 #if defined(ANDROID) && !defined(MOZ_WIDGET_GONK)
103 // Use proc/pid/maps to get the dalvik-jit section since it has
104 // no associated phdrs
105 if (strcmp(name, "/dev/ashmem/dalvik-jit-code-cache") != 0)
106 continue;
107 #else
108 if (strcmp(perm, "r-xp") != 0) {
109 // Ignore entries that are writable and/or shared.
110 // At least one graphics driver uses short-lived "rwxs" mappings
111 // (see bug 926734 comment 5), so just checking for 'x' isn't enough.
112 continue;
113 }
114 #endif
115 SharedLibrary shlib(start, end, offset, "", name);
116 info.AddSharedLibrary(shlib);
117 if (count > 10000) {
118 LOG("Get maps failed");
119 break;
120 }
121 count++;
122 }
123 return info;
124 }