[PATCH] D112386: [ELF][X86] Support R_X86_64_PLTOFF64

Fangrui Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 25 10:49:10 PDT 2021


MaskRay added a comment.

In D112386#3084962 <https://reviews.llvm.org/D112386#3084962>, @peter.smith wrote:

> FWIW this looks like it matches the description in https://refspecs.linuxbase.org/elf/x86_64-abi-0.99.pdf . Would be good to get this checked over by someone that knows x86_64 better than me.



  // a.c
  void bar();
  int main() { bar(); }
  
  // b.c
  #include <stdio.h>
  void foo() { puts("foo"); }
  void bar() { foo(); }

  .MAKE.MODE = meta curDirOk=true
  
  all: a b.so
  
  a: a.c b.so
          $(CC) a.c ./b.so -ldl -o $@ -g
  
  b.so: b.c
          $(CC) -shared -fpic -mcmodel=large -O2 -Wl,-Bsymbolic -g $> -o $@

I have verified that `bmake; ./a` works. (With an incorrect computation for R_X86_64_PLTOFF64 `./a` would segfault.)

Clang -mcmodel=large always uses -fno-plt like code generation with R_X86_64_GOTOFF64 instead of R_X86_64_PLTOFF64, so GCC must be used for verification.

> If there's no-one left I can approve.

It's more or less the case now but fortunately not many changes are needed...

> This may be a naive question, just thinking of Arm/AArch64 where the code often loads the base of the GOT with the __GLOBAL_OFFSET_TABLE__ symbol. It may be worth checking on GOT being .got.plt. I'm guessing that in the large-code model some bit of code loads the base of the .got.plt. Is that done via the __GLOBAL_OFFSET_TABLE__ symbol or some other more direct method? Just thinking of the case where __GLOBAL_OFFSET_TABLE__ is not placed in between .got or .got.plt, this wouldn't be a problem if LLD always placed __GLOBAL_OFFSET_TABLE__ at the base of the .got.plt if it existed. No problems if there is a more direct method for the code to get the base of the .got.plt.

LLD defines `__GLOBAL_OFFSET_TABLE__` only when it is referenced. `R_X86_64_PLTOFF64` does not force creation of the symbol (LLD matches GNU ld).

`global-offset-table-position.s` checks that `__GLOBAL_OFFSET_TABLE__` is placed at `.got.plt` for x86-64.
`__GLOBAL_OFFSET_TABLE__` is either at start(.got) or start(.got.plt). All our `RelExpr` formulae use either start(.got) or start(.got.plt), not `__GLOBAL_OFFSET_TABLE__`.

So I think it is fine not to check the symbol in the new test.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D112386



More information about the llvm-commits mailing list