forked from OSchip/llvm-project
Replace trivial use of external rc.exe by writing our own .res file.
This patch removes the dependency on the external rc.exe tool by writing a simple .res file using our own library. In this patch I also added an explicit definition for the .res file magic. Furthermore, I added a unittest for embeded manifests and fixed a bug exposed by the test. llvm-svn: 306311
This commit is contained in:
parent
393b55ffe2
commit
2a81089116
|
@ -20,6 +20,7 @@
|
||||||
#include "Symbols.h"
|
#include "Symbols.h"
|
||||||
#include "llvm/ADT/Optional.h"
|
#include "llvm/ADT/Optional.h"
|
||||||
#include "llvm/ADT/StringSwitch.h"
|
#include "llvm/ADT/StringSwitch.h"
|
||||||
|
#include "llvm/BinaryFormat/COFF.h"
|
||||||
#include "llvm/Object/COFF.h"
|
#include "llvm/Object/COFF.h"
|
||||||
#include "llvm/Object/WindowsResource.h"
|
#include "llvm/Object/WindowsResource.h"
|
||||||
#include "llvm/Option/Arg.h"
|
#include "llvm/Option/Arg.h"
|
||||||
|
@ -27,6 +28,7 @@
|
||||||
#include "llvm/Option/Option.h"
|
#include "llvm/Option/Option.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
#include "llvm/Support/FileUtilities.h"
|
#include "llvm/Support/FileUtilities.h"
|
||||||
|
#include "llvm/Support/MathExtras.h"
|
||||||
#include "llvm/Support/Process.h"
|
#include "llvm/Support/Process.h"
|
||||||
#include "llvm/Support/Program.h"
|
#include "llvm/Support/Program.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
@ -42,6 +44,9 @@ namespace lld {
|
||||||
namespace coff {
|
namespace coff {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
const uint16_t SUBLANG_ENGLISH_US = 0x0409;
|
||||||
|
const uint16_t RT_MANIFEST = 24;
|
||||||
|
|
||||||
class Executor {
|
class Executor {
|
||||||
public:
|
public:
|
||||||
explicit Executor(StringRef S) : Prog(Saver.save(S)) {}
|
explicit Executor(StringRef S) : Prog(Saver.save(S)) {}
|
||||||
|
@ -258,26 +263,6 @@ void parseManifestUAC(StringRef Arg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quote each line with "". Existing double-quote is converted
|
|
||||||
// to two double-quotes.
|
|
||||||
static void quoteAndPrint(raw_ostream &Out, StringRef S) {
|
|
||||||
while (!S.empty()) {
|
|
||||||
StringRef Line;
|
|
||||||
std::tie(Line, S) = S.split("\n");
|
|
||||||
if (Line.empty())
|
|
||||||
continue;
|
|
||||||
Out << '\"';
|
|
||||||
for (int I = 0, E = Line.size(); I != E; ++I) {
|
|
||||||
if (Line[I] == '\"') {
|
|
||||||
Out << "\"\"";
|
|
||||||
} else {
|
|
||||||
Out << Line[I];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Out << "\"\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// An RAII temporary file class that automatically removes a temporary file.
|
// An RAII temporary file class that automatically removes a temporary file.
|
||||||
namespace {
|
namespace {
|
||||||
class TemporaryFile {
|
class TemporaryFile {
|
||||||
|
@ -391,38 +376,64 @@ static std::string createManifestXml() {
|
||||||
return readFile(File2.Path);
|
return readFile(File2.Path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::unique_ptr<MemoryBuffer>
|
||||||
|
createMemoryBufferForManifestRes(size_t ManifestSize) {
|
||||||
|
size_t ResSize = alignTo(object::WIN_RES_MAGIC_SIZE +
|
||||||
|
object::WIN_RES_NULL_ENTRY_SIZE +
|
||||||
|
sizeof(object::WinResHeaderPrefix) +
|
||||||
|
sizeof(object::WinResIDs) +
|
||||||
|
sizeof(object::WinResHeaderSuffix) +
|
||||||
|
ManifestSize,
|
||||||
|
object::WIN_RES_DATA_ALIGNMENT);
|
||||||
|
return MemoryBuffer::getNewMemBuffer(ResSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void writeResFileHeader(char *&Buf) {
|
||||||
|
memcpy(Buf, COFF::WinResMagic, sizeof(COFF::WinResMagic));
|
||||||
|
Buf += sizeof(COFF::WinResMagic);
|
||||||
|
memset(Buf, 0, object::WIN_RES_NULL_ENTRY_SIZE);
|
||||||
|
Buf += object::WIN_RES_NULL_ENTRY_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void writeResEntryHeader(char *&Buf, size_t ManifestSize) {
|
||||||
|
// Write the prefix.
|
||||||
|
auto *Prefix = reinterpret_cast<object::WinResHeaderPrefix *>(Buf);
|
||||||
|
Prefix->DataSize = ManifestSize;
|
||||||
|
Prefix->HeaderSize = sizeof(object::WinResHeaderPrefix) +
|
||||||
|
sizeof(object::WinResIDs) +
|
||||||
|
sizeof(object::WinResHeaderSuffix);
|
||||||
|
Buf += sizeof(object::WinResHeaderPrefix);
|
||||||
|
|
||||||
|
// Write the Type/Name IDs.
|
||||||
|
auto *IDs = reinterpret_cast<object::WinResIDs *>(Buf);
|
||||||
|
IDs->setType(RT_MANIFEST);
|
||||||
|
IDs->setName(Config->ManifestID);
|
||||||
|
Buf += sizeof(object::WinResIDs);
|
||||||
|
|
||||||
|
// Write the suffix.
|
||||||
|
auto *Suffix = reinterpret_cast<object::WinResHeaderSuffix *>(Buf);
|
||||||
|
Suffix->DataVersion = 0;
|
||||||
|
Suffix->MemoryFlags = object::WIN_RES_PURE_MOVEABLE;
|
||||||
|
Suffix->Language = SUBLANG_ENGLISH_US;
|
||||||
|
Suffix->Version = 0;
|
||||||
|
Suffix->Characteristics = 0;
|
||||||
|
Buf += sizeof(object::WinResHeaderSuffix);
|
||||||
|
}
|
||||||
|
|
||||||
// Create a resource file containing a manifest XML.
|
// Create a resource file containing a manifest XML.
|
||||||
std::unique_ptr<MemoryBuffer> createManifestRes() {
|
std::unique_ptr<MemoryBuffer> createManifestRes() {
|
||||||
// Create a temporary file for the resource script file.
|
std::string Manifest = createManifestXml();
|
||||||
TemporaryFile RCFile("manifest", "rc");
|
|
||||||
|
|
||||||
// Open the temporary file for writing.
|
std::unique_ptr<MemoryBuffer> Res =
|
||||||
std::error_code EC;
|
createMemoryBufferForManifestRes(Manifest.size());
|
||||||
raw_fd_ostream Out(RCFile.Path, EC, sys::fs::F_Text);
|
|
||||||
if (EC)
|
|
||||||
fatal(EC, "failed to open " + RCFile.Path);
|
|
||||||
|
|
||||||
// Write resource script to the RC file.
|
char *Buf = const_cast<char *>(Res->getBufferStart());
|
||||||
Out << "#define LANG_ENGLISH 9\n"
|
writeResFileHeader(Buf);
|
||||||
<< "#define SUBLANG_DEFAULT 1\n"
|
writeResEntryHeader(Buf, Manifest.size());
|
||||||
<< "#define APP_MANIFEST " << Config->ManifestID << "\n"
|
|
||||||
<< "#define RT_MANIFEST 24\n"
|
|
||||||
<< "LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT\n"
|
|
||||||
<< "APP_MANIFEST RT_MANIFEST {\n";
|
|
||||||
quoteAndPrint(Out, createManifestXml());
|
|
||||||
Out << "}\n";
|
|
||||||
Out.close();
|
|
||||||
|
|
||||||
// Create output resource file.
|
// Copy the manifest data into the .res file.
|
||||||
TemporaryFile ResFile("output-resource", "res");
|
std::copy(Manifest.begin(), Manifest.end(), Buf);
|
||||||
|
return std::move(Res);
|
||||||
Executor E("rc.exe");
|
|
||||||
E.add("/fo");
|
|
||||||
E.add(ResFile.Path);
|
|
||||||
E.add("/nologo");
|
|
||||||
E.add(RCFile.Path);
|
|
||||||
E.run();
|
|
||||||
return ResFile.getMemoryBuffer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void createSideBySideManifest() {
|
void createSideBySideManifest() {
|
||||||
|
|
|
@ -8,3 +8,28 @@
|
||||||
|
|
||||||
CHECK: <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
CHECK: <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
CHECK: <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"><dependency><dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity></dependentAssembly></dependency><trustInfo><security><requestedPrivileges><requestedExecutionLevel level="requireAdministrator" uiAccess="false"></requestedExecutionLevel></requestedPrivileges></security></trustInfo></assembly>
|
CHECK: <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"><dependency><dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity></dependentAssembly></dependency><trustInfo><security><requestedPrivileges><requestedExecutionLevel level="requireAdministrator" uiAccess="false"></requestedExecutionLevel></requestedPrivileges></security></trustInfo></assembly>
|
||||||
|
|
||||||
|
# RUN: yaml2obj %p/Inputs/ret42.yaml > %t.obj
|
||||||
|
# RUN: lld-link /out:%t.exe /entry:main \
|
||||||
|
# RUN: /manifest:embed \
|
||||||
|
# RUN: /manifestuac:"level='requireAdministrator'" \
|
||||||
|
# RUN: /manifestinput:%p/Inputs/manifestinput.test %t.obj
|
||||||
|
# RUN: llvm-readobj -coff-resources -file-headers %t.exe | FileCheck %s \
|
||||||
|
# RUN: -check-prefix TEST_EMBED
|
||||||
|
|
||||||
|
TEST_EMBED: ResourceTableRVA: 0x1000
|
||||||
|
TEST_EMBED-NEXT: ResourceTableSize: 0x298
|
||||||
|
TEST_EMBED-DAG: Resources [
|
||||||
|
TEST_EMBED-NEXT: Total Number of Resources: 1
|
||||||
|
TEST_EMBED-DAG: Number of String Entries: 0
|
||||||
|
TEST_EMBED-NEXT: Number of ID Entries: 1
|
||||||
|
TEST_EMBED-NEXT: Type: kRT_MANIFEST (ID 24) [
|
||||||
|
TEST_EMBED-NEXT: Table Offset: 0x18
|
||||||
|
TEST_EMBED-NEXT: Number of String Entries: 0
|
||||||
|
TEST_EMBED-NEXT: Number of ID Entries: 1
|
||||||
|
TEST_EMBED-NEXT: Name: (ID 1) [
|
||||||
|
TEST_EMBED-NEXT: Table Offset: 0x30
|
||||||
|
TEST_EMBED-NEXT: Number of String Entries: 0
|
||||||
|
TEST_EMBED-NEXT: Number of ID Entries: 1
|
||||||
|
TEST_EMBED-NEXT: Language: (ID 1033) [
|
||||||
|
TEST_EMBED-NEXT: Entry Offset: 0x48
|
||||||
|
|
|
@ -262,6 +262,7 @@ llvm_config_cmd.wait()
|
||||||
# Set a fake constant version so that we get consitent output.
|
# Set a fake constant version so that we get consitent output.
|
||||||
config.environment['LLD_VERSION'] = 'LLD 1.0'
|
config.environment['LLD_VERSION'] = 'LLD 1.0'
|
||||||
|
|
||||||
# Check if the mt.exe Microsoft utility exists.
|
# Indirectly check if the mt.exe Microsoft utility exists by searching for
|
||||||
if lit.util.which('mt.exe', config.environment['PATH']):
|
# cvtres, which always accompanies it.
|
||||||
|
if lit.util.which('cvtres', config.environment['PATH']):
|
||||||
config.available_features.add('win_mt')
|
config.available_features.add('win_mt')
|
||||||
|
|
|
@ -46,6 +46,12 @@ static const char ClGlObjMagic[] = {
|
||||||
'\xac', '\x9b', '\xd6', '\xb6', '\x22', '\x26', '\x53', '\xc2',
|
'\xac', '\x9b', '\xd6', '\xb6', '\x22', '\x26', '\x53', '\xc2',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// The signature bytes that start a .res file.
|
||||||
|
static const char WinResMagic[] = {
|
||||||
|
'\x00', '\x00', '\x00', '\x00', '\x20', '\x00', '\x00', '\x00',
|
||||||
|
'\xff', '\xff', '\x00', '\x00', '\xff', '\xff', '\x00', '\x00',
|
||||||
|
};
|
||||||
|
|
||||||
// Sizes in bytes of various things in the COFF format.
|
// Sizes in bytes of various things in the COFF format.
|
||||||
enum {
|
enum {
|
||||||
Header16Size = 20,
|
Header16Size = 20,
|
||||||
|
|
|
@ -47,6 +47,44 @@ namespace object {
|
||||||
|
|
||||||
class WindowsResource;
|
class WindowsResource;
|
||||||
|
|
||||||
|
const size_t WIN_RES_MAGIC_SIZE = 16;
|
||||||
|
const size_t WIN_RES_NULL_ENTRY_SIZE = 16;
|
||||||
|
const uint32_t WIN_RES_HEADER_ALIGNMENT = 4;
|
||||||
|
const uint32_t WIN_RES_DATA_ALIGNMENT = 4;
|
||||||
|
const uint16_t WIN_RES_PURE_MOVEABLE = 0x0030;
|
||||||
|
|
||||||
|
struct WinResHeaderPrefix {
|
||||||
|
support::ulittle32_t DataSize;
|
||||||
|
support::ulittle32_t HeaderSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Type and Name may each either be an integer ID or a string. This struct is
|
||||||
|
// only used in the case where they are both IDs.
|
||||||
|
struct WinResIDs {
|
||||||
|
uint16_t TypeFlag;
|
||||||
|
support::ulittle16_t TypeID;
|
||||||
|
uint16_t NameFlag;
|
||||||
|
support::ulittle16_t NameID;
|
||||||
|
|
||||||
|
void setType(uint16_t ID) {
|
||||||
|
TypeFlag = 0xffff;
|
||||||
|
TypeID = ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setName(uint16_t ID) {
|
||||||
|
NameFlag = 0xffff;
|
||||||
|
NameID = ID;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WinResHeaderSuffix {
|
||||||
|
support::ulittle32_t DataVersion;
|
||||||
|
support::ulittle16_t MemoryFlags;
|
||||||
|
support::ulittle16_t Language;
|
||||||
|
support::ulittle32_t Version;
|
||||||
|
support::ulittle32_t Characteristics;
|
||||||
|
};
|
||||||
|
|
||||||
class ResourceEntryRef {
|
class ResourceEntryRef {
|
||||||
public:
|
public:
|
||||||
Error moveNext(bool &End);
|
Error moveNext(bool &End);
|
||||||
|
@ -70,14 +108,6 @@ private:
|
||||||
|
|
||||||
Error loadNext();
|
Error loadNext();
|
||||||
|
|
||||||
struct HeaderSuffix {
|
|
||||||
support::ulittle32_t DataVersion;
|
|
||||||
support::ulittle16_t MemoryFlags;
|
|
||||||
support::ulittle16_t Language;
|
|
||||||
support::ulittle32_t Version;
|
|
||||||
support::ulittle32_t Characteristics;
|
|
||||||
};
|
|
||||||
|
|
||||||
BinaryStreamReader Reader;
|
BinaryStreamReader Reader;
|
||||||
bool IsStringType;
|
bool IsStringType;
|
||||||
ArrayRef<UTF16> Type;
|
ArrayRef<UTF16> Type;
|
||||||
|
@ -85,7 +115,7 @@ private:
|
||||||
bool IsStringName;
|
bool IsStringName;
|
||||||
ArrayRef<UTF16> Name;
|
ArrayRef<UTF16> Name;
|
||||||
uint16_t NameID;
|
uint16_t NameID;
|
||||||
const HeaderSuffix *Suffix = nullptr;
|
const WinResHeaderSuffix *Suffix = nullptr;
|
||||||
ArrayRef<uint8_t> Data;
|
ArrayRef<uint8_t> Data;
|
||||||
const WindowsResource *OwningRes = nullptr;
|
const WindowsResource *OwningRes = nullptr;
|
||||||
};
|
};
|
||||||
|
|
|
@ -51,7 +51,8 @@ file_magic llvm::identify_magic(StringRef Magic) {
|
||||||
return file_magic::coff_import_library;
|
return file_magic::coff_import_library;
|
||||||
}
|
}
|
||||||
// Windows resource file
|
// Windows resource file
|
||||||
if (startswith(Magic, "\0\0\0\0\x20\0\0\0\xFF"))
|
if (Magic.size() >= sizeof(COFF::WinResMagic) &&
|
||||||
|
memcmp(Magic.data(), COFF::WinResMagic, sizeof(COFF::WinResMagic)) == 0)
|
||||||
return file_magic::windows_resource;
|
return file_magic::windows_resource;
|
||||||
// 0x0000 = COFF unknown machine type
|
// 0x0000 = COFF unknown machine type
|
||||||
if (Magic[1] == 0)
|
if (Magic[1] == 0)
|
||||||
|
|
|
@ -36,23 +36,19 @@ const uint32_t MIN_HEADER_SIZE = 7 * sizeof(uint32_t) + 2 * sizeof(uint16_t);
|
||||||
// 8-byte because it makes everyone happy.
|
// 8-byte because it makes everyone happy.
|
||||||
const uint32_t SECTION_ALIGNMENT = sizeof(uint64_t);
|
const uint32_t SECTION_ALIGNMENT = sizeof(uint64_t);
|
||||||
|
|
||||||
static const size_t ResourceMagicSize = 16;
|
|
||||||
|
|
||||||
static const size_t NullEntrySize = 16;
|
|
||||||
|
|
||||||
uint32_t WindowsResourceParser::TreeNode::StringCount = 0;
|
uint32_t WindowsResourceParser::TreeNode::StringCount = 0;
|
||||||
uint32_t WindowsResourceParser::TreeNode::DataCount = 0;
|
uint32_t WindowsResourceParser::TreeNode::DataCount = 0;
|
||||||
|
|
||||||
WindowsResource::WindowsResource(MemoryBufferRef Source)
|
WindowsResource::WindowsResource(MemoryBufferRef Source)
|
||||||
: Binary(Binary::ID_WinRes, Source) {
|
: Binary(Binary::ID_WinRes, Source) {
|
||||||
size_t LeadingSize = ResourceMagicSize + NullEntrySize;
|
size_t LeadingSize = WIN_RES_MAGIC_SIZE + WIN_RES_NULL_ENTRY_SIZE;
|
||||||
BBS = BinaryByteStream(Data.getBuffer().drop_front(LeadingSize),
|
BBS = BinaryByteStream(Data.getBuffer().drop_front(LeadingSize),
|
||||||
support::little);
|
support::little);
|
||||||
}
|
}
|
||||||
|
|
||||||
Expected<std::unique_ptr<WindowsResource>>
|
Expected<std::unique_ptr<WindowsResource>>
|
||||||
WindowsResource::createWindowsResource(MemoryBufferRef Source) {
|
WindowsResource::createWindowsResource(MemoryBufferRef Source) {
|
||||||
if (Source.getBufferSize() < ResourceMagicSize + NullEntrySize)
|
if (Source.getBufferSize() < WIN_RES_MAGIC_SIZE + WIN_RES_NULL_ENTRY_SIZE)
|
||||||
return make_error<GenericBinaryError>(
|
return make_error<GenericBinaryError>(
|
||||||
"File too small to be a resource file",
|
"File too small to be a resource file",
|
||||||
object_error::invalid_file_type);
|
object_error::invalid_file_type);
|
||||||
|
@ -105,12 +101,10 @@ static Error readStringOrId(BinaryStreamReader &Reader, uint16_t &ID,
|
||||||
}
|
}
|
||||||
|
|
||||||
Error ResourceEntryRef::loadNext() {
|
Error ResourceEntryRef::loadNext() {
|
||||||
uint32_t DataSize;
|
const WinResHeaderPrefix *Prefix;
|
||||||
RETURN_IF_ERROR(Reader.readInteger(DataSize));
|
RETURN_IF_ERROR(Reader.readObject(Prefix));
|
||||||
uint32_t HeaderSize;
|
|
||||||
RETURN_IF_ERROR(Reader.readInteger(HeaderSize));
|
|
||||||
|
|
||||||
if (HeaderSize < MIN_HEADER_SIZE)
|
if (Prefix->HeaderSize < MIN_HEADER_SIZE)
|
||||||
return make_error<GenericBinaryError>("Header size is too small.",
|
return make_error<GenericBinaryError>("Header size is too small.",
|
||||||
object_error::parse_failed);
|
object_error::parse_failed);
|
||||||
|
|
||||||
|
@ -118,13 +112,13 @@ Error ResourceEntryRef::loadNext() {
|
||||||
|
|
||||||
RETURN_IF_ERROR(readStringOrId(Reader, NameID, Name, IsStringName));
|
RETURN_IF_ERROR(readStringOrId(Reader, NameID, Name, IsStringName));
|
||||||
|
|
||||||
RETURN_IF_ERROR(Reader.padToAlignment(sizeof(uint32_t)));
|
RETURN_IF_ERROR(Reader.padToAlignment(WIN_RES_HEADER_ALIGNMENT));
|
||||||
|
|
||||||
RETURN_IF_ERROR(Reader.readObject(Suffix));
|
RETURN_IF_ERROR(Reader.readObject(Suffix));
|
||||||
|
|
||||||
RETURN_IF_ERROR(Reader.readArray(Data, DataSize));
|
RETURN_IF_ERROR(Reader.readArray(Data, Prefix->DataSize));
|
||||||
|
|
||||||
RETURN_IF_ERROR(Reader.padToAlignment(sizeof(uint32_t)));
|
RETURN_IF_ERROR(Reader.padToAlignment(WIN_RES_DATA_ALIGNMENT));
|
||||||
|
|
||||||
return Error::success();
|
return Error::success();
|
||||||
}
|
}
|
||||||
|
@ -468,8 +462,6 @@ void WindowsResourceCOFFWriter::writeFirstSectionHeader() {
|
||||||
SectionOneHeader->PointerToLinenumbers = 0;
|
SectionOneHeader->PointerToLinenumbers = 0;
|
||||||
SectionOneHeader->NumberOfRelocations = Data.size();
|
SectionOneHeader->NumberOfRelocations = Data.size();
|
||||||
SectionOneHeader->NumberOfLinenumbers = 0;
|
SectionOneHeader->NumberOfLinenumbers = 0;
|
||||||
SectionOneHeader->Characteristics = COFF::IMAGE_SCN_ALIGN_1BYTES;
|
|
||||||
SectionOneHeader->Characteristics += COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
|
|
||||||
SectionOneHeader->Characteristics += COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
|
SectionOneHeader->Characteristics += COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
|
||||||
SectionOneHeader->Characteristics += COFF::IMAGE_SCN_MEM_READ;
|
SectionOneHeader->Characteristics += COFF::IMAGE_SCN_MEM_READ;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,8 @@ const char macho_dsym_companion[] =
|
||||||
"\xfe\xed\xfa\xce........\x00\x00\x00\x0a............";
|
"\xfe\xed\xfa\xce........\x00\x00\x00\x0a............";
|
||||||
const char macho_kext_bundle[] =
|
const char macho_kext_bundle[] =
|
||||||
"\xfe\xed\xfa\xce........\x00\x00\x00\x0b............";
|
"\xfe\xed\xfa\xce........\x00\x00\x00\x0b............";
|
||||||
const char windows_resource[] = "\x00\x00\x00\x00\x020\x00\x00\x00\xff";
|
const char windows_resource[] =
|
||||||
|
"\x00\x00\x00\x00\x020\x00\x00\x00\xff\xff\x00\x00\xff\xff\x00\x00";
|
||||||
const char macho_dynamically_linked_shared_lib_stub[] =
|
const char macho_dynamically_linked_shared_lib_stub[] =
|
||||||
"\xfe\xed\xfa\xce........\x00\x00\x00\x09............";
|
"\xfe\xed\xfa\xce........\x00\x00\x00\x09............";
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue