xref: /llvm-project/llvm/unittests/tools/llvm-exegesis/X86/SubprocessMemoryTest.cpp (revision fac87b889c50f493ba332950f613fa15a45be9a9)
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