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> {
SetUp__anon935258540111::BinaryContextTester15   void SetUp() override {
16     initalizeLLVM();
17     prepareElf();
18     initializeBOLT();
19   }
20 
21 protected:
initalizeLLVM__anon935258540111::BinaryContextTester22   void initalizeLLVM() {
23     llvm::InitializeAllTargetInfos();
24     llvm::InitializeAllTargetMCs();
25     llvm::InitializeAllAsmParsers();
26     llvm::InitializeAllDisassemblers();
27     llvm::InitializeAllTargets();
28     llvm::InitializeAllAsmPrinters();
29   }
30 
prepareElf__anon935258540111::BinaryContextTester31   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 
initializeBOLT__anon935258540111::BinaryContextTester41   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 
TEST_P(BinaryContextTester,BaseAddress)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