https://sourceware.org/bugzilla/show_bug.cgi?id=34540
Bug ID: 34540
Summary: SAME_INODE change makes two distinct -T linker scripts
fail on mingw hosts
Product: binutils
Version: 2.47
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: ld
Assignee: unassigned at sourceware dot org
Reporter: [email protected]
Target Milestone: ---
Since 2.47, linking with two distinct -T scripts fails on a Windows host:
ld.exe: error: linker script file 'C:/src/file1.ld (C:/src/file2.ld)' appears
multiple times
The two files are unrelated. 2.46.1 links the same command line properly, and
ld/ldfile.c is byte-identical between the two releases.
The change is in include/same-inode.h, "same-inode.h: don't depend on
_GL_WINDOWS_STAT_INODES". Before that, the _WIN32 branch fell through to
#define SAME_INODE(a, b) 0 unless _GL_WINDOWS_STAT_INODES was defined, and it
isn't defined anywhere in the binutils tree outside gnulib/gdb, so the PR 24576
duplicate-script check in ldfile_find_command_file wasn't doing anything on
Windows. Now it runs this code:
#define SAME_INODE(a, b) \
(!((a).st_ino == 0 && (a).st_dev == 0) \
&& (a).st_ino == (b).st_ino && (a).st_dev == (b).st_dev)
and without gnulib's windows-stat-inodes replacement, msvcrt's stat() sets
st_ino to 0 but leaves st_dev as the drive number. So the "information not
available" guard never triggers since st_dev is nonzero, and the comparison
then succeeds on 0 == 0 && drive == drive. Any two files on the same drive look
like the same file.
Compiling both releases' headers as-is with mingw and stat()ing two obviously
different files:
2.46.1 a: dev=25 ino=0 | b: dev=25 ino=0 | SAME_INODE=0
2.47 a: dev=25 ino=0 | b: dev=25 ino=0 | SAME_INODE=1
Keying the guard on st_ino alone, which is the field the CRT leaves unset,
fixes it:
- (!((a).st_ino == 0 && (a).st_dev == 0) \
+ ((a).st_ino != 0 \
&& (a).st_ino == (b).st_ino && (a).st_dev == (b).st_dev)
That restores 2.46.1 behaviour for plain stat(). SAME_INODE is simply never
true, so the duplicate check goes back to a no-op on Windows, while staying
correct for consumers that do use gnulib's replacement, where st_ino is a
nonzero file index. It doesn't make the duplicate check actually work on
Windows, and the commit message already said it wouldn't, but a linker that
refuses to link is worse than one that misses a diagnostic.
Patching 2.47 with the above and rebuilding the mipsel-none-elf cross toolchain
gives an ld that links the original command line fine on Windows.
--
You are receiving this mail because:
You are on the CC list for the bug.