16#include <sys/resource.h>
17#include <sys/syscall.h>
29#include <sys/sysmacros.h>
52 return new PosixDefaultTimezoneCache();
64 long size = sysconf(_SC_PAGESIZE);
65 FILE* f = fopen(OS::GetGCFakeMMapFile(),
"w+");
67 OS::PrintError(
"Failed to open %s\n", OS::GetGCFakeMMapFile());
71 MAP_PRIVATE, fileno(f), 0);
81 mremap(old_address, 0, size, MREMAP_FIXED | MREMAP_MAYMOVE, new_address);
83 if (
result == MAP_FAILED) {
93 std::optional<OS::MemoryRange>
result;
98 FILE* fp = fopen(
"/proc/self/maps",
"r");
99 if (fp ==
nullptr)
return {};
104 uintptr_t gap_start = 0, gap_end = 0;
110 gap_start < boundary_end) {
114 if (gap_end > boundary_start) {
117 const uintptr_t overlap_start =
118 RoundUp(std::max(gap_start, boundary_start), alignment);
119 const uintptr_t overlap_end =
120 RoundDown(std::min(gap_end, boundary_end), alignment);
121 if (overlap_start < overlap_end &&
122 overlap_end - overlap_start >= minimum_size) {
123 result = {overlap_start, overlap_end};
134 }
while ((c != EOF) && (c !=
'\n'));
145 unsigned dev_major = 0, dev_minor = 0;
159 ®ion.start, ®ion.end, region.permissions, &
offset,
160 &dev_major, &dev_minor, &
inode, &path_index) < 7) {
164 region.inode =
inode;
166 region.dev = makedev(dev_major, dev_minor);
167 region.pathname.assign(line + path_index);
174std::unique_ptr<std::vector<MemoryRegion>> ParseProcSelfMaps(
175 FILE* fp, std::function<
bool(
const MemoryRegion&)> predicate,
176 bool early_stopping) {
177 auto result = std::make_unique<std::vector<MemoryRegion>>();
179 if (!fp) fp = fopen(
"/proc/self/maps",
"r");
180 if (!fp)
return nullptr;
184 const int kMaxLineLength = 2 * FILENAME_MAX;
185 std::unique_ptr<char[]> line = std::make_unique<char[]>(kMaxLineLength);
193 if (fgets(line.get(), kMaxLineLength, fp) ==
nullptr) {
194 if (feof(fp)) error =
false;
198 size_t line_length = strlen(line.get());
205 if (line.get()[line_length - 1] !=
'\n')
break;
206 line.get()[line_length - 1] =
'\0';
215 if (predicate(*region)) {
216 result->push_back(std::move(*region));
217 if (early_stopping)
break;
227MemoryRegion FindEnclosingMapping(uintptr_t target_start,
size_t size) {
228 auto result = ParseProcSelfMaps(
230 [=](
const MemoryRegion& region) {
231 return region.start <= target_start && target_start + size < region.end;
243 auto regions = ParseProcSelfMaps(
246 if (region.permissions[0] ==
'r' && region.permissions[1] ==
'-' &&
247 region.permissions[2] ==
'x') {
254 if (!regions)
return {};
256 std::vector<OS::SharedLibraryAddress>
result;
258 uintptr_t
start = region.start;
260 if (region.pathname.size() < 4 ||
261 region.pathname.compare(region.pathname.size() - 4, 4,
".apk") != 0) {
265 start -= region.offset;
268 start -= region.offset;
270 result.emplace_back(region.pathname,
start, region.end);
277 return ::v8::base::GetSharedLibraryAddresses(
nullptr);
281bool OS::RemapPages(
const void* address,
size_t size,
void* new_address,
282 MemoryPermission access) {
283 uintptr_t address_addr =
reinterpret_cast<uintptr_t
>(address);
290 MemoryRegion enclosing_region = FindEnclosingMapping(address_addr, size);
292 if (!enclosing_region.start)
return false;
295 if (enclosing_region.pathname.empty())
return false;
309 int fd = open(enclosing_region.pathname.c_str(), O_RDONLY);
310 if (fd == -1)
return false;
321 struct stat stat_buf;
322 if (fstat(fd, &stat_buf)) {
328 if (stat_buf.st_dev != enclosing_region.dev ||
329 stat_buf.st_ino != enclosing_region.inode) {
334 size_t offset_in_mapping = address_addr - enclosing_region.start;
335 size_t offset_in_file = enclosing_region.offset + offset_in_mapping;
338 void* mapped_address = mmap(new_address, size, protection,
339 MAP_FIXED | MAP_PRIVATE, fd, offset_in_file);
343 if (mapped_address != new_address) {
static void * GetRandomMmapAddr()
static V8_WARN_UNUSED_RESULT void * RemapShared(void *old_address, void *new_address, size_t size)
static void SignalCodeMovingGC()
static size_t AllocatePageSize()
static std::vector< SharedLibraryAddress > GetSharedLibraryAddresses()
static V8_WARN_UNUSED_RESULT bool RemapPages(const void *address, size_t size, void *new_address, MemoryPermission access)
static TimezoneCache * CreateTimezoneCache()
static void Free(void *address, size_t size)
static std::optional< MemoryRange > GetFirstFreeMemoryRangeWithin(Address boundary_start, Address boundary_end, size_t minimum_size, size_t alignment)
static void AdjustSchedulingParams()
ZoneVector< RpoNumber > & result
int GetProtectionFromMemoryPermission(OS::MemoryPermission access)
std::vector< OS::SharedLibraryAddress > GetSharedLibraryAddresses(FILE *fp)
#define DCHECK_NE(v1, v2)
#define DCHECK(condition)
constexpr T RoundUp(T x, intptr_t m)
constexpr T RoundDown(T x, intptr_t m)
constexpr bool IsAligned(T value, U alignment)
static std::optional< MemoryRegion > FromMapsLine(const char *line)