1 //===-- ModuleSpecTest.cpp ------------------------------------------------===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "TestingSupport/SubsystemRAII.h"
10 #include "TestingSupport/TestUtilities.h"
11 
12 #include "lldb/Core/Module.h"
13 #include "lldb/Core/ModuleSpec.h"
14 #include "lldb/Utility/DataBuffer.h"
15 
16 #include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
17 #include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
18 #include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h"
19 
20 #include "gtest/gtest.h"
21 
22 using namespace lldb;
23 using namespace lldb_private;
24 
25 extern const char *TestMainArgv0;
26 
27 // This test file intentionally doesn't initialize the FileSystem.
28 // Everything in this file should be able to run without requiring
29 // any interaction with the FileSystem class; by keeping it
30 // uninitialized, it will assert if anything tries to interact with
31 // it.
32 
TEST(ModuleSpecTest,InvalidInMemoryBuffer)33 TEST(ModuleSpecTest, InvalidInMemoryBuffer) {
34   uint8_t Invalid[] = "This is not a binary file.";
35   DataBufferSP InvalidBufferSP =
36       std::make_shared<DataBufferUnowned>(Invalid, sizeof(Invalid));
37   ModuleSpec Spec(FileSpec(), UUID(), InvalidBufferSP);
38 
39   auto InvalidModuleSP = std::make_shared<Module>(Spec);
40   ASSERT_EQ(InvalidModuleSP->GetObjectFile(), nullptr);
41 }
42 
TEST(ModuleSpecTest,InvalidInMemoryBufferValidFile)43 TEST(ModuleSpecTest, InvalidInMemoryBufferValidFile) {
44   uint8_t Invalid[] = "This is not a binary file.";
45   DataBufferSP InvalidBufferSP =
46       std::make_shared<DataBufferUnowned>(Invalid, sizeof(Invalid));
47   ModuleSpec Spec(FileSpec(TestMainArgv0), UUID(), InvalidBufferSP);
48 
49   auto InvalidModuleSP = std::make_shared<Module>(Spec);
50   ASSERT_EQ(InvalidModuleSP->GetObjectFile(), nullptr);
51 }
52 
TEST(ModuleSpecTest,TestELFFile)53 TEST(ModuleSpecTest, TestELFFile) {
54   SubsystemRAII<ObjectFileELF> subsystems;
55 
56   auto ExpectedFile = TestFile::fromYaml(R"(
57 --- !ELF
58 FileHeader:
59   Class:           ELFCLASS64
60   Data:            ELFDATA2LSB
61   Type:            ET_REL
62   Machine:         EM_X86_64
63 Sections:
64   - Name:            .text
65     Type:            SHT_PROGBITS
66     Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
67     AddressAlign:    0x0000000000000010
68 ...
69 )");
70   ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
71 
72   auto M = std::make_shared<Module>(ExpectedFile->moduleSpec());
73   ObjectFile *OF = M->GetObjectFile();
74 
75   ASSERT_EQ(llvm::isa<ObjectFileELF>(OF), true);
76 }
77 
TEST(ModuleSpecTest,TestCOFFFile)78 TEST(ModuleSpecTest, TestCOFFFile) {
79   SubsystemRAII<ObjectFilePECOFF> subsystems;
80 
81   auto ExpectedFile = TestFile::fromYaml(R"(
82 --- !COFF
83 OptionalHeader:
84   AddressOfEntryPoint: 0
85   ImageBase:       16777216
86   SectionAlignment: 4096
87   FileAlignment:   512
88   MajorOperatingSystemVersion: 6
89   MinorOperatingSystemVersion: 0
90   MajorImageVersion: 0
91   MinorImageVersion: 0
92   MajorSubsystemVersion: 6
93   MinorSubsystemVersion: 0
94   Subsystem:       IMAGE_SUBSYSTEM_WINDOWS_CUI
95   DLLCharacteristics: [ IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT ]
96   SizeOfStackReserve: 1048576
97   SizeOfStackCommit: 4096
98   SizeOfHeapReserve: 1048576
99   SizeOfHeapCommit: 4096
100 header:
101   Machine:         IMAGE_FILE_MACHINE_AMD64
102   Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE ]
103 sections:
104   - Name:            .text
105     Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
106     VirtualAddress:  4096
107     VirtualSize:     4096
108 symbols:         []
109 ...
110 )");
111   ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
112 
113   auto M = std::make_shared<Module>(ExpectedFile->moduleSpec());
114   ObjectFile *OF = M->GetObjectFile();
115 
116   ASSERT_EQ(llvm::isa<ObjectFilePECOFF>(OF), true);
117 }
118 
TEST(ModuleSpecTest,TestMachOFile)119 TEST(ModuleSpecTest, TestMachOFile) {
120   SubsystemRAII<ObjectFileMachO> subsystems;
121 
122   auto ExpectedFile = TestFile::fromYaml(R"(
123 --- !mach-o
124 FileHeader:
125   magic:           0xFEEDFACF
126   cputype:         0x0100000C
127   cpusubtype:      0x00000000
128   filetype:        0x00000001
129   ncmds:           1
130   sizeofcmds:      232
131   flags:           0x00002000
132   reserved:        0x00000000
133 LoadCommands:
134   - cmd:             LC_SEGMENT_64
135     cmdsize:         232
136     segname:         ''
137     vmaddr:          0
138     vmsize:          56
139     fileoff:         392
140     filesize:        56
141     maxprot:         7
142     initprot:        7
143     nsects:          1
144     flags:           0
145     Sections:
146       - sectname:        __text
147         segname:         __TEXT
148         addr:            0x0000000000000000
149         size:            24
150         offset:          0x00000188
151         align:           2
152         reloff:          0x00000000
153         nreloc:          0
154         flags:           0x80000400
155         reserved1:       0x00000000
156         reserved2:       0x00000000
157         reserved3:       0x00000000
158 ...
159 )");
160   ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
161 
162   auto M = std::make_shared<Module>(ExpectedFile->moduleSpec());
163   ObjectFile *OF = M->GetObjectFile();
164 
165   ASSERT_EQ(llvm::isa<ObjectFileMachO>(OF), true);
166 }
167