[lld] r370436 - [LLD] [COFF] Support merging resource object files

Martin Storsjo via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 29 23:56:33 PDT 2019


Author: mstorsjo
Date: Thu Aug 29 23:56:33 2019
New Revision: 370436

URL: http://llvm.org/viewvc/llvm-project?rev=370436&view=rev
Log:
[LLD] [COFF] Support merging resource object files

Extend WindowsResourceParser to support using a ResourceSectionRef for
loading resources from an object file.

Only allow merging resource object files in mingw mode; keep the
existing error on multiple resource objects in link mode.

If there only is one resource object file and no .res resources,
don't parse and recreate the .rsrc section, but just link it in without
inspecting it. This allows users to produce any .rsrc section (outside
of what the parser supports), just like before. (I don't have a specific
need for this, but it reduces the risk of this new feature.)

Separate out the .rsrc section chunks in InputFiles.cpp, and only include
them in the list of section chunks to link if we've determined that there
only was one single resource object. (We need to keep other chunks from
those object files, as they can legitimately contain other sections as
well, in addition to .rsrc section chunks.)

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

Added:
    lld/trunk/test/COFF/Inputs/combined-resources-2.yaml
    lld/trunk/test/COFF/Inputs/combined-resources.yaml
    lld/trunk/test/COFF/mixed-resource-obj.yaml
Modified:
    lld/trunk/COFF/Driver.cpp
    lld/trunk/COFF/Driver.h
    lld/trunk/COFF/DriverUtils.cpp
    lld/trunk/COFF/InputFiles.cpp
    lld/trunk/COFF/InputFiles.h
    lld/trunk/test/COFF/combined-resources.test
    lld/trunk/test/COFF/force-multipleres.test

Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=370436&r1=370435&r2=370436&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Thu Aug 29 23:56:33 2019
@@ -991,30 +991,37 @@ static void parsePDBAltPath(StringRef al
   config->pdbAltPath = buf;
 }
 
-/// Check that at most one resource obj file was used.
+/// Convert resource files and potentially merge input resource object
+/// trees into one resource tree.
 /// Call after ObjFile::Instances is complete.
-static void diagnoseMultipleResourceObjFiles() {
-  // The .rsrc$01 section in a resource obj file contains a tree description
-  // of resources.  Merging multiple resource obj files would require merging
-  // the trees instead of using usual linker section merging semantics.
-  // Since link.exe disallows linking more than one resource obj file with
-  // LNK4078, mirror that.  The normal use of resource files is to give the
-  // linker many .res files, which are then converted to a single resource obj
-  // file internally, so this is not a big restriction in practice.
-  ObjFile *resourceObjFile = nullptr;
-  for (ObjFile *f : ObjFile::instances) {
-    if (!f->isResourceObjFile)
-      continue;
+void LinkerDriver::convertResources() {
+  std::vector<ObjFile *> resourceObjFiles;
 
-    if (!resourceObjFile) {
-      resourceObjFile = f;
-      continue;
-    }
+  for (ObjFile *f : ObjFile::instances) {
+    if (f->isResourceObjFile())
+      resourceObjFiles.push_back(f);
+  }
 
-    error(toString(f) +
+  if (!config->mingw &&
+      (resourceObjFiles.size() > 1 ||
+       (resourceObjFiles.size() == 1 && !resources.empty()))) {
+    error((!resources.empty() ? "internal .obj file created from .res files"
+                              : toString(resourceObjFiles[1])) +
           ": more than one resource obj file not allowed, already got " +
-          toString(resourceObjFile));
+          toString(resourceObjFiles.front()));
+    return;
   }
+
+  if (resources.empty() && resourceObjFiles.size() <= 1) {
+    // No resources to convert, and max one resource object file in
+    // the input. Keep that preconverted resource section as is.
+    for (ObjFile *f : resourceObjFiles)
+      f->includeResourceChunks();
+    return;
+  }
+  ObjFile *f = make<ObjFile>(convertResToCOFF(resources, resourceObjFiles));
+  symtab->addFile(f);
+  f->includeResourceChunks();
 }
 
 // In MinGW, if no symbols are chosen to be exported, then all symbols are
@@ -1583,12 +1590,6 @@ void LinkerDriver::link(ArrayRef<const c
   for (auto *arg : args.filtered(OPT_functionpadmin, OPT_functionpadmin_opt))
     parseFunctionPadMin(arg, config->machine);
 
-  // Input files can be Windows resource files (.res files). We use
-  // WindowsResource to convert resource files to a regular COFF file,
-  // then link the resulting file normally.
-  if (!resources.empty())
-    symtab->addFile(make<ObjFile>(convertResToCOFF(resources)));
-
   if (tar)
     tar->append("response.txt",
                 createResponseFile(args, filePaths,
@@ -1906,7 +1907,7 @@ void LinkerDriver::link(ArrayRef<const c
     markLive(symtab->getChunks());
 
   // Needs to happen after the last call to addFile().
-  diagnoseMultipleResourceObjFiles();
+  convertResources();
 
   // Identify identical COMDAT sections to merge them.
   if (config->doICF) {

Modified: lld/trunk/COFF/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.h?rev=370436&r1=370435&r2=370436&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.h (original)
+++ lld/trunk/COFF/Driver.h Thu Aug 29 23:56:33 2019
@@ -98,6 +98,10 @@ private:
   // Library search path. The first element is always "" (current directory).
   std::vector<StringRef> searchPaths;
 
+  // Convert resource files and potentially merge input resource object
+  // trees into one resource tree.
+  void convertResources();
+
   void maybeExportMinGWSymbols(const llvm::opt::InputArgList &args);
 
   // We don't want to add the same file more than once.
@@ -184,7 +188,8 @@ void assignExportOrdinals();
 void checkFailIfMismatch(StringRef arg, InputFile *source);
 
 // Convert Windows resource files (.res files) to a .obj file.
-MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> mbs);
+MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> mbs,
+                                 ArrayRef<ObjFile *> objs);
 
 void runMSVCLinker(std::string rsp, ArrayRef<StringRef> objects);
 

Modified: lld/trunk/COFF/DriverUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/DriverUtils.cpp?rev=370436&r1=370435&r2=370436&view=diff
==============================================================================
--- lld/trunk/COFF/DriverUtils.cpp (original)
+++ lld/trunk/COFF/DriverUtils.cpp Thu Aug 29 23:56:33 2019
@@ -700,26 +700,40 @@ void checkFailIfMismatch(StringRef arg,
 
 // Convert Windows resource files (.res files) to a .obj file.
 // Does what cvtres.exe does, but in-process and cross-platform.
-MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> mbs) {
+MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> mbs,
+                                 ArrayRef<ObjFile *> objs) {
   object::WindowsResourceParser parser;
 
+  std::vector<std::string> duplicates;
   for (MemoryBufferRef mb : mbs) {
     std::unique_ptr<object::Binary> bin = check(object::createBinary(mb));
     object::WindowsResource *rf = dyn_cast<object::WindowsResource>(bin.get());
     if (!rf)
       fatal("cannot compile non-resource file as resource");
 
-    std::vector<std::string> duplicates;
     if (auto ec = parser.parse(rf, duplicates))
       fatal(toString(std::move(ec)));
+  }
+
+  // Note: This processes all .res files before all objs. Ideally they'd be
+  // handled in the same order they were linked (to keep the right one, if
+  // there are duplicates that are tolerated due to forceMultipleRes).
+  for (ObjFile *f : objs) {
+    object::ResourceSectionRef rsf;
+    if (auto ec = rsf.load(f->getCOFFObj()))
+      fatal(toString(f) + ": " + toString(std::move(ec)));
 
-    for (const auto &dupeDiag : duplicates)
-      if (config->forceMultipleRes)
-        warn(dupeDiag);
-      else
-        error(dupeDiag);
+    if (auto ec = parser.parse(rsf, f->getName(), duplicates))
+      fatal(toString(std::move(ec)));
   }
 
+
+  for (const auto &dupeDiag : duplicates)
+    if (config->forceMultipleRes)
+      warn(dupeDiag);
+    else
+      error(dupeDiag);
+
   Expected<std::unique_ptr<MemoryBuffer>> e =
       llvm::object::writeWindowsResourceCOFF(config->machine, parser,
                                              config->timestamp);

Modified: lld/trunk/COFF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/InputFiles.cpp?rev=370436&r1=370435&r2=370436&view=diff
==============================================================================
--- lld/trunk/COFF/InputFiles.cpp (original)
+++ lld/trunk/COFF/InputFiles.cpp Thu Aug 29 23:56:33 2019
@@ -206,10 +206,6 @@ SectionChunk *ObjFile::readSection(uint3
   if (def)
     c->checksum = def->CheckSum;
 
-  // link.exe uses the presence of .rsrc$01 for LNK4078, so match that.
-  if (name == ".rsrc$01")
-    isResourceObjFile = true;
-
   // CodeView sections are stored to a different vector because they are not
   // linked in the regular manner.
   if (c->isCodeView())
@@ -226,12 +222,18 @@ SectionChunk *ObjFile::readSection(uint3
     // relocations, in .rdata, leader symbol name matches the MSVC name mangling
     // for string literals) are subject to string tail merging.
     MergeChunk::addSection(c);
+  else if (name == ".rsrc" || name.startswith(".rsrc$"))
+    resourceChunks.push_back(c);
   else
     chunks.push_back(c);
 
   return c;
 }
 
+void ObjFile::includeResourceChunks() {
+  chunks.insert(chunks.end(), resourceChunks.begin(), resourceChunks.end());
+}
+
 void ObjFile::readAssociativeDefinition(
     COFFSymbolRef sym, const coff_aux_section_definition *def) {
   readAssociativeDefinition(sym, def, def->getNumber(sym.isBigObj()));

Modified: lld/trunk/COFF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/InputFiles.h?rev=370436&r1=370435&r2=370436&view=diff
==============================================================================
--- lld/trunk/COFF/InputFiles.h (original)
+++ lld/trunk/COFF/InputFiles.h Thu Aug 29 23:56:33 2019
@@ -134,6 +134,10 @@ public:
     return symbols.size() - 1;
   }
 
+  void includeResourceChunks();
+
+  bool isResourceObjFile() const { return !resourceChunks.empty(); }
+
   static std::vector<ObjFile *> instances;
 
   // Flags in the absolute @feat.00 symbol if it is present. These usually
@@ -161,9 +165,6 @@ public:
   // precompiled object. Any difference indicates out-of-date objects.
   llvm::Optional<uint32_t> pchSignature;
 
-  // Whether this is an object file created from .res files.
-  bool isResourceObjFile = false;
-
   // Whether this file was compiled with /hotpatch.
   bool hotPatchable = false;
 
@@ -233,6 +234,8 @@ private:
   // chunks and non-section chunks for common symbols.
   std::vector<Chunk *> chunks;
 
+  std::vector<SectionChunk *> resourceChunks;
+
   // CodeView debug info sections.
   std::vector<SectionChunk *> debugChunks;
 

Added: lld/trunk/test/COFF/Inputs/combined-resources-2.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/Inputs/combined-resources-2.yaml?rev=370436&view=auto
==============================================================================
--- lld/trunk/test/COFF/Inputs/combined-resources-2.yaml (added)
+++ lld/trunk/test/COFF/Inputs/combined-resources-2.yaml Thu Aug 29 23:56:33 2019
@@ -0,0 +1,137 @@
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [ IMAGE_FILE_32BIT_MACHINE ]
+sections:
+  - Name:            '.debug$S'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    SectionData:     04000000F30000004E000000005A3A5C686F6D655C6D617274696E5C636F64655C6C6C766D5C746F6F6C735C6C6C645C746573745C434F46465C496E707574735C636F6D62696E65642D7265736F75726365732D322E726573000000F400000018000000010000001001C20ABB57742312AC65B588238495D1AC0000F10000001101000051000111000000005A3A5C686F6D655C6D617274696E5C636F64655C6C6C766D5C746F6F6C735C6C6C645C746573745C434F46465C496E707574735C636F6D62696E65642D7265736F75726365732D322E6F002D003C1108020000D00000000000000000000E001400746B01004D6963726F736F66742028522920435654524553008D003D1100637764005A3A5C686F6D655C6D617274696E5C636F64655C6C6C766D5C746F6F6C735C6C6C645C746573745C434F46465C496E7075747300657865005A3A5C686F6D655C6D617274696E5C6D737663323031395C76635C746F6F6C735C6D7376635C31342E32302E32373530385C62696E5C486F73747838365C7836345C6376747265732E6578650000000000
+    Subsections:
+      - !StringTable
+        Strings:
+          - 'Z:\home\martin\code\llvm\tools\lld\test\COFF\Inputs\combined-resources-2.res'
+      - !FileChecksums
+        Checksums:
+          - FileName:        'Z:\home\martin\code\llvm\tools\lld\test\COFF\Inputs\combined-resources-2.res'
+            Kind:            MD5
+            Checksum:        C20ABB57742312AC65B588238495D1AC
+      - !Symbols
+        Records:
+          - Kind:            S_OBJNAME
+            ObjNameSym:
+              Signature:       0
+              ObjectName:      'Z:\home\martin\code\llvm\tools\lld\test\COFF\Inputs\combined-resources-2.o'
+          - Kind:            S_COMPILE3
+            Compile3Sym:
+              Flags:           [ NoDbgInfo ]
+              Machine:         X64
+              FrontendMajor:   0
+              FrontendMinor:   0
+              FrontendBuild:   0
+              FrontendQFE:     0
+              BackendMajor:    14
+              BackendMinor:    20
+              BackendBuild:    27508
+              BackendQFE:      1
+              Version:         'Microsoft (R) CVTRES'
+          - Kind:            S_ENVBLOCK
+            EnvBlockSym:
+              Entries:
+                - cwd
+                - 'Z:\home\martin\code\llvm\tools\lld\test\COFF\Inputs'
+                - exe
+                - 'Z:\home\martin\msvc2019\vc\tools\msvc\14.20.27508\bin\Hostx86\x64\cvtres.exe'
+  - Name:            '.rsrc$01'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    SectionData:     0000000000000000000000000000020009000000200000800A0000003800008000000000000000000000000001000000E40000805000008000000000000000000000000001000000D0000080680000800000000000000000000000000000010004080000900000000000000000000000000000000000030009040000A000000004080000B000000007100000C0000000000000001800000000000000000000000000000036000000000000000000000000000000430000000000000000000000000000004200000000000000000000000900520041004E0044004F004D004400410054000E004D00590041004300430045004C0045005200410054004F00520053000000
+    Relocations:
+      - VirtualAddress:  160
+        SymbolName:      '$R000000'
+        Type:            IMAGE_REL_AMD64_ADDR32NB
+      - VirtualAddress:  176
+        SymbolName:      '$R000038'
+        Type:            IMAGE_REL_AMD64_ADDR32NB
+      - VirtualAddress:  192
+        SymbolName:      '$R000080'
+        Type:            IMAGE_REL_AMD64_ADDR32NB
+      - VirtualAddress:  144
+        SymbolName:      '$R0000C8'
+        Type:            IMAGE_REL_AMD64_ADDR32NB
+  - Name:            '.rsrc$02'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    SectionData:     7468697320697320612072616E646F6D20626974206F6620646174612074686174206D65616E73206E6F7468696E6700A9230E14F4F600007A68653420736869342079693167653420737569326A693120646520736875346A75342C207A68653420796934776569347A6865207368656E326D6500A9230E14F4F6000000000044696573206973742065696E207A7566C3A46C6C696765732042697420766F6E20446174656E2C20646965206E696368747320626564657574657400A9230E14F4F600000000000011000300E70300000D0044004C04000082001200BC010000
+symbols:
+  - Name:            '@comp.id'
+    Value:           16739188
+    SectionNumber:   -1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+  - Name:            '@feat.00'
+    Value:           17
+    SectionNumber:   -1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+  - Name:            '.debug$S'
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          408
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            '.rsrc$01'
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          260
+      NumberOfRelocations: 4
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            '.rsrc$02'
+    Value:           0
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          224
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            '$R000000'
+    Value:           0
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+  - Name:            '$R000038'
+    Value:           56
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+  - Name:            '$R000080'
+    Value:           128
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+  - Name:            '$R0000C8'
+    Value:           200
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+...

Added: lld/trunk/test/COFF/Inputs/combined-resources.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/Inputs/combined-resources.yaml?rev=370436&view=auto
==============================================================================
--- lld/trunk/test/COFF/Inputs/combined-resources.yaml (added)
+++ lld/trunk/test/COFF/Inputs/combined-resources.yaml Thu Aug 29 23:56:33 2019
@@ -0,0 +1,42 @@
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [ IMAGE_FILE_LINE_NUMS_STRIPPED ]
+sections:
+  - Name:            .rsrc
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       4
+    SectionData:     000000000000000000000000010004008801008038000080020000006800008004000000B80000800500000008010080090000003801008000000000000000000000000001000000A00100805000008000000000000000000000000000000100090400001002000000000000000000000000000002000000B601008088000080C4010080A000008000000000000000000000000000000100090400002002000000000000000000000000000000000100090400003002000000000000000000000000000001000100CE010080D800008060380000F000008000000000000000000000000000000100090C00004002000000000000000000000000000000000100040800005002000000000000000000000000000001000000DA0100802001008000000000000000000000000000000100090400006002000000000000000000000000000001000100F0010080580100800C000000700100800000000000000000000000000000010009040000700200000000000000000000000000000000010009040000800200000B0053005400520049004E004700410052005200410059000A004D0059005200450053004F005500520043004500060043005500520053004F00520004004F004B00410059000500220045004100540022000A0054004500530054004400490041004C004F0047000E004D00590041004300430045004C0045005200410054004F0052005300000090020000390000000000000000000000D0020000280300000000000000000000F805000028030000000000000000000020090000300000000000000000000000500900002E0000000000000000000000800900006C0000000000000000000000F0090000180000000000000000000000080A0000180000000000000000000000746869732069732061207573657220646566696E6564207265736F7572636500697420636F6E7461696E73206D616E7920737472696E67730000000000000000280000001000000010000000010018000000000000030000C40E0000C40E00000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7F7C7C7C787878757575FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF979797FFFFFFFFFFFF838383AAAAAADBDBDB797979757575FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C9C9C989898FFFFFF888888DBDBDBB7B7B77D7D7DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0A0A09C9C9C939393ADADADF2F2F2848484818181FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4A4A4D7D7D79D9D9DD0D0D0EEEEEE9191918D8D8DFFFFFFFFFFFF8181817E7E7EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9A9A9F2F2F2E5E5E5E2E2E29595959191918D8D8D898989868686FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADADADF2F2F2E1E1E1DFDFDFE7E7E7E4E4E4BBBBBB8E8E8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5B5B5F2F2F2E8E8E8E7E7E7EAEAEAC6C6C69E9E9EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9F4F4F4ECECECEDEDEDCBCBCBA7A7A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBDBDF7F7F7EFEFEFD0D0D0AFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1C1C1F7F7F7D5D5D5B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4C4C4D9D9D9BEBEBEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C8C5C5C5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF280000001000000010000000010018000000000000030000C40E0000C40E00000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0E3A901B31801B31801B31801B31801B31801B31861D06FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01B31800D7331CDB49DBF9E29BEFAF00D73300D73301B318FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01B31800DE55F6FEF9DBFAE7FEFFFE86EFAE00DE5501B318FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01B31800E676DBFBEC00E67657EFA5FBFFFD55EEA401B318FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01B31800ED9800ED9800ED9800ED9887F7CFFEFFFF01B318FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01B31800F4BA00F4BA00F4BA00F4BA00F4BA9CFBE401B318FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01B31800FBDB00FBDB00FBDB00FBDB00FBDB00FBDB01B318FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9FE2A801B31801B31801B31801B31801B31801B31861D06FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000064006600690073006800000000006500730061006C00610064000000800066006400750063006B0000000000000000006400790075000000000065007300680061006C0061000000800066006B0061006F0079006100000000000000C0800000000002000A000A00C8002C01000000005400650073007400000001000250000000000A000A00E6000E000100FFFF820043006F006E00740069006E00750065003A0000000000000001500000000042008600A1000D000200FFFF800026004F004B00000000000000000011000300E70300000D0044004C04000082001200BC01000011005800A40000000D0048002E16000082001200BC010000
+    Relocations:
+      - VirtualAddress:  528
+        SymbolName:      .rsrc
+        Type:            IMAGE_REL_AMD64_ADDR32NB
+      - VirtualAddress:  544
+        SymbolName:      .rsrc
+        Type:            IMAGE_REL_AMD64_ADDR32NB
+      - VirtualAddress:  560
+        SymbolName:      .rsrc
+        Type:            IMAGE_REL_AMD64_ADDR32NB
+      - VirtualAddress:  576
+        SymbolName:      .rsrc
+        Type:            IMAGE_REL_AMD64_ADDR32NB
+      - VirtualAddress:  592
+        SymbolName:      .rsrc
+        Type:            IMAGE_REL_AMD64_ADDR32NB
+      - VirtualAddress:  608
+        SymbolName:      .rsrc
+        Type:            IMAGE_REL_AMD64_ADDR32NB
+      - VirtualAddress:  624
+        SymbolName:      .rsrc
+        Type:            IMAGE_REL_AMD64_ADDR32NB
+      - VirtualAddress:  640
+        SymbolName:      .rsrc
+        Type:            IMAGE_REL_AMD64_ADDR32NB
+symbols:
+  - Name:            .rsrc
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+...

Modified: lld/trunk/test/COFF/combined-resources.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/combined-resources.test?rev=370436&r1=370435&r2=370436&view=diff
==============================================================================
--- lld/trunk/test/COFF/combined-resources.test (original)
+++ lld/trunk/test/COFF/combined-resources.test Thu Aug 29 23:56:33 2019
@@ -4,6 +4,10 @@
 // > rc /fo combined-resources.res /nologo combined-resources.rc
 // > rc /fo combined-resources-2.res /nologo combined-resources-2.rc
 
+// The object files were generated with GNU windres and MS cvtres.exe,
+// > x86_64-w64-mingw32-windres combined-resources.res combined-resources.o
+// > cvtres -machine:x64 -out:combined-resources-2.o combined-resources.res
+
 # RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
 # RUN: lld-link /out:%t.exe /entry:main %t.obj %p/Inputs/resource.res \
 # RUN:   %p/Inputs/combined-resources.res %p/Inputs/combined-resources-2.res
@@ -11,6 +15,21 @@
 # RUN: llvm-readobj --coff-resources --file-headers --section-data %t.exe | \
 # RUN:   FileCheck %s
 
+# RUN: yaml2obj < %p/Inputs/combined-resources.yaml > %t-combined-resources.o
+# RUN: yaml2obj < %p/Inputs/combined-resources-2.yaml > %t-combined-resources-2.o
+
+# RUN: lld-link /lldmingw /out:%t-resobj.exe /entry:main %t.obj %p/Inputs/resource.res \
+# RUN:   %t-combined-resources.o %t-combined-resources-2.o
+
+// As input resources are traversed in a slightly different order, the
+// RVAs of data blobs will end up slightly different, even if they are
+// equivalent. Filter out such addresses from llvm-readobj's output,
+// and compare the rest to make sure it is equivalent.
+
+# RUN: llvm-readobj --coff-resources %t.exe | sed -E 's/(RVA|Address|File): .*//' > %t-orig.txt
+# RUN: llvm-readobj --coff-resources %t-resobj.exe | sed -E 's/(RVA|Address|File): .*//' > %t-resobj.txt
+# RUN: cmp %t-orig.txt %t-resobj.txt
+
 CHECK:      ResourceTableRVA: 0x2000
 CHECK-NEXT: ResourceTableSize: 0xC20
 CHECK-DAG:  Resources [

Modified: lld/trunk/test/COFF/force-multipleres.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/force-multipleres.test?rev=370436&r1=370435&r2=370436&view=diff
==============================================================================
--- lld/trunk/test/COFF/force-multipleres.test (original)
+++ lld/trunk/test/COFF/force-multipleres.test Thu Aug 29 23:56:33 2019
@@ -9,13 +9,21 @@ RUN: rm -rf %t.dir
 RUN: mkdir %t.dir
 RUN: cp %S/Inputs/id.res %t.dir/id1.res
 RUN: cp %S/Inputs/id.res %t.dir/id2.res
+RUN: cp %S/Inputs/id.res.o %t.dir/id1.o
+RUN: cp %S/Inputs/id.res.o %t.dir/id2.o
 
 RUN: not lld-link /machine:x64 /nodefaultlib /noentry /dll %t.dir/id1.res %t.dir/id2.res 2>&1 | \
 RUN:     FileCheck -check-prefix=ERR %s
-ERR: error: duplicate resource: type STRINGTABLE (ID 6)/name ID 3/language 1033, in {{.*}}id1.res and in {{.*}}id2.res
+RUN: not lld-link /lldmingw /machine:x64 /nodefaultlib /noentry /dll %t.dir/id1.res %t.dir/id2.o 2>&1 | \
+RUN:     FileCheck -check-prefix=ERR %s
+RUN: not lld-link /lldmingw /machine:x64 /nodefaultlib /noentry /dll %t.dir/id1.o %t.dir/id2.o 2>&1 | \
+RUN:     FileCheck -check-prefix=ERR %s
+ERR: error: duplicate resource: type STRINGTABLE (ID 6)/name ID 3/language 1033, in {{.*}}id1.{{res|o}} and in {{.*}}id2.{{res|o}}
 
 RUN: lld-link /force /machine:x64 /nodefaultlib /noentry /dll %t.dir/id1.res %t.dir/id2.res 2>&1 | \
 RUN:     FileCheck -check-prefix=WARN %s
 RUN: lld-link /force:multipleres /machine:x64 /nodefaultlib /noentry /dll %t.dir/id1.res %t.dir/id2.res 2>&1 | \
 RUN:     FileCheck -check-prefix=WARN %s
-WARN: warning: duplicate resource: type STRINGTABLE (ID 6)/name ID 3/language 1033, in {{.*}}id1.res and in {{.*}}id2.res
+RUN: lld-link /lldmingw /force:multipleres /machine:x64 /nodefaultlib /noentry /dll %t.dir/id1.o %t.dir/id2.o 2>&1 | \
+RUN:     FileCheck -check-prefix=WARN %s
+WARN: warning: duplicate resource: type STRINGTABLE (ID 6)/name ID 3/language 1033, in {{.*}}id1.{{res|o}} and in {{.*}}id2.{{res|o}}

Added: lld/trunk/test/COFF/mixed-resource-obj.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/mixed-resource-obj.yaml?rev=370436&view=auto
==============================================================================
--- lld/trunk/test/COFF/mixed-resource-obj.yaml (added)
+++ lld/trunk/test/COFF/mixed-resource-obj.yaml Thu Aug 29 23:56:33 2019
@@ -0,0 +1,61 @@
+# RUN: yaml2obj < %s > %t.o
+
+# Test that we get both the resource and the code from a single object
+# file that contains both, while merging resources from another object
+# file.
+
+# RUN: lld-link -lldmingw -out:%t.exe %t.o %p/Inputs/id.res.o -entry:main
+# RUN: llvm-readobj --coff-resources %t.exe | FileCheck %s --check-prefix=CHECK-RESOURCES
+# RUN: llvm-objdump -d %t.exe | FileCheck %s --check-prefix=CHECK-DISASM
+
+# CHECK-RESOURCES: Resources [
+# CHECK-RESOURCES-NEXT: Total Number of Resources: 2
+
+# CHECK-DISASM: Disassembly of section .text:
+# CHECK-DISASM: .text:
+# CHECK-DISASM-NEXT: movl $42, %eax
+# CHECK-DISASM-NEXT: retq
+
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [ IMAGE_FILE_LINE_NUMS_STRIPPED ]
+sections:
+  - Name:            .rsrc
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       4
+    SectionData:     0000000000000000000000000000010005000000180000800000000000000000000000000100000048000080300000800000000000000000000000000000010009040000600000000A0054004500530054004400490041004C004F0047000000700000006C00000000000000000000000000C0800000000002000A000A00C8002C01000000005400650073007400000001000250000000000A000A00E6000E000100FFFF820043006F006E00740069006E00750065003A0000000000000001500000000042008600A1000D000200FFFF800026004F004B000000000000000000
+    Relocations:
+      - VirtualAddress:  96
+        SymbolName:      .rsrc
+        Type:            IMAGE_REL_AMD64_ADDR32NB
+  - Name:            '.text'
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       16
+    SectionData:     B82A000000C3
+symbols:
+  - Name:            .rsrc
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+  - Name:            '.text'
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          6
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            main
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...




More information about the llvm-commits mailing list