Skip to content

Commit 8eafd93

Browse files
authored
[Support] Set OF_Delete for InMemoryBuffer's call to openFileForWrite under commit (#140109)
#134787 unintentionally enabled `--mmap-output-file` by default under LLD which caused the Windows-only test `lld\test\ELF\link-open-file.test` to fail. This failure uncovered what appears to be an inconsistency on Windows between `createOnDiskBuffer` and `createInMemoryBuffer` with respect to `DELETE` access for the output file. The output file created by `createOnDiskBuffer` sets the flag `OF_Delete` as part of `fs::TempFile::create` while the output file created by `createInMemoryBuffer` sets `OF_None` under `InMemoryBuffer::commit`. The test `lld\test\ELF\link-open-file.test` ensures that if `FILE_SHARE_DELETE` is _not_ specified for an output file that LLD is expected to overwrite, LLD should fail. This only happens if: "the file or device has been opened for delete access" which is only done for `fs::TempFile::create`. See https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew#FILE_SHARE_DELETE. Therefore, I propose setting `OF_Delete` for `InMemoryBuffer::commit`'s call to `openFileForWrite` to stay consistent with `fs::TempFile::create`.
1 parent 910220b commit 8eafd93

File tree

2 files changed

+10
-4
lines changed

2 files changed

+10
-4
lines changed

lld/test/ELF/link-open-file.test

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010
## FILE_SHARE_WRITE = 2
1111
## FILE_SHARE_DELETE = 4
1212

13-
# RUN: %python %s %t.o 7
14-
# RUN: not %python %s %t.o 3 2>&1 | FileCheck %s
13+
# RUN: %python %s %t.o 7 false
14+
# RUN: not %python %s %t.o 3 false 2>&1 | FileCheck %s
15+
# RUN: %python %s %t.o 7 true
16+
# RUN: not %python %s %t.o 3 true 2>&1 | FileCheck %s
1517
# CHECK: error: failed to write output '{{.*}}': {{.*}}
1618

1719
import contextlib
@@ -26,6 +28,7 @@ import time
2628

2729
object_file = sys.argv[1]
2830
share_flags = int(sys.argv[2])
31+
use_mmap = bool(sys.argv[3])
2932

3033
@contextlib.contextmanager
3134
def open_with_share_flags(filename, share_flags):
@@ -55,7 +58,10 @@ os.makedirs(outdir)
5558
elf = os.path.join(outdir, 'output_file.elf')
5659
open(elf, 'wb').close()
5760
with open_with_share_flags(elf, share_flags):
58-
subprocess.check_call(['ld.lld.exe', object_file, '-o', elf])
61+
args = ['ld.lld.exe', object_file, '-o', elf]
62+
if use_mmap:
63+
args.append("--mmap-output-file")
64+
subprocess.check_call(args)
5965

6066
## Check the linker wrote the output file.
6167
with open(elf, 'rb') as f:

llvm/lib/Support/FileOutputBuffer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ class InMemoryBuffer : public FileOutputBuffer {
9999
int FD;
100100
std::error_code EC;
101101
if (auto EC =
102-
openFileForWrite(FinalPath, FD, CD_CreateAlways, OF_None, Mode))
102+
openFileForWrite(FinalPath, FD, CD_CreateAlways, OF_Delete, Mode))
103103
return errorCodeToError(EC);
104104
raw_fd_ostream OS(FD, /*shouldClose=*/true, /*unbuffered=*/true);
105105
OS << StringRef((const char *)Buffer.base(), BufferSize);

0 commit comments

Comments
 (0)