diff --git a/node.gyp b/node.gyp index 409ea60c5a2d5c..463e990a1e0947 100644 --- a/node.gyp +++ b/node.gyp @@ -230,6 +230,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', @@ -310,6 +323,13 @@ # the executable and rename it back to node.exe later 'product_name': '<(node_core_target_name)-win', }], + [ '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 41d1e8f7a11b8e..190133ed4a2a3a 100644 --- a/src/large_pages/node_large_page.cc +++ b/src/large_pages/node_large_page.cc @@ -79,7 +79,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__) @@ -129,6 +133,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) { @@ -152,21 +158,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)); @@ -326,7 +326,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: