This is an archive of the discontinued LLVM Phabricator instance.

[COFF] Fix manifest resource file creation on Windows
ClosedPublic

Authored by Ilod on Nov 14 2016, 6:15 PM.

Details

Reviewers
ruiu
Summary

createManifestRes was generating a MemoryBuffer from a TemporaryFile, keeping the data but removing the file, before passing the file path to CVTRES.exe, leading to the following error:
CVTRES : fatal error CVT1101: cannot open 'C:\Users\user\AppData\Local\Temp\lld-output-resource-bfee19.res' for reading
With this, we instead create a new TemporaryFile before passing it to cvtres.

Diff Detail

Event Timeline

Ilod updated this revision to Diff 77936.Nov 14 2016, 6:15 PM
Ilod retitled this revision from to [COFF] Fix manifest resource file creation on Windows.
Ilod updated this object.
Ilod added a reviewer: ruiu.
Ilod added a project: lld.
Ilod added a subscriber: llvm-commits.
ruiu added inline comments.Nov 14 2016, 6:23 PM
COFF/DriverUtils.cpp
416

Does this work?

return MemoryBuffer::getMemBufferCopy(ResFile.getMemoryBuffer().getBuffer());

This creates a copy of memory buffer that do not refer the original memory buffer, so you don't need to define the subclass of MemoryBuffer.

Ilod added inline comments.Nov 14 2016, 6:40 PM
COFF/DriverUtils.cpp
416

I don't think so. The point of the subclass is to keep the TemporaryFile alive. In fact in this particular case we don't really care about the MemoryBuffer, we just stick with it because LinkerDriver::link keep a list of MemoryBuffer to reference resources, then call ConvertResToCOFF on this resource list, but only forward the underlying file path to CVTRES (by adding MB.getBufferIdentifier() to its parameters).
Returning a copy of the membuffer won't change that the TemporaryFile objet is destroyed, removing the underlying file, thus making cvtres fail. Having a subclass allow us to move the TemporaryFile in a member, thus not deleting the file before the MemoryBuffer is also destroyed.

ruiu added inline comments.Nov 14 2016, 6:47 PM
COFF/DriverUtils.cpp
416

I see. Thank you for the explanation. Honestly, I prefer simple code than the runtime efficiency here. How about writing MemoryBuffers to temporary files in convertResToCOFF before passing them to cvtres?

Ilod added inline comments.Nov 14 2016, 7:03 PM
COFF/DriverUtils.cpp
416

It would also work, and be way simpler, yeah.
It would however probably be a waste on projets with a bunch of resources, as it seems the manifest is the only one which have this problem (because it's the only one we create internally in a TemporaryFile, others are created externally), so we would copy many files already existing.
I don't know if it's really a problem, I never used a project with more than a few resources.

I can make a patch tomorrow if you think it's a better way to do it.

ruiu added inline comments.Nov 14 2016, 7:41 PM
COFF/DriverUtils.cpp
416

It would be slower for sure, but it is probably negligible. We can optimize later if it turns out to be too slow.

Ilod updated this revision to Diff 78035.Nov 15 2016, 11:06 AM
Ilod updated this object.

Not much simpler in fact, because we need to handle a vector of files, but more local, so probably easier to understand.

ruiu accepted this revision.Nov 15 2016, 11:10 AM
ruiu edited edge metadata.

LGTM. Thank you for fixing this!

COFF/DriverUtils.cpp
591

Please add a comment why we are doing this; we cannot pass paths of the files because the file may be a temporary file and in that case the path have already been removed.

This revision is now accepted and ready to land.Nov 15 2016, 11:10 AM
Ilod updated this revision to Diff 78042.Nov 15 2016, 11:33 AM
Ilod edited edge metadata.

Added comment.
I don't have commit rights, so I will depend on you for this.

ruiu closed this revision.Nov 15 2016, 1:35 PM

Submitted as r287034.