diff --git a/node.gyp b/node.gyp index 0274f198934409..8afa563c6a6225 100644 --- a/node.gyp +++ b/node.gyp @@ -311,6 +311,19 @@ }, 'targets': [ + { + 'target_name': 'node_text_start', + 'type': 'none', + 'conditions': [ + [ 'OS=="linux" and ' + 'target_arch=="x64"', { + 'type': 'static_library', + 'sources': [ + 'src/large_pages/node_text_start.S' + ] + }], + ] + }, { 'target_name': '<(node_core_target_name)', 'type': 'executable', @@ -496,6 +509,13 @@ 'src/node_snapshot_stub.cc' ], }], + [ 'OS=="linux" and ' + 'target_arch=="x64"', { + 'dependencies': [ 'node_text_start' ], + 'ldflags+': [ + '<(PRODUCT_DIR)/obj.target/node_text_start/src/large_pages/node_text_start.o' + ] + }], ], }, # node_core_target_name { diff --git a/src/large_pages/node_large_page.cc b/src/large_pages/node_large_page.cc index a72cb65bb65674..31d85c1734a63c 100644 --- a/src/large_pages/node_large_page.cc +++ b/src/large_pages/node_large_page.cc @@ -71,7 +71,11 @@ #if defined(__linux__) extern "C" { -extern char __executable_start; +// This symbol must be declared weak because this file becomes part of all +// Node.js targets (like node_mksnapshot, node_mkcodecache, and cctest) and +// those files do not supply the symbol. +extern char __attribute__((weak)) __node_text_start; +extern char __start_lpstub; } // extern "C" #endif // defined(__linux__) @@ -121,6 +125,8 @@ struct text_region FindNodeTextRegion() { std::string dev; char dash; uintptr_t start, end, offset, inode; + uintptr_t node_text_start = reinterpret_cast(&__node_text_start); + uintptr_t lpstub_start = reinterpret_cast(&__start_lpstub); ifs.open("/proc/self/maps"); if (!ifs) { @@ -144,21 +150,15 @@ struct text_region FindNodeTextRegion() { std::string pathname; iss >> pathname; - if (start != reinterpret_cast(&__executable_start)) + if (permission != "r-xp") continue; - // The next line is our .text section. - if (!std::getline(ifs, map_line)) - break; - - iss = std::istringstream(map_line); - iss >> std::hex >> start; - iss >> dash; - iss >> std::hex >> end; - iss >> permission; + if (node_text_start < start || node_text_start >= end) + continue; - if (permission != "r-xp") - break; + start = node_text_start; + if (lpstub_start > start && lpstub_start <= end) + end = lpstub_start; char* from = reinterpret_cast(hugepage_align_up(start)); char* to = reinterpret_cast(hugepage_align_down(end)); @@ -318,7 +318,7 @@ static bool IsSuperPagesEnabled() { // d. If successful copy the code there and unmap the original region int #if !defined(__APPLE__) -__attribute__((__section__(".lpstub"))) +__attribute__((__section__("lpstub"))) #else __attribute__((__section__("__TEXT,__lpstub"))) #endif diff --git a/src/large_pages/node_text_start.S b/src/large_pages/node_text_start.S new file mode 100644 index 00000000000000..1609b254f0495a --- /dev/null +++ b/src/large_pages/node_text_start.S @@ -0,0 +1,5 @@ +.text +.align 0x2000 +.global __node_text_start +.hidden __node_text_start +__node_text_start: