diff options
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp | 3 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp | 7 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp | 40 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h | 3 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/SectionChunks.h | 8 | ||||
| -rw-r--r-- | lld/test/elf/Mips/tls-2-64.test | 69 | ||||
| -rw-r--r-- | lld/test/elf/Mips/tls-5-64.test | 71 | 
7 files changed, 188 insertions, 13 deletions
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp index 3fbb3a79597..7bffcbeb5c0 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp @@ -84,6 +84,9 @@ bool MipsLinkingContext::isDynamicRelocation(const Reference &r) const {    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; diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp index 0bbf01dbf9a..db99b045ae8 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp @@ -121,6 +121,10 @@ static MipsRelocationParams getRelocationParams(uint32_t rType) {    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> calculateRelocation(const Reference &ref,    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: diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp index 950ecda4dc5..6d2ac9e09c5 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp @@ -32,6 +32,8 @@ static const uint8_t mipsGotModulePointerAtomContent[] = {  // 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<Mips64ELType>::rawContent() const {  }  /// \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>::getTLSGOTEntry(const Atom *a) {    _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>::getTLSGdGOTEntry(const Atom *a) {    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>::getTLSLdmGOTEntry(const Atom *a) {    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;  } diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h b/lld/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h index 3d1c2629e88..c9abf1b7bde 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h @@ -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;        } diff --git a/lld/lib/ReaderWriter/ELF/SectionChunks.h b/lld/lib/ReaderWriter/ELF/SectionChunks.h index 7496b7239c6..f21698ce5db 100644 --- a/lld/lib/ReaderWriter/ELF/SectionChunks.h +++ b/lld/lib/ReaderWriter/ELF/SectionChunks.h @@ -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 " diff --git a/lld/test/elf/Mips/tls-2-64.test b/lld/test/elf/Mips/tls-2-64.test new file mode 100644 index 00000000000..a068934aeaf --- /dev/null +++ b/lld/test/elf/Mips/tls-2-64.test @@ -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 +... diff --git a/lld/test/elf/Mips/tls-5-64.test b/lld/test/elf/Mips/tls-5-64.test new file mode 100644 index 00000000000..784d71efc48 --- /dev/null +++ b/lld/test/elf/Mips/tls-5-64.test @@ -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 +...  | 

