[Mips] Implement .plt and .got.plt section creation.
llvm-svn: 199516
This commit is contained in:
		
							parent
							
								
									66338224be
								
							
						
					
					
						commit
						362bdc125e
					
				| 
						 | 
					@ -56,3 +56,16 @@ void MipsLinkingContext::addPasses(PassManager &pm) {
 | 
				
			||||||
    pm.add(std::move(pass));
 | 
					    pm.add(std::move(pass));
 | 
				
			||||||
  ELFLinkingContext::addPasses(pm);
 | 
					  ELFLinkingContext::addPasses(pm);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool MipsLinkingContext::isPLTRelocation(const DefinedAtom &,
 | 
				
			||||||
 | 
					                                         const Reference &r) const {
 | 
				
			||||||
 | 
					  if (r.kindNamespace() != Reference::KindNamespace::ELF)
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					  assert(r.kindArch() == Reference::KindArch::Mips);
 | 
				
			||||||
 | 
					  switch (r.kindValue()) {
 | 
				
			||||||
 | 
					  case llvm::ELF::R_MIPS_JUMP_SLOT:
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					  default:
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,7 +21,11 @@ enum {
 | 
				
			||||||
  /// \brief The same as R_MIPS_GOT16 but for global symbols.
 | 
					  /// \brief The same as R_MIPS_GOT16 but for global symbols.
 | 
				
			||||||
  LLD_R_MIPS_GLOBAL_GOT16 = 1025,
 | 
					  LLD_R_MIPS_GLOBAL_GOT16 = 1025,
 | 
				
			||||||
  /// \brief The same as R_MIPS_26 but for global symbols.
 | 
					  /// \brief The same as R_MIPS_26 but for global symbols.
 | 
				
			||||||
  LLD_R_MIPS_GLOBAL_26 = 1026
 | 
					  LLD_R_MIPS_GLOBAL_26 = 1026,
 | 
				
			||||||
 | 
					  /// \brief Setup hi 16 bits using the symbol this reference refers to.
 | 
				
			||||||
 | 
					  LLD_R_MIPS_HI16 = 1027,
 | 
				
			||||||
 | 
					  /// \brief Setup low 16 bits using the symbol this reference refers to.
 | 
				
			||||||
 | 
					  LLD_R_MIPS_LO16 = 1028
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef llvm::object::ELFType<llvm::support::little, 2, false> Mips32ElELFType;
 | 
					typedef llvm::object::ELFType<llvm::support::little, 2, false> Mips32ElELFType;
 | 
				
			||||||
| 
						 | 
					@ -41,6 +45,7 @@ public:
 | 
				
			||||||
  virtual StringRef entrySymbolName() const;
 | 
					  virtual StringRef entrySymbolName() const;
 | 
				
			||||||
  virtual StringRef getDefaultInterpreter() const;
 | 
					  virtual StringRef getDefaultInterpreter() const;
 | 
				
			||||||
  virtual void addPasses(PassManager &pm);
 | 
					  virtual void addPasses(PassManager &pm);
 | 
				
			||||||
 | 
					  virtual bool isPLTRelocation(const DefinedAtom &, const Reference &r) const;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // elf
 | 
					} // elf
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -105,6 +105,18 @@ void relocCall16(uint8_t *location, uint64_t P, uint64_t S, int64_t A,
 | 
				
			||||||
  applyReloc(location, result);
 | 
					  applyReloc(location, result);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// \brief LLD_R_MIPS_HI16
 | 
				
			||||||
 | 
					void relocLldHi16(uint8_t *location, uint64_t S) {
 | 
				
			||||||
 | 
					  int32_t result = lld::scatterBits<uint32_t>((S + 0x8000) >> 16, 0xffff);
 | 
				
			||||||
 | 
					  applyReloc(location, result);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// \brief LLD_R_MIPS_LO16
 | 
				
			||||||
 | 
					void relocLldLo16(uint8_t *location, uint64_t S) {
 | 
				
			||||||
 | 
					  int32_t result = lld::scatterBits<uint32_t>(S, 0xffff);
 | 
				
			||||||
 | 
					  applyReloc(location, result);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // end anon namespace
 | 
					} // end anon namespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MipsTargetRelocationHandler::MipsTargetRelocationHandler(
 | 
					MipsTargetRelocationHandler::MipsTargetRelocationHandler(
 | 
				
			||||||
| 
						 | 
					@ -200,6 +212,9 @@ error_code MipsTargetRelocationHandler::applyRelocation(
 | 
				
			||||||
  case R_MIPS_JALR:
 | 
					  case R_MIPS_JALR:
 | 
				
			||||||
    // We do not do JALR optimization now.
 | 
					    // We do not do JALR optimization now.
 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
 | 
					  case R_MIPS_JUMP_SLOT:
 | 
				
			||||||
 | 
					    // Ignore runtime relocations.
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
  case LLD_R_MIPS_GLOBAL_GOT:
 | 
					  case LLD_R_MIPS_GLOBAL_GOT:
 | 
				
			||||||
    // Do nothing.
 | 
					    // Do nothing.
 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
| 
						 | 
					@ -210,6 +225,12 @@ error_code MipsTargetRelocationHandler::applyRelocation(
 | 
				
			||||||
  case LLD_R_MIPS_GLOBAL_26:
 | 
					  case LLD_R_MIPS_GLOBAL_26:
 | 
				
			||||||
    reloc26(location, relocVAddress, targetVAddress, false);
 | 
					    reloc26(location, relocVAddress, targetVAddress, false);
 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
 | 
					  case LLD_R_MIPS_HI16:
 | 
				
			||||||
 | 
					    relocLldHi16(location, targetVAddress);
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  case LLD_R_MIPS_LO16:
 | 
				
			||||||
 | 
					    relocLldLo16(location, targetVAddress);
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
  default: {
 | 
					  default: {
 | 
				
			||||||
    std::string str;
 | 
					    std::string str;
 | 
				
			||||||
    llvm::raw_string_ostream s(str);
 | 
					    llvm::raw_string_ostream s(str);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,6 +24,26 @@ const uint8_t mipsGot0AtomContent[] = { 0x00, 0x00, 0x00, 0x00 };
 | 
				
			||||||
// Module pointer
 | 
					// Module pointer
 | 
				
			||||||
const uint8_t mipsGotModulePointerAtomContent[] = { 0x00, 0x00, 0x00, 0x80 };
 | 
					const uint8_t mipsGotModulePointerAtomContent[] = { 0x00, 0x00, 0x00, 0x80 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PLT0 entry
 | 
				
			||||||
 | 
					const uint8_t mipsPlt0AtomContent[] = {
 | 
				
			||||||
 | 
					  0x00, 0x00, 0x1c, 0x3c, // lui   $28, %hi(&GOTPLT[0])
 | 
				
			||||||
 | 
					  0x00, 0x00, 0x99, 0x8f, // lw    $25, %lo(&GOTPLT[0])($28)
 | 
				
			||||||
 | 
					  0x00, 0x00, 0x9c, 0x27, // addiu $28, $28, %lo(&GOTPLT[0])
 | 
				
			||||||
 | 
					  0x23, 0xc0, 0x1c, 0x03, // subu  $24, $24, $28
 | 
				
			||||||
 | 
					  0x21, 0x78, 0xe0, 0x03, // move  $15, $31
 | 
				
			||||||
 | 
					  0x82, 0xc0, 0x18, 0x00, // srl   $24, $24, 2
 | 
				
			||||||
 | 
					  0x09, 0xf8, 0x20, 0x03, // jalr  $25
 | 
				
			||||||
 | 
					  0xfe, 0xff, 0x18, 0x27  // subu  $24, $24, 2
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Regular PLT entry
 | 
				
			||||||
 | 
					const uint8_t mipsPltAAtomContent[] = {
 | 
				
			||||||
 | 
					  0x00, 0x00, 0x0f, 0x3c, // lui   $15, %hi(.got.plt entry)
 | 
				
			||||||
 | 
					  0x00, 0x00, 0xf9, 0x8d, // l[wd] $25, %lo(.got.plt entry)($15)
 | 
				
			||||||
 | 
					  0x08, 0x00, 0x20, 0x03, // jr    $25
 | 
				
			||||||
 | 
					  0x00, 0x00, 0xf8, 0x25  // addiu $24, $15, %lo(.got.plt entry)
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// \brief Abstract base class represent MIPS GOT entries.
 | 
					/// \brief Abstract base class represent MIPS GOT entries.
 | 
				
			||||||
class MipsGOTAtom : public GOTAtom {
 | 
					class MipsGOTAtom : public GOTAtom {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
| 
						 | 
					@ -52,6 +72,36 @@ public:
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PLT0Atom : public PLTAtom {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  PLT0Atom(const File &f) : PLTAtom(f, ".plt") {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virtual ArrayRef<uint8_t> rawContent() const {
 | 
				
			||||||
 | 
					    return llvm::makeArrayRef(mipsPlt0AtomContent);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PLTAAtom : public PLTAtom {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  PLTAAtom(const File &f) : PLTAtom(f, ".plt") {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virtual ArrayRef<uint8_t> rawContent() const {
 | 
				
			||||||
 | 
					    return llvm::makeArrayRef(mipsPltAAtomContent);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// \brief MIPS GOT PLT entry
 | 
				
			||||||
 | 
					class GOTPLTAtom : public GOTAtom {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  GOTPLTAtom(const File &f) : GOTAtom(f, ".got.plt") {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virtual Alignment alignment() const { return Alignment(2); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virtual ArrayRef<uint8_t> rawContent() const {
 | 
				
			||||||
 | 
					    return llvm::makeArrayRef(mipsGot0AtomContent);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RelocationPassFile : public SimpleFile {
 | 
					class RelocationPassFile : public SimpleFile {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  RelocationPassFile(const ELFLinkingContext &ctx)
 | 
					  RelocationPassFile(const ELFLinkingContext &ctx)
 | 
				
			||||||
| 
						 | 
					@ -90,6 +140,20 @@ public:
 | 
				
			||||||
      got->setOrdinal(ordinal++);
 | 
					      got->setOrdinal(ordinal++);
 | 
				
			||||||
      mf->addAtom(*got);
 | 
					      mf->addAtom(*got);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (auto &plt : _pltVector) {
 | 
				
			||||||
 | 
					      DEBUG_WITH_TYPE("MipsGOT", llvm::dbgs() << "[ PLT ] Adding "
 | 
				
			||||||
 | 
					                                              << plt->name() << "\n");
 | 
				
			||||||
 | 
					      plt->setOrdinal(ordinal++);
 | 
				
			||||||
 | 
					      mf->addAtom(*plt);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (auto &gotplt : _gotpltVector) {
 | 
				
			||||||
 | 
					      DEBUG_WITH_TYPE("MipsGOT", llvm::dbgs() << "[ GOTPLT ] Adding "
 | 
				
			||||||
 | 
					                                              << gotplt->name() << "\n");
 | 
				
			||||||
 | 
					      gotplt->setOrdinal(ordinal++);
 | 
				
			||||||
 | 
					      mf->addAtom(*gotplt);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
| 
						 | 
					@ -105,6 +169,15 @@ private:
 | 
				
			||||||
  /// \brief the list of global GOT atoms.
 | 
					  /// \brief the list of global GOT atoms.
 | 
				
			||||||
  std::vector<GOTAtom *> _globalGotVector;
 | 
					  std::vector<GOTAtom *> _globalGotVector;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// \brief Map Atoms to their PLT entries.
 | 
				
			||||||
 | 
					  llvm::DenseMap<const Atom *, PLTAtom *> _pltMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// \brief the list of PLT atoms.
 | 
				
			||||||
 | 
					  std::vector<PLTAtom *> _pltVector;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// \brief the list of GOTPLT atoms.
 | 
				
			||||||
 | 
					  std::vector<GOTAtom *> _gotpltVector;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// \brief Handle a specific reference.
 | 
					  /// \brief Handle a specific reference.
 | 
				
			||||||
  void handleReference(const DefinedAtom &atom, const Reference &ref) {
 | 
					  void handleReference(const DefinedAtom &atom, const Reference &ref) {
 | 
				
			||||||
    if (ref.kindNamespace() != lld::Reference::KindNamespace::ELF)
 | 
					    if (ref.kindNamespace() != lld::Reference::KindNamespace::ELF)
 | 
				
			||||||
| 
						 | 
					@ -131,7 +204,8 @@ private:
 | 
				
			||||||
    if (ref.kindValue() == R_MIPS_26 && !isLocal(ref.target()))
 | 
					    if (ref.kindValue() == R_MIPS_26 && !isLocal(ref.target()))
 | 
				
			||||||
      const_cast<Reference &>(ref).setKindValue(LLD_R_MIPS_GLOBAL_26);
 | 
					      const_cast<Reference &>(ref).setKindValue(LLD_R_MIPS_GLOBAL_26);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // FIXME (simon): Create PLT entry.
 | 
					    if (isa<SharedLibraryAtom>(ref.target()))
 | 
				
			||||||
 | 
					      const_cast<Reference &>(ref).setTarget(getPLTEntry(ref.target()));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void handleGOT(const Reference &ref) {
 | 
					  void handleGOT(const Reference &ref) {
 | 
				
			||||||
| 
						 | 
					@ -187,6 +261,69 @@ private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return ga;
 | 
					    return ga;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void createPLTHeader() {
 | 
				
			||||||
 | 
					    assert(_pltVector.empty() && _gotpltVector.empty());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto pa = new (_file._alloc) PLT0Atom(_file);
 | 
				
			||||||
 | 
					    _pltVector.push_back(pa);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto ga0 = new (_file._alloc) GOTPLTAtom(_file);
 | 
				
			||||||
 | 
					    _gotpltVector.push_back(ga0);
 | 
				
			||||||
 | 
					    auto ga1 = new (_file._alloc) GOTPLTAtom(_file);
 | 
				
			||||||
 | 
					    _gotpltVector.push_back(ga1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Setup reference to fixup the PLT0 entry.
 | 
				
			||||||
 | 
					    pa->addReferenceELF_Mips(LLD_R_MIPS_HI16, 0, ga0, 0);
 | 
				
			||||||
 | 
					    pa->addReferenceELF_Mips(LLD_R_MIPS_LO16, 4, ga0, 0);
 | 
				
			||||||
 | 
					    pa->addReferenceELF_Mips(LLD_R_MIPS_LO16, 8, ga0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DEBUG_WITH_TYPE("MipsGOT", {
 | 
				
			||||||
 | 
					      pa->_name = "__plt0";
 | 
				
			||||||
 | 
					      llvm::dbgs() << "[ PLT ] Create PLT0\n";
 | 
				
			||||||
 | 
					      ga0->_name = "__gotplt0";
 | 
				
			||||||
 | 
					      llvm::dbgs() << "[ GOTPLT ] Create GOTPLT0\n";
 | 
				
			||||||
 | 
					      ga1->_name = "__gotplt1";
 | 
				
			||||||
 | 
					      llvm::dbgs() << "[ GOTPLT ] Create GOTPLT1\n";
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const PLTAtom *getPLTEntry(const Atom *a) {
 | 
				
			||||||
 | 
					    auto plt = _pltMap.find(a);
 | 
				
			||||||
 | 
					    if (plt != _pltMap.end())
 | 
				
			||||||
 | 
					      return plt->second;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (_pltVector.empty())
 | 
				
			||||||
 | 
					      createPLTHeader();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto pa = new (_file._alloc) PLTAAtom(_file);
 | 
				
			||||||
 | 
					    _pltMap[a] = pa;
 | 
				
			||||||
 | 
					    _pltVector.push_back(pa);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto ga = new (_file._alloc) GOTPLTAtom(_file);
 | 
				
			||||||
 | 
					    _gotpltVector.push_back(ga);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Setup reference to fixup the PLT entry.
 | 
				
			||||||
 | 
					    pa->addReferenceELF_Mips(LLD_R_MIPS_HI16, 0, ga, 0);
 | 
				
			||||||
 | 
					    pa->addReferenceELF_Mips(LLD_R_MIPS_LO16, 4, ga, 0);
 | 
				
			||||||
 | 
					    pa->addReferenceELF_Mips(LLD_R_MIPS_LO16, 12, ga, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Setup reference to assign initial value to the .got.plt entry.
 | 
				
			||||||
 | 
					    ga->addReferenceELF_Mips(R_MIPS_32, 0, _pltVector.front(), 0);
 | 
				
			||||||
 | 
					    // Create dynamic relocation to adjust the .got.plt entry at runtime.
 | 
				
			||||||
 | 
					    ga->addReferenceELF_Mips(R_MIPS_JUMP_SLOT, 0, a, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DEBUG_WITH_TYPE("MipsGOT", {
 | 
				
			||||||
 | 
					      pa->_name = "__plt_";
 | 
				
			||||||
 | 
					      pa->_name += a->name();
 | 
				
			||||||
 | 
					      llvm::dbgs() << "[ PLT ] Create " << a->name() << "\n";
 | 
				
			||||||
 | 
					      ga->_name = "__got_plt_";
 | 
				
			||||||
 | 
					      ga->_name += a->name();
 | 
				
			||||||
 | 
					      llvm::dbgs() << "[ GOTPLT ] Create " << a->name() << "\n";
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return pa;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // end anon namespace
 | 
					} // end anon namespace
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -201,8 +201,11 @@ const Registry::KindStrings MipsTargetHandler::kindStrings[] = {
 | 
				
			||||||
  LLD_KIND_STRING_ENTRY(R_MIPS_GOT16),
 | 
					  LLD_KIND_STRING_ENTRY(R_MIPS_GOT16),
 | 
				
			||||||
  LLD_KIND_STRING_ENTRY(R_MIPS_CALL16),
 | 
					  LLD_KIND_STRING_ENTRY(R_MIPS_CALL16),
 | 
				
			||||||
  LLD_KIND_STRING_ENTRY(R_MIPS_JALR),
 | 
					  LLD_KIND_STRING_ENTRY(R_MIPS_JALR),
 | 
				
			||||||
 | 
					  LLD_KIND_STRING_ENTRY(R_MIPS_JUMP_SLOT),
 | 
				
			||||||
  LLD_KIND_STRING_ENTRY(LLD_R_MIPS_GLOBAL_GOT),
 | 
					  LLD_KIND_STRING_ENTRY(LLD_R_MIPS_GLOBAL_GOT),
 | 
				
			||||||
  LLD_KIND_STRING_ENTRY(LLD_R_MIPS_GLOBAL_GOT16),
 | 
					  LLD_KIND_STRING_ENTRY(LLD_R_MIPS_GLOBAL_GOT16),
 | 
				
			||||||
  LLD_KIND_STRING_ENTRY(LLD_R_MIPS_GLOBAL_26),
 | 
					  LLD_KIND_STRING_ENTRY(LLD_R_MIPS_GLOBAL_26),
 | 
				
			||||||
 | 
					  LLD_KIND_STRING_ENTRY(LLD_R_MIPS_HI16),
 | 
				
			||||||
 | 
					  LLD_KIND_STRING_ENTRY(LLD_R_MIPS_LO16),
 | 
				
			||||||
  LLD_KIND_STRING_END
 | 
					  LLD_KIND_STRING_END
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,7 +35,7 @@ public:
 | 
				
			||||||
  createSection(StringRef name, int32_t type,
 | 
					  createSection(StringRef name, int32_t type,
 | 
				
			||||||
                DefinedAtom::ContentPermissions permissions,
 | 
					                DefinedAtom::ContentPermissions permissions,
 | 
				
			||||||
                Layout::SectionOrder order) {
 | 
					                Layout::SectionOrder order) {
 | 
				
			||||||
    if (type == DefinedAtom::typeGOT)
 | 
					    if (type == DefinedAtom::typeGOT && name == ".got")
 | 
				
			||||||
      return _gotSection;
 | 
					      return _gotSection;
 | 
				
			||||||
    return DefaultLayout<ELFType>::createSection(name, type, permissions,
 | 
					    return DefaultLayout<ELFType>::createSection(name, type, permissions,
 | 
				
			||||||
                                                 order);
 | 
					                                                 order);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,40 @@
 | 
				
			||||||
 | 
					# Check initialization of .plt header entries.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Build shared library
 | 
				
			||||||
 | 
					# RUN: llvm-mc -triple=mipsel -filetype=obj -relocation-model=pic \
 | 
				
			||||||
 | 
					# RUN:         -o=%t1 %p/Inputs/ext.s
 | 
				
			||||||
 | 
					# RUN: lld -flavor gnu -target mipsel -shared -o %t2 %t1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Build executable
 | 
				
			||||||
 | 
					# RUN: llvm-mc -triple=mipsel -filetype=obj -o=%t3 %s
 | 
				
			||||||
 | 
					# RUN: lld -flavor gnu -target mipsel -e glob -o %t4 %t3 %t2
 | 
				
			||||||
 | 
					# RUN: llvm-objdump -section-headers -disassemble %t4 | \
 | 
				
			||||||
 | 
					# RUN:   FileCheck -check-prefix=EXE %s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# EXE: Disassembly of section .plt:
 | 
				
			||||||
 | 
					# EXE: .plt:
 | 
				
			||||||
 | 
					# PLT0 entry. Points to the .got.plt[0]
 | 
				
			||||||
 | 
					# EXE:   400170:  40 00 1c 3c  lui     $gp, 64
 | 
				
			||||||
 | 
					# EXE:   400174:  00 20 99 8f  lw      $25, 8192($gp)
 | 
				
			||||||
 | 
					# EXE:   400178:  00 20 9c 27  addiu   $gp, $gp, 8192
 | 
				
			||||||
 | 
					# EXE:   40017c:  23 c0 1c 03  subu    $24, $24, $gp
 | 
				
			||||||
 | 
					# EXE:   400180:  21 78 e0 03  move    $15, $ra
 | 
				
			||||||
 | 
					# EXE:   400184:  82 c0 18 00  srl     $24, $24, 2
 | 
				
			||||||
 | 
					# EXE:   400188:  09 f8 20 03  jalr    $25
 | 
				
			||||||
 | 
					# EXE:   40018c:  fe ff 18 27  addiu   $24, $24, -2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# EXE: Sections:
 | 
				
			||||||
 | 
					# EXE: Idx Name          Size      Address          Type
 | 
				
			||||||
 | 
					# EXE:   6 .plt          00000030 0000000000400170 TEXT DATA
 | 
				
			||||||
 | 
					# EXE:  10 .got.plt      0000000c 0000000000402000 DATA
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .abicalls
 | 
				
			||||||
 | 
					    .global glob
 | 
				
			||||||
 | 
					    .ent    glob
 | 
				
			||||||
 | 
					glob:
 | 
				
			||||||
 | 
					    jal     $t9
 | 
				
			||||||
 | 
					    jal     loc
 | 
				
			||||||
 | 
					loc:
 | 
				
			||||||
 | 
					    jal     glob
 | 
				
			||||||
 | 
					    jal     ext1
 | 
				
			||||||
 | 
					    .end    glob
 | 
				
			||||||
| 
						 | 
					@ -7,33 +7,58 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Build executable
 | 
					# Build executable
 | 
				
			||||||
# RUN: llvm-mc -triple=mipsel -filetype=obj -o=%t3 %s
 | 
					# RUN: llvm-mc -triple=mipsel -filetype=obj -o=%t3 %s
 | 
				
			||||||
# RUN: llvm-objdump -r %t3 | FileCheck -check-prefix=REL %s
 | 
					# RUN: llvm-readobj -relocations %t3 | FileCheck -check-prefix=OBJ-REL %s
 | 
				
			||||||
# RUN: lld -flavor gnu -target mipsel -e glob -o %t4 %t3 %t2
 | 
					# RUN: lld -flavor gnu -target mipsel -e glob -o %t4 %t3 %t2
 | 
				
			||||||
# RUN: llvm-objdump -disassemble %t4 | FileCheck -check-prefix=EXE %s
 | 
					# RUN: llvm-objdump -section-headers -disassemble %t4 | \
 | 
				
			||||||
 | 
					# RUN:   FileCheck -check-prefix=EXE %s
 | 
				
			||||||
 | 
					# RUN: llvm-readobj -relocations %t4 | FileCheck -check-prefix=EXE-REL %s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Object file has three R_MIPS_26 relocations
 | 
					# Object file has three R_MIPS_26 relocations
 | 
				
			||||||
# REL: RELOCATION RECORDS FOR [.rel.text]:
 | 
					# OBJ-REL: Relocations [
 | 
				
			||||||
# REL: 8 R_MIPS_26 Unknown
 | 
					# OBJ-REL:   Section (2) .rel.text {
 | 
				
			||||||
# REL: 16 R_MIPS_26 Unknown
 | 
					# OBJ-REL:      0x8 R_MIPS_26 .text 0x0
 | 
				
			||||||
# REL: 24 R_MIPS_26 Unknown
 | 
					# OBJ-REL:     0x10 R_MIPS_26 glob  0x0
 | 
				
			||||||
 | 
					# OBJ-REL:     0x18 R_MIPS_26 ext1  0x0
 | 
				
			||||||
 | 
					# OBJ-REL:   }
 | 
				
			||||||
 | 
					# OBJ-REL: ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Executable file has the only relocation for external symbol
 | 
				
			||||||
 | 
					# EXE-REL: Relocations [
 | 
				
			||||||
 | 
					# EXE-REL:   Section (5) .rela.plt {
 | 
				
			||||||
 | 
					# EXE-REL:     0x402008 R_MIPS_JUMP_SLOT ext1 0x0
 | 
				
			||||||
 | 
					# EXE-REL:   }
 | 
				
			||||||
 | 
					# EXE-REL: ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# EXE: Disassembly of section .plt:
 | 
				
			||||||
 | 
					# EXE: .plt:
 | 
				
			||||||
 | 
					# PLTA entry. Points to the .got.plt[1]
 | 
				
			||||||
 | 
					# EXE:   400190:  40 00 0f 3c  lui     $15, 64
 | 
				
			||||||
 | 
					# EXE:   400194:  08 20 f9 8d  lw      $25, 8200($15)
 | 
				
			||||||
 | 
					# EXE:   400198:  08 00 20 03  jr      $25
 | 
				
			||||||
 | 
					# EXE:   40019c:  08 20 f8 25  addiu   $24, $15, 8200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# EXE: Disassembly of section .text:
 | 
					# EXE: Disassembly of section .text:
 | 
				
			||||||
# EXE: glob:
 | 
					# EXE: glob:
 | 
				
			||||||
# EXE:   40014c:  09 f8 20 03  jalr    $25
 | 
					# EXE:   4001a0:  09 f8 20 03  jalr    $25
 | 
				
			||||||
# EXE:   400150:  00 00 00 00  nop
 | 
					# EXE:   4001a4:  00 00 00 00  nop
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Jump to 'loc' label address
 | 
					# Jump to 'loc' label address
 | 
				
			||||||
# EXE:   400154:  57 00 10 0c  jal     4194652
 | 
					# EXE:   4001a8:  6c 00 10 0c  jal     4194736
 | 
				
			||||||
# EXE:   400158:  00 00 00 00  nop
 | 
					# EXE:   4001ac:  00 00 00 00  nop
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# EXE: loc:
 | 
					# EXE: loc:
 | 
				
			||||||
# Jump to 'glob' label address
 | 
					# Jump to 'glob' label address
 | 
				
			||||||
# EXE:   40015c:  53 00 10 0c  jal     4194636
 | 
					# EXE:   4001b0:  68 00 10 0c  jal     4194720
 | 
				
			||||||
# EXE:   400160:  00 00 00 00  nop
 | 
					# EXE:   4001b4:  00 00 00 00  nop
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Jump to the first PLT entry (.plt + 32) for ext1 entry
 | 
					# Jump to the first PLT entry (.plt + 32) for ext1 entry
 | 
				
			||||||
# EXE:   400164:  00 00 00 0c  jal     0
 | 
					# EXE:   4001b8:  64 00 10 0c  jal     4194704
 | 
				
			||||||
# EXE:   400168:  00 00 00 00  nop
 | 
					# EXE:   4001bc:  00 00 00 00  nop
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# EXE: Sections:
 | 
				
			||||||
 | 
					# EXE: Idx Name          Size      Address          Type
 | 
				
			||||||
 | 
					# EXE:   6 .plt          00000030 0000000000400170 TEXT DATA
 | 
				
			||||||
 | 
					# EXE:  10 .got.plt      0000000c 0000000000402000 DATA
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .abicalls
 | 
					    .abicalls
 | 
				
			||||||
    .global glob
 | 
					    .global glob
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue