Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel Schulhof <gabriel.schulhof@intel.com>2020-03-13 07:02:46 +0300
committerMyles Borins <mylesborins@google.com>2020-03-24 09:55:06 +0300
commitc00ce7b7088d6f8af79dab2d832ce60c7351690d (patch)
tree481710abd231952e62aa5c74931fe4a6511cadd0 /src/large_pages
parentdf1d4f708ff029a977be81181be211ba8455a7b0 (diff)
src: find .text section using dl_iterate_phdr
Use `dl_iterate_phdr(3)` to find the mapping containing `__node_text_start` instead of parsing `/proc/self/maps`. Signed-off-by: Gabriel Schulhof <gabriel.schulhof@intel.com> Co-Authored-By: Ben Noordhuis <info@bnoordhuis.nl> PR-URL: https://github.com/nodejs/node/pull/32244 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: David Carlier <devnexen@gmail.com>
Diffstat (limited to 'src/large_pages')
-rw-r--r--src/large_pages/node_large_page.cc120
1 files changed, 57 insertions, 63 deletions
diff --git a/src/large_pages/node_large_page.cc b/src/large_pages/node_large_page.cc
index 31d85c1734a..e3972f52559 100644
--- a/src/large_pages/node_large_page.cc
+++ b/src/large_pages/node_large_page.cc
@@ -29,7 +29,12 @@
#include "util.h"
#include "uv.h"
-#include <fcntl.h> // _O_RDWR
+#if defined(__linux__)
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <link.h>
+#endif
#include <sys/types.h>
#include <sys/mman.h>
#if defined(__FreeBSD__)
@@ -38,19 +43,17 @@
#elif defined(__APPLE__)
#include <mach/vm_map.h>
#endif
-#include <unistd.h> // readlink
+#include <unistd.h> // getpid
#include <climits> // PATH_MAX
#include <clocale>
#include <csignal>
-#include <cstdio>
#include <cstdlib>
#include <cstdint>
#include <cstring>
#include <string>
#include <fstream>
#include <iostream>
-#include <sstream>
#include <vector>
// 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) {
return ((addr) & ~((hps) - 1));
}
-// The format of the maps file is the following
-// address perms offset dev inode pathname
-// 00400000-00452000 r-xp 00000000 08:02 173521 /usr/bin/dbus-daemon
-// This is also handling the case where the first line is not the binary.
+struct dl_iterate_params {
+ uintptr_t start;
+ uintptr_t end;
+ uintptr_t reference_sym;
+};
+
+#if defined(__linux__)
+int FindMapping(struct dl_phdr_info* info, size_t, void* data) {
+ if (info->dlpi_name[0] == 0) {
+ for (int idx = 0; idx < info->dlpi_phnum; idx++) {
+ const ElfW(Phdr)* phdr = &info->dlpi_phdr[idx];
+ if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X)) {
+ auto dl_params = static_cast<dl_iterate_params*>(data);
+ uintptr_t start = info->dlpi_addr + phdr->p_vaddr;
+ uintptr_t end = start + phdr->p_memsz;
+
+ if (dl_params->reference_sym >= start &&
+ dl_params->reference_sym <= end) {
+ dl_params->start = start;
+ dl_params->end = end;
+ return 1;
+ }
+ }
+ }
+ }
+ return 0;
+}
+#endif // defined(__linux__)
struct text_region FindNodeTextRegion() {
struct text_region nregion;
nregion.found_text_region = false;
#if defined(__linux__)
- std::ifstream ifs;
- std::string map_line;
- std::string permission;
- std::string dev;
- char dash;
- uintptr_t start, end, offset, inode;
- uintptr_t node_text_start = reinterpret_cast<uintptr_t>(&__node_text_start);
+ dl_iterate_params dl_params = {
+ 0, 0, reinterpret_cast<uintptr_t>(&__node_text_start)
+ };
uintptr_t lpstub_start = reinterpret_cast<uintptr_t>(&__start_lpstub);
- ifs.open("/proc/self/maps");
- if (!ifs) {
- PrintWarning("could not open /proc/self/maps");
- return nregion;
- }
-
- while (std::getline(ifs, map_line)) {
- std::istringstream iss(map_line);
- iss >> std::hex >> start;
- iss >> dash;
- iss >> std::hex >> end;
- iss >> permission;
- iss >> offset;
- iss >> dev;
- iss >> inode;
-
- if (inode == 0)
- continue;
-
- std::string pathname;
- iss >> pathname;
-
- if (permission != "r-xp")
- continue;
-
- if (node_text_start < start || node_text_start >= end)
- continue;
-
- start = node_text_start;
- if (lpstub_start > start && lpstub_start <= end)
- end = lpstub_start;
-
- char* from = reinterpret_cast<char*>(hugepage_align_up(start));
- char* to = reinterpret_cast<char*>(hugepage_align_down(end));
-
- if (from >= to)
- break;
-
- size_t size = to - from;
- nregion.found_text_region = true;
- nregion.from = from;
- nregion.to = to;
- nregion.total_hugepages = size / hps;
-
- break;
+ if (dl_iterate_phdr(FindMapping, &dl_params) == 1) {
+ dl_params.start = dl_params.reference_sym;
+ if (lpstub_start > dl_params.start && lpstub_start <= dl_params.end)
+ dl_params.end = lpstub_start;
+
+ if (dl_params.start < dl_params.end) {
+ char* from = reinterpret_cast<char*>(hugepage_align_up(dl_params.start));
+ char* to = reinterpret_cast<char*>(hugepage_align_down(dl_params.end));
+ if (from < to) {
+ size_t pagecount = (to - from) / hps;
+ if (pagecount > 0) {
+ nregion.found_text_region = true;
+ nregion.from = from;
+ nregion.to = to;
+ nregion.total_hugepages = pagecount;
+ }
+ }
+ }
}
-
- ifs.close();
#elif defined(__FreeBSD__)
std::string exename;
{
@@ -289,7 +283,7 @@ bool IsTransparentHugePagesEnabled() {
return always == "[always]" || madvise == "[madvise]";
}
#elif defined(__FreeBSD__)
-static bool IsSuperPagesEnabled() {
+bool IsSuperPagesEnabled() {
// It is enabled by default on amd64.
unsigned int super_pages = 0;
size_t super_pages_length = sizeof(super_pages);