cpp/perfevents/detail/FileBackedMappingsList.h (71 lines of code) (raw):
/**
* Copyright 2004-present, Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <procmaps.h>
#include <cstring>
#include <map>
namespace facebook {
namespace perfevents {
namespace detail {
struct FileBackedMappingsList {
struct Mapping {
uint64_t start;
uint64_t end;
};
void fillFromProcMaps() {
auto memorymap = memorymap_snapshot(getpid());
if (memorymap == nullptr) {
return;
}
for (auto vma = memorymap_first_vma(memorymap); vma != nullptr;
vma = memorymap_vma_next(vma)) {
auto file = memorymap_vma_file(vma);
if (isAnonymous(file)) {
continue;
}
add(memorymap_vma_start(vma), memorymap_vma_end(vma));
}
memorymap_destroy(memorymap);
}
void add(uint64_t start, uint64_t end) {
const auto iter = file_mappings.lower_bound(start);
if (iter == file_mappings.cend() || iter->second.start != start ||
iter->second.end != end) {
file_mappings.emplace(end, Mapping{start, end});
}
}
bool contains(uint64_t addr) {
const auto iter = file_mappings.lower_bound(addr);
if (iter == file_mappings.cend()) {
return false;
}
auto& mapping = iter->second;
return mapping.start <= addr && addr < mapping.end;
}
static inline bool isAnonymous(const char* filename) {
if (filename == nullptr || strlen(filename) == 0 ||
strcmp(filename, " ") == 0) {
return true;
}
static constexpr char kDevAshmem[] = "/dev/ashmem/";
if (strncmp(filename, kDevAshmem, strlen(kDevAshmem)) == 0) {
return true;
}
static constexpr char kBracketStack[] = "[stack";
// e.g. "[stack:1101]" or "[stack]"
if (strncmp(filename, kBracketStack, strlen(kBracketStack)) == 0) {
return true;
}
static constexpr char kBracketAnon[] = "[anon:";
// e.g. "[anon:linker_alloc]"
if (strncmp(filename, kBracketAnon, strlen(kBracketAnon)) == 0) {
return true;
}
static constexpr char kAnonInode[] = "anon_inode";
// e.g. "anon_inode:[perf_event]"
if (strncmp(filename, kAnonInode, strlen(kAnonInode)) == 0) {
return true;
}
return false;
}
private:
std::map<uint64_t, Mapping> file_mappings;
};
} // namespace detail
} // namespace perfevents
} // namespace facebook