Skip to content

Commit f3643bf

Browse files
author
Gabriel Schulhof
committed
src: start the .text section with an asm symbol
We create an object file in assembly which introduces the symbol `__node_text_start` into the .text section and place the resulting object file as the first file the linker encounters. We do this to ensure that we can recognize the boundaries of the .text section when attempting to establish the address range to map to large pages. Additionally, we rename the section containing the remapping code from `.lpstub` to `lpstub` so as to take advantage of the linker's feature whereby it inserts the symbol `__start_lpstub` when the section's name can be rendered as a valid C variable. We need this symbol in order to avoid self-mapping the remapping code to large pages, because doing so would cause the process to crash. PR-URL: #31981 Reviewed-By: Franziska Hinkelmann <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: David Carlier <[email protected]> Signed-off-by: Gabriel Schulhof <[email protected]>
1 parent 8a7f607 commit f3643bf

File tree

3 files changed

+39
-14
lines changed

3 files changed

+39
-14
lines changed

node.gyp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,19 @@
230230
},
231231

232232
'targets': [
233+
{
234+
'target_name': 'node_text_start',
235+
'type': 'none',
236+
'conditions': [
237+
[ 'OS=="linux" and '
238+
'target_arch=="x64"', {
239+
'type': 'static_library',
240+
'sources': [
241+
'src/large_pages/node_text_start.S'
242+
]
243+
}],
244+
]
245+
},
233246
{
234247
'target_name': '<(node_core_target_name)',
235248
'type': 'executable',
@@ -310,6 +323,13 @@
310323
# the executable and rename it back to node.exe later
311324
'product_name': '<(node_core_target_name)-win',
312325
}],
326+
[ 'OS=="linux" and '
327+
'target_arch=="x64"', {
328+
'dependencies': [ 'node_text_start' ],
329+
'ldflags+': [
330+
'<(PRODUCT_DIR)/obj.target/node_text_start/src/large_pages/node_text_start.o'
331+
]
332+
}],
313333
],
314334
}, # node_core_target_name
315335
{

src/large_pages/node_large_page.cc

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,11 @@
7979

8080
#if defined(__linux__)
8181
extern "C" {
82-
extern char __executable_start;
82+
// This symbol must be declared weak because this file becomes part of all
83+
// Node.js targets (like node_mksnapshot, node_mkcodecache, and cctest) and
84+
// those files do not supply the symbol.
85+
extern char __attribute__((weak)) __node_text_start;
86+
extern char __start_lpstub;
8387
} // extern "C"
8488
#endif // defined(__linux__)
8589

@@ -129,6 +133,8 @@ struct text_region FindNodeTextRegion() {
129133
std::string dev;
130134
char dash;
131135
uintptr_t start, end, offset, inode;
136+
uintptr_t node_text_start = reinterpret_cast<uintptr_t>(&__node_text_start);
137+
uintptr_t lpstub_start = reinterpret_cast<uintptr_t>(&__start_lpstub);
132138

133139
ifs.open("/proc/self/maps");
134140
if (!ifs) {
@@ -152,21 +158,15 @@ struct text_region FindNodeTextRegion() {
152158
std::string pathname;
153159
iss >> pathname;
154160

155-
if (start != reinterpret_cast<uintptr_t>(&__executable_start))
161+
if (permission != "r-xp")
156162
continue;
157163

158-
// The next line is our .text section.
159-
if (!std::getline(ifs, map_line))
160-
break;
161-
162-
iss = std::istringstream(map_line);
163-
iss >> std::hex >> start;
164-
iss >> dash;
165-
iss >> std::hex >> end;
166-
iss >> permission;
164+
if (node_text_start < start || node_text_start >= end)
165+
continue;
167166

168-
if (permission != "r-xp")
169-
break;
167+
start = node_text_start;
168+
if (lpstub_start > start && lpstub_start <= end)
169+
end = lpstub_start;
170170

171171
char* from = reinterpret_cast<char*>(hugepage_align_up(start));
172172
char* to = reinterpret_cast<char*>(hugepage_align_down(end));
@@ -326,7 +326,7 @@ static bool IsSuperPagesEnabled() {
326326
// d. If successful copy the code there and unmap the original region
327327
int
328328
#if !defined(__APPLE__)
329-
__attribute__((__section__(".lpstub")))
329+
__attribute__((__section__("lpstub")))
330330
#else
331331
__attribute__((__section__("__TEXT,__lpstub")))
332332
#endif

src/large_pages/node_text_start.S

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.text
2+
.align 0x2000
3+
.global __node_text_start
4+
.hidden __node_text_start
5+
__node_text_start:

0 commit comments

Comments
 (0)