1 #include "bolt/Core/BinaryContext.h" 2 #include "llvm/BinaryFormat/ELF.h" 3 #include "llvm/DebugInfo/DWARF/DWARFContext.h" 4 #include "llvm/Object/ELFObjectFile.h" 5 #include "llvm/Support/TargetSelect.h" 6 #include "gtest/gtest.h" 7 8 using namespace llvm; 9 using namespace llvm::object; 10 using namespace llvm::ELF; 11 using namespace bolt; 12 13 namespace { 14 struct BinaryContextTester : public testing::TestWithParam<Triple::ArchType> { 15 void SetUp() override { 16 initalizeLLVM(); 17 prepareElf(); 18 initializeBOLT(); 19 } 20 21 protected: 22 void initalizeLLVM() { 23 llvm::InitializeAllTargetInfos(); 24 llvm::InitializeAllTargetMCs(); 25 llvm::InitializeAllAsmParsers(); 26 llvm::InitializeAllDisassemblers(); 27 llvm::InitializeAllTargets(); 28 llvm::InitializeAllAsmPrinters(); 29 } 30 31 void prepareElf() { 32 memcpy(ElfBuf, "\177ELF", 4); 33 ELF64LE::Ehdr *EHdr = reinterpret_cast<typename ELF64LE::Ehdr *>(ElfBuf); 34 EHdr->e_ident[llvm::ELF::EI_CLASS] = llvm::ELF::ELFCLASS64; 35 EHdr->e_ident[llvm::ELF::EI_DATA] = llvm::ELF::ELFDATA2LSB; 36 EHdr->e_machine = GetParam() == Triple::aarch64 ? EM_AARCH64 : EM_X86_64; 37 MemoryBufferRef Source(StringRef(ElfBuf, sizeof(ElfBuf)), "ELF"); 38 ObjFile = cantFail(ObjectFile::createObjectFile(Source)); 39 } 40 41 void initializeBOLT() { 42 BC = cantFail(BinaryContext::createBinaryContext( 43 ObjFile.get(), true, DWARFContext::create(*ObjFile.get()))); 44 ASSERT_FALSE(!BC); 45 } 46 47 char ElfBuf[sizeof(typename ELF64LE::Ehdr)] = {}; 48 std::unique_ptr<ObjectFile> ObjFile; 49 std::unique_ptr<BinaryContext> BC; 50 }; 51 } // namespace 52 53 #ifdef X86_AVAILABLE 54 55 INSTANTIATE_TEST_SUITE_P(X86, BinaryContextTester, 56 ::testing::Values(Triple::x86_64)); 57 58 #endif 59 60 #ifdef AARCH64_AVAILABLE 61 62 INSTANTIATE_TEST_SUITE_P(AArch64, BinaryContextTester, 63 ::testing::Values(Triple::aarch64)); 64 65 #endif 66 67 TEST_P(BinaryContextTester, BaseAddress) { 68 // Check that base address calculation is correct for a binary with the 69 // following segment layout: 70 BC->SegmentMapInfo[0] = SegmentInfo{0, 0x10e8c2b4, 0, 0x10e8c2b4, 0x1000}; 71 BC->SegmentMapInfo[0x10e8d2b4] = 72 SegmentInfo{0x10e8d2b4, 0x3952faec, 0x10e8c2b4, 0x3952faec, 0x1000}; 73 BC->SegmentMapInfo[0x4a3bddc0] = 74 SegmentInfo{0x4a3bddc0, 0x148e828, 0x4a3bbdc0, 0x148e828, 0x1000}; 75 BC->SegmentMapInfo[0x4b84d5e8] = 76 SegmentInfo{0x4b84d5e8, 0x294f830, 0x4b84a5e8, 0x3d3820, 0x1000}; 77 78 Optional<uint64_t> BaseAddress = 79 BC->getBaseAddressForMapping(0x7f13f5556000, 0x10e8c000); 80 ASSERT_TRUE(BaseAddress.hasValue()); 81 ASSERT_EQ(*BaseAddress, 0x7f13e46c9000ULL); 82 83 BaseAddress = BC->getBaseAddressForMapping(0x7f13f5556000, 0x137a000); 84 ASSERT_FALSE(BaseAddress.hasValue()); 85 } 86