forked from OSchip/llvm-project
parent
ceb0b86822
commit
bf987c2dae
|
@ -46,6 +46,19 @@ void MipsLinkingContext::addPasses(PassManager &pm) {
|
||||||
ELFLinkingContext::addPasses(pm);
|
ELFLinkingContext::addPasses(pm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MipsLinkingContext::isDynamicRelocation(const DefinedAtom &,
|
||||||
|
const Reference &r) const {
|
||||||
|
if (r.kindNamespace() != Reference::KindNamespace::ELF)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (r.kindValue()) {
|
||||||
|
case llvm::ELF::R_MIPS_COPY:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool MipsLinkingContext::isPLTRelocation(const DefinedAtom &,
|
bool MipsLinkingContext::isPLTRelocation(const DefinedAtom &,
|
||||||
const Reference &r) const {
|
const Reference &r) const {
|
||||||
if (r.kindNamespace() != Reference::KindNamespace::ELF)
|
if (r.kindNamespace() != Reference::KindNamespace::ELF)
|
||||||
|
|
|
@ -46,6 +46,8 @@ public:
|
||||||
virtual StringRef getDefaultInterpreter() const;
|
virtual StringRef getDefaultInterpreter() const;
|
||||||
virtual void addPasses(PassManager &pm);
|
virtual void addPasses(PassManager &pm);
|
||||||
virtual bool isRelaOutputFormat() const { return false; }
|
virtual bool isRelaOutputFormat() const { return false; }
|
||||||
|
virtual bool isDynamicRelocation(const DefinedAtom &,
|
||||||
|
const Reference &r) const;
|
||||||
virtual bool isPLTRelocation(const DefinedAtom &, const Reference &r) const;
|
virtual bool isPLTRelocation(const DefinedAtom &, const Reference &r) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -155,6 +155,11 @@ public:
|
||||||
gotplt->setOrdinal(ordinal++);
|
gotplt->setOrdinal(ordinal++);
|
||||||
mf->addAtom(*gotplt);
|
mf->addAtom(*gotplt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto obj : _objectVector) {
|
||||||
|
obj->setOrdinal(ordinal++);
|
||||||
|
mf->addAtom(*obj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -176,18 +181,30 @@ private:
|
||||||
/// \brief Map Atoms to their PLT entries.
|
/// \brief Map Atoms to their PLT entries.
|
||||||
llvm::DenseMap<const Atom *, PLTAtom *> _pltMap;
|
llvm::DenseMap<const Atom *, PLTAtom *> _pltMap;
|
||||||
|
|
||||||
|
/// \brief Map Atoms to their Object entries.
|
||||||
|
llvm::DenseMap<const Atom *, ObjectAtom *> _objectMap;
|
||||||
|
|
||||||
/// \brief the list of PLT atoms.
|
/// \brief the list of PLT atoms.
|
||||||
std::vector<PLTAtom *> _pltVector;
|
std::vector<PLTAtom *> _pltVector;
|
||||||
|
|
||||||
/// \brief the list of GOTPLT atoms.
|
/// \brief the list of GOTPLT atoms.
|
||||||
std::vector<GOTAtom *> _gotpltVector;
|
std::vector<GOTAtom *> _gotpltVector;
|
||||||
|
|
||||||
|
/// \brief the list of Object entries.
|
||||||
|
std::vector<ObjectAtom *> _objectVector;
|
||||||
|
|
||||||
/// \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)
|
||||||
return;
|
return;
|
||||||
assert(ref.kindArch() == Reference::KindArch::Mips);
|
assert(ref.kindArch() == Reference::KindArch::Mips);
|
||||||
switch (ref.kindValue()) {
|
switch (ref.kindValue()) {
|
||||||
|
case R_MIPS_32:
|
||||||
|
case R_MIPS_HI16:
|
||||||
|
case R_MIPS_LO16:
|
||||||
|
// FIXME (simon): Handle dynamic/static linking differently.
|
||||||
|
handlePlain(ref);
|
||||||
|
break;
|
||||||
case R_MIPS_26:
|
case R_MIPS_26:
|
||||||
handlePLT(ref);
|
handlePLT(ref);
|
||||||
break;
|
break;
|
||||||
|
@ -204,6 +221,14 @@ private:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handlePlain(const Reference &ref) {
|
||||||
|
if (!ref.target())
|
||||||
|
return;
|
||||||
|
auto sla = dyn_cast<SharedLibraryAtom>(ref.target());
|
||||||
|
if (sla && sla->type() == SharedLibraryAtom::Type::Data)
|
||||||
|
const_cast<Reference &>(ref).setTarget(getObjectEntry(sla));
|
||||||
|
}
|
||||||
|
|
||||||
void handlePLT(const Reference &ref) {
|
void handlePLT(const Reference &ref) {
|
||||||
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);
|
||||||
|
@ -332,6 +357,22 @@ private:
|
||||||
|
|
||||||
return pa;
|
return pa;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ObjectAtom *getObjectEntry(const SharedLibraryAtom *a) {
|
||||||
|
auto obj = _objectMap.find(a);
|
||||||
|
if (obj != _objectMap.end())
|
||||||
|
return obj->second;
|
||||||
|
|
||||||
|
auto oa = new (_file._alloc) ObjectAtom(_file);
|
||||||
|
oa->addReferenceELF_Mips(R_MIPS_COPY, 0, oa, 0);
|
||||||
|
oa->_name = a->name();
|
||||||
|
oa->_size = a->size();
|
||||||
|
|
||||||
|
_objectMap[a] = oa;
|
||||||
|
_objectVector.push_back(oa);
|
||||||
|
|
||||||
|
return oa;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end anon namespace
|
} // end anon namespace
|
||||||
|
|
|
@ -56,6 +56,7 @@ 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_COPY),
|
||||||
LLD_KIND_STRING_ENTRY(R_MIPS_JUMP_SLOT),
|
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),
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
# Check handling of R_MIPS_COPY relocation
|
||||||
|
|
||||||
|
# Build shared library
|
||||||
|
# RUN: llvm-mc -triple=mipsel -filetype=obj -relocation-model=pic \
|
||||||
|
# RUN: -o=%t-obj %p/Inputs/ext.s
|
||||||
|
# RUN: lld -flavor gnu -target mipsel -shared -o %t-so %t-obj
|
||||||
|
|
||||||
|
# Build executable
|
||||||
|
# RUN: llvm-mc -triple=mipsel -filetype=obj -o=%t-obj %s
|
||||||
|
# RUN: lld -flavor gnu -target mipsel -e glob -o %t %t-obj %t-so
|
||||||
|
# RUN: llvm-readobj -relocations -symbols -dyn-symbols %t | FileCheck %s
|
||||||
|
|
||||||
|
# CHECK: Relocations [
|
||||||
|
# CHECK-NEXT: Section ({{[0-9]+}}) .rel.dyn {
|
||||||
|
# CHECK-NEXT: 0x{{[1-9A-F][0-9A-F]*}} R_MIPS_COPY data1 0x0
|
||||||
|
# CHECK-NEXT: }
|
||||||
|
# CHECK-NEXT: ]
|
||||||
|
|
||||||
|
# CHECK: Name: data1 ({{[0-9]+}}
|
||||||
|
# CHECK-NEXT: Value: 0x{{[1-9A-F][0-9A-F]*}}
|
||||||
|
# CHECK-NEXT: Size: 4
|
||||||
|
# CHECK-NEXT: Binding: Global (0x1)
|
||||||
|
# CHECK-NEXT: Type: Object (0x1)
|
||||||
|
# CHECK-NEXT: Other: 0
|
||||||
|
# CHECK-NEXT: Section: .bss (0x{{[1-9A-F][0-9A-F]*}})
|
||||||
|
|
||||||
|
# CHECK: Name: data1@ ({{[0-9]+}}
|
||||||
|
# CHECK-NEXT: Value: 0x{{[1-9A-F][0-9A-F]*}}
|
||||||
|
# CHECK-NEXT: Size: 4
|
||||||
|
# CHECK-NEXT: Binding: Global (0x1)
|
||||||
|
# CHECK-NEXT: Type: Object (0x1)
|
||||||
|
# CHECK-NEXT: Other: 0
|
||||||
|
# CHECK-NEXT: Section: .bss (0x{{[1-9A-F][0-9A-F]*}})
|
||||||
|
|
||||||
|
.abicalls
|
||||||
|
.option pic0
|
||||||
|
.global glob
|
||||||
|
.ent glob
|
||||||
|
glob:
|
||||||
|
lui $2,%hi(data1)
|
||||||
|
lw $2,%lo(data1)($2)
|
||||||
|
.end glob
|
Loading…
Reference in New Issue