[PATCH] D85782: [X86][ELF] Prefer lowering MC_GlobalAddress operands to .Lfoo$local only for STV_DEFAULT globals

Fangrui Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 25 09:12:26 PDT 2020


MaskRay added a subscriber: xiangzhangllvm.
MaskRay added a comment.

In D85782#2235567 <https://reviews.llvm.org/D85782#2235567>, @skan wrote:

> I think this introduces an old issue when lowering the instruction.
>
> Ref: https://sourceware.org/bugzilla/show_bug.cgi?id=13600
>
> **Reproducer:**
>
>   __attribute__((visibility("protected"))) void * foo (void) { return (void *)foo; }
>
>
>
>   clang -c  -O0  -fpic test.c 
>   clang -O0  -fpic test.o  -shared
>
> **Error message:**
> bfd/bin/ld: test.o: relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>
> **Analysis:**
>  Consider visibility in canBenefitFromLocalAlias function limits the MC's ability to use local reference when selecting operand.
>
> Before this patch, the assemble looks like
>
>           .text
>           .file   "test.c"
>           .protected      foo                     # -- Begin function foo
>           .globl  foo
>           .p2align        4, 0x90
>           .type   foo, at function
>   foo:                                    # @foo
>   .Lfoo$local:
>           .cfi_startproc
>   # %bb.0:                                # %entry
>           pushq   %rbp
>           .cfi_def_cfa_offset 16
>           .cfi_offset %rbp, -16
>           movq    %rsp, %rbp
>           .cfi_def_cfa_register %rbp
>           leaq    .Lfoo$local(%rip), %rax
>           popq    %rbp
>           .cfi_def_cfa %rsp, 8
>           retq
>   .Lfunc_end0:
>
> `.Lfoo$local(%rip)` can be calculated directly and is not a relocation when emiting object file, so we no need to worry about the visibility of foo.
>
> After this patch
>
>   leaq    .Lfoo$local(%rip), %rax    ->  leaq    foo(%rip), %rax
>
> The visibility of foo conflicts with the relocation type..

tl;dr This is a longstanding GNU ld bug introduced in binutils 2.26

  % cat a.c
  __attribute__((visibility("protected"))) void * foo (void) { return (void *)foo; }
  % gcc -fpic a.c -shared -fuse-ld=bfd # relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object

clang does not behave worse than GCC+GNU ld, so there is no regression on our side.

---

Longer answer:

binutils 2.26 introduced a regression: R_X86_64_PC32 can no longer be used against a protected symbol https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=ca3fe95e469b9daec153caa2c90665f5daaec2b5

The original issue is "Copy relocation against protected symbol doesn't work".
I agree with Rich Felker (https://gcc.gnu.org/ml/gcc/2016-04/msg00168.html) and
Cary Coutant (https://sourceware.org/ml/binutils/2016-03/msg00407.html https://gcc.gnu.org/ml/gcc/2016-04/msg00158.html https://gcc.gnu.org/ml/gcc/2016-04/msg00169.html) that we should
keep using direct access against protected symbols and disallow copy relocations against protected symbols.

I appreciate that Cary Coutant and Rafael Ávila de Espíndola added diagnostics to gold and lld, respectively:

- gold (https://sourceware.org/bugzilla/show_bug.cgi?id=19823)
- lld (https://bugs.llvm.org/show_bug.cgi?id=31476)

@xiangzhangllvm Perhaps you are in a good position to change the resolutions to the following issues:)

GCC 5 x86-64 introduced a regression (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65248)
i386 was flagged as a reproduce (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55012)

  __attribute__((visibility("protected"))) int a;
  int foo() { return a; } // GCC>=5 uses R_X86_64_GOTPCREL/R_X86_64_REX_GOTPCRELX instead of R_X86_64_PC32

binutils 2.26 introduced a regression R_X86_64_PC32 can no longer be used against a protected symbol https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=ca3fe95e469b9daec153caa2c90665f5daaec2b5


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85782/new/

https://reviews.llvm.org/D85782



More information about the llvm-commits mailing list