]> granicus.if.org Git - llvm/commitdiff
Revert "Revert "Replace trivial use of external rc.exe by writing our own .res file.""
authorEric Beckmann <ecbeckmann@google.com>
Sat, 1 Jul 2017 03:59:54 +0000 (03:59 +0000)
committerEric Beckmann <ecbeckmann@google.com>
Sat, 1 Jul 2017 03:59:54 +0000 (03:59 +0000)
Summary:
This reverts commit 51931072a7c9a52540baf76fc30ef391d2529a2f.

This revert was originally done because the integrations of the new
WindowsResource library into LLD was causing error in chromium, due to
bugs in how resource sections were handled.  These bugs were fixed,
meaning that the features may be reintegrated.

Subscribers: hiraditya, llvm-commits

Differential Revision: https://reviews.llvm.org/D34922

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306941 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/BinaryFormat/COFF.h
include/llvm/Object/WindowsResource.h
lib/BinaryFormat/Magic.cpp
lib/Object/WindowsResource.cpp
unittests/BinaryFormat/TestFileMagic.cpp

index 138e44bfec28df7d8960fee8ac839c2886907d20..b395db6eaa8387d87c899e718998b210be317a01 100644 (file)
@@ -46,6 +46,12 @@ static const char ClGlObjMagic[] = {
     '\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.
 enum {
   Header16Size = 20,
index 1ef00e2909f3ab4b1f5f33b3ad5e086c5c44f010..3d32409fd4aca447fa0ccea3d6c12db7883695e7 100644 (file)
 #include <map>
 
 namespace llvm {
-
 namespace object {
 
 class WindowsResource;
 
-enum class Machine { UNKNOWN, ARM, X64, X86 };
+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 {
 public:
@@ -73,14 +108,6 @@ private:
 
   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;
   bool IsStringType;
   ArrayRef<UTF16> Type;
@@ -88,7 +115,7 @@ private:
   bool IsStringName;
   ArrayRef<UTF16> Name;
   uint16_t NameID;
-  const HeaderSuffix *Suffix = nullptr;
+  const WinResHeaderSuffix *Suffix = nullptr;
   ArrayRef<uint8_t> Data;
   const WindowsResource *OwningRes = nullptr;
 };
index 5d0a71fc7802c95e81567b7da6e87c3ec1018450..b19a07a9066b059ca2949aafbb90fd9f7193d450 100644 (file)
@@ -51,7 +51,8 @@ file_magic llvm::identify_magic(StringRef Magic) {
       return file_magic::coff_import_library;
     }
     // 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;
     // 0x0000 = COFF unknown machine type
     if (Magic[1] == 0)
index 539c8100716e475d5272396cad9c27d0e5f0a974..1371eacdf8f2d09431e70247611abd1cedeae2d5 100644 (file)
@@ -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.
 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::DataCount = 0;
 
 WindowsResource::WindowsResource(MemoryBufferRef 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),
                          support::little);
 }
 
 Expected<std::unique_ptr<WindowsResource>>
 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>(
         "File too small to be a resource file",
         object_error::invalid_file_type);
@@ -105,12 +101,10 @@ static Error readStringOrId(BinaryStreamReader &Reader, uint16_t &ID,
 }
 
 Error ResourceEntryRef::loadNext() {
-  uint32_t DataSize;
-  RETURN_IF_ERROR(Reader.readInteger(DataSize));
-  uint32_t HeaderSize;
-  RETURN_IF_ERROR(Reader.readInteger(HeaderSize));
+  const WinResHeaderPrefix *Prefix;
+  RETURN_IF_ERROR(Reader.readObject(Prefix));
 
-  if (HeaderSize < MIN_HEADER_SIZE)
+  if (Prefix->HeaderSize < MIN_HEADER_SIZE)
     return make_error<GenericBinaryError>("Header size is too small.",
                                           object_error::parse_failed);
 
@@ -118,13 +112,13 @@ Error ResourceEntryRef::loadNext() {
 
   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.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();
 }
@@ -325,7 +319,6 @@ private:
   void writeDirectoryTree();
   void writeDirectoryStringTable();
   void writeFirstSectionRelocations();
-
   std::unique_ptr<MemoryBuffer> OutputBuffer;
   char *BufferStart;
   uint64_t CurrentOffset = 0;
@@ -469,8 +462,6 @@ void WindowsResourceCOFFWriter::writeFirstSectionHeader() {
   SectionOneHeader->PointerToLinenumbers = 0;
   SectionOneHeader->NumberOfRelocations = Data.size();
   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_MEM_READ;
 }
index fc2c1eef9fbf79170caee225025a7bd343a84d2f..68b3ade0095436e163f59845ac21c08b91d7646b 100644 (file)
@@ -76,7 +76,8 @@ const char macho_dsym_companion[] =
     "\xfe\xed\xfa\xce........\x00\x00\x00\x0a............";
 const char macho_kext_bundle[] =
     "\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[] =
     "\xfe\xed\xfa\xce........\x00\x00\x00\x09............";