lkl / linux

Linux kernel source tree
https://lkl.github.io/
Other
815 stars 137 forks source link

Windows: Corrupted COFF symbol table #292

Open petrosagg opened 7 years ago

petrosagg commented 7 years ago

When trying to link liblkl.a using the MSVS linker it fails with the following error:

LNK1314: corrupt or invalid COFF symbol table (undefined static or label symbol)

I made a minimal test case using the following C program which comes from minimising kernel/sys_ni.c

long sys_ni_syscall(void) {
    return -38;
}

asm( ".weak " "_" "sys_quotactl" "\n\t" ".set  " "_" "sys_quotactl" "," "_" "sys_ni_syscall");
asm( ".weak " "_" "sys32_quotactl" "\n\t" ".set  " "_" "sys32_quotactl" "," "_" "sys_ni_syscall");

After compiling this program with i686-w64-mingw32-gcc -c -o a.o a.c and inspecting the object with i686-w64-mingw32-objdump -x a.o we can see that the aux entries are correct:

[ 12](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 .weak._sys_quotactl._sys_ni_syscall
[ 13](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 .weak._sys32_quotactl._sys_ni_syscall
[ 14](sec  0)(fl 0x00)(ty   0)(scl 105) (nx 1) 0x00000000 _sys_quotactl
AUX lnno 1 size 0x0 tagndx 12
[ 16](sec  0)(fl 0x00)(ty   0)(scl 105) (nx 1) 0x00000000 _sys32_quotactl
AUX lnno 1 size 0x0 tagndx 13

However, after passing the object through ld using i686-w64-mingw32-ld -r -o r.o a.o the aux entries are no longer pointing to valid locations. In fact, one of them points to itself:

[ 12](sec  0)(fl 0x00)(ty   0)(scl 105) (nx 1) 0x00000000 _sys32_quotactl
AUX lnno 1 size 0x0 tagndx 13
[ 14](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 .weak._sys_quotactl._sys_ni_syscall
[ 15](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 .weak._sys32_quotactl._sys_ni_syscall
[ 16](sec  0)(fl 0x00)(ty   0)(scl 105) (nx 1) 0x00000000 _sys_quotactl
AUX lnno 1 size 0x0 tagndx 12

Furthermore, when such corrupted object file passes through objcopy with a -G flag, which is how lkl.o is generated, the weak symbols become undefined instead of being resolved to their local alternatives.

[petrosagg@satie linux-lkl]$ i686-w64-mingw32-nm lkl.o | grep sys_semget
         U _sys_semget
0001c070 t .weak._sys_semget._sys_ni_syscall

This seems to be related to @tavip's binutils patch for weak NT externals support. The patched ld handles aux entry relocation for some cases but not all. I haven't figured out what is the differentiating factor.

I would appreciate any help or pointers on where to look next.

staalmannen commented 7 years ago

On Fri, Jan 13, 2017 at 11:44:05PM -0800, Petros Angelatos wrote:

When trying to link liblkl.a using the MSVS linker it fails with the following error:

I thought that libraries built with gcc were not compatible with MSVC ? I tried before to build lkl using the new Clang/C2 (lkl with llvmlinux patches) specifically because of that (to have MSVC-compatible lkl libraries).

Since I did not need it myself and it was mostly out of curiosity I did not pursue it further.

LNK1314: corrupt or invalid COFF symbol table (undefined static or label symbol)

I made a minimal test case using the following C program which comes from minimising kernel/sys_ni.c

long sys_ni_syscall(void) { return -38; }

asm( ".weak " "_" "sysquotactl" "\n\t" ".set " "" "sysquotactl" "," "" "sys_nisyscall"); asm( ".weak " "" "sys32quotactl" "\n\t" ".set " "" "sys32quotactl" "," "" "sys_ni_syscall");

After compiling this program with i686-w64-mingw32-gcc -c -o a.o a.c and inspecting the object with i686-w64-mingw32-objdump -x a.o we can see that the aux entries are correct:

[ 12](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 .weak._sys_quotactl._sys_ni_syscall [ 13](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 .weak._sys32_quotactl._sys_ni_syscall [ 14](sec 0)(fl 0x00)(ty 0)(scl 105) (nx 1) 0x00000000 _sys_quotactl AUX lnno 1 size 0x0 tagndx 12 [ 16](sec 0)(fl 0x00)(ty 0)(scl 105) (nx 1) 0x00000000 _sys32_quotactl AUX lnno 1 size 0x0 tagndx 13

However, after passing the object through ld using i686-w64-mingw32-ld -r -o r.o a.o the aux entries are no longer pointing to valid locations. In fact, one of them points to itself:

[ 12](sec 0)(fl 0x00)(ty 0)(scl 105) (nx 1) 0x00000000 _sys32_quotactl AUX lnno 1 size 0x0 tagndx 13 [ 14](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 .weak._sys_quotactl._sys_ni_syscall [ 15](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 .weak._sys32_quotactl._sys_ni_syscall [ 16](sec 0)(fl 0x00)(ty 0)(scl 105) (nx 1) 0x00000000 _sys_quotactl AUX lnno 1 size 0x0 tagndx 12

Furthermore, when such corrupted object file passes through objcopy with a -G flag, which is how lkl.o is generated, the weak symbols become undefined instead of being resolved to their local alternatives.

[petrosagg@satie linux-lkl]$ i686-w64-mingw32-nm lkl.o | grep sys_semget U _sys_semget 0001c070 t .weak._sys_semget._sys_ni_syscall

This seems to be related to @tavip's binutils patch for weak NT externals support. The patched ld handles aux entry relocation for some cases but not all. I haven't figured out what is the differentiating factor.

I would appreciate any help or pointers on where to look next.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.*

petrosagg commented 7 years ago

@staalmannen while there are some things to take into account like name mangling it is possible to link a GCC produced dll/object file in MVSC. http://www.mingw.org/wiki/msvc_and_mingw_dlls

But this issue is not directly related to the interoperability of the two compilers, it's just the the MSVC linker uncovered the issue. The object files are still corrupted when inspected in a pure GCC environment.

Rondom commented 7 years ago

Maybe, once this issue is fixed, one can have another try at upstreaming the patch.

mxi1 commented 7 years ago

@staalmannen

I tried before to build lkl using the new Clang/C2 (lkl with llvmlinux patches)

Have you got it work under clang? Thanks.