From 5ea3d60db1793c81a1bbbd957fe87184e8d1b7ab Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Tue, 28 Jan 2020 11:01:32 +0100 Subject: [PATCH] src: use __executable_start for linux hugepages `__executable_start` is provided by GNU's and LLVM's default linker scripts, obviating the need to plug in a custom linker script. The problem with our bespoke linker script is that it works with ld.bfd but not ld.gold and cannot easily be ported because the latter linker doesn't understand the `INSERT BEFORE` directive. The /proc/self/maps scanner is updated to account for the fact that there are a number of sections between `&__executable_start` and the start of the .text section. Fortunately, those sections are all mapped into the same memory segment so we only need to look at the next line to find the start of our text segment. Fixes: https://github.com/nodejs/node/issues/31520 Backport-PR-URL: https://github.com/nodejs/node/pull/32092 PR-URL: https://github.com/nodejs/node/pull/31547 Reviewed-By: Anna Henningsen Reviewed-By: Gus Caplan Reviewed-By: James M Snell Reviewed-By: Rich Trott Reviewed-By: David Carlier --- node.gyp | 3 +- node.gypi | 16 ----- src/large_pages/ld.implicit.script | 10 ---- src/large_pages/ld.implicit.script.lld | 3 - src/large_pages/node_large_page.cc | 83 ++++++++++++++------------ 5 files changed, 47 insertions(+), 68 deletions(-) delete mode 100644 src/large_pages/ld.implicit.script delete mode 100644 src/large_pages/ld.implicit.script.lld diff --git a/node.gyp b/node.gyp index 6f0a95781ef67f..7b80676e4368d8 100644 --- a/node.gyp +++ b/node.gyp @@ -854,7 +854,8 @@ ], }], [ 'OS in "linux freebsd mac" and ' - 'target_arch=="x64"', { + 'target_arch=="x64" and ' + 'node_target_type=="executable"', { 'defines': [ 'NODE_ENABLE_LARGE_CODE_PAGES=1' ], 'sources': [ 'src/large_pages/node_large_page.cc', diff --git a/node.gypi b/node.gypi index a22800af0903ce..116c1c7149425b 100644 --- a/node.gypi +++ b/node.gypi @@ -317,22 +317,6 @@ 'ldflags': [ '-Wl,-z,relro', '-Wl,-z,now' ] }], - [ 'OS=="linux" and ' - 'target_arch=="x64" and ' - 'llvm_version=="0.0"', { - 'ldflags': [ - '-Wl,-T', - '> std::hex >> start; @@ -136,26 +129,42 @@ static struct text_region FindNodeTextRegion() { iss >> offset; iss >> dev; iss >> inode; - if (inode != 0) { - std::string pathname; - iss >> pathname; - if (pathname == exename && permission == "r-xp") { - uintptr_t ntext = reinterpret_cast(&__nodetext); - if (ntext >= start && ntext < end) { - char* from = reinterpret_cast(hugepage_align_up(ntext)); - char* to = reinterpret_cast(hugepage_align_down(end)); - - if (from < to) { - size_t size = to - from; - nregion.found_text_region = true; - nregion.from = from; - nregion.to = to; - nregion.total_hugepages = size / hps; - } - break; - } - } - } + + if (inode == 0) + continue; + + std::string pathname; + iss >> pathname; + + if (start != reinterpret_cast(&__executable_start)) + 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 (permission != "r-xp") + break; + + char* from = reinterpret_cast(hugepage_align_up(start)); + char* to = reinterpret_cast(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; } ifs.close(); @@ -408,14 +417,12 @@ int MapStaticCodeToLargePages() { return -1; } -#if defined(__linux__) || defined(__FreeBSD__) - if (r.from > reinterpret_cast(&MoveTextRegionToLargePages)) - return MoveTextRegionToLargePages(r); +#if defined(__FreeBSD__) + if (r.from < reinterpret_cast(&MoveTextRegionToLargePages)) + return -1; +#endif - return -1; -#elif defined(__APPLE__) return MoveTextRegionToLargePages(r); -#endif } bool IsLargePagesEnabled() {