|
29 | 29 | #include"util.h" |
30 | 30 | #include"uv.h" |
31 | 31 |
|
32 | | -#include<fcntl.h>// _O_RDWR |
| 32 | +#if defined(__linux__) |
| 33 | +#ifndef _GNU_SOURCE |
| 34 | +#define_GNU_SOURCE |
| 35 | +#endif |
| 36 | +#include<link.h> |
| 37 | +#endif |
33 | 38 | #include<sys/types.h> |
34 | 39 | #include<sys/mman.h> |
35 | 40 | #if defined(__FreeBSD__) |
|
38 | 43 | #elif defined(__APPLE__) |
39 | 44 | #include<mach/vm_map.h> |
40 | 45 | #endif |
41 | | -#include<unistd.h>//readlink |
| 46 | +#include<unistd.h>//getpid |
42 | 47 |
|
43 | 48 | #include<climits>// PATH_MAX |
44 | 49 | #include<clocale> |
45 | 50 | #include<csignal> |
46 | | -#include<cstdio> |
47 | 51 | #include<cstdlib> |
48 | 52 | #include<cstdint> |
49 | 53 | #include<cstring> |
50 | 54 | #include<string> |
51 | 55 | #include<fstream> |
52 | 56 | #include<iostream> |
53 | | -#include<sstream> |
54 | 57 | #include<vector> |
55 | 58 |
|
56 | 59 | // The functions in this file map the text segment of node into 2M pages. |
@@ -110,72 +113,63 @@ inline uintptr_t hugepage_align_down(uintptr_t addr) { |
110 | 113 | return ((addr) & ~((hps) - 1)); |
111 | 114 | } |
112 | 115 |
|
113 | | -// The format of the maps file is the following |
114 | | -// address perms offset dev inode pathname |
115 | | -// 00400000-00452000 r-xp 00000000 08:02 173521 /usr/bin/dbus-daemon |
116 | | -// This is also handling the case where the first line is not the binary. |
| 116 | +structdl_iterate_params { |
| 117 | +uintptr_t start; |
| 118 | +uintptr_t end; |
| 119 | +uintptr_t reference_sym; |
| 120 | +}; |
| 121 | + |
| 122 | +#if defined(__linux__) |
| 123 | +intFindMapping(structdl_phdr_info* info, size_t, void* data) { |
| 124 | +if (info->dlpi_name[0] == 0) { |
| 125 | +for (int idx = 0; idx < info->dlpi_phnum; idx++) { |
| 126 | +constElfW(Phdr)* phdr = &info->dlpi_phdr[idx]; |
| 127 | +if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X)) { |
| 128 | +auto dl_params = static_cast<dl_iterate_params*>(data); |
| 129 | +uintptr_t start = info->dlpi_addr + phdr->p_vaddr; |
| 130 | +uintptr_t end = start + phdr->p_memsz; |
| 131 | + |
| 132 | +if (dl_params->reference_sym >= start && |
| 133 | + dl_params->reference_sym <= end) { |
| 134 | + dl_params->start = start; |
| 135 | + dl_params->end = end; |
| 136 | +return1; |
| 137 | + } |
| 138 | + } |
| 139 | + } |
| 140 | + } |
| 141 | +return0; |
| 142 | +} |
| 143 | +#endif// defined(__linux__) |
117 | 144 |
|
118 | 145 | structtext_regionFindNodeTextRegion() { |
119 | 146 | structtext_region nregion; |
120 | 147 | nregion.found_text_region = false; |
121 | 148 | #if defined(__linux__) |
122 | | - std::ifstream ifs; |
123 | | - std::string map_line; |
124 | | - std::string permission; |
125 | | - std::string dev; |
126 | | -char dash; |
127 | | -uintptr_t start, end, offset, inode; |
128 | | -uintptr_t node_text_start = reinterpret_cast<uintptr_t>(&__node_text_start); |
| 149 | + dl_iterate_params dl_params = { |
| 150 | +0, 0, reinterpret_cast<uintptr_t>(&__node_text_start) |
| 151 | + }; |
129 | 152 | uintptr_t lpstub_start = reinterpret_cast<uintptr_t>(&__start_lpstub); |
130 | 153 |
|
131 | | - ifs.open("/proc/self/maps"); |
132 | | -if (!ifs) { |
133 | | -PrintWarning("could not open /proc/self/maps"); |
134 | | -return nregion; |
135 | | - } |
136 | | - |
137 | | -while (std::getline(ifs, map_line)) { |
138 | | - std::istringstream iss(map_line); |
139 | | - iss >> std::hex >> start; |
140 | | - iss >> dash; |
141 | | - iss >> std::hex >> end; |
142 | | - iss >> permission; |
143 | | - iss >> offset; |
144 | | - iss >> dev; |
145 | | - iss >> inode; |
146 | | - |
147 | | -if (inode == 0) |
148 | | -continue; |
149 | | - |
150 | | - std::string pathname; |
151 | | - iss >> pathname; |
152 | | - |
153 | | -if (permission != "r-xp") |
154 | | -continue; |
155 | | - |
156 | | -if (node_text_start < start || node_text_start >= end) |
157 | | -continue; |
158 | | - |
159 | | - start = node_text_start; |
160 | | -if (lpstub_start > start && lpstub_start <= end) |
161 | | - end = lpstub_start; |
162 | | - |
163 | | -char* from = reinterpret_cast<char*>(hugepage_align_up(start)); |
164 | | -char* to = reinterpret_cast<char*>(hugepage_align_down(end)); |
165 | | - |
166 | | -if (from >= to) |
167 | | -break; |
168 | | - |
169 | | -size_t size = to - from; |
170 | | - nregion.found_text_region = true; |
171 | | - nregion.from = from; |
172 | | - nregion.to = to; |
173 | | - nregion.total_hugepages = size / hps; |
174 | | - |
175 | | -break; |
| 154 | +if (dl_iterate_phdr(FindMapping, &dl_params) == 1) { |
| 155 | + dl_params.start = dl_params.reference_sym; |
| 156 | +if (lpstub_start > dl_params.start && lpstub_start <= dl_params.end) |
| 157 | + dl_params.end = lpstub_start; |
| 158 | + |
| 159 | +if (dl_params.start < dl_params.end) { |
| 160 | +char* from = reinterpret_cast<char*>(hugepage_align_up(dl_params.start)); |
| 161 | +char* to = reinterpret_cast<char*>(hugepage_align_down(dl_params.end)); |
| 162 | +if (from < to) { |
| 163 | +size_t pagecount = (to - from) / hps; |
| 164 | +if (pagecount > 0) { |
| 165 | + nregion.found_text_region = true; |
| 166 | + nregion.from = from; |
| 167 | + nregion.to = to; |
| 168 | + nregion.total_hugepages = pagecount; |
| 169 | + } |
| 170 | + } |
| 171 | + } |
176 | 172 | } |
177 | | - |
178 | | - ifs.close(); |
179 | 173 | #elif defined(__FreeBSD__) |
180 | 174 | std::string exename; |
181 | 175 | { |
@@ -289,7 +283,7 @@ bool IsTransparentHugePagesEnabled() { |
289 | 283 | return always == "[always]" || madvise == "[madvise]"; |
290 | 284 | } |
291 | 285 | #elif defined(__FreeBSD__) |
292 | | -staticboolIsSuperPagesEnabled() { |
| 286 | +boolIsSuperPagesEnabled() { |
293 | 287 | // It is enabled by default on amd64. |
294 | 288 | unsignedint super_pages = 0; |
295 | 289 | size_t super_pages_length = sizeof(super_pages); |
|
0 commit comments