As of commit 67f846b59b32f3d704c601669409c2584383fea9 gas tries to use simple heuristics to determine if the given input and output files are distinct (at gas/as.c). The files are stat()'d and then the `st_ino' members compared. The logic is sound on 100% POSIX conforming platforms, however, the same cannot be said for e.g. MinGW. MinGW uses a zero `st_ino' for any (existing) file (based on a quick search this is by design, so not likely to change anytime soon). Thus, if all input and output files exist, gas will spit out "The input and output files must be distinct", which is not true. As a funny side-effect, even if the input and output file are determined as ``non-distinct'', something within the GCC chain still removes the output file. So, any even invocation will fail, while any odd invocation will succeed -- which is utterly confusing unless one takes a look at the source code and is aware of the POSIX internals at some level. Anyway, this commit effectively hinders any platform that does not supply an unique `st_ino' for a given file. Given that gas has been working just fine (and it ain't a filesystem utility), right out-of-the-box, for a long time without this, be it a native or a cross-compiling build, I see that this commit causes much, much more harm than good. (Cygwin is not affected by this, as it appears to emulate an unique `st_ino'.)
Created attachment 11001 [details] Proposed patch Hi Pekka, Please could you try out the uploaded patch and let me know if it solves the problem ? Cheers Nick
Hi Nick, My apologies for a late response; The patch appears to work just fine as expected. However, it just occured to me that IEEE Std 1003.1 (2016 edition), i.e. the POSIX specs, state that ``The st_ino and st_dev fields taken together uniquely identify the file within the system'' (pg. 392), so I guess the attached patch shouldn't be applied but one that fails only if the st_dev is the same, too (and has the non-POSIX compliant quirk workaround enabled way or another). By the way, the GCC folks simply do not do any stat()s for MinGW targets (so any compliant system does not get the zero serial number ignored).
Hi Pekka, > so I guess the > attached patch shouldn't be applied but one that fails only if the st_dev is > the same, too Can you confirm that MingW always returns 0 for the st_dev field as well ? (I assume that it does, but I would like to make sure). If so then I will apply the patch modified as you suggest. Cheers Nick
(In reply to Nick Clifton from comment #3) > Hi Pekka, > > Can you confirm that MingW always returns 0 for the st_dev field as well ? > (I assume that it does, but I would like to make sure). If so then I > will apply the patch modified as you suggest. > No, MinGW populates the st_dev field with some apparently non-random value (i.e. might be zero or not, but it's not always zero). I didn't check from what it acquires or derives that value, but it's neither always zero nor the same what Cygwin's stat() will return. Only the st_ino is always zero, which is indeed a bit shame.
Hi Pekka, > No, MinGW populates the st_dev field with some apparently non-random value In which case I will go with the original patch. I know that technically a valid file might have an inode of 0, but I think that in practice this will never happen since most file systems do not use inode 0, (at least not for ordinary files). Or if they do, it is for a special purpose, such as marking that the file has been deleted. Cheers Nick
The master branch has been updated by Nick Clifton <nickc@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=c3533c4c7c5db84b27e4dc8994a3c3a893077c03 commit c3533c4c7c5db84b27e4dc8994a3c3a893077c03 Author: Nick Clifton <nickc@redhat.com> Date: Mon May 14 13:05:02 2018 +0100 Fix a problem in the assembler when checking for overlapping input and output files on non-POSIX compliant systems. PR 23153 * as.c (main): When checking for an output file that is also an input file, also check that the inode is not zero.
Patch applied.
(In reply to Nick Clifton from comment #5) > Hi Pekka, > > > No, MinGW populates the st_dev field with some apparently non-random value > > In which case I will go with the original patch. I know that technically > a valid file might have an inode of 0, but I think that in practice this > will never happen since most file systems do not use inode 0, (at least not > for ordinary files). Or if they do, it is for a special purpose, such as > marking that the file has been deleted. On XFS, inode 0 can be used for regular files created by applications. Only newer versions have code in them to avoid inode 0. Some old applications have comments that inode 0 indicates a deleted directory entry, but this appears to be an invention and not something that has ever occurred in practice.
(In reply to Florian Weimer from comment #8) > On XFS, inode 0 can be used for regular files created by applications. Only > newer versions have code in them to avoid inode 0. Some old applications > have comments that inode 0 indicates a deleted directory entry, but this > appears to be an invention and not something that has ever occurred in > practice. My assumption is that even if inode 0 is valid for the filesystem it is extremely unlikely that this value will just happen to be used for an assembler input file, and extremely unlucky if this file is then used as the output from the assembler too. So basically, it is not worth worrying about.
(In reply to Nick Clifton from comment #9) > My assumption is that even if inode 0 is valid for the filesystem it is > extremely unlikely that this value will just happen to be used for an > assembler input file, > and extremely unlucky if this file is then used as the output from the > assembler too. So basically, it is not worth worrying about. Agreed. If this safety check does not kick in because the input and output files are the same and have inode 0, then this is not a huge problem. I just wanted to point out that inode number 0 is *not* special on most systems because that's a common misconception.