Add relocation type R_X86_64_REX_GOTPCRELX
ClosedPublic

Authored by Phyx on Jun 4 2016, 5:14 PM.

Details

Summary

Adding support for the R_X86_64_REX_GOTPCRELX relocation type.
This relocation is treated by the linker the same as the R_X86_64_GOTPCRELX type
G + GOT + A - P to generate relative offsets to the GOT.
The REX prefix has no influence in this stage.

This is based on https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-r252.pdf

Test Plan

./validate

Diff Detail

Repository
rGHC Glasgow Haskell Compiler
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.
Phyx retitled this revision from to Add relocation type R_X86_64_REX_GOTPCRELX.Jun 4 2016, 5:14 PM
Phyx updated this object.
Phyx edited the test plan for this revision. (Show Details)
Phyx updated the Trac tickets for this revision.
Phyx added a subscriber: Restricted Project.
austin added a comment.Jun 4 2016, 5:44 PM

whateverworks

Have you tested this on a newer Arch system, like mentioned in Trac #12147?

erikd accepted this revision.Jun 4 2016, 7:22 PM

I'd like to see this tested on system which displays the problem, but otherwise LGTM.

This revision is now accepted and ready to land.Jun 4 2016, 7:22 PM
Phyx planned changes to this revision.EditedJun 5 2016, 1:04 AM

I need to add R_X86_64_GOTPCRELX as well.

The documentation states:

Instead of generating 
R_X86_64_GOTPCREL relocation agasint foo for foo@GOTPCREL(%rip), 
we generate R_X86_64_GOTPCRELX or R_X86_64_REX_GOTPCRELX if there 
is a REX prefix.  Linker can treat them the same as R_X86_64_GOTPCREL

So it seems like R_X86_64_GOTPCREL got split into two.

Also this needs an updated glibc to compile because of the two new constants. How should this be handled?

As for test the simple test I used on Fedora:

# x86_64
# as as_test.s -o as_test.o && objdump -Dr as_test.o
# ghc --interactive hs_test as_test.o

.text
.globl foo

foo:
	push %rbp
	mov %rsp, %rbp

	mov msg@GOTPCREL(%rip), %rdi
	call puts@PLT

	pop %rbp
	ret

.data
msg:
	.ascii "Hello World!\0"
	len = . - msg

Which produces the expected relocation

as_test.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <foo>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   48 83 ec 10             sub    $0x10,%rsp
   8:   48 8b 3d 00 00 00 00    mov    0x0(%rip),%rdi        # f <foo+0xf>
                        b: R_X86_64_REX_GOTPCRELX       msg-0x4
   f:   e8 00 00 00 00          callq  14 <foo+0x14>
                        10: R_X86_64_PLT32      puts-0x4
  14:   c3                      retq

Disassembly of section .data:

0000000000000000 <msg>:
   0:   48                      rex.W
   1:   65 6c                   gs insb (%dx),%es:(%rdi)
   3:   6c                      insb   (%dx),%es:(%rdi)
   4:   6f                      outsl  %ds:(%rsi),(%dx)
   5:   20 57 6f                and    %dl,0x6f(%rdi)
   8:   72 6c                   jb     76 <len+0x69>
   a:   64 21 00                and    %eax,%fs:(%rax)

With

[phyx@localhost ~]$ as --version
GNU assembler (GNU Binutils) 2.26.20160125

Using the Haskell file

foreign import ccall foo :: IO ()

main = foo

I compiled GHC with DYNAMIC_GHC_PROGRAMS=NO

And then tried loading them into ghci

inplace/bin/ghc-stage2 --interactive hs_test.hs as_test.o

This crashed as expected

[phyx@localhost ~]$ ghc/inplace/bin/ghc-stage2 --interactive as_test.o hs_test.hs
GHCi, version 8.1.20160604: http://www.haskell.org/ghc/  :? for help
ghc-stage2: as_test.o: unhandled ELF relocation(RelA) type 42

linking extra libraries/objects failed

Adding the relocations produced the expected result:

GHCi, version 8.1.20160604: http://www.haskell.org/ghc/  :? for help
[1 of 1] Compiling Main             ( hs_test.hs, interpreted )
Ok, modules loaded: Main.
*Main> main
Hello World!
erikd added a comment.EditedJun 5 2016, 1:30 AM
In D2303#67068, @Phyx wrote:

Also this needs an updated glibc to compile because of the two new constants. How should this be handled?

I'm pretty sure that will be handled by the Linux distros. They wouldn't ship an GNU as until their glibc handled these new relocations.

Phyx updated this revision to Diff 7855.Jun 5 2016, 2:00 AM
  • T12147: Add R_X86_64_GOTPCRELX as well
This revision is now accepted and ready to land.Jun 5 2016, 2:00 AM
Phyx added a comment.Jun 5 2016, 2:17 AM
In D2303#67070, @erikd wrote:

I'm pretty sure that will be handled by the Linux distros. They wouldn't ship an GNU as until their glibc handled these new relocations.

I meant compile time, currently with a glibc older than 2.23 the relocations won't exist in elf.h and so compiling GHC will fail.
But we still want to support older versions don't we (for compiling)?

So should I put these in an #ifdef or something? I'm not sure what the proper thing to do here so I'll defer to you and @austin

erikd added a comment.Jun 5 2016, 2:40 AM

Yes, an #ifdef is acceptable around that.

Phyx updated this revision to Diff 7856.Jun 5 2016, 3:00 AM
  • T12147: Added #ifdef for new constants
Phyx added a comment.Jun 5 2016, 3:48 AM

Cheers, thanks @erikd

This revision was automatically updated to reflect the committed changes.