146 lines · cpp
1//===-- SubprocessMemoryTest.cpp --------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "SubprocessMemory.h"10 11#include "X86/TestBase.h"12#include "gtest/gtest.h"13#include <string>14#include <unordered_map>15 16#ifdef __linux__17#include <endian.h>18#include <fcntl.h>19#include <sys/mman.h>20#include <sys/syscall.h>21#include <unistd.h>22#endif // __linux__23 24namespace llvm {25namespace exegesis {26 27#if defined(__linux__) && !defined(__ANDROID__) && \28 !(defined(__powerpc__) || defined(__s390x__) || defined(__sparc__))29 30// This needs to be updated anytime a test is added or removed from the test31// suite.32static constexpr size_t TestCount = 4;33 34class SubprocessMemoryTest : public X86TestBase {35protected:36 int getSharedMemoryNumber(const unsigned TestNumber) {37 // Do a process similar to 2D array indexing so that each process gets it's38 // own shared memory space to avoid collisions. This will not overflow as39 // the maximum value a PID can take on is 10^22.40 return getpid() * TestCount + TestNumber;41 }42 43 void44 testCommon(std::unordered_map<std::string, MemoryValue> MemoryDefinitions,45 const unsigned TestNumber) {46 EXPECT_FALSE(47 SM.initializeSubprocessMemory(getSharedMemoryNumber(TestNumber)));48 EXPECT_FALSE(SM.addMemoryDefinition(MemoryDefinitions,49 getSharedMemoryNumber(TestNumber)));50 }51 52 std::string getSharedMemoryName(const unsigned TestNumber,53 const unsigned DefinitionNumber) {54 long CurrentTID = syscall(SYS_gettid);55 return "/" + std::to_string(getSharedMemoryNumber(TestNumber)) + "t" +56 std::to_string(CurrentTID) + "memdef" +57 std::to_string(DefinitionNumber);58 }59 60 void checkSharedMemoryDefinition(const std::string &DefinitionName,61 size_t DefinitionSize,62 std::vector<uint8_t> ExpectedValue) {63 int SharedMemoryFD =64 shm_open(DefinitionName.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);65 uint8_t *SharedMemoryMapping = (uint8_t *)mmap(66 NULL, DefinitionSize, PROT_READ, MAP_SHARED, SharedMemoryFD, 0);67 EXPECT_NE(reinterpret_cast<intptr_t>(SharedMemoryMapping), -1);68 for (size_t I = 0; I < ExpectedValue.size(); ++I) {69 EXPECT_EQ(SharedMemoryMapping[I], ExpectedValue[I]);70 }71 munmap(SharedMemoryMapping, DefinitionSize);72 }73 74 SubprocessMemory SM;75};76 77// Some of the tests below are failing on s390x and PPC due to the shared78// memory calls not working in some cases, so they have been disabled.79// TODO(boomanaiden154): Investigate and fix this issue on PPC.80 81TEST_F(SubprocessMemoryTest, OneDefinition) {82 testCommon({{"test1", {APInt(8, 0xff), 4096, 0}}}, 0);83 checkSharedMemoryDefinition(getSharedMemoryName(0, 0), 4096, {0xff});84}85 86TEST_F(SubprocessMemoryTest, MultipleDefinitions) {87 testCommon({{"test1", {APInt(8, 0xaa), 4096, 0}},88 {"test2", {APInt(8, 0xbb), 4096, 1}},89 {"test3", {APInt(8, 0xcc), 4096, 2}}},90 1);91 checkSharedMemoryDefinition(getSharedMemoryName(1, 0), 4096, {0xaa});92 checkSharedMemoryDefinition(getSharedMemoryName(1, 1), 4096, {0xbb});93 checkSharedMemoryDefinition(getSharedMemoryName(1, 2), 4096, {0xcc});94}95 96TEST_F(SubprocessMemoryTest, DefinitionFillsCompletely) {97 testCommon({{"test1", {APInt(8, 0xaa), 4096, 0}},98 {"test2", {APInt(16, 0xbbbb), 4096, 1}},99 {"test3", {APInt(24, 0xcccccc), 4096, 2}}},100 2);101 std::vector<uint8_t> Test1Expected(512, 0xaa);102 std::vector<uint8_t> Test2Expected(512, 0xbb);103 std::vector<uint8_t> Test3Expected(512, 0xcc);104 checkSharedMemoryDefinition(getSharedMemoryName(2, 0), 4096, Test1Expected);105 checkSharedMemoryDefinition(getSharedMemoryName(2, 1), 4096, Test2Expected);106 checkSharedMemoryDefinition(getSharedMemoryName(2, 2), 4096, Test3Expected);107}108 109// The following test is only supported on little endian systems.110#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__111TEST_F(SubprocessMemoryTest, DISABLED_DefinitionEndTruncation) {112#else113TEST_F(SubprocessMemoryTest, DefinitionEndTruncation) {114#endif115 testCommon({{"test1", {APInt(48, 0xaabbccddeeff), 4096, 0}}}, 3);116 std::vector<uint8_t> Test1Expected(512, 0);117 // order is reversed since we're assuming a little endian system.118 for (size_t I = 0; I < Test1Expected.size(); ++I) {119 switch (I % 6) {120 case 0:121 Test1Expected[I] = 0xff;122 break;123 case 1:124 Test1Expected[I] = 0xee;125 break;126 case 2:127 Test1Expected[I] = 0xdd;128 break;129 case 3:130 Test1Expected[I] = 0xcc;131 break;132 case 4:133 Test1Expected[I] = 0xbb;134 break;135 case 5:136 Test1Expected[I] = 0xaa;137 }138 }139 checkSharedMemoryDefinition(getSharedMemoryName(3, 0), 4096, Test1Expected);140}141 142#endif // __linux__ && !__ANDROID__ && !(__powerpc__ || __s390x__ || __sparc__)143 144} // namespace exegesis145} // namespace llvm146