2929#include " util.h"
3030#include " uv.h"
3131
32- #include < fcntl.h> // _O_RDWR
32+ #if defined(__linux__)
33+ #ifndef _GNU_SOURCE
34+ #define _GNU_SOURCE
35+ #endif
36+ #include < link.h>
37+ #endif
3338#include < sys/types.h>
3439#include < sys/mman.h>
3540#if defined(__FreeBSD__)
3843#elif defined(__APPLE__)
3944#include < mach/vm_map.h>
4045#endif
41- #include < unistd.h> // readlink
46+ #include < unistd.h> // getpid
4247
4348#include < climits> // PATH_MAX
4449#include < clocale>
4550#include < csignal>
46- #include < cstdio>
4751#include < cstdlib>
4852#include < cstdint>
4953#include < cstring>
5054#include < string>
5155#include < fstream>
5256#include < iostream>
53- #include < sstream>
5457#include < vector>
5558
5659// 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) {
110113 return ((addr) & ~((hps) - 1 ));
111114}
112115
113- // The format of the maps file is the following
114- // address perms offset dev inode pathname
115- // 00400000-00452000 r-xp 00000000 08:02 173521 /usr/bin/dbus-daemon
116- // This is also handling the case where the first line is not the binary.
116+ struct dl_iterate_params {
117+ uintptr_t start;
118+ uintptr_t end;
119+ uintptr_t reference_sym;
120+ };
121+
122+ #if defined(__linux__)
123+ int FindMapping (struct dl_phdr_info * info, size_t , void * data) {
124+ if (info->dlpi_name [0 ] == 0 ) {
125+ for (int idx = 0 ; idx < info->dlpi_phnum ; idx++) {
126+ const ElfW (Phdr)* phdr = &info->dlpi_phdr [idx];
127+ if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X)) {
128+ auto dl_params = static_cast <dl_iterate_params*>(data);
129+ uintptr_t start = info->dlpi_addr + phdr->p_vaddr ;
130+ uintptr_t end = start + phdr->p_memsz ;
131+
132+ if (dl_params->reference_sym >= start &&
133+ dl_params->reference_sym <= end) {
134+ dl_params->start = start;
135+ dl_params->end = end;
136+ return 1 ;
137+ }
138+ }
139+ }
140+ }
141+ return 0 ;
142+ }
143+ #endif // defined(__linux__)
117144
118145struct text_region FindNodeTextRegion () {
119146 struct text_region nregion;
120147 nregion.found_text_region = false ;
121148#if defined(__linux__)
122- std::ifstream ifs;
123- std::string map_line;
124- std::string permission;
125- std::string dev;
126- char dash;
127- uintptr_t start, end, offset, inode;
128- uintptr_t node_text_start = reinterpret_cast <uintptr_t >(&__node_text_start);
149+ dl_iterate_params dl_params = {
150+ 0 , 0 , reinterpret_cast <uintptr_t >(&__node_text_start)
151+ };
129152 uintptr_t lpstub_start = reinterpret_cast <uintptr_t >(&__start_lpstub);
130153
131- ifs.open (" /proc/self/maps" );
132- if (!ifs) {
133- PrintWarning (" could not open /proc/self/maps" );
134- return nregion;
135- }
136-
137- while (std::getline (ifs, map_line)) {
138- std::istringstream iss (map_line);
139- iss >> std::hex >> start;
140- iss >> dash;
141- iss >> std::hex >> end;
142- iss >> permission;
143- iss >> offset;
144- iss >> dev;
145- iss >> inode;
146-
147- if (inode == 0 )
148- continue ;
149-
150- std::string pathname;
151- iss >> pathname;
152-
153- if (permission != " r-xp" )
154- continue ;
155-
156- if (node_text_start < start || node_text_start >= end)
157- continue ;
158-
159- start = node_text_start;
160- if (lpstub_start > start && lpstub_start <= end)
161- end = lpstub_start;
162-
163- char * from = reinterpret_cast <char *>(hugepage_align_up (start));
164- char * to = reinterpret_cast <char *>(hugepage_align_down (end));
165-
166- if (from >= to)
167- break ;
168-
169- size_t size = to - from;
170- nregion.found_text_region = true ;
171- nregion.from = from;
172- nregion.to = to;
173- nregion.total_hugepages = size / hps;
174-
175- break ;
154+ if (dl_iterate_phdr (FindMapping, &dl_params) == 1 ) {
155+ dl_params.start = dl_params.reference_sym ;
156+ if (lpstub_start > dl_params.start && lpstub_start <= dl_params.end )
157+ dl_params.end = lpstub_start;
158+
159+ if (dl_params.start < dl_params.end ) {
160+ char * from = reinterpret_cast <char *>(hugepage_align_up (dl_params.start ));
161+ char * to = reinterpret_cast <char *>(hugepage_align_down (dl_params.end ));
162+ if (from < to) {
163+ size_t pagecount = (to - from) / hps;
164+ if (pagecount > 0 ) {
165+ nregion.found_text_region = true ;
166+ nregion.from = from;
167+ nregion.to = to;
168+ nregion.total_hugepages = pagecount;
169+ }
170+ }
171+ }
176172 }
177-
178- ifs.close ();
179173#elif defined(__FreeBSD__)
180174 std::string exename;
181175 {
@@ -289,7 +283,7 @@ bool IsTransparentHugePagesEnabled() {
289283 return always == " [always]" || madvise == " [madvise]" ;
290284}
291285#elif defined(__FreeBSD__)
292- static bool IsSuperPagesEnabled () {
286+ bool IsSuperPagesEnabled () {
293287 // It is enabled by default on amd64.
294288 unsigned int super_pages = 0 ;
295289 size_t super_pages_length = sizeof (super_pages);
0 commit comments