forked from OSchip/llvm-project
[Mips] Reject R_MIPS_CALL16 against local symbols
llvm-svn: 240765
This commit is contained in:
parent
52db6aefcc
commit
253125af03
|
@ -547,15 +547,23 @@ static bool isBranchReloc(Reference::KindValue kind) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isGotReloc(Reference::KindValue kind) {
|
static bool isGotReloc(Reference::KindValue kind) {
|
||||||
return kind == R_MIPS_GOT16 || kind == R_MIPS_GOT_HI16 ||
|
return kind == R_MIPS_GOT16 || kind == R_MICROMIPS_GOT16;
|
||||||
kind == R_MIPS_GOT_LO16 || kind == R_MICROMIPS_GOT16 ||
|
}
|
||||||
kind == R_MICROMIPS_GOT_HI16 || kind == R_MICROMIPS_GOT_LO16;
|
|
||||||
|
static bool isAllGotReloc(Reference::KindValue kind) {
|
||||||
|
return isGotReloc(kind) || kind == R_MIPS_GOT_HI16 ||
|
||||||
|
kind == R_MIPS_GOT_LO16 || kind == R_MICROMIPS_GOT_HI16 ||
|
||||||
|
kind == R_MICROMIPS_GOT_LO16;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isCallReloc(Reference::KindValue kind) {
|
static bool isCallReloc(Reference::KindValue kind) {
|
||||||
return kind == R_MIPS_CALL16 || kind == R_MIPS_CALL_HI16 ||
|
return kind == R_MIPS_CALL16 || kind == R_MICROMIPS_CALL16;
|
||||||
kind == R_MIPS_CALL_LO16 || kind == R_MICROMIPS_CALL16 ||
|
}
|
||||||
kind == R_MICROMIPS_CALL_HI16 || kind == R_MICROMIPS_CALL_LO16;
|
|
||||||
|
static bool isAllCallReloc(Reference::KindValue kind) {
|
||||||
|
return isCallReloc(kind) || kind == R_MIPS_CALL_HI16 ||
|
||||||
|
kind == R_MIPS_CALL_LO16 || kind == R_MICROMIPS_CALL_HI16 ||
|
||||||
|
kind == R_MICROMIPS_CALL_LO16;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isGotDispReloc(Reference::KindValue kind) {
|
static bool isGotDispReloc(Reference::KindValue kind) {
|
||||||
|
@ -610,8 +618,8 @@ void RelocationPass<ELFT>::handleReference(const MipsELFDefinedAtom<ELFT> &atom,
|
||||||
handlePlain(atom, ref);
|
handlePlain(atom, ref);
|
||||||
else if (isBranchReloc(kind))
|
else if (isBranchReloc(kind))
|
||||||
handleBranch(atom, ref);
|
handleBranch(atom, ref);
|
||||||
else if (isGotReloc(kind) || isCallReloc(kind) || isGotDispReloc(kind) ||
|
else if (isAllGotReloc(kind) || isAllCallReloc(kind) ||
|
||||||
isGotPageReloc(kind) || kind == R_MIPS_EH)
|
isGotDispReloc(kind) || isGotPageReloc(kind) || kind == R_MIPS_EH)
|
||||||
handleGOT(ref);
|
handleGOT(ref);
|
||||||
else if (isTlsDtpReloc(kind))
|
else if (isTlsDtpReloc(kind))
|
||||||
ref.setAddend(ref.addend() - atom.file().getDTPOffset());
|
ref.setAddend(ref.addend() - atom.file().getDTPOffset());
|
||||||
|
@ -672,7 +680,8 @@ RelocationPass<ELFT>::collectReferenceInfo(const MipsELFDefinedAtom<ELFT> &atom,
|
||||||
else
|
else
|
||||||
_hasStaticRelocations.insert(ref.target());
|
_hasStaticRelocations.insert(ref.target());
|
||||||
|
|
||||||
if (!isBranchReloc(refKind) && !isCallReloc(refKind) && refKind != R_MIPS_EH)
|
if (!isBranchReloc(refKind) && !isAllCallReloc(refKind) &&
|
||||||
|
refKind != R_MIPS_EH)
|
||||||
_requiresPtrEquality.insert(ref.target());
|
_requiresPtrEquality.insert(ref.target());
|
||||||
|
|
||||||
return std::error_code();
|
return std::error_code();
|
||||||
|
@ -703,6 +712,15 @@ make_external_gprel32_reloc_error(const ELFLinkingContext &ctx,
|
||||||
ref.target()->name() + " in file " + atom.file().path());
|
ref.target()->name() + " in file " + atom.file().path());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::error_code
|
||||||
|
make_local_call16_reloc_error(const ELFLinkingContext &ctx,
|
||||||
|
const DefinedAtom &atom, const Reference &ref) {
|
||||||
|
return make_dynamic_error_code("R_MIPS_CALL16 (11) relocation cannot be used "
|
||||||
|
"against local symbol " +
|
||||||
|
ref.target()->name() + " in file " +
|
||||||
|
atom.file().path());
|
||||||
|
}
|
||||||
|
|
||||||
template <typename ELFT>
|
template <typename ELFT>
|
||||||
std::error_code
|
std::error_code
|
||||||
RelocationPass<ELFT>::validateRelocation(const DefinedAtom &atom,
|
RelocationPass<ELFT>::validateRelocation(const DefinedAtom &atom,
|
||||||
|
@ -713,6 +731,9 @@ RelocationPass<ELFT>::validateRelocation(const DefinedAtom &atom,
|
||||||
if (ref.kindValue() == R_MIPS_GPREL32 && !isLocal(ref.target()))
|
if (ref.kindValue() == R_MIPS_GPREL32 && !isLocal(ref.target()))
|
||||||
return make_external_gprel32_reloc_error(this->_ctx, atom, ref);
|
return make_external_gprel32_reloc_error(this->_ctx, atom, ref);
|
||||||
|
|
||||||
|
if (isCallReloc(ref.kindValue()) && isLocal(ref.target()))
|
||||||
|
return make_local_call16_reloc_error(this->_ctx, atom, ref);
|
||||||
|
|
||||||
if (this->_ctx.getOutputELFType() != ET_DYN)
|
if (this->_ctx.getOutputELFType() != ET_DYN)
|
||||||
return std::error_code();
|
return std::error_code();
|
||||||
|
|
||||||
|
@ -765,7 +786,7 @@ static bool isMipsReadonly(const MipsELFDefinedAtom<ELFT> &atom) {
|
||||||
template <typename ELFT>
|
template <typename ELFT>
|
||||||
bool RelocationPass<ELFT>::mightBeDynamic(const MipsELFDefinedAtom<ELFT> &atom,
|
bool RelocationPass<ELFT>::mightBeDynamic(const MipsELFDefinedAtom<ELFT> &atom,
|
||||||
Reference::KindValue refKind) const {
|
Reference::KindValue refKind) const {
|
||||||
if (isGotReloc(refKind) || isCallReloc(refKind))
|
if (isAllGotReloc(refKind) || isAllCallReloc(refKind))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (refKind != R_MIPS_32 && refKind != R_MIPS_64)
|
if (refKind != R_MIPS_32 && refKind != R_MIPS_64)
|
||||||
|
@ -902,10 +923,8 @@ template <typename ELFT> void RelocationPass<ELFT>::handleGOT(Reference &ref) {
|
||||||
ref.setTarget(getGlobalGOTEntry(ref.target()));
|
ref.setTarget(getGlobalGOTEntry(ref.target()));
|
||||||
else if (isGotPageReloc(ref.kindValue()))
|
else if (isGotPageReloc(ref.kindValue()))
|
||||||
ref.setTarget(getLocalGOTPageEntry(ref));
|
ref.setTarget(getLocalGOTPageEntry(ref));
|
||||||
else if (isLocal(ref.target()) && (ref.kindValue() == R_MIPS_GOT16 ||
|
else if (isLocal(ref.target()) &&
|
||||||
ref.kindValue() == R_MIPS_CALL16 ||
|
(isCallReloc(ref.kindValue()) || isGotReloc(ref.kindValue())))
|
||||||
ref.kindValue() == R_MICROMIPS_GOT16 ||
|
|
||||||
ref.kindValue() == R_MICROMIPS_CALL16))
|
|
||||||
ref.setTarget(getLocalGOTPageEntry(ref));
|
ref.setTarget(getLocalGOTPageEntry(ref));
|
||||||
else
|
else
|
||||||
ref.setTarget(getLocalGOTEntry(ref));
|
ref.setTarget(getLocalGOTEntry(ref));
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
# Check that the linker does not accept R_MIPS_CALL16 relocation
|
||||||
|
# against local symbol.
|
||||||
|
|
||||||
|
# RUN: yaml2obj -format=elf -docnum 1 %s > %t.o
|
||||||
|
# RUN: not lld -flavor gnu -target mipsel -e T0 -o %t.exe %t.o 2>&1 \
|
||||||
|
# RUN: | FileCheck %s
|
||||||
|
|
||||||
|
# CHECK: R_MIPS_CALL16 (11) relocation cannot be used against local symbol L0 in file {{.*}}validate-rel-03.test.tmp.o
|
||||||
|
|
||||||
|
---
|
||||||
|
FileHeader:
|
||||||
|
Class: ELFCLASS32
|
||||||
|
Data: ELFDATA2LSB
|
||||||
|
Type: ET_REL
|
||||||
|
Machine: EM_MIPS
|
||||||
|
Flags: [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
|
||||||
|
|
||||||
|
Sections:
|
||||||
|
- Name: .text
|
||||||
|
Type: SHT_PROGBITS
|
||||||
|
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||||
|
AddressAlign: 16
|
||||||
|
Size: 16
|
||||||
|
|
||||||
|
- Name: .rel.text
|
||||||
|
Type: SHT_REL
|
||||||
|
Link: .symtab
|
||||||
|
AddressAlign: 4
|
||||||
|
Info: .text
|
||||||
|
Relocations:
|
||||||
|
- Offset: 8
|
||||||
|
Symbol: T0
|
||||||
|
Type: R_MIPS_CALL16
|
||||||
|
- Offset: 4
|
||||||
|
Symbol: L0
|
||||||
|
Type: R_MIPS_CALL16
|
||||||
|
|
||||||
|
Symbols:
|
||||||
|
Local:
|
||||||
|
- Name: L0
|
||||||
|
Type: STT_FUNC
|
||||||
|
Section: .text
|
||||||
|
Value: 0
|
||||||
|
Size: 4
|
||||||
|
Global:
|
||||||
|
- Name: T0
|
||||||
|
Type: STT_FUNC
|
||||||
|
Section: .text
|
||||||
|
Value: 4
|
||||||
|
Size: 4
|
||||||
|
- Name: T1
|
||||||
|
Type: STT_FUNC
|
||||||
|
Section: .text
|
||||||
|
Value: 8
|
||||||
|
Size: 8
|
||||||
|
...
|
Loading…
Reference in New Issue