[lld] r232361 - [Mips] Implement R_MIPS_TLS_xxx relocation handling in case of N64 ABI

Simon Atanasyan simon at atanasyan.com
Mon Mar 16 02:14:28 PDT 2015


Author: atanasyan
Date: Mon Mar 16 04:14:28 2015
New Revision: 232361

URL: http://llvm.org/viewvc/llvm-project?rev=232361&view=rev
Log:
[Mips] Implement R_MIPS_TLS_xxx relocation handling in case of N64 ABI

Added:
    lld/trunk/test/elf/Mips/tls-2-64.test
    lld/trunk/test/elf/Mips/tls-5-64.test
Modified:
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h
    lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp?rev=232361&r1=232360&r2=232361&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp Mon Mar 16 04:14:28 2015
@@ -84,6 +84,9 @@ bool MipsLinkingContext::isDynamicReloca
   case llvm::ELF::R_MIPS_TLS_DTPMOD32:
   case llvm::ELF::R_MIPS_TLS_DTPREL32:
   case llvm::ELF::R_MIPS_TLS_TPREL32:
+  case llvm::ELF::R_MIPS_TLS_DTPMOD64:
+  case llvm::ELF::R_MIPS_TLS_DTPREL64:
+  case llvm::ELF::R_MIPS_TLS_TPREL64:
     return true;
   default:
     return false;

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp?rev=232361&r1=232360&r2=232361&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp Mon Mar 16 04:14:28 2015
@@ -121,6 +121,10 @@ static MipsRelocationParams getRelocatio
   case R_MIPS_TLS_TPREL32:
     // Ignore runtime relocations.
     return {4, 0x0, 0, false};
+  case R_MIPS_TLS_DTPMOD64:
+  case R_MIPS_TLS_DTPREL64:
+  case R_MIPS_TLS_TPREL64:
+    return {8, 0x0, 0, false};
   case LLD_R_MIPS_GLOBAL_GOT:
   case LLD_R_MIPS_STO_PLT:
     // Do nothing.
@@ -385,6 +389,9 @@ static ErrorOr<uint64_t> calculateReloca
   case R_MIPS_TLS_DTPMOD32:
   case R_MIPS_TLS_DTPREL32:
   case R_MIPS_TLS_TPREL32:
+  case R_MIPS_TLS_DTPMOD64:
+  case R_MIPS_TLS_DTPREL64:
+  case R_MIPS_TLS_TPREL64:
     // Ignore runtime relocations.
     return 0;
   case R_MIPS_PC32:

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp?rev=232361&r1=232360&r2=232361&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp Mon Mar 16 04:14:28 2015
@@ -32,6 +32,8 @@ static const uint8_t mipsGotModulePointe
 // TLS GD Entry
 static const uint8_t mipsGotTlsGdAtomContent[] = {
   0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00
 };
 
@@ -135,15 +137,21 @@ ArrayRef<uint8_t> GOTModulePointerAtom<M
 }
 
 /// \brief MIPS GOT TLS GD entry.
-class GOTTLSGdAtom : public MipsGOTAtom {
+template <typename ELFT> class GOTTLSGdAtom : public MipsGOTAtom {
 public:
   GOTTLSGdAtom(const File &f) : MipsGOTAtom(f) {}
 
-  ArrayRef<uint8_t> rawContent() const override {
-    return llvm::makeArrayRef(mipsGotTlsGdAtomContent);
-  }
+  ArrayRef<uint8_t> rawContent() const override;
 };
 
+template <> ArrayRef<uint8_t> GOTTLSGdAtom<Mips32ELType>::rawContent() const {
+    return llvm::makeArrayRef(mipsGotTlsGdAtomContent).slice(8);
+}
+
+template <> ArrayRef<uint8_t> GOTTLSGdAtom<Mips64ELType>::rawContent() const {
+    return llvm::makeArrayRef(mipsGotTlsGdAtomContent);
+}
+
 class GOTPLTAtom : public GOTAtom {
 public:
   GOTPLTAtom(const File &f) : GOTAtom(f, ".got.plt") {}
@@ -294,7 +302,7 @@ private:
   llvm::DenseMap<const Atom *, GOTAtom *> _gotTLSGdMap;
 
   /// \brief GOT entry for the R_xxxMIPS_TLS_LDM relocations.
-  GOTTLSGdAtom *_gotLDMEntry;
+  GOTTLSGdAtom<ELFT> *_gotLDMEntry;
 
   /// \brief the list of local GOT atoms.
   std::vector<GOTAtom *> _localGotVector;
@@ -859,7 +867,9 @@ const GOTAtom *RelocationPass<ELFT>::get
   _gotTLSMap[a] = ga;
 
   _tlsGotVector.push_back(ga);
-  ga->addReferenceELF_Mips(R_MIPS_TLS_TPREL32, 0, a, 0);
+  Reference::KindValue relKind =
+      ELFT::Is64Bits ? R_MIPS_TLS_TPREL64 : R_MIPS_TLS_TPREL32;
+  ga->addReferenceELF_Mips(relKind, 0, a, 0);
 
   return ga;
 }
@@ -870,12 +880,17 @@ const GOTAtom *RelocationPass<ELFT>::get
   if (got != _gotTLSGdMap.end())
     return got->second;
 
-  auto ga = new (_file._alloc) GOTTLSGdAtom(_file);
+  auto ga = new (_file._alloc) GOTTLSGdAtom<ELFT>(_file);
   _gotTLSGdMap[a] = ga;
 
   _tlsGotVector.push_back(ga);
-  ga->addReferenceELF_Mips(R_MIPS_TLS_DTPMOD32, 0, a, 0);
-  ga->addReferenceELF_Mips(R_MIPS_TLS_DTPREL32, 4, a, 0);
+  if (ELFT::Is64Bits) {
+    ga->addReferenceELF_Mips(R_MIPS_TLS_DTPMOD64, 0, a, 0);
+    ga->addReferenceELF_Mips(R_MIPS_TLS_DTPREL64, 8, a, 0);
+  } else {
+    ga->addReferenceELF_Mips(R_MIPS_TLS_DTPMOD32, 0, a, 0);
+    ga->addReferenceELF_Mips(R_MIPS_TLS_DTPREL32, 4, a, 0);
+  }
 
   return ga;
 }
@@ -885,9 +900,12 @@ const GOTAtom *RelocationPass<ELFT>::get
   if (_gotLDMEntry)
     return _gotLDMEntry;
 
-  _gotLDMEntry = new (_file._alloc) GOTTLSGdAtom(_file);
+  _gotLDMEntry = new (_file._alloc) GOTTLSGdAtom<ELFT>(_file);
   _tlsGotVector.push_back(_gotLDMEntry);
-  _gotLDMEntry->addReferenceELF_Mips(R_MIPS_TLS_DTPMOD32, 0, _gotLDMEntry, 0);
+  if (ELFT::Is64Bits)
+    _gotLDMEntry->addReferenceELF_Mips(R_MIPS_TLS_DTPMOD64, 0, _gotLDMEntry, 0);
+  else
+    _gotLDMEntry->addReferenceELF_Mips(R_MIPS_TLS_DTPMOD32, 0, _gotLDMEntry, 0);
 
   return _gotLDMEntry;
 }

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h?rev=232361&r1=232360&r2=232361&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h Mon Mar 16 04:14:28 2015
@@ -63,10 +63,13 @@ public:
         return AtomSection<ELFType>::appendAtom(atom);
       case R_MIPS_TLS_TPREL32:
       case R_MIPS_TLS_DTPREL32:
+      case R_MIPS_TLS_TPREL64:
+      case R_MIPS_TLS_DTPREL64:
         _hasNonLocal = true;
         _tlsMap[r->target()] = _tlsMap.size();
         return AtomSection<ELFType>::appendAtom(atom);
       case R_MIPS_TLS_DTPMOD32:
+      case R_MIPS_TLS_DTPMOD64:
         _hasNonLocal = true;
         break;
       }

Modified: lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h?rev=232361&r1=232360&r2=232361&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h Mon Mar 16 04:14:28 2015
@@ -1023,12 +1023,16 @@ private:
   std::vector<std::pair<const DefinedAtom *, const Reference *> > _relocs;
   const DynamicSymbolTable<ELFT> *_symbolTable;
 
+  bool isMips64ELOutput() const {
+    return this->_context.getTriple().getArch() == llvm::Triple::mips64el;
+  }
+
   void writeRela(ELFWriter *writer, Elf_Rela &r, const DefinedAtom &atom,
                  const Reference &ref) {
     uint32_t index =
         _symbolTable ? _symbolTable->getSymbolTableIndex(ref.target())
                      : (uint32_t)STN_UNDEF;
-    r.setSymbolAndType(index, ref.kindValue(), false);
+    r.setSymbolAndType(index, ref.kindValue(), isMips64ELOutput());
     r.r_offset = writer->addressOfAtom(&atom) + ref.offsetInAtom();
     r.r_addend = 0;
     // The addend is used only by relative relocations
@@ -1046,7 +1050,7 @@ private:
     uint32_t index =
         _symbolTable ? _symbolTable->getSymbolTableIndex(ref.target())
                      : (uint32_t)STN_UNDEF;
-    r.setSymbolAndType(index, ref.kindValue(), false);
+    r.setSymbolAndType(index, ref.kindValue(), isMips64ELOutput());
     r.r_offset = writer->addressOfAtom(&atom) + ref.offsetInAtom();
     DEBUG_WITH_TYPE("ELFRelocationTable",
                     llvm::dbgs() << ref.kindValue() << " relocation at "

Added: lld/trunk/test/elf/Mips/tls-2-64.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/tls-2-64.test?rev=232361&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/tls-2-64.test (added)
+++ lld/trunk/test/elf/Mips/tls-2-64.test Mon Mar 16 04:14:28 2015
@@ -0,0 +1,69 @@
+# Check handling of R_MIPS_TLS_GOTTPREL and R_MIPS_TLS_GD relocations
+# and generation of corresponding dynamic relocations R_MIPS_TLS_TPREL64,
+# R_MIPS_TLS_DTPMOD64 and R_MIPS_TLS_DTPREL64 in case of shared library.
+
+# Create a shared library with thread symbol D1.
+# RUN: yaml2obj -format=elf -o %t-so.o %s
+# RUN: lld -flavor gnu -target mips64el -shared -o %t.so %t-so.o
+
+# Check dynamic relocations and GOT in the shared library.
+# RUN: llvm-readobj -r %t.so | FileCheck -check-prefix=REL %s
+# RUN: llvm-readobj -dynamic-table %t.so | FileCheck -check-prefix=DYN %s
+# RUN: llvm-readobj -dt %t.so | FileCheck -check-prefix=SYM %s
+# RUN: llvm-objdump -s %t.so | FileCheck -check-prefix=GOT %s
+
+# REL:      Section (4) .rel.dyn {
+# REL-NEXT:   0x2010 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE D1 0x0
+# REL-NEXT:   0x2018 R_MIPS_TLS_DTPREL64/R_MIPS_NONE/R_MIPS_NONE D1 0x0
+# REL-NEXT: }
+
+# DYN: 0x000000007000000A MIPS_LOCAL_GOTNO 2
+# DYN: 0x0000000070000013 MIPS_GOTSYM      0x3
+
+# SYM: Name: T1@ (1)
+# SYM: Name: D1@ (4)
+
+# GOT:      Contents of section .got:
+# GOT-NEXT:  2000 00000000 00000000 00000000 00000080 ................
+# GOT-NEXT:  2010 00000000 00000000 00000000 00000000  ................
+
+---
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ARCH_64]
+
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    4
+    Size:            4
+  - Name:            .rel.text
+    Type:            SHT_RELA
+    Link:            .symtab
+    Info:            .text
+    AddressAlign:    4
+    Relocations:
+      - Offset:      0
+        Symbol:      D1
+        Type:        R_MIPS_TLS_GD
+  - Name:            .tdata
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC, SHF_TLS ]
+    AddressAlign:    4
+    Size:            8
+
+Symbols:
+  Global:
+    - Name:          T1
+      Type:          STT_FUNC
+      Section:       .text
+      Size:          4
+    - Name:          D1
+      Type:          STT_TLS
+      Section:       .tdata
+      Size:          8
+...

Added: lld/trunk/test/elf/Mips/tls-5-64.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/tls-5-64.test?rev=232361&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/tls-5-64.test (added)
+++ lld/trunk/test/elf/Mips/tls-5-64.test Mon Mar 16 04:14:28 2015
@@ -0,0 +1,71 @@
+# Check that in case of an executable file linking symbol referred
+# by the R_MIPS_TLS_GD relocation gets an entry in the dynamic symbol table.
+
+# RUN: yaml2obj -format=elf -o %t-o.o %s
+# RUN: lld -flavor gnu -target mips64el -e T0 -o %t.exe %t-o.o
+
+# Check dynamic relocations:
+# RUN: llvm-readobj -r %t.exe | FileCheck -check-prefix=REL %s
+# Check dynamic symbol table:
+# RUN: llvm-readobj -dt %t.exe | FileCheck -check-prefix=SYM %s
+
+# REL:      Relocations [
+# REL-NEXT:   Section (5) .rel.dyn {
+# REL-NEXT:     0x120002010 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE T1 0x0
+# REL-NEXT:     0x120002018 R_MIPS_TLS_DTPREL64/R_MIPS_NONE/R_MIPS_NONE T1 0x0
+# REL-NEXT:   }
+# REL-NEXT: ]
+
+# SYM:      Symbol {
+# SYM:        Name: T1@ (1)
+# SYM-NEXT:   Value: 0x0
+# SYM-NEXT:   Size: 8
+# SYM-NEXT:   Binding: Global (0x1)
+# SYM-NEXT:   Type: TLS (0x6)
+# SYM-NEXT:   Other: 0
+# SYM-NEXT:   Section: .tdata (0x7)
+# SYM-NEXT: }
+
+---
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ARCH_64]
+
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x10
+    Size:            8
+
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    AddressAlign:    4
+    Info:            .text
+    Relocations:
+      - Offset:      0
+        Symbol:      T1
+        Type:        R_MIPS_TLS_GD
+
+  - Name:            .tdata
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC, SHF_TLS ]
+    AddressAlign:    4
+    Size:            8
+
+Symbols:
+  Global:
+    - Name:          T0
+      Type:          STT_FUNC
+      Section:       .text
+      Size:          8
+    - Name:          T1
+      Type:          STT_TLS
+      Section:       .tdata
+      Value:         0
+      Size:          8
+...





More information about the llvm-commits mailing list