llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.13k stars 12.01k forks source link

clang integrated assembler is missing support for -Wa,-mno-shared #64603

Open nickdesaulniers opened 1 year ago

nickdesaulniers commented 1 year ago

Consider the following test case:

; x.s
.global foo
foo:
  jmp foo
$ clang x.s -c && llvm-objdump -dr x.o | tail -n 3 
0000000000000000 <foo>:
       0: e9 00 00 00 00                jmp 0x5 <foo+0x5>
        0000000000000001:  R_X86_64_PLT32   foo-0x4

compare that with GNU as

$ as x.s -o x.o && llvm-objdump -dr x.o | tail -n 2
0000000000000000 <foo>:
       0: eb fe                         jmp 0x0 <foo>

I don't think we need to emit the relocation.

llvmbot commented 1 year ago

@llvm/issue-subscribers-backend-x86

nickdesaulniers commented 1 year ago

@MaskRay mentions that gas has -mshared and will produce the relocation with that flag.

Perhaps clang is missing -Wa,-mno-shared, and should default to that behavior.

nickdesaulniers commented 1 year ago

This might be x86 specific behavior of gas.

MaskRay commented 1 year ago

I think suppressing R_X86_64_PLT32 is actually an odd behavior in binutils's x86 port in its default -mno-shared mode (gas/config/tc-i386.c:shared): https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=b084df0b8d1262fb1e969c74bcc5c61e262a6199. I think most other ports of GNU assembler generate a branch relocation.

This behavior requires quite a few heuristics and it's difficult to get right. For example, GRP_COMDAT section groups can discard STB_GLOBAL symbols. Suppressing R_X86_64_PLT32 can lead to an odd jump destination. There may be other corner cases.

I don't think -Wa,-mno-shared is a useful feature for LLVM integrated assembler. Hmm, gas i386 added the option -mno-relax but then reverted it in 2015.