Skip to content

Commit

Permalink
COFF: Add resource files to linkrepro instead of the cvtres object file.
Browse files Browse the repository at this point in the history
Now that we have our own implementation of cvtres, we can add resource
files directly to the linkrepro.

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

llvm-svn: 315954
  • Loading branch information
pcc committed Oct 16, 2017
1 parent 400a64e commit 9362ac6
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 23 deletions.
29 changes: 15 additions & 14 deletions lld/COFF/Driver.cpp
Expand Up @@ -113,16 +113,15 @@ MemoryBufferRef LinkerDriver::takeBuffer(std::unique_ptr<MemoryBuffer> MB) {
void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> MB,
bool WholeArchive) {
MemoryBufferRef MBRef = takeBuffer(std::move(MB));
FilePaths.push_back(MBRef.getBufferIdentifier());

// File type is detected by contents, not by file extension.
file_magic Magic = identify_magic(MBRef.getBuffer());
if (Magic == file_magic::windows_resource) {
switch (identify_magic(MBRef.getBuffer())) {
case file_magic::windows_resource:
Resources.push_back(MBRef);
return;
}
break;

FilePaths.push_back(MBRef.getBufferIdentifier());
if (Magic == file_magic::archive) {
case file_magic::archive:
if (WholeArchive) {
std::unique_ptr<Archive> File =
check(Archive::create(MBRef),
Expand All @@ -133,19 +132,21 @@ void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> MB,
return;
}
Symtab->addFile(make<ArchiveFile>(MBRef));
return;
}
break;

if (Magic == file_magic::bitcode) {
case file_magic::bitcode:
Symtab->addFile(make<BitcodeFile>(MBRef));
return;
}
break;

if (Magic == file_magic::coff_cl_gl_object)
case file_magic::coff_cl_gl_object:
error(MBRef.getBufferIdentifier() + ": is not a native COFF file. "
"Recompile without /GL");
else
break;

default:
Symtab->addFile(make<ObjFile>(MBRef));
break;
}
}

void LinkerDriver::enqueuePath(StringRef Path, bool WholeArchive) {
Expand Down Expand Up @@ -1078,7 +1079,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
// WindowsResource to convert resource files to a regular COFF file,
// then link the resulting file normally.
if (!Resources.empty())
addBuffer(convertResToCOFF(Resources), false);
Symtab->addFile(make<ObjFile>(convertResToCOFF(Resources)));

if (Tar)
Tar->append("response.txt",
Expand Down
6 changes: 2 additions & 4 deletions lld/COFF/Driver.h
Expand Up @@ -169,10 +169,8 @@ void assignExportOrdinals();
// incompatible objects.
void checkFailIfMismatch(StringRef Arg);

// Convert Windows resource files (.res files) to a .obj file
// using cvtres.exe.
std::unique_ptr<MemoryBuffer>
convertResToCOFF(const std::vector<MemoryBufferRef> &MBs);
// Convert Windows resource files (.res files) to a .obj file.
MemoryBufferRef convertResToCOFF(const std::vector<MemoryBufferRef> &MBs);

void runMSVCLinker(std::string Rsp, ArrayRef<StringRef> Objects);

Expand Down
11 changes: 6 additions & 5 deletions lld/COFF/DriverUtils.cpp
Expand Up @@ -639,10 +639,8 @@ void checkFailIfMismatch(StringRef Arg) {
Config->MustMatch[K] = V;
}

// Convert Windows resource files (.res files) to a .obj file
// using cvtres.exe.
std::unique_ptr<MemoryBuffer>
convertResToCOFF(const std::vector<MemoryBufferRef> &MBs) {
// Convert Windows resource files (.res files) to a .obj file.
MemoryBufferRef convertResToCOFF(const std::vector<MemoryBufferRef> &MBs) {
object::WindowsResourceParser Parser;

for (MemoryBufferRef MB : MBs) {
Expand All @@ -658,7 +656,10 @@ convertResToCOFF(const std::vector<MemoryBufferRef> &MBs) {
llvm::object::writeWindowsResourceCOFF(Config->Machine, Parser);
if (!E)
fatal(errorToErrorCode(E.takeError()), "failed to write .res to COFF");
return std::move(E.get());

MemoryBufferRef MBRef = **E;
make<std::unique_ptr<MemoryBuffer>>(std::move(*E)); // take ownership
return MBRef;
}

// Run MSVC link.exe for given in-memory object files.
Expand Down
12 changes: 12 additions & 0 deletions lld/test/COFF/linkrepro-res.test
@@ -0,0 +1,12 @@
# REQUIRES: x86, shell

# RUN: rm -rf %t.dir
# RUN: mkdir -p %t.dir/build
# RUN: cd %t.dir/build
# RUN: lld-link %p/Inputs/resource.res /subsystem:console /machine:x64 \
# RUN: /entry:__ImageBase /linkrepro:. /out:%t.exe
# RUN: tar xf repro.tar
# RUN: diff %p/Inputs/resource.res repro/%:p/Inputs/resource.res
# RUN: FileCheck %s --check-prefix=RSP < repro/response.txt

# RSP: resource.res

0 comments on commit 9362ac6

Please sign in to comment.