1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "src/base/test/vm_test_utils.h" 18 19 #include <memory> 20 21 #include <errno.h> 22 #include <string.h> 23 #include <sys/mman.h> 24 #include <sys/stat.h> 25 26 #include "gtest/gtest.h" 27 #include "perfetto/base/build_config.h" 28 29 namespace perfetto { 30 namespace base { 31 namespace vm_test_utils { 32 33 bool IsMapped(void* start, size_t size) { 34 #if PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX) 35 using PageState = char; 36 static constexpr PageState kIncoreMask = MINCORE_INCORE; 37 #else 38 using PageState = unsigned char; 39 static constexpr PageState kIncoreMask = 1; 40 #endif 41 EXPECT_EQ(0u, size % 4096); 42 const size_t num_pages = size / 4096; 43 std::unique_ptr<PageState[]> page_states(new PageState[num_pages]); 44 memset(page_states.get(), 0, num_pages * sizeof(PageState)); 45 int res = mincore(start, size, page_states.get()); 46 // Linux returns ENOMEM when an unmapped memory range is passed. 47 // MacOS instead returns 0 but leaves the page_states empty. 48 if (res == -1 && errno == ENOMEM) 49 return false; 50 EXPECT_EQ(0, res); 51 for (size_t i = 0; i < num_pages; i++) { 52 if (!(page_states[i] & kIncoreMask)) 53 return false; 54 } 55 return true; 56 } 57 58 } // namespace vm_test_utils 59 } // namespace base 60 } // namespace perfetto 61