Skip to content

[X86][MC] Support R_X86_64_CODE_4_GOTPC32_TLSDESC #116908

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 22, 2024

Conversation

fzou1
Copy link
Contributor

@fzou1 fzou1 commented Nov 20, 2024

For

lea name@tlsdesc(%rip), %reg

add

R_X86_64_CODE_4_GOTPC32_TLSDESC = 45

if the instruction starts at 4 bytes before the relocation offset. This should be used if reg is one of the additional general-purpose registers, r16-r31, in Intel APX. It is similar to R_X86_64_GOTPC32_TLSDESC and linker optimization must take the different instruction encoding into account.

Linker can convert the instructions with R_X86_64_CODE_4_GOTPC32_TLSDESC to

mov $name@tpoff, %reg

if the first byte of the instruction at the relocation offset - 4 is 0xd5 (namely, encoded w/REX2 prefix) when possible.

Binutils patch: bminor/binutils-gdb@a533c8d
Binutils mailthread: https://sourceware.org/pipermail/binutils/2023-December/131463.html
ABI discussion: https://groups.google.com/g/x86-64-abi/c/ACwD-UQXVDs/m/vrgTenKyFwAJ
Blog: https://kanrobert.github.io/rfc/All-about-APX-relocation

@llvmbot
Copy link
Member

llvmbot commented Nov 20, 2024

@llvm/pr-subscribers-mc
@llvm/pr-subscribers-backend-x86

@llvm/pr-subscribers-llvm-binary-utilities

Author: Feng Zou (fzou1)

Changes

For

lea name@tlsdesc(%rip), %reg

add

R_X86_64_CODE_4_GOTPC32_TLSDESC = 45

if the instruction starts at 4 bytes before the relocation offset. This should be used if reg is one of the additional general-purpose registers, r16-r31, in Intel APX. It is similar to R_X86_64_GOTPC32_TLSDESC and linker optimization must take the different instruction encoding into account.

Linker can convert the instructions with R_X86_64_CODE_4_GOTPC32_TLSDESC to

mov $name@tpoff, %reg

if the first byte of the instruction at the relocation offset - 4 is 0xd5 (namely, encoded w/REX2 prefix) when possible.

Binutils patch: bminor/binutils-gdb@a533c8d
Binutils mailthread: https://sourceware.org/pipermail/binutils/2023-December/131463.html
ABI discussion: https://groups.google.com/g/x86-64-abi/c/ACwD-UQXVDs/m/vrgTenKyFwAJ
Blog: https://kanrobert.github.io/rfc/All-about-APX-relocation


Full diff: https://github.com/llvm/llvm-project/pull/116908.diff

4 Files Affected:

  • (modified) llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def (+1)
  • (modified) llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp (+2)
  • (modified) llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp (+1)
  • (modified) llvm/test/MC/X86/tlsdesc-64.s (+12)
diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def
index 161b1969abfeb4..1008263b3213ec 100644
--- a/llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def
+++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def
@@ -44,3 +44,4 @@ ELF_RELOC(R_X86_64_IRELATIVE,   37)
 ELF_RELOC(R_X86_64_GOTPCRELX,   41)
 ELF_RELOC(R_X86_64_REX_GOTPCRELX,    42)
 ELF_RELOC(R_X86_64_REX2_GOTPCRELX,    43)
+ELF_RELOC(R_X86_64_CODE_4_GOTPC32_TLSDESC,    45)
\ No newline at end of file
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
index 90222278d1ad6f..f0a7cc7c263e55 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
@@ -191,6 +191,8 @@ static unsigned getRelocType64(MCContext &Ctx, SMLoc Loc,
   case MCSymbolRefExpr::VK_TLSCALL:
     return ELF::R_X86_64_TLSDESC_CALL;
   case MCSymbolRefExpr::VK_TLSDESC:
+    if ((unsigned)Kind == X86::reloc_riprel_4byte_relax_rex2)
+      return ELF::R_X86_64_CODE_4_GOTPC32_TLSDESC;
     return ELF::R_X86_64_GOTPC32_TLSDESC;
   case MCSymbolRefExpr::VK_TLSGD:
     checkIs32(Ctx, Loc, Type);
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index 206436191c2584..510fc9fc417f2f 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -666,6 +666,7 @@ void X86MCCodeEmitter::emitMemModRMByte(
       case X86::SBB64rm:
       case X86::SUB64rm:
       case X86::XOR64rm:
+      case X86::LEA64r:
         return Kind == REX2  ? X86::reloc_riprel_4byte_relax_rex2
                : Kind == REX ? X86::reloc_riprel_4byte_relax_rex
                              : X86::reloc_riprel_4byte_relax;
diff --git a/llvm/test/MC/X86/tlsdesc-64.s b/llvm/test/MC/X86/tlsdesc-64.s
index ebe1710c3e869b..93e0f2bda0691d 100644
--- a/llvm/test/MC/X86/tlsdesc-64.s
+++ b/llvm/test/MC/X86/tlsdesc-64.s
@@ -17,3 +17,15 @@
 leaq a@tlsdesc(%rip), %rax
 call *a@tlscall(%rax)
 addq %fs:0, %rax
+
+# PRINT:      leaq a@tlsdesc(%rip), %r16
+# PRINT-NEXT: callq *a@tlscall(%r16)
+
+# CHECK:      12: leaq (%rip), %r16  # 0x1a <{{.*}}>
+# CHECK-NEXT:   0000000000000016: R_X86_64_CODE_4_GOTPC32_TLSDESC a-0x4
+# CHECK-NEXT: 1a: callq *(%r16)
+# CHECK-NEXT:   000000000000001a: R_X86_64_TLSDESC_CALL a
+
+leaq a@tlsdesc(%rip), %r16
+call *a@tlscall(%r16)
+addq %fs:0, %r16
\ No newline at end of file

fzou1 added a commit to fzou1/llvm-project that referenced this pull request Nov 20, 2024
For

  lea name@tlsdesc(%rip), %reg

add

  R_X86_64_CODE_4_GOTPC32_TLSDESC = 45

in llvm#116908.

Linker can treat R_X86_64_CODE_4_GOTPC32_TLSDESC as R_X86_64_GOTPC32_TLSDESC or
convert the instruction above to

  mov $name@tpoff, %reg

if the first byte of the instruction at the relocation offset - 4 is 0xd5
(namely, encoded w/REX2 prefix) when possible.

Binutils patch: bminor/binutils-gdb@a533c8d
Binutils mailthread: https://sourceware.org/pipermail/binutils/2023-December/131463.html
ABI discussion: https://groups.google.com/g/x86-64-abi/c/ACwD-UQXVDs/m/vrgTenKyFwAJ
Blog: https://kanrobert.github.io/rfc/All-about-APX-relocation
@RKSimon RKSimon requested a review from KanRobert November 20, 2024 10:58
@KanRobert KanRobert requested a review from MaskRay November 20, 2024 12:27
Comment on lines 194 to 196
if ((unsigned)Kind == X86::reloc_riprel_4byte_relax_rex2)
return ELF::R_X86_64_CODE_4_GOTPC32_TLSDESC;
return ELF::R_X86_64_GOTPC32_TLSDESC;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use condition operator?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. I'll update.

@@ -44,3 +44,4 @@ ELF_RELOC(R_X86_64_IRELATIVE, 37)
ELF_RELOC(R_X86_64_GOTPCRELX, 41)
ELF_RELOC(R_X86_64_REX_GOTPCRELX, 42)
ELF_RELOC(R_X86_64_REX2_GOTPCRELX, 43)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe merge #116737 first and rebase? So that it does not look strange.

Copy link
Contributor Author

@fzou1 fzou1 Nov 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay for me. Please help merge that PR. Thanks.

@@ -666,6 +666,7 @@ void X86MCCodeEmitter::emitMemModRMByte(
case X86::SBB64rm:
case X86::SUB64rm:
case X86::XOR64rm:
case X86::LEA64r:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need LEA64r before REX2?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry. I don't understand. We need to check LEA64r with REX2 prefix and add R_X86_64_CODE_4_GOTPC32_TLSDESC relocation for it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My question is: Why we don't need to check LEA64r when REX prefix was added? Is LEA64r special to REX2?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not special to REX2. Here we need to distinguish REX2 prefix and others and set corresponding relocation type (R_X86_64_CODE_4_GOTPC32_TLSDESC) if it's REX2 prefix. For REX prefix, we didn't have to distinguish it and others in the past.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it.

Copy link
Member

@MaskRay MaskRay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code/test looks good to me

For

  lea name@tlsdesc(%rip), %reg

add

  R_X86_64_CODE_4_GOTPC32_TLSDESC = 45

if the instruction starts at 4 bytes before the relocation offset. This should
be used if reg is one of the additional general-purpose registers, r16-r31, in
Intel APX.  It is similar to R_X86_64_GOTPC32_TLSDESC and linker optimization
must take the different instruction encoding into account.

Linker can convert the instructions with R_X86_64_CODE_4_GOTPC32_TLSDESC to

  mov $name@tpoff, %reg

if the first byte of the instruction at the relocation offset - 4 is
0xd5 (namely, encoded w/REX2 prefix) when possible.

Binutils patch: bminor/binutils-gdb@a533c8d
Binutils mailthread: https://sourceware.org/pipermail/binutils/2023-December/131463.html
ABI discussion: https://groups.google.com/g/x86-64-abi/c/ACwD-UQXVDs/m/vrgTenKyFwAJ
Blog: https://kanrobert.github.io/rfc/All-about-APX-relocation
@fzou1 fzou1 force-pushed the mc-code-4-tlsdesc branch from 10360a6 to a45ba4f Compare November 21, 2024 10:40
# CHECK: 12: leaq (%rip), %r16 # 0x1a <{{.*}}>
# CHECK-NEXT: 0000000000000016: R_X86_64_CODE_4_GOTPC32_TLSDESC a-0x4
# CHECK-NEXT: 1a: callq *(%r16)
# CHECK-NEXT: 000000000000001a: R_X86_64_TLSDESC_CALL a
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is R_X86_64_TLSDESC_CALL expected? Or we need to check R_X86_64_CODE_4_TLSDESC_CALL?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. R_X86_64_TLSDESC_CALL is expected. There is no R_X86_64_CODE_4_TLSDESC_CALL type. As I understand, we don't need to rewrite/change the instruction so we don't need to know how many bytes the instruction starts before relocation offset.

Copy link
Contributor

@KanRobert KanRobert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@KanRobert KanRobert merged commit 8223982 into llvm:main Nov 22, 2024
8 checks passed
@fzou1 fzou1 deleted the mc-code-4-tlsdesc branch November 22, 2024 01:31
fzou1 added a commit to fzou1/llvm-project that referenced this pull request Nov 22, 2024
For

  lea name@tlsdesc(%rip), %reg

add

  R_X86_64_CODE_4_GOTPC32_TLSDESC = 45

in llvm#116908.

Linker can treat R_X86_64_CODE_4_GOTPC32_TLSDESC as R_X86_64_GOTPC32_TLSDESC or
convert the instruction above to

  mov $name@tpoff, %reg

if the first byte of the instruction at the relocation offset - 4 is 0xd5
(namely, encoded w/REX2 prefix) when possible.

Binutils patch: bminor/binutils-gdb@a533c8d
Binutils mailthread: https://sourceware.org/pipermail/binutils/2023-December/131463.html
ABI discussion: https://groups.google.com/g/x86-64-abi/c/ACwD-UQXVDs/m/vrgTenKyFwAJ
Blog: https://kanrobert.github.io/rfc/All-about-APX-relocation
fzou1 added a commit that referenced this pull request Nov 27, 2024
…16909)

For

  lea name@tlsdesc(%rip), %reg

add

  R_X86_64_CODE_4_GOTPC32_TLSDESC = 45

in #116908.

Linker can treat R_X86_64_CODE_4_GOTPC32_TLSDESC as
R_X86_64_GOTPC32_TLSDESC or convert the instruction above to

  mov $name@tpoff, %reg

if the first byte of the instruction at the relocation offset - 4 is
0xd5 (namely, encoded w/REX2 prefix) when possible.

Binutils patch: bminor/binutils-gdb@a533c8d
Binutils mailthread: https://sourceware.org/pipermail/binutils/2023-December/131463.html
ABI discussion: https://groups.google.com/g/x86-64-abi/c/ACwD-UQXVDs/m/vrgTenKyFwAJ
Blog: https://kanrobert.github.io/rfc/All-about-APX-relocation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants