diff options
Diffstat (limited to 'contrib/llvm/patches/patch-r262261-llvm-r200962-sparc.diff')
-rw-r--r-- | contrib/llvm/patches/patch-r262261-llvm-r200962-sparc.diff | 378 |
1 files changed, 378 insertions, 0 deletions
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r200962-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r200962-sparc.diff new file mode 100644 index 0000000..2e668a3 --- /dev/null +++ b/contrib/llvm/patches/patch-r262261-llvm-r200962-sparc.diff @@ -0,0 +1,378 @@ +Pull in r200962 from upstream llvm trunk (by Venkatraman Govindaraju): + + [Sparc] Emit relocations for Thread Local Storage (TLS) when integrated assembler is used. + +Introduced here: http://svn.freebsd.org/changeset/base/262261 + +Index: lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp +=================================================================== +--- lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp ++++ lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp +@@ -26,31 +26,65 @@ static unsigned adjustFixupValue(unsigned Kind, ui + case FK_Data_4: + case FK_Data_8: + return Value; ++ + case Sparc::fixup_sparc_wplt30: + case Sparc::fixup_sparc_call30: + return (Value >> 2) & 0x3fffffff; ++ + case Sparc::fixup_sparc_br22: + return (Value >> 2) & 0x3fffff; ++ + case Sparc::fixup_sparc_br19: + return (Value >> 2) & 0x7ffff; ++ + case Sparc::fixup_sparc_pc22: + case Sparc::fixup_sparc_got22: ++ case Sparc::fixup_sparc_tls_gd_hi22: ++ case Sparc::fixup_sparc_tls_ldm_hi22: ++ case Sparc::fixup_sparc_tls_ie_hi22: + case Sparc::fixup_sparc_hi22: + return (Value >> 10) & 0x3fffff; ++ + case Sparc::fixup_sparc_pc10: + case Sparc::fixup_sparc_got10: ++ case Sparc::fixup_sparc_tls_gd_lo10: ++ case Sparc::fixup_sparc_tls_ldm_lo10: ++ case Sparc::fixup_sparc_tls_ie_lo10: + case Sparc::fixup_sparc_lo10: + return Value & 0x3ff; ++ ++ case Sparc::fixup_sparc_tls_ldo_hix22: ++ case Sparc::fixup_sparc_tls_le_hix22: ++ return (~Value >> 10) & 0x3fffff; ++ ++ case Sparc::fixup_sparc_tls_ldo_lox10: ++ case Sparc::fixup_sparc_tls_le_lox10: ++ return (~(~Value & 0x3ff)) & 0x1fff; ++ + case Sparc::fixup_sparc_h44: + return (Value >> 22) & 0x3fffff; ++ + case Sparc::fixup_sparc_m44: + return (Value >> 12) & 0x3ff; ++ + case Sparc::fixup_sparc_l44: + return Value & 0xfff; ++ + case Sparc::fixup_sparc_hh: + return (Value >> 42) & 0x3fffff; ++ + case Sparc::fixup_sparc_hm: + return (Value >> 32) & 0x3ff; ++ ++ case Sparc::fixup_sparc_tls_gd_add: ++ case Sparc::fixup_sparc_tls_gd_call: ++ case Sparc::fixup_sparc_tls_ldm_add: ++ case Sparc::fixup_sparc_tls_ldm_call: ++ case Sparc::fixup_sparc_tls_ldo_add: ++ case Sparc::fixup_sparc_tls_ie_ld: ++ case Sparc::fixup_sparc_tls_ie_ldx: ++ case Sparc::fixup_sparc_tls_ie_add: ++ return 0; + } + } + +@@ -81,7 +115,25 @@ namespace { + { "fixup_sparc_pc10", 22, 10, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_sparc_got22", 10, 22, 0 }, + { "fixup_sparc_got10", 22, 10, 0 }, +- { "fixup_sparc_wplt30", 2, 30, MCFixupKindInfo::FKF_IsPCRel } ++ { "fixup_sparc_wplt30", 2, 30, MCFixupKindInfo::FKF_IsPCRel }, ++ { "fixup_sparc_tls_gd_hi22", 10, 22, 0 }, ++ { "fixup_sparc_tls_gd_lo10", 22, 10, 0 }, ++ { "fixup_sparc_tls_gd_add", 0, 0, 0 }, ++ { "fixup_sparc_tls_gd_call", 0, 0, 0 }, ++ { "fixup_sparc_tls_ldm_hi22", 10, 22, 0 }, ++ { "fixup_sparc_tls_ldm_lo10", 22, 10, 0 }, ++ { "fixup_sparc_tls_ldm_add", 0, 0, 0 }, ++ { "fixup_sparc_tls_ldm_call", 0, 0, 0 }, ++ { "fixup_sparc_tls_ldo_hix22", 10, 22, 0 }, ++ { "fixup_sparc_tls_ldo_lox10", 22, 10, 0 }, ++ { "fixup_sparc_tls_ldo_add", 0, 0, 0 }, ++ { "fixup_sparc_tls_ie_hi22", 10, 22, 0 }, ++ { "fixup_sparc_tls_ie_lo10", 22, 10, 0 }, ++ { "fixup_sparc_tls_ie_ld", 0, 0, 0 }, ++ { "fixup_sparc_tls_ie_ldx", 0, 0, 0 }, ++ { "fixup_sparc_tls_ie_add", 0, 0, 0 }, ++ { "fixup_sparc_tls_le_hix22", 0, 0, 0 }, ++ { "fixup_sparc_tls_le_lox10", 0, 0, 0 } + }; + + if (Kind < FirstTargetFixupKind) +@@ -101,11 +153,28 @@ namespace { + bool &IsResolved) { + switch ((Sparc::Fixups)Fixup.getKind()) { + default: break; +- case Sparc::fixup_sparc_wplt30: IsResolved = false; break; ++ case Sparc::fixup_sparc_wplt30: ++ case Sparc::fixup_sparc_tls_gd_hi22: ++ case Sparc::fixup_sparc_tls_gd_lo10: ++ case Sparc::fixup_sparc_tls_gd_add: ++ case Sparc::fixup_sparc_tls_gd_call: ++ case Sparc::fixup_sparc_tls_ldm_hi22: ++ case Sparc::fixup_sparc_tls_ldm_lo10: ++ case Sparc::fixup_sparc_tls_ldm_add: ++ case Sparc::fixup_sparc_tls_ldm_call: ++ case Sparc::fixup_sparc_tls_ldo_hix22: ++ case Sparc::fixup_sparc_tls_ldo_lox10: ++ case Sparc::fixup_sparc_tls_ldo_add: ++ case Sparc::fixup_sparc_tls_ie_hi22: ++ case Sparc::fixup_sparc_tls_ie_lo10: ++ case Sparc::fixup_sparc_tls_ie_ld: ++ case Sparc::fixup_sparc_tls_ie_ldx: ++ case Sparc::fixup_sparc_tls_ie_add: ++ case Sparc::fixup_sparc_tls_le_hix22: ++ case Sparc::fixup_sparc_tls_le_lox10: IsResolved = false; break; + } + } + +- + bool mayNeedRelaxation(const MCInst &Inst) const { + // FIXME. + return false; +Index: lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h +=================================================================== +--- lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h ++++ lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h +@@ -63,6 +63,26 @@ namespace llvm { + /// fixup_sparc_wplt30 + fixup_sparc_wplt30, + ++ /// fixups for Thread Local Storage ++ fixup_sparc_tls_gd_hi22, ++ fixup_sparc_tls_gd_lo10, ++ fixup_sparc_tls_gd_add, ++ fixup_sparc_tls_gd_call, ++ fixup_sparc_tls_ldm_hi22, ++ fixup_sparc_tls_ldm_lo10, ++ fixup_sparc_tls_ldm_add, ++ fixup_sparc_tls_ldm_call, ++ fixup_sparc_tls_ldo_hix22, ++ fixup_sparc_tls_ldo_lox10, ++ fixup_sparc_tls_ldo_add, ++ fixup_sparc_tls_ie_hi22, ++ fixup_sparc_tls_ie_lo10, ++ fixup_sparc_tls_ie_ld, ++ fixup_sparc_tls_ie_ldx, ++ fixup_sparc_tls_ie_add, ++ fixup_sparc_tls_le_hix22, ++ fixup_sparc_tls_le_lox10, ++ + // Marker + LastTargetFixupKind, + NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind +Index: lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp +=================================================================== +--- lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp ++++ lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp +@@ -91,6 +91,24 @@ unsigned SparcELFObjectWriter::GetRelocType(const + case Sparc::fixup_sparc_hm: return ELF::R_SPARC_HM10; + case Sparc::fixup_sparc_got22: return ELF::R_SPARC_GOT22; + case Sparc::fixup_sparc_got10: return ELF::R_SPARC_GOT10; ++ case Sparc::fixup_sparc_tls_gd_hi22: return ELF::R_SPARC_TLS_GD_HI22; ++ case Sparc::fixup_sparc_tls_gd_lo10: return ELF::R_SPARC_TLS_GD_LO10; ++ case Sparc::fixup_sparc_tls_gd_add: return ELF::R_SPARC_TLS_GD_ADD; ++ case Sparc::fixup_sparc_tls_gd_call: return ELF::R_SPARC_TLS_GD_CALL; ++ case Sparc::fixup_sparc_tls_ldm_hi22: return ELF::R_SPARC_TLS_LDM_HI22; ++ case Sparc::fixup_sparc_tls_ldm_lo10: return ELF::R_SPARC_TLS_LDM_LO10; ++ case Sparc::fixup_sparc_tls_ldm_add: return ELF::R_SPARC_TLS_LDM_ADD; ++ case Sparc::fixup_sparc_tls_ldm_call: return ELF::R_SPARC_TLS_LDM_CALL; ++ case Sparc::fixup_sparc_tls_ldo_hix22: return ELF::R_SPARC_TLS_LDO_HIX22; ++ case Sparc::fixup_sparc_tls_ldo_lox10: return ELF::R_SPARC_TLS_LDO_LOX10; ++ case Sparc::fixup_sparc_tls_ldo_add: return ELF::R_SPARC_TLS_LDO_ADD; ++ case Sparc::fixup_sparc_tls_ie_hi22: return ELF::R_SPARC_TLS_IE_HI22; ++ case Sparc::fixup_sparc_tls_ie_lo10: return ELF::R_SPARC_TLS_IE_LO10; ++ case Sparc::fixup_sparc_tls_ie_ld: return ELF::R_SPARC_TLS_IE_LD; ++ case Sparc::fixup_sparc_tls_ie_ldx: return ELF::R_SPARC_TLS_IE_LDX; ++ case Sparc::fixup_sparc_tls_ie_add: return ELF::R_SPARC_TLS_IE_ADD; ++ case Sparc::fixup_sparc_tls_le_hix22: return ELF::R_SPARC_TLS_LE_HIX22; ++ case Sparc::fixup_sparc_tls_le_lox10: return ELF::R_SPARC_TLS_LE_LOX10; + } + + return ELF::R_SPARC_NONE; +Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp +=================================================================== +--- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp ++++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp +@@ -135,6 +135,25 @@ Sparc::Fixups SparcMCExpr::getFixupKind(SparcMCExp + case VK_Sparc_PC10: return Sparc::fixup_sparc_pc10; + case VK_Sparc_GOT22: return Sparc::fixup_sparc_got22; + case VK_Sparc_GOT10: return Sparc::fixup_sparc_got10; ++ case VK_Sparc_WPLT30: return Sparc::fixup_sparc_wplt30; ++ case VK_Sparc_TLS_GD_HI22: return Sparc::fixup_sparc_tls_gd_hi22; ++ case VK_Sparc_TLS_GD_LO10: return Sparc::fixup_sparc_tls_gd_lo10; ++ case VK_Sparc_TLS_GD_ADD: return Sparc::fixup_sparc_tls_gd_add; ++ case VK_Sparc_TLS_GD_CALL: return Sparc::fixup_sparc_tls_gd_call; ++ case VK_Sparc_TLS_LDM_HI22: return Sparc::fixup_sparc_tls_ldm_hi22; ++ case VK_Sparc_TLS_LDM_LO10: return Sparc::fixup_sparc_tls_ldm_lo10; ++ case VK_Sparc_TLS_LDM_ADD: return Sparc::fixup_sparc_tls_ldm_add; ++ case VK_Sparc_TLS_LDM_CALL: return Sparc::fixup_sparc_tls_ldm_call; ++ case VK_Sparc_TLS_LDO_HIX22: return Sparc::fixup_sparc_tls_ldo_hix22; ++ case VK_Sparc_TLS_LDO_LOX10: return Sparc::fixup_sparc_tls_ldo_lox10; ++ case VK_Sparc_TLS_LDO_ADD: return Sparc::fixup_sparc_tls_ldo_add; ++ case VK_Sparc_TLS_IE_HI22: return Sparc::fixup_sparc_tls_ie_hi22; ++ case VK_Sparc_TLS_IE_LO10: return Sparc::fixup_sparc_tls_ie_lo10; ++ case VK_Sparc_TLS_IE_LD: return Sparc::fixup_sparc_tls_ie_ld; ++ case VK_Sparc_TLS_IE_LDX: return Sparc::fixup_sparc_tls_ie_ldx; ++ case VK_Sparc_TLS_IE_ADD: return Sparc::fixup_sparc_tls_ie_add; ++ case VK_Sparc_TLS_LE_HIX22: return Sparc::fixup_sparc_tls_le_hix22; ++ case VK_Sparc_TLS_LE_LOX10: return Sparc::fixup_sparc_tls_le_lox10; + } + } + +@@ -147,7 +166,33 @@ SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Re + } + + static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) { +- assert(0 && "Implement fixELFSymbolsInTLSFixupsImpl!"); ++ switch (Expr->getKind()) { ++ case MCExpr::Target: ++ llvm_unreachable("Can't handle nested target expr!"); ++ break; ++ ++ case MCExpr::Constant: ++ break; ++ ++ case MCExpr::Binary: { ++ const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr); ++ fixELFSymbolsInTLSFixupsImpl(BE->getLHS(), Asm); ++ fixELFSymbolsInTLSFixupsImpl(BE->getRHS(), Asm); ++ break; ++ } ++ ++ case MCExpr::SymbolRef: { ++ const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr); ++ MCSymbolData &SD = Asm.getOrCreateSymbolData(SymRef.getSymbol()); ++ MCELF::SetType(SD, ELF::STT_TLS); ++ break; ++ } ++ ++ case MCExpr::Unary: ++ fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm); ++ break; ++ } ++ + } + + void SparcMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const { +Index: lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp +=================================================================== +--- lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp ++++ lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp +@@ -20,6 +20,7 @@ + #include "llvm/MC/MCExpr.h" + #include "llvm/MC/MCInst.h" + #include "llvm/MC/MCRegisterInfo.h" ++#include "llvm/MC/MCSymbol.h" + #include "llvm/ADT/Statistic.h" + #include "llvm/Support/raw_ostream.h" + +@@ -76,6 +77,21 @@ EncodeInstruction(const MCInst &MI, raw_ostream &O + OS << (char)(Bits >> 24); + Bits <<= 8; + } ++ unsigned tlsOpNo = 0; ++ switch (MI.getOpcode()) { ++ default: break; ++ case SP::TLS_CALL: tlsOpNo = 1; break; ++ case SP::TLS_ADDrr: ++ case SP::TLS_ADDXrr: ++ case SP::TLS_LDrr: ++ case SP::TLS_LDXrr: tlsOpNo = 3; break; ++ } ++ if (tlsOpNo != 0) { ++ const MCOperand &MO = MI.getOperand(tlsOpNo); ++ uint64_t op = getMachineOpValue(MI, MO, Fixups); ++ assert(op == 0 && "Unexpected operand value!"); ++ (void)op; // suppress warning. ++ } + + ++MCNumEmitted; // Keep track of the # of mi's emitted. + } +@@ -114,6 +130,21 @@ getCallTargetOpValue(const MCInst &MI, unsigned Op + if (MO.isReg() || MO.isImm()) + return getMachineOpValue(MI, MO, Fixups); + ++ if (MI.getOpcode() == SP::TLS_CALL) { ++ // No fixups for __tls_get_addr. Will emit for fixups for tls_symbol in ++ // EncodeInstruction. ++#ifndef NDEBUG ++ // Verify that the callee is actually __tls_get_addr. ++ const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(MO.getExpr()); ++ assert(SExpr && SExpr->getSubExpr()->getKind() == MCExpr::SymbolRef && ++ "Unexpected expression in TLS_CALL"); ++ const MCSymbolRefExpr *SymExpr = cast<MCSymbolRefExpr>(SExpr->getSubExpr()); ++ assert(SymExpr->getSymbol().getName() == "__tls_get_addr" && ++ "Unexpected function for TLS_CALL"); ++#endif ++ return 0; ++ } ++ + MCFixupKind fixupKind = (MCFixupKind)Sparc::fixup_sparc_call30; + + if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(MO.getExpr())) { +Index: test/CodeGen/SPARC/tls.ll +=================================================================== +--- test/CodeGen/SPARC/tls.ll ++++ test/CodeGen/SPARC/tls.ll +@@ -3,6 +3,10 @@ + ; RUN: llc <%s -march=sparc -relocation-model=pic | FileCheck %s --check-prefix=pic + ; RUN: llc <%s -march=sparcv9 -relocation-model=pic | FileCheck %s --check-prefix=pic + ++; RUN: llc <%s -march=sparc -relocation-model=static -filetype=obj | llvm-readobj -r | FileCheck %s --check-prefix=v8abs-obj ++; RUN: llc <%s -march=sparcv9 -relocation-model=static -filetype=obj | llvm-readobj -r | FileCheck %s --check-prefix=v9abs-obj ++; RUN: llc <%s -march=sparc -relocation-model=pic -filetype=obj | llvm-readobj -r | FileCheck %s --check-prefix=pic-obj ++; RUN: llc <%s -march=sparcv9 -relocation-model=pic -filetype=obj | llvm-readobj -r | FileCheck %s --check-prefix=pic-obj + + @local_symbol = internal thread_local global i32 0 + @extern_symbol = external thread_local global i32 +@@ -69,3 +73,47 @@ entry: + store i32 %1, i32* @extern_symbol, align 4 + ret i32 %1 + } ++ ++ ++; v8abs-obj: Relocations [ ++; v8abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LE_HIX22 local_symbol 0x0 ++; v8abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LE_LOX10 local_symbol 0x0 ++; v8abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_HI22 _GLOBAL_OFFSET_TABLE_ 0x0 ++; v8abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_LO10 _GLOBAL_OFFSET_TABLE_ 0x0 ++; v8abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_IE_HI22 extern_symbol 0x0 ++; v8abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_IE_LO10 extern_symbol 0x0 ++; v8abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_IE_LD extern_symbol 0x0 ++; v8abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_IE_ADD extern_symbol 0x0 ++; v8abs-obj: ] ++ ++; v9abs-obj: Relocations [ ++; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LE_HIX22 local_symbol 0x0 ++; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LE_LOX10 local_symbol 0x0 ++; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_H44 _GLOBAL_OFFSET_TABLE_ 0x0 ++; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_M44 _GLOBAL_OFFSET_TABLE_ 0x0 ++; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_L44 _GLOBAL_OFFSET_TABLE_ 0x0 ++; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_IE_HI22 extern_symbol 0x0 ++; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_IE_LO10 extern_symbol 0x0 ++; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_IE_LDX extern_symbol 0x0 ++; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_IE_ADD extern_symbol 0x0 ++; v9abs-obj: ] ++ ++; pic-obj: Relocations [ ++; pic-obj: Section (2) .rela.text { ++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_PC22 _GLOBAL_OFFSET_TABLE_ 0x4 ++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_PC10 _GLOBAL_OFFSET_TABLE_ 0x8 ++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LDO_HIX22 local_symbol 0x0 ++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LDO_LOX10 local_symbol 0x0 ++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LDM_HI22 local_symbol 0x0 ++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LDM_LO10 local_symbol 0x0 ++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LDM_ADD local_symbol 0x0 ++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LDM_CALL local_symbol 0x0 ++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LDO_ADD local_symbol 0x0 ++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_PC22 _GLOBAL_OFFSET_TABLE_ 0x4 ++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_PC10 _GLOBAL_OFFSET_TABLE_ 0x8 ++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_GD_HI22 extern_symbol 0x0 ++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_GD_LO10 extern_symbol 0x0 ++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_GD_ADD extern_symbol 0x0 ++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_GD_CALL extern_symbol 0x0 ++; pic-obj: ] ++ |