1 //===- ObjCopyTest.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 "llvm/ObjCopy/ObjCopy.h"
10 #include "llvm/ADT/SmallString.h"
11 #include "llvm/ObjCopy/ConfigManager.h"
12 #include "llvm/Object/ObjectFile.h"
13 #include "llvm/ObjectYAML/yaml2obj.h"
14 #include "llvm/Support/Error.h"
15 #include "llvm/Support/FileUtilities.h"
16 #include "llvm/Testing/Support/Error.h"
17 #include "gtest/gtest.h"
18 
19 using namespace llvm;
20 using namespace object;
21 using namespace objcopy;
22 using namespace yaml;
23 
24 void copySimpleInMemoryFileImpl(
25     const char *YamlCreationString,
26     std::function<bool(const Binary &File)> IsValidFormat) {
27   auto ErrHandler = [&](const Twine &Msg) { FAIL() << "Error: " << Msg; };
28 
29   // Create Object file from YAML description.
30   SmallVector<char> Storage;
31   std::unique_ptr<ObjectFile> Obj =
32       yaml2ObjectFile(Storage, YamlCreationString, ErrHandler);
33   ASSERT_TRUE(Obj);
34   ASSERT_TRUE(IsValidFormat(*Obj));
35 
36   ConfigManager Config;
37   Config.Common.OutputFilename = "a.out";
38 
39   // Call executeObjcopyOnBinary()
40   SmallVector<char> DataVector;
41   raw_svector_ostream OutStream(DataVector);
42   Error Err = objcopy::executeObjcopyOnBinary(Config, *Obj.get(), OutStream);
43   ASSERT_FALSE(std::move(Err));
44 
45   MemoryBufferRef Buffer(StringRef(DataVector.data(), DataVector.size()),
46                          Config.Common.OutputFilename);
47 
48   // Check copied file.
49   Expected<std::unique_ptr<Binary>> Result = createBinary(Buffer);
50   ASSERT_THAT_EXPECTED(Result, Succeeded());
51   ASSERT_TRUE(IsValidFormat(**Result));
52 }
53 
54 TEST(CopySimpleInMemoryFile, COFF) {
55   SCOPED_TRACE("CopySimpleInMemoryFileCOFF");
56 
57   copySimpleInMemoryFileImpl(
58       R"(
59 --- !COFF
60 header:
61   Machine:         IMAGE_FILE_MACHINE_AMD64
62   Characteristics: [  ]
63 sections:
64   - Name:            .text
65     Characteristics: [  ]
66     Alignment:       4
67     SectionData:     E800000000C3C3C3
68 symbols:
69 ...
70 )",
71       [](const Binary &File) { return File.isCOFF(); });
72 }
73 
74 TEST(CopySimpleInMemoryFile, ELF) {
75   SCOPED_TRACE("CopySimpleInMemoryFileELF");
76 
77   copySimpleInMemoryFileImpl(
78       R"(
79 --- !ELF
80 FileHeader:
81    Class:    ELFCLASS64
82    Data:     ELFDATA2LSB
83    Type:     ET_REL)",
84       [](const Binary &File) { return File.isELF(); });
85 }
86 
87 TEST(CopySimpleInMemoryFile, MachO) {
88   SCOPED_TRACE("CopySimpleInMemoryFileMachO");
89 
90   copySimpleInMemoryFileImpl(
91       R"(
92 --- !mach-o
93 FileHeader:
94   magic:           0xFEEDFACF
95   cputype:         0x01000007
96   cpusubtype:      0x80000003
97   filetype:        0x00000002
98   ncmds:           0
99   sizeofcmds:      0
100   flags:           0x00218085
101   reserved:        0x00000000
102 ...
103 )",
104       [](const Binary &File) { return File.isMachO(); });
105 }
106 
107 TEST(CopySimpleInMemoryFile, Wasm) {
108   SCOPED_TRACE("CopySimpleInMemoryFileWasm");
109 
110   copySimpleInMemoryFileImpl(
111       R"(
112 --- !WASM
113 FileHeader:
114   Version:         0x00000001
115 ...
116 )",
117       [](const Binary &File) { return File.isWasm(); });
118 }
119