1f75da0c8SAlexey Lapshin //===- ObjCopyTest.cpp ----------------------------------------------------===//
2f75da0c8SAlexey Lapshin //
3f75da0c8SAlexey Lapshin // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4f75da0c8SAlexey Lapshin // See https://llvm.org/LICENSE.txt for license information.
5f75da0c8SAlexey Lapshin // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f75da0c8SAlexey Lapshin //
7f75da0c8SAlexey Lapshin //===----------------------------------------------------------------------===//
8f75da0c8SAlexey Lapshin
9f75da0c8SAlexey Lapshin #include "llvm/ObjCopy/ObjCopy.h"
10f75da0c8SAlexey Lapshin #include "llvm/ObjCopy/ConfigManager.h"
11f75da0c8SAlexey Lapshin #include "llvm/Object/ObjectFile.h"
12f75da0c8SAlexey Lapshin #include "llvm/ObjectYAML/yaml2obj.h"
13f75da0c8SAlexey Lapshin #include "llvm/Support/Error.h"
14f75da0c8SAlexey Lapshin #include "llvm/Support/FileUtilities.h"
15f75da0c8SAlexey Lapshin #include "llvm/Testing/Support/Error.h"
16f75da0c8SAlexey Lapshin #include "gtest/gtest.h"
17f75da0c8SAlexey Lapshin
18f75da0c8SAlexey Lapshin using namespace llvm;
19f75da0c8SAlexey Lapshin using namespace object;
20f75da0c8SAlexey Lapshin using namespace objcopy;
21f75da0c8SAlexey Lapshin using namespace yaml;
22f75da0c8SAlexey Lapshin
232dc4a80eSAlexey Lapshin const char *SimpleFileCOFFYAML = R"(
24f75da0c8SAlexey Lapshin --- !COFF
25f75da0c8SAlexey Lapshin header:
26f75da0c8SAlexey Lapshin Machine: IMAGE_FILE_MACHINE_AMD64
27f75da0c8SAlexey Lapshin Characteristics: [ ]
28f75da0c8SAlexey Lapshin sections:
29f75da0c8SAlexey Lapshin - Name: .text
30f75da0c8SAlexey Lapshin Characteristics: [ ]
31f75da0c8SAlexey Lapshin Alignment: 4
32f75da0c8SAlexey Lapshin SectionData: E800000000C3C3C3
33f75da0c8SAlexey Lapshin symbols:
34f75da0c8SAlexey Lapshin ...
352dc4a80eSAlexey Lapshin )";
36f75da0c8SAlexey Lapshin
372dc4a80eSAlexey Lapshin const char *SimpleFileELFYAML = R"(
38f75da0c8SAlexey Lapshin --- !ELF
39f75da0c8SAlexey Lapshin FileHeader:
40f75da0c8SAlexey Lapshin Class: ELFCLASS64
41f75da0c8SAlexey Lapshin Data: ELFDATA2LSB
422dc4a80eSAlexey Lapshin Type: ET_REL
432dc4a80eSAlexey Lapshin Sections:
44a6f3fedcSAlexey Lapshin - Name: .text
452dc4a80eSAlexey Lapshin Type: SHT_PROGBITS
462dc4a80eSAlexey Lapshin Flags: [ SHF_ALLOC ]
472dc4a80eSAlexey Lapshin Content: "12345678"
482dc4a80eSAlexey Lapshin )";
49a6f3fedcSAlexey Lapshin
502dc4a80eSAlexey Lapshin const char *SimpleFileMachOYAML = R"(
51a6f3fedcSAlexey Lapshin --- !mach-o
52a6f3fedcSAlexey Lapshin FileHeader:
53a6f3fedcSAlexey Lapshin magic: 0xFEEDFACF
54a6f3fedcSAlexey Lapshin cputype: 0x01000007
55a6f3fedcSAlexey Lapshin cpusubtype: 0x80000003
56a6f3fedcSAlexey Lapshin filetype: 0x00000001
57a6f3fedcSAlexey Lapshin ncmds: 1
58a6f3fedcSAlexey Lapshin sizeofcmds: 152
59a6f3fedcSAlexey Lapshin flags: 0x00002000
60a6f3fedcSAlexey Lapshin reserved: 0x00000000
61a6f3fedcSAlexey Lapshin LoadCommands:
62a6f3fedcSAlexey Lapshin - cmd: LC_SEGMENT_64
63a6f3fedcSAlexey Lapshin cmdsize: 152
64a6f3fedcSAlexey Lapshin segname: __TEXT
65a6f3fedcSAlexey Lapshin vmaddr: 0
66a6f3fedcSAlexey Lapshin vmsize: 4
67a6f3fedcSAlexey Lapshin fileoff: 184
68a6f3fedcSAlexey Lapshin filesize: 4
69a6f3fedcSAlexey Lapshin maxprot: 7
70a6f3fedcSAlexey Lapshin initprot: 7
71a6f3fedcSAlexey Lapshin nsects: 1
72a6f3fedcSAlexey Lapshin flags: 0
73a6f3fedcSAlexey Lapshin Sections:
74a6f3fedcSAlexey Lapshin - sectname: __text
75a6f3fedcSAlexey Lapshin segname: __TEXT
76a6f3fedcSAlexey Lapshin addr: 0x0000000000000000
77a6f3fedcSAlexey Lapshin content: 'AABBCCDD'
78a6f3fedcSAlexey Lapshin size: 4
79a6f3fedcSAlexey Lapshin offset: 184
80a6f3fedcSAlexey Lapshin align: 0
81a6f3fedcSAlexey Lapshin reloff: 0x00000000
82a6f3fedcSAlexey Lapshin nreloc: 0
83a6f3fedcSAlexey Lapshin flags: 0x80000400
84a6f3fedcSAlexey Lapshin reserved1: 0x00000000
85a6f3fedcSAlexey Lapshin reserved2: 0x00000000
86a6f3fedcSAlexey Lapshin reserved3: 0x00000000
87a6f3fedcSAlexey Lapshin ...
882dc4a80eSAlexey Lapshin )";
892dc4a80eSAlexey Lapshin
902dc4a80eSAlexey Lapshin const char *SimpleFileWasmYAML = R"(
912dc4a80eSAlexey Lapshin --- !WASM
922dc4a80eSAlexey Lapshin FileHeader:
932dc4a80eSAlexey Lapshin Version: 0x00000001
942dc4a80eSAlexey Lapshin Sections:
952dc4a80eSAlexey Lapshin - Type: CUSTOM
962dc4a80eSAlexey Lapshin Name: text
972dc4a80eSAlexey Lapshin Payload: ABC123
982dc4a80eSAlexey Lapshin ...
992dc4a80eSAlexey Lapshin )";
1002dc4a80eSAlexey Lapshin
1012dc4a80eSAlexey Lapshin // Create ObjectFile from \p YamlCreationString and do validation using \p
1022dc4a80eSAlexey Lapshin // IsValidFormat checker. \p Storage is a storage for data. \returns created
1032dc4a80eSAlexey Lapshin // ObjectFile.
createObjectFileFromYamlDescription(const char * YamlCreationString,SmallVector<char> & Storage,function_ref<bool (const Binary & File)> IsValidFormat)1042dc4a80eSAlexey Lapshin Expected<std::unique_ptr<ObjectFile>> createObjectFileFromYamlDescription(
1052dc4a80eSAlexey Lapshin const char *YamlCreationString, SmallVector<char> &Storage,
1062dc4a80eSAlexey Lapshin function_ref<bool(const Binary &File)> IsValidFormat) {
1072dc4a80eSAlexey Lapshin auto ErrHandler = [&](const Twine &Msg) { FAIL() << "Error: " << Msg; };
1082dc4a80eSAlexey Lapshin
1092dc4a80eSAlexey Lapshin std::unique_ptr<ObjectFile> Obj =
1102dc4a80eSAlexey Lapshin yaml2ObjectFile(Storage, YamlCreationString, ErrHandler);
1112dc4a80eSAlexey Lapshin if (!Obj)
1122dc4a80eSAlexey Lapshin return createError("could not create ObjectFile from yaml description");
1132dc4a80eSAlexey Lapshin
1142dc4a80eSAlexey Lapshin if (!IsValidFormat(*Obj))
1152dc4a80eSAlexey Lapshin return createError("wrong file format");
1162dc4a80eSAlexey Lapshin
117*dedf006fSAlexey Lapshin return std::move(Obj);
1182dc4a80eSAlexey Lapshin }
1192dc4a80eSAlexey Lapshin
1202dc4a80eSAlexey Lapshin // Call objcopy::executeObjcopyOnBinary for \p Config and \p In. \p DataVector
1212dc4a80eSAlexey Lapshin // is a holder for data. \returns Binary for copied data.
1222dc4a80eSAlexey Lapshin Expected<std::unique_ptr<Binary>>
callObjCopy(ConfigManager & Config,object::Binary & In,SmallVector<char> & DataVector,function_ref<bool (const Binary & File)> IsValidFormat)1232dc4a80eSAlexey Lapshin callObjCopy(ConfigManager &Config, object::Binary &In,
1242dc4a80eSAlexey Lapshin SmallVector<char> &DataVector,
1252dc4a80eSAlexey Lapshin function_ref<bool(const Binary &File)> IsValidFormat) {
1262dc4a80eSAlexey Lapshin raw_svector_ostream OutStream(DataVector);
1272dc4a80eSAlexey Lapshin
1282dc4a80eSAlexey Lapshin if (Error Err = objcopy::executeObjcopyOnBinary(Config, In, OutStream))
1292dc4a80eSAlexey Lapshin return std::move(Err);
1302dc4a80eSAlexey Lapshin
1312dc4a80eSAlexey Lapshin MemoryBufferRef Buffer(StringRef(DataVector.data(), DataVector.size()),
1322dc4a80eSAlexey Lapshin Config.Common.OutputFilename);
1332dc4a80eSAlexey Lapshin
1342dc4a80eSAlexey Lapshin Expected<std::unique_ptr<Binary>> Result = createBinary(Buffer);
1352dc4a80eSAlexey Lapshin
1362dc4a80eSAlexey Lapshin // Check copied file.
1372dc4a80eSAlexey Lapshin if (!Result)
1382dc4a80eSAlexey Lapshin return Result;
1392dc4a80eSAlexey Lapshin
1402dc4a80eSAlexey Lapshin if (!IsValidFormat(**Result))
1412dc4a80eSAlexey Lapshin return createError("wrong file format");
1422dc4a80eSAlexey Lapshin
1432dc4a80eSAlexey Lapshin if (!(*Result)->isObject())
1442dc4a80eSAlexey Lapshin return createError("binary is not object file");
1452dc4a80eSAlexey Lapshin
1462dc4a80eSAlexey Lapshin return Result;
1472dc4a80eSAlexey Lapshin }
1482dc4a80eSAlexey Lapshin
1492dc4a80eSAlexey Lapshin // \returns true if specified \p File has a section named \p SectionName.
hasSection(ObjectFile & File,StringRef SectionName)1502dc4a80eSAlexey Lapshin bool hasSection(ObjectFile &File, StringRef SectionName) {
1512dc4a80eSAlexey Lapshin for (const object::SectionRef &Sec : File.sections()) {
1522dc4a80eSAlexey Lapshin Expected<StringRef> CurSecNameOrErr = Sec.getName();
1532dc4a80eSAlexey Lapshin if (!CurSecNameOrErr)
1542dc4a80eSAlexey Lapshin continue;
1552dc4a80eSAlexey Lapshin
1562dc4a80eSAlexey Lapshin if (*CurSecNameOrErr == SectionName)
1572dc4a80eSAlexey Lapshin return true;
1582dc4a80eSAlexey Lapshin }
1592dc4a80eSAlexey Lapshin
1602dc4a80eSAlexey Lapshin return false;
1612dc4a80eSAlexey Lapshin }
1622dc4a80eSAlexey Lapshin
1632dc4a80eSAlexey Lapshin // Check that specified \p File has a section \p SectionName and its data
1642dc4a80eSAlexey Lapshin // matches \p SectionData.
checkSectionData(ObjectFile & File,StringRef SectionName,StringRef SectionData)1652dc4a80eSAlexey Lapshin void checkSectionData(ObjectFile &File, StringRef SectionName,
1662dc4a80eSAlexey Lapshin StringRef SectionData) {
1672dc4a80eSAlexey Lapshin for (const object::SectionRef &Sec : File.sections()) {
1682dc4a80eSAlexey Lapshin Expected<StringRef> CurSecNameOrErr = Sec.getName();
1692dc4a80eSAlexey Lapshin ASSERT_THAT_EXPECTED(CurSecNameOrErr, Succeeded());
1702dc4a80eSAlexey Lapshin
1712dc4a80eSAlexey Lapshin if (*CurSecNameOrErr == SectionName) {
1722dc4a80eSAlexey Lapshin Expected<StringRef> CurSectionData = Sec.getContents();
1732dc4a80eSAlexey Lapshin ASSERT_THAT_EXPECTED(CurSectionData, Succeeded());
1742dc4a80eSAlexey Lapshin EXPECT_TRUE(Sec.getSize() == SectionData.size());
1752dc4a80eSAlexey Lapshin EXPECT_TRUE(memcmp(CurSectionData->data(), SectionData.data(),
1762dc4a80eSAlexey Lapshin SectionData.size()) == 0);
1772dc4a80eSAlexey Lapshin return;
1782dc4a80eSAlexey Lapshin }
1792dc4a80eSAlexey Lapshin }
1802dc4a80eSAlexey Lapshin
1812dc4a80eSAlexey Lapshin // Section SectionName must be presented.
1822dc4a80eSAlexey Lapshin EXPECT_TRUE(false);
1832dc4a80eSAlexey Lapshin }
1842dc4a80eSAlexey Lapshin
copySimpleInMemoryFileImpl(const char * YamlCreationString,function_ref<bool (const Binary & File)> IsValidFormat)1852dc4a80eSAlexey Lapshin void copySimpleInMemoryFileImpl(
1862dc4a80eSAlexey Lapshin const char *YamlCreationString,
1872dc4a80eSAlexey Lapshin function_ref<bool(const Binary &File)> IsValidFormat) {
1882dc4a80eSAlexey Lapshin SCOPED_TRACE("copySimpleInMemoryFileImpl");
1892dc4a80eSAlexey Lapshin
1902dc4a80eSAlexey Lapshin // Create Object file from YAML description.
1912dc4a80eSAlexey Lapshin SmallVector<char> Storage;
1922dc4a80eSAlexey Lapshin Expected<std::unique_ptr<ObjectFile>> Obj =
1932dc4a80eSAlexey Lapshin createObjectFileFromYamlDescription(YamlCreationString, Storage,
1942dc4a80eSAlexey Lapshin IsValidFormat);
1952dc4a80eSAlexey Lapshin ASSERT_THAT_EXPECTED(Obj, Succeeded());
1962dc4a80eSAlexey Lapshin
1972dc4a80eSAlexey Lapshin ConfigManager Config;
1982dc4a80eSAlexey Lapshin Config.Common.OutputFilename = "a.out";
1992dc4a80eSAlexey Lapshin
2002dc4a80eSAlexey Lapshin // Call executeObjcopyOnBinary()
2012dc4a80eSAlexey Lapshin SmallVector<char> DataVector;
2022dc4a80eSAlexey Lapshin Expected<std::unique_ptr<Binary>> Result =
2032dc4a80eSAlexey Lapshin callObjCopy(Config, *Obj.get(), DataVector, IsValidFormat);
2042dc4a80eSAlexey Lapshin ASSERT_THAT_EXPECTED(Result, Succeeded());
2052dc4a80eSAlexey Lapshin }
2062dc4a80eSAlexey Lapshin
TEST(CopySimpleInMemoryFile,COFF)2072dc4a80eSAlexey Lapshin TEST(CopySimpleInMemoryFile, COFF) {
2082dc4a80eSAlexey Lapshin SCOPED_TRACE("CopySimpleInMemoryFileCOFF");
2092dc4a80eSAlexey Lapshin
2102dc4a80eSAlexey Lapshin copySimpleInMemoryFileImpl(SimpleFileCOFFYAML,
2112dc4a80eSAlexey Lapshin [](const Binary &File) { return File.isCOFF(); });
2122dc4a80eSAlexey Lapshin }
2132dc4a80eSAlexey Lapshin
TEST(CopySimpleInMemoryFile,ELF)2142dc4a80eSAlexey Lapshin TEST(CopySimpleInMemoryFile, ELF) {
2152dc4a80eSAlexey Lapshin SCOPED_TRACE("CopySimpleInMemoryFileELF");
2162dc4a80eSAlexey Lapshin
2172dc4a80eSAlexey Lapshin copySimpleInMemoryFileImpl(SimpleFileELFYAML,
2182dc4a80eSAlexey Lapshin [](const Binary &File) { return File.isELF(); });
2192dc4a80eSAlexey Lapshin }
2202dc4a80eSAlexey Lapshin
TEST(CopySimpleInMemoryFile,MachO)2212dc4a80eSAlexey Lapshin TEST(CopySimpleInMemoryFile, MachO) {
2222dc4a80eSAlexey Lapshin SCOPED_TRACE("CopySimpleInMemoryFileMachO");
2232dc4a80eSAlexey Lapshin
2242dc4a80eSAlexey Lapshin copySimpleInMemoryFileImpl(SimpleFileMachOYAML,
2252dc4a80eSAlexey Lapshin [](const Binary &File) { return File.isMachO(); });
2262dc4a80eSAlexey Lapshin }
2272dc4a80eSAlexey Lapshin
TEST(CopySimpleInMemoryFile,Wasm)2282dc4a80eSAlexey Lapshin TEST(CopySimpleInMemoryFile, Wasm) {
2292dc4a80eSAlexey Lapshin SCOPED_TRACE("CopySimpleInMemoryFileWasm");
2302dc4a80eSAlexey Lapshin
2312dc4a80eSAlexey Lapshin copySimpleInMemoryFileImpl(SimpleFileWasmYAML,
2322dc4a80eSAlexey Lapshin [](const Binary &File) { return File.isWasm(); });
2332dc4a80eSAlexey Lapshin }
2342dc4a80eSAlexey Lapshin
2352dc4a80eSAlexey Lapshin enum Action : uint8_t { AddSection, UpdateSection };
2362dc4a80eSAlexey Lapshin
addOrUpdateSectionToFileImpl(const char * YamlCreationString,function_ref<bool (const Binary & File)> IsValidFormat,StringRef NewSectionName,StringRef NewSectionData,Action SectionAction)2372dc4a80eSAlexey Lapshin void addOrUpdateSectionToFileImpl(
2382dc4a80eSAlexey Lapshin const char *YamlCreationString,
2392dc4a80eSAlexey Lapshin function_ref<bool(const Binary &File)> IsValidFormat,
2402dc4a80eSAlexey Lapshin StringRef NewSectionName, StringRef NewSectionData, Action SectionAction) {
2412dc4a80eSAlexey Lapshin SCOPED_TRACE("addOrUpdateSectionToFileImpl");
2422dc4a80eSAlexey Lapshin
2432dc4a80eSAlexey Lapshin // Create Object file from YAML description.
2442dc4a80eSAlexey Lapshin SmallVector<char> Storage;
2452dc4a80eSAlexey Lapshin Expected<std::unique_ptr<ObjectFile>> Obj =
2462dc4a80eSAlexey Lapshin createObjectFileFromYamlDescription(YamlCreationString, Storage,
2472dc4a80eSAlexey Lapshin IsValidFormat);
2482dc4a80eSAlexey Lapshin ASSERT_THAT_EXPECTED(Obj, Succeeded());
2492dc4a80eSAlexey Lapshin
2502dc4a80eSAlexey Lapshin std::unique_ptr<MemoryBuffer> NewSectionBuffer =
2512dc4a80eSAlexey Lapshin MemoryBuffer::getMemBuffer(NewSectionData, NewSectionName, false);
2522dc4a80eSAlexey Lapshin std::string Name;
2532dc4a80eSAlexey Lapshin if ((*Obj)->isMachO())
2542dc4a80eSAlexey Lapshin Name = "__TEXT," + NewSectionName.str();
2552dc4a80eSAlexey Lapshin else
2562dc4a80eSAlexey Lapshin Name = NewSectionName.str();
2572dc4a80eSAlexey Lapshin
2582dc4a80eSAlexey Lapshin ConfigManager Config;
2592dc4a80eSAlexey Lapshin Config.Common.OutputFilename = "a.out";
2602dc4a80eSAlexey Lapshin if (SectionAction == AddSection)
2612dc4a80eSAlexey Lapshin Config.Common.AddSection.push_back({Name, std::move(NewSectionBuffer)});
2622dc4a80eSAlexey Lapshin else
2632dc4a80eSAlexey Lapshin Config.Common.UpdateSection.push_back({Name, std::move(NewSectionBuffer)});
2642dc4a80eSAlexey Lapshin
2652dc4a80eSAlexey Lapshin // Call executeObjcopyOnBinary()
2662dc4a80eSAlexey Lapshin SmallVector<char> DataVector;
2672dc4a80eSAlexey Lapshin Expected<std::unique_ptr<Binary>> Result =
2682dc4a80eSAlexey Lapshin callObjCopy(Config, *Obj.get(), DataVector, IsValidFormat);
2692dc4a80eSAlexey Lapshin ASSERT_THAT_EXPECTED(Result, Succeeded());
2702dc4a80eSAlexey Lapshin
2712dc4a80eSAlexey Lapshin // Check that copied file has the new section.
2722dc4a80eSAlexey Lapshin checkSectionData(*static_cast<ObjectFile *>((*Result).get()), NewSectionName,
2732dc4a80eSAlexey Lapshin NewSectionData);
2742dc4a80eSAlexey Lapshin }
2752dc4a80eSAlexey Lapshin
TEST(AddSection,COFF)2762dc4a80eSAlexey Lapshin TEST(AddSection, COFF) {
2772dc4a80eSAlexey Lapshin SCOPED_TRACE("addSectionToFileCOFF");
2782dc4a80eSAlexey Lapshin
2792dc4a80eSAlexey Lapshin addOrUpdateSectionToFileImpl(
2802dc4a80eSAlexey Lapshin SimpleFileCOFFYAML, [](const Binary &File) { return File.isCOFF(); },
2812dc4a80eSAlexey Lapshin ".foo", "1234", AddSection);
2822dc4a80eSAlexey Lapshin }
2832dc4a80eSAlexey Lapshin
TEST(AddSection,ELF)2842dc4a80eSAlexey Lapshin TEST(AddSection, ELF) {
2852dc4a80eSAlexey Lapshin SCOPED_TRACE("addSectionToFileELF");
2862dc4a80eSAlexey Lapshin
2872dc4a80eSAlexey Lapshin addOrUpdateSectionToFileImpl(
2882dc4a80eSAlexey Lapshin SimpleFileELFYAML, [](const Binary &File) { return File.isELF(); },
2892dc4a80eSAlexey Lapshin ".foo", "1234", AddSection);
2902dc4a80eSAlexey Lapshin }
2912dc4a80eSAlexey Lapshin
TEST(AddSection,MachO)2922dc4a80eSAlexey Lapshin TEST(AddSection, MachO) {
2932dc4a80eSAlexey Lapshin SCOPED_TRACE("addSectionToFileMachO");
2942dc4a80eSAlexey Lapshin
2952dc4a80eSAlexey Lapshin addOrUpdateSectionToFileImpl(
2962dc4a80eSAlexey Lapshin SimpleFileMachOYAML, [](const Binary &File) { return File.isMachO(); },
2972dc4a80eSAlexey Lapshin "__foo", "1234", AddSection);
298a6f3fedcSAlexey Lapshin }
299a6f3fedcSAlexey Lapshin
TEST(AddSection,Wasm)300a6f3fedcSAlexey Lapshin TEST(AddSection, Wasm) {
301a6f3fedcSAlexey Lapshin SCOPED_TRACE("addSectionToFileWasm");
302a6f3fedcSAlexey Lapshin
303a6f3fedcSAlexey Lapshin addOrUpdateSectionToFileImpl(
3042dc4a80eSAlexey Lapshin SimpleFileWasmYAML, [](const Binary &File) { return File.isWasm(); },
3052dc4a80eSAlexey Lapshin ".foo", "1234", AddSection);
306a6f3fedcSAlexey Lapshin }
307a6f3fedcSAlexey Lapshin
TEST(UpdateSection,COFF)308a6f3fedcSAlexey Lapshin TEST(UpdateSection, COFF) {
309a6f3fedcSAlexey Lapshin SCOPED_TRACE("updateSectionToFileCOFF");
310a6f3fedcSAlexey Lapshin
311a6f3fedcSAlexey Lapshin addOrUpdateSectionToFileImpl(
3122dc4a80eSAlexey Lapshin SimpleFileCOFFYAML, [](const Binary &File) { return File.isCOFF(); },
3132dc4a80eSAlexey Lapshin ".text", "1234", UpdateSection);
314a6f3fedcSAlexey Lapshin }
315a6f3fedcSAlexey Lapshin
TEST(UpdateSection,ELF)316a6f3fedcSAlexey Lapshin TEST(UpdateSection, ELF) {
317a6f3fedcSAlexey Lapshin SCOPED_TRACE("updateSectionToFileELF");
318a6f3fedcSAlexey Lapshin
319a6f3fedcSAlexey Lapshin addOrUpdateSectionToFileImpl(
3202dc4a80eSAlexey Lapshin SimpleFileELFYAML, [](const Binary &File) { return File.isELF(); },
3212dc4a80eSAlexey Lapshin ".text", "1234", UpdateSection);
322a6f3fedcSAlexey Lapshin }
323a6f3fedcSAlexey Lapshin
TEST(UpdateSection,MachO)324a6f3fedcSAlexey Lapshin TEST(UpdateSection, MachO) {
325a6f3fedcSAlexey Lapshin SCOPED_TRACE("updateSectionToFileMachO");
326a6f3fedcSAlexey Lapshin
327a6f3fedcSAlexey Lapshin addOrUpdateSectionToFileImpl(
3282dc4a80eSAlexey Lapshin SimpleFileMachOYAML, [](const Binary &File) { return File.isMachO(); },
3292dc4a80eSAlexey Lapshin "__text", "1234", UpdateSection);
3302dc4a80eSAlexey Lapshin }
3312dc4a80eSAlexey Lapshin
removeSectionByPatternImpl(const char * YamlCreationString,function_ref<bool (const Binary & File)> IsValidFormat,StringRef SectionWildcard,StringRef SectionName)3322dc4a80eSAlexey Lapshin void removeSectionByPatternImpl(
3332dc4a80eSAlexey Lapshin const char *YamlCreationString,
3342dc4a80eSAlexey Lapshin function_ref<bool(const Binary &File)> IsValidFormat,
3352dc4a80eSAlexey Lapshin StringRef SectionWildcard, StringRef SectionName) {
3362dc4a80eSAlexey Lapshin SCOPED_TRACE("removeSectionByPatternImpl");
3372dc4a80eSAlexey Lapshin
3382dc4a80eSAlexey Lapshin // Create Object file from YAML description.
3392dc4a80eSAlexey Lapshin SmallVector<char> Storage;
3402dc4a80eSAlexey Lapshin Expected<std::unique_ptr<ObjectFile>> Obj =
3412dc4a80eSAlexey Lapshin createObjectFileFromYamlDescription(YamlCreationString, Storage,
3422dc4a80eSAlexey Lapshin IsValidFormat);
3432dc4a80eSAlexey Lapshin ASSERT_THAT_EXPECTED(Obj, Succeeded());
3442dc4a80eSAlexey Lapshin
3452dc4a80eSAlexey Lapshin // Check that section is present.
3462dc4a80eSAlexey Lapshin EXPECT_TRUE(hasSection(**Obj, SectionName));
3472dc4a80eSAlexey Lapshin
3482dc4a80eSAlexey Lapshin Expected<NameOrPattern> Pattern = objcopy::NameOrPattern::create(
3492dc4a80eSAlexey Lapshin SectionWildcard, objcopy::MatchStyle::Wildcard,
3502dc4a80eSAlexey Lapshin [](Error Err) { return Err; });
3512dc4a80eSAlexey Lapshin
3522dc4a80eSAlexey Lapshin ConfigManager Config;
3532dc4a80eSAlexey Lapshin Config.Common.OutputFilename = "a.out";
3542dc4a80eSAlexey Lapshin EXPECT_THAT_ERROR(Config.Common.ToRemove.addMatcher(std::move(Pattern)),
3552dc4a80eSAlexey Lapshin Succeeded());
3562dc4a80eSAlexey Lapshin
3572dc4a80eSAlexey Lapshin SmallVector<char> DataVector;
3582dc4a80eSAlexey Lapshin Expected<std::unique_ptr<Binary>> Result =
3592dc4a80eSAlexey Lapshin callObjCopy(Config, *Obj.get(), DataVector, IsValidFormat);
3602dc4a80eSAlexey Lapshin ASSERT_THAT_EXPECTED(Result, Succeeded());
3612dc4a80eSAlexey Lapshin
3622dc4a80eSAlexey Lapshin // Check that section was removed.
3632dc4a80eSAlexey Lapshin EXPECT_FALSE(
3642dc4a80eSAlexey Lapshin hasSection(*static_cast<ObjectFile *>((*Result).get()), SectionName));
3652dc4a80eSAlexey Lapshin }
3662dc4a80eSAlexey Lapshin
TEST(RemoveSectionByPattern,COFF)3672dc4a80eSAlexey Lapshin TEST(RemoveSectionByPattern, COFF) {
3682dc4a80eSAlexey Lapshin SCOPED_TRACE("removeSectionByPatternCOFF");
3692dc4a80eSAlexey Lapshin
3702dc4a80eSAlexey Lapshin removeSectionByPatternImpl(
3712dc4a80eSAlexey Lapshin SimpleFileCOFFYAML, [](const Binary &File) { return File.isCOFF(); },
3722dc4a80eSAlexey Lapshin "\\.text*", ".text");
3732dc4a80eSAlexey Lapshin }
3742dc4a80eSAlexey Lapshin
TEST(RemoveSectionByPattern,ELF)3752dc4a80eSAlexey Lapshin TEST(RemoveSectionByPattern, ELF) {
3762dc4a80eSAlexey Lapshin SCOPED_TRACE("removeSectionByPatternELF");
3772dc4a80eSAlexey Lapshin
3782dc4a80eSAlexey Lapshin removeSectionByPatternImpl(
3792dc4a80eSAlexey Lapshin SimpleFileELFYAML, [](const Binary &File) { return File.isELF(); },
3802dc4a80eSAlexey Lapshin "\\.text*", ".text");
3812dc4a80eSAlexey Lapshin }
3822dc4a80eSAlexey Lapshin
TEST(RemoveSectionByPattern,MachO)3832dc4a80eSAlexey Lapshin TEST(RemoveSectionByPattern, MachO) {
3842dc4a80eSAlexey Lapshin SCOPED_TRACE("removeSectionByPatternMachO");
3852dc4a80eSAlexey Lapshin
3862dc4a80eSAlexey Lapshin removeSectionByPatternImpl(
3872dc4a80eSAlexey Lapshin SimpleFileMachOYAML, [](const Binary &File) { return File.isMachO(); },
3882dc4a80eSAlexey Lapshin "__TEXT,__text*", "__text");
3892dc4a80eSAlexey Lapshin }
3902dc4a80eSAlexey Lapshin
TEST(RemoveSectionByPattern,Wasm)3912dc4a80eSAlexey Lapshin TEST(RemoveSectionByPattern, Wasm) {
3922dc4a80eSAlexey Lapshin SCOPED_TRACE("removeSectionByPatternWasm");
3932dc4a80eSAlexey Lapshin
3942dc4a80eSAlexey Lapshin removeSectionByPatternImpl(
3952dc4a80eSAlexey Lapshin SimpleFileWasmYAML, [](const Binary &File) { return File.isWasm(); },
3962dc4a80eSAlexey Lapshin "text*", "text");
397a6f3fedcSAlexey Lapshin }
398