Source: llvm-toolchain-4.0
Version: 1:4.0.1-10
Severity: normal
Tags: patch
Usertags: sparc64


In order to get the Rust compiler work on sparc64, we need another
LLVM patch which is currently being upstreamed [1] which fixes the
code generation on sparc64.

Without the patch, LLVM generates invalid code that binutils stumbles
over and crashes with an internal error [2]. With the patch merged,
LLVM is working properly and allows a full native build of the Rust
compiler on sparc64 :).

Since Rust upstream is currently still on LLVM 4.0, even for Rust
1.24, it would be nice to have the patch merged for the 4.0 version
as well as the 6.0 version of the llvm-toolchain package. Although
we are going to convince upstream to backport the patch for 6.0.


> [1]
> [2]

 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer -
`. `'   Freie Universitaet Berlin -
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913
Description: [Sparc] Include __tls_get_addr in symbol table for TLS calls to it
 Global Dynamic and Local Dynamic call relocations only implicitly
 reference __tls_get_addr, but it still needs to be in the symbol table
 to be bound at link time otherwise it fails to link. For details, see
Author: James Clarke <>
Last-Update: 2018-02-14

--- llvm-toolchain-4.0-4.0.1.orig/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
+++ llvm-toolchain-4.0-4.0.1/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
@@ -194,14 +194,30 @@ static void fixELFSymbolsInTLSFixupsImpl
 void SparcMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
   switch(getKind()) {
   default: return;
+  case VK_Sparc_TLS_GD_CALL:
+  case VK_Sparc_TLS_LDM_CALL: {
+    // The corresponding relocations reference __tls_get_addr, as they call it,
+    // but this is only implicit; there is no connection in the ELF file
+    // between the relocation and the symbol, other than the specification for
+    // the semantics of the relocations. However, the symbol must be included
+    // in our symbol table despite the lack of references to it, since it needs
+    // to be bound during linking for these relocations. For details see
+    //
+    MCSymbol *Symbol = Asm.getContext().getOrCreateSymbol("__tls_get_addr");
+    Asm.registerSymbol(*Symbol);
+    auto ELFSymbol = cast<MCSymbolELF>(Symbol);
+    if (!ELFSymbol->isBindingSet()) {
+      ELFSymbol->setBinding(ELF::STB_GLOBAL);
+      ELFSymbol->setExternal(true);
+    }
+  }
   case VK_Sparc_TLS_GD_HI22:
   case VK_Sparc_TLS_GD_LO10:
   case VK_Sparc_TLS_GD_ADD:
-  case VK_Sparc_TLS_GD_CALL:
   case VK_Sparc_TLS_LDM_HI22:
   case VK_Sparc_TLS_LDM_LO10:
   case VK_Sparc_TLS_LDM_ADD:
-  case VK_Sparc_TLS_LDM_CALL:
   case VK_Sparc_TLS_LDO_HIX22:
   case VK_Sparc_TLS_LDO_LOX10:
   case VK_Sparc_TLS_LDO_ADD:

Reply via email to