-
-
Notifications
You must be signed in to change notification settings - Fork 31.7k
src: find .text section using dl_iterate_phdr #32244
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
31c03a2
f6531aa
5932d05
617e601
ba539ef
2d6be5e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,7 +29,12 @@ | |
#include "util.h" | ||
#include "uv.h" | ||
|
||
#include <fcntl.h> // _O_RDWR | ||
#if defined(__linux__) | ||
#ifndef _GNU_SOURCE | ||
#define _GNU_SOURCE | ||
#endif | ||
#include <link.h> | ||
#endif | ||
#include <sys/types.h> | ||
#include <sys/mman.h> | ||
#if defined(__FreeBSD__) | ||
|
@@ -38,19 +43,17 @@ | |
#elif defined(__APPLE__) | ||
#include <mach/vm_map.h> | ||
#endif | ||
#include <unistd.h> // readlink | ||
#include <unistd.h> // getpid | ||
|
||
#include <climits> // PATH_MAX | ||
#include <clocale> | ||
#include <csignal> | ||
#include <cstdio> | ||
gabrielschulhof marked this conversation as resolved.
Show resolved
Hide resolved
|
||
#include <cstdlib> | ||
#include <cstdint> | ||
#include <cstring> | ||
#include <string> | ||
#include <fstream> | ||
#include <iostream> | ||
#include <sstream> | ||
#include <vector> | ||
|
||
// 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) { | |
return ((addr) & ~((hps) - 1)); | ||
} | ||
|
||
// The format of the maps file is the following | ||
// address perms offset dev inode pathname | ||
// 00400000-00452000 r-xp 00000000 08:02 173521 /usr/bin/dbus-daemon | ||
// This is also handling the case where the first line is not the binary. | ||
struct dl_iterate_params { | ||
uintptr_t start; | ||
uintptr_t end; | ||
uintptr_t reference_sym; | ||
}; | ||
|
||
#if defined(__linux__) | ||
int FindMapping(struct dl_phdr_info* info, size_t, void* data) { | ||
if (info->dlpi_name[0] == 0) { | ||
for (int idx = 0; idx < info->dlpi_phnum; idx++) { | ||
const ElfW(Phdr)* phdr = &info->dlpi_phdr[idx]; | ||
if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X)) { | ||
auto dl_params = static_cast<dl_iterate_params*>(data); | ||
uintptr_t start = info->dlpi_addr + phdr->p_vaddr; | ||
uintptr_t end = start + phdr->p_memsz; | ||
|
||
if (dl_params->reference_sym >= start && | ||
dl_params->reference_sym <= end) { | ||
dl_params->start = start; | ||
dl_params->end = end; | ||
return 1; | ||
} | ||
} | ||
} | ||
} | ||
return 0; | ||
} | ||
#endif // defined(__linux__) | ||
|
||
struct text_region FindNodeTextRegion() { | ||
struct text_region nregion; | ||
nregion.found_text_region = false; | ||
#if defined(__linux__) | ||
std::ifstream ifs; | ||
std::string map_line; | ||
std::string permission; | ||
std::string dev; | ||
char dash; | ||
uintptr_t start, end, offset, inode; | ||
uintptr_t node_text_start = reinterpret_cast<uintptr_t>(&__node_text_start); | ||
dl_iterate_params dl_params = { | ||
0, 0, reinterpret_cast<uintptr_t>(&__node_text_start) | ||
}; | ||
uintptr_t lpstub_start = reinterpret_cast<uintptr_t>(&__start_lpstub); | ||
|
||
ifs.open("/proc/self/maps"); | ||
if (!ifs) { | ||
PrintWarning("could not open /proc/self/maps"); | ||
return nregion; | ||
} | ||
|
||
while (std::getline(ifs, map_line)) { | ||
std::istringstream iss(map_line); | ||
iss >> std::hex >> start; | ||
iss >> dash; | ||
iss >> std::hex >> end; | ||
iss >> permission; | ||
iss >> offset; | ||
iss >> dev; | ||
iss >> inode; | ||
|
||
if (inode == 0) | ||
continue; | ||
|
||
std::string pathname; | ||
iss >> pathname; | ||
|
||
if (permission != "r-xp") | ||
continue; | ||
|
||
if (node_text_start < start || node_text_start >= end) | ||
continue; | ||
|
||
start = node_text_start; | ||
if (lpstub_start > start && lpstub_start <= end) | ||
end = lpstub_start; | ||
|
||
char* from = reinterpret_cast<char*>(hugepage_align_up(start)); | ||
char* to = reinterpret_cast<char*>(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; | ||
if (dl_iterate_phdr(FindMapping, &dl_params) == 1) { | ||
dl_params.start = dl_params.reference_sym; | ||
if (lpstub_start > dl_params.start && lpstub_start <= dl_params.end) | ||
dl_params.end = lpstub_start; | ||
|
||
if (dl_params.start < dl_params.end) { | ||
char* from = reinterpret_cast<char*>(hugepage_align_up(dl_params.start)); | ||
char* to = reinterpret_cast<char*>(hugepage_align_down(dl_params.end)); | ||
if (from < to) { | ||
size_t pagecount = (to - from) / hps; | ||
if (pagecount > 0) { | ||
nregion.found_text_region = true; | ||
nregion.from = from; | ||
nregion.to = to; | ||
nregion.total_hugepages = pagecount; | ||
} | ||
} | ||
} | ||
Comment on lines
+159
to
+171
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @bnoordhuis I added some more sanity checks to ensure that we create a region that has proper offsets and > 0 page count. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ... or rather, that we consider the region to have been found only if it has proper offsets and >0 page count. |
||
} | ||
|
||
ifs.close(); | ||
#elif defined(__FreeBSD__) | ||
std::string exename; | ||
{ | ||
|
@@ -289,7 +283,7 @@ bool IsTransparentHugePagesEnabled() { | |
return always == "[always]" || madvise == "[madvise]"; | ||
} | ||
#elif defined(__FreeBSD__) | ||
static bool IsSuperPagesEnabled() { | ||
bool IsSuperPagesEnabled() { | ||
// It is enabled by default on amd64. | ||
unsigned int super_pages = 0; | ||
size_t super_pages_length = sizeof(super_pages); | ||
|
Uh oh!
There was an error while loading. Please reload this page.