15a63b2b3SAiden Grossman //===-- SubprocessMemoryTest.cpp --------------------------------*- C++ -*-===// 25a63b2b3SAiden Grossman // 35a63b2b3SAiden Grossman // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45a63b2b3SAiden Grossman // See https://llvm.org/LICENSE.txt for license information. 55a63b2b3SAiden Grossman // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65a63b2b3SAiden Grossman // 75a63b2b3SAiden Grossman //===----------------------------------------------------------------------===// 85a63b2b3SAiden Grossman 95a63b2b3SAiden Grossman #include "SubprocessMemory.h" 105a63b2b3SAiden Grossman 115a63b2b3SAiden Grossman #include "X86/TestBase.h" 125a63b2b3SAiden Grossman #include "gtest/gtest.h" 13adb01deaSAiden Grossman #include <string> 145a63b2b3SAiden Grossman #include <unordered_map> 155a63b2b3SAiden Grossman 165a63b2b3SAiden Grossman #ifdef __linux__ 175a63b2b3SAiden Grossman #include <endian.h> 185a63b2b3SAiden Grossman #include <fcntl.h> 195a63b2b3SAiden Grossman #include <sys/mman.h> 2050e62181SAiden Grossman #include <sys/syscall.h> 21adb01deaSAiden Grossman #include <unistd.h> 225a63b2b3SAiden Grossman #endif // __linux__ 235a63b2b3SAiden Grossman 245a63b2b3SAiden Grossman namespace llvm { 255a63b2b3SAiden Grossman namespace exegesis { 265a63b2b3SAiden Grossman 27a417083eSRainer Orth #if defined(__linux__) && !defined(__ANDROID__) && \ 28a417083eSRainer Orth !(defined(__powerpc__) || defined(__s390x__) || defined(__sparc__)) 295a63b2b3SAiden Grossman 307b3f6e64SBjorn Pettersson // This needs to be updated anytime a test is added or removed from the test 317b3f6e64SBjorn Pettersson // suite. 327b3f6e64SBjorn Pettersson static constexpr const size_t TestCount = 4; 337b3f6e64SBjorn Pettersson 345a63b2b3SAiden Grossman class SubprocessMemoryTest : public X86TestBase { 355a63b2b3SAiden Grossman protected: 36adb01deaSAiden Grossman int getSharedMemoryNumber(const unsigned TestNumber) { 37adb01deaSAiden Grossman // Do a process similar to 2D array indexing so that each process gets it's 38adb01deaSAiden Grossman // own shared memory space to avoid collisions. This will not overflow as 39adb01deaSAiden Grossman // the maximum value a PID can take on is 10^22. 40adb01deaSAiden Grossman return getpid() * TestCount + TestNumber; 41adb01deaSAiden Grossman } 42adb01deaSAiden Grossman 435a63b2b3SAiden Grossman void 445a63b2b3SAiden Grossman testCommon(std::unordered_map<std::string, MemoryValue> MemoryDefinitions, 45adb01deaSAiden Grossman const unsigned TestNumber) { 46adb01deaSAiden Grossman EXPECT_FALSE( 47adb01deaSAiden Grossman SM.initializeSubprocessMemory(getSharedMemoryNumber(TestNumber))); 48adb01deaSAiden Grossman EXPECT_FALSE(SM.addMemoryDefinition(MemoryDefinitions, 49adb01deaSAiden Grossman getSharedMemoryNumber(TestNumber))); 50adb01deaSAiden Grossman } 51adb01deaSAiden Grossman 52adb01deaSAiden Grossman std::string getSharedMemoryName(const unsigned TestNumber, 53adb01deaSAiden Grossman const unsigned DefinitionNumber) { 5450e62181SAiden Grossman long CurrentTID = syscall(SYS_gettid); 5550e62181SAiden Grossman return "/" + std::to_string(getSharedMemoryNumber(TestNumber)) + "t" + 5650e62181SAiden Grossman std::to_string(CurrentTID) + "memdef" + 57adb01deaSAiden Grossman std::to_string(DefinitionNumber); 585a63b2b3SAiden Grossman } 595a63b2b3SAiden Grossman 605a63b2b3SAiden Grossman void checkSharedMemoryDefinition(const std::string &DefinitionName, 615a63b2b3SAiden Grossman size_t DefinitionSize, 625a63b2b3SAiden Grossman std::vector<uint8_t> ExpectedValue) { 635a63b2b3SAiden Grossman int SharedMemoryFD = 645a63b2b3SAiden Grossman shm_open(DefinitionName.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); 655a63b2b3SAiden Grossman uint8_t *SharedMemoryMapping = (uint8_t *)mmap( 665a63b2b3SAiden Grossman NULL, DefinitionSize, PROT_READ, MAP_SHARED, SharedMemoryFD, 0); 67*fac87b88SAiden Grossman EXPECT_NE(reinterpret_cast<intptr_t>(SharedMemoryMapping), -1); 685a63b2b3SAiden Grossman for (size_t I = 0; I < ExpectedValue.size(); ++I) { 695a63b2b3SAiden Grossman EXPECT_EQ(SharedMemoryMapping[I], ExpectedValue[I]); 705a63b2b3SAiden Grossman } 715a63b2b3SAiden Grossman munmap(SharedMemoryMapping, DefinitionSize); 725a63b2b3SAiden Grossman } 735a63b2b3SAiden Grossman 745a63b2b3SAiden Grossman SubprocessMemory SM; 755a63b2b3SAiden Grossman }; 765a63b2b3SAiden Grossman 77f8927838SAiden Grossman // Some of the tests below are failing on s390x and PPC due to the shared 78f8927838SAiden Grossman // memory calls not working in some cases, so they have been disabled. 79f8927838SAiden Grossman // TODO(boomanaiden154): Investigate and fix this issue on PPC. 80f8927838SAiden Grossman 815a63b2b3SAiden Grossman TEST_F(SubprocessMemoryTest, OneDefinition) { 825a63b2b3SAiden Grossman testCommon({{"test1", {APInt(8, 0xff), 4096, 0}}}, 0); 83adb01deaSAiden Grossman checkSharedMemoryDefinition(getSharedMemoryName(0, 0), 4096, {0xff}); 845a63b2b3SAiden Grossman } 855a63b2b3SAiden Grossman 865a63b2b3SAiden Grossman TEST_F(SubprocessMemoryTest, MultipleDefinitions) { 875a63b2b3SAiden Grossman testCommon({{"test1", {APInt(8, 0xaa), 4096, 0}}, 885a63b2b3SAiden Grossman {"test2", {APInt(8, 0xbb), 4096, 1}}, 895a63b2b3SAiden Grossman {"test3", {APInt(8, 0xcc), 4096, 2}}}, 905a63b2b3SAiden Grossman 1); 91adb01deaSAiden Grossman checkSharedMemoryDefinition(getSharedMemoryName(1, 0), 4096, {0xaa}); 92adb01deaSAiden Grossman checkSharedMemoryDefinition(getSharedMemoryName(1, 1), 4096, {0xbb}); 93adb01deaSAiden Grossman checkSharedMemoryDefinition(getSharedMemoryName(1, 2), 4096, {0xcc}); 945a63b2b3SAiden Grossman } 955a63b2b3SAiden Grossman 965a63b2b3SAiden Grossman TEST_F(SubprocessMemoryTest, DefinitionFillsCompletely) { 975a63b2b3SAiden Grossman testCommon({{"test1", {APInt(8, 0xaa), 4096, 0}}, 985a63b2b3SAiden Grossman {"test2", {APInt(16, 0xbbbb), 4096, 1}}, 995a63b2b3SAiden Grossman {"test3", {APInt(24, 0xcccccc), 4096, 2}}}, 1005a63b2b3SAiden Grossman 2); 1015a63b2b3SAiden Grossman std::vector<uint8_t> Test1Expected(512, 0xaa); 1025a63b2b3SAiden Grossman std::vector<uint8_t> Test2Expected(512, 0xbb); 1035a63b2b3SAiden Grossman std::vector<uint8_t> Test3Expected(512, 0xcc); 104adb01deaSAiden Grossman checkSharedMemoryDefinition(getSharedMemoryName(2, 0), 4096, Test1Expected); 105adb01deaSAiden Grossman checkSharedMemoryDefinition(getSharedMemoryName(2, 1), 4096, Test2Expected); 106adb01deaSAiden Grossman checkSharedMemoryDefinition(getSharedMemoryName(2, 2), 4096, Test3Expected); 1075a63b2b3SAiden Grossman } 1085a63b2b3SAiden Grossman 109f8927838SAiden Grossman // The following test is only supported on little endian systems. 110a417083eSRainer Orth #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 111f8927838SAiden Grossman TEST_F(SubprocessMemoryTest, DISABLED_DefinitionEndTruncation) { 112f8927838SAiden Grossman #else 1135a63b2b3SAiden Grossman TEST_F(SubprocessMemoryTest, DefinitionEndTruncation) { 114f8927838SAiden Grossman #endif 1155a63b2b3SAiden Grossman testCommon({{"test1", {APInt(48, 0xaabbccddeeff), 4096, 0}}}, 3); 1165a63b2b3SAiden Grossman std::vector<uint8_t> Test1Expected(512, 0); 1175a63b2b3SAiden Grossman // order is reversed since we're assuming a little endian system. 1185a63b2b3SAiden Grossman for (size_t I = 0; I < Test1Expected.size(); ++I) { 1195a63b2b3SAiden Grossman switch (I % 6) { 1205a63b2b3SAiden Grossman case 0: 1215a63b2b3SAiden Grossman Test1Expected[I] = 0xff; 1225a63b2b3SAiden Grossman break; 1235a63b2b3SAiden Grossman case 1: 1245a63b2b3SAiden Grossman Test1Expected[I] = 0xee; 1255a63b2b3SAiden Grossman break; 1265a63b2b3SAiden Grossman case 2: 1275a63b2b3SAiden Grossman Test1Expected[I] = 0xdd; 1285a63b2b3SAiden Grossman break; 1295a63b2b3SAiden Grossman case 3: 1305a63b2b3SAiden Grossman Test1Expected[I] = 0xcc; 1315a63b2b3SAiden Grossman break; 1325a63b2b3SAiden Grossman case 4: 1335a63b2b3SAiden Grossman Test1Expected[I] = 0xbb; 1345a63b2b3SAiden Grossman break; 1355a63b2b3SAiden Grossman case 5: 1365a63b2b3SAiden Grossman Test1Expected[I] = 0xaa; 1375a63b2b3SAiden Grossman } 1385a63b2b3SAiden Grossman } 139adb01deaSAiden Grossman checkSharedMemoryDefinition(getSharedMemoryName(3, 0), 4096, Test1Expected); 1405a63b2b3SAiden Grossman } 1415a63b2b3SAiden Grossman 142a417083eSRainer Orth #endif // __linux__ && !__ANDROID__ && !(__powerpc__ || __s390x__ || __sparc__) 1435a63b2b3SAiden Grossman 1445a63b2b3SAiden Grossman } // namespace exegesis 1455a63b2b3SAiden Grossman } // namespace llvm 146