Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

lld writing to Windows RAM drive fails with "cannot open output file ...: function not supported" #51047

Open Quuxplusone opened 3 years ago

Quuxplusone commented 3 years ago
Bugzilla Link PR52080
Status NEW
Importance P enhancement
Reported by Bernhard (bernhard_mlist@outlook.com)
Reported on 2021-10-05 07:20:21 -0700
Last modified on 2021-11-10 10:36:53 -0800
Version 12.0
Hardware PC Windows NT
CC akhuang@google.com, llvm-bugs@lists.llvm.org, smithp352@googlemail.com
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
Hello

Since LLVM-11.0.1-rc2, writing an output file with lld fails with the following
error when the target directory is on a RAM drive.

> lld-link-11.0.1-rc2.exe /OUT:R:\llvmtest.exe llvmtest.o
> lld-link-11.0.1-rc2: error: cannot open output file llvmtest.exe: function
not supported

After the error is reported and lld aborts, a file named
R:\llvmtest.exe.tmpXXXXXXX (random 7 hex digit suffix) of 0 byte length remains.

The same is also true for other lld variations like wasm-ld.exe. Both the win64
and win32 builds from the official GitHub releases page are affected. Any
version since LLVM 11.0.1-rc2 (released Dec 19, 2020) seems to be affected.
Versions 11.0.1-rc1 (released Nov 26, 2020) and older don't show the problem
and generate the output file as if it were a physical hard drive.

I use the free software "ImDisk Virtual Disk Driver for Windows" to create RAM
drives, formatted with NTFS. It is available from http://www.ltr-
data.se/opencode.html/#ImDisk
On the issue tracker of LDC (LLVM-based D Compiler) there is a report about the
same error message from someone using another software called "Primo Ramdisk":
https://github.com/ldc-developers/ldc/issues/3675#issuecomment-783864814

I tried to write to various drive targets and network shares also showed some
weirdness starting with that same version. It writes the output without error
message but then it leaves behind a 1 byte file llvmtest.exe.tmpXXXXXXX.

Here's various tests with the drives C: (physical hard drive), R: (RAM drive),
N: (Network drive) and \\x.x.x.x\x (UNC network share).

> lld-link-11.0.1-rc1.exe /OUT:C:\llvmtest.exe llvmtest.o
>   => no error, leaves only C:\llvmtest.exe
>
> lld-link-11.0.1-rc2.exe /OUT:C:\llvmtest.exe llvmtest.o
>   => no error, leaves only C:\llvmtest.exe
>
> lld-link-11.0.1-rc1.exe /OUT:R:\llvmtest.exe llvmtest.o
>   => no error, leaves only N:\llvmtest.exe
>
> lld-link-11.0.1-rc2.exe /OUT:R:\llvmtest.exe llvmtest.o
>   => shows error, and leaves only R:\llvmtest.exe.tmpXXXXXXX (0 bytes)
>
> lld-link-11.0.1-rc1.exe /OUT:N:\llvmtest.exe llvmtest.o
>   => no error, leaves only N:\llvmtest.exe
>
> lld-link-11.0.1-rc2.exe /OUT:N:\llvmtest.exe llvmtest.o
>   => no error, but leaves both N:\llvmtest.exe (ok) and
N:\llvmtest.exe.tmpXXXXXXX (1 bytes)
>
> lld-link-11.0.1-rc1.exe /OUT:\\x.x.x.x\x\llvmtest.exe llvmtest.o
>   => no error, leaves only \\x.x.x.x\x\llvmtest.exe
>
> lld-link-11.0.1-rc2.exe /OUT:\\x.x.x.x\x\llvmtest.exe llvmtest.o
>   => no error, but leaves both \\x.x.x.x\x\llvmtest.exe and
\\x.x.x.x\x\llvmtest.exe.tmpXXXXXXX (1 bytes)

The llvmtest.o file I tested with was created with Clang which works fine in
any version of Clang as far as I can tell.

> int main() { return 1; }
> int mainCRTStartup() { return 2; }

> clang-11.0.1-rc2.exe -c llvmtest.c -o llvmtest.o

The generated EXE file (if it succeeds) returns the exit status 2 (result of
mainCRTStartup).

Thanks for checking.
Quuxplusone commented 2 years ago

I think this should be fixed by https://reviews.llvm.org/rG177176f75c6fa3f624d6d964b9d340ce39511565, could you verify?