else if (isa<DefinedRegular<ELFT>>(Body))
ESym->st_shndx = SHN_ABS;
- // On MIPS we need to mark symbol which has a PLT entry and requires pointer
- // equality by STO_MIPS_PLT flag. That is necessary to help dynamic linker
- // distinguish such symbols and MIPS lazy-binding stubs.
- // https://sourceware.org/ml/binutils/2008-07/txt00000.txt
- if (Config->EMachine == EM_MIPS && Body->isInPlt() &&
- Body->NeedsCopyOrPltAddr)
- ESym->st_other |= STO_MIPS_PLT;
+ if (Config->EMachine == EM_MIPS) {
+ // On MIPS we need to mark symbol which has a PLT entry and requires
+ // pointer equality by STO_MIPS_PLT flag. That is necessary to help
+ // dynamic linker distinguish such symbols and MIPS lazy-binding stubs.
+ // https://sourceware.org/ml/binutils/2008-07/txt00000.txt
+ if (Body->isInPlt() && Body->NeedsCopyOrPltAddr)
+ ESym->st_other |= STO_MIPS_PLT;
+ if (Config->Relocatable) {
+ auto *D = dyn_cast<DefinedRegular<ELFT>>(Body);
+ if (D && D->isMipsPIC())
+ ESym->st_other |= STO_MIPS_PIC;
+ }
+ }
++ESym;
}
}
Defined::Defined(Kind K, uint32_t NameOffset, uint8_t StOther, uint8_t Type)
: SymbolBody(K, NameOffset, StOther, Type) {}
+template <class ELFT> bool DefinedRegular<ELFT>::isMipsPIC() const {
+ if (!Section || !isFunc())
+ return false;
+ return (this->StOther & STO_MIPS_MIPS16) == STO_MIPS_PIC ||
+ (Section->getFile()->getObj().getHeader()->e_flags & EF_MIPS_PIC);
+}
+
Undefined::Undefined(StringRef Name, uint8_t StOther, uint8_t Type,
InputFile *File)
: SymbolBody(SymbolBody::UndefinedKind, Name, StOther, Type) {
template uint64_t SymbolBody::template getSize<ELF64LE>() const;
template uint64_t SymbolBody::template getSize<ELF64BE>() const;
+template class elf::DefinedRegular<ELF32LE>;
+template class elf::DefinedRegular<ELF32BE>;
+template class elf::DefinedRegular<ELF64LE>;
+template class elf::DefinedRegular<ELF64BE>;
+
template class elf::DefinedSynthetic<ELF32LE>;
template class elf::DefinedSynthetic<ELF32BE>;
template class elf::DefinedSynthetic<ELF64LE>;
this->File = F;
}
+ // Return true if the symbol is a PIC function.
+ bool isMipsPIC() const;
+
static bool classof(const SymbolBody *S) {
return S->kind() == SymbolBody::DefinedRegularKind;
}
if (F->getObj().getHeader()->e_flags & EF_MIPS_PIC)
return Expr;
auto *D = dyn_cast<DefinedRegular<ELFT>>(&S);
- if (!D || !D->Section)
- return Expr;
// LA25 is required if target file has PIC code
// or target symbol is a PIC symbol.
- const ELFFile<ELFT> &DefFile = D->Section->getFile()->getObj();
- bool PicFile = DefFile.getHeader()->e_flags & EF_MIPS_PIC;
- bool PicSym = (D->StOther & STO_MIPS_MIPS16) == STO_MIPS_PIC;
- return (PicFile || PicSym) ? R_THUNK_ABS : Expr;
+ return D && D->isMipsPIC() ? R_THUNK_ABS : Expr;
}
template <class ELFT>
--- /dev/null
+# In case of linking PIC and non-PIC code together and generation
+# of a relocatable object, all PIC symbols should have STO_MIPS_PIC
+# flag in the symbol table of the ouput file.
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-npic.o
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
+# RUN: %p/Inputs/mips-pic.s -o %t-pic.o
+# RUN: ld.lld -r %t-npic.o %t-pic.o -o %t-rel.o
+# RUN: llvm-readobj -t %t-rel.o | FileCheck %s
+
+# REQUIRES: mips
+
+# CHECK: Symbol {
+# CHECK: Name: main
+# CHECK-NEXT: Value:
+# CHECK-NEXT: Size:
+# CHECK-NEXT: Binding: Local
+# CHECK-NEXT: Type: None
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: .text
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: foo1a
+# CHECK-NEXT: Value:
+# CHECK-NEXT: Size:
+# CHECK-NEXT: Binding: Global
+# CHECK-NEXT: Type: Function
+# CHECK-NEXT: Other [
+# CHECK-NEXT: STO_MIPS_PIC
+# CHECK-NEXT: ]
+# CHECK-NEXT: Section: .text
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: foo1b
+# CHECK-NEXT: Value:
+# CHECK-NEXT: Size:
+# CHECK-NEXT: Binding: Global
+# CHECK-NEXT: Type: Function
+# CHECK-NEXT: Other [
+# CHECK-NEXT: STO_MIPS_PIC
+# CHECK-NEXT: ]
+# CHECK-NEXT: Section: .text
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: foo2
+# CHECK-NEXT: Value:
+# CHECK-NEXT: Size:
+# CHECK-NEXT: Binding: Global
+# CHECK-NEXT: Type: Function
+# CHECK-NEXT: Other [
+# CHECK-NEXT: STO_MIPS_PIC
+# CHECK-NEXT: ]
+# CHECK-NEXT: Section: .text
+# CHECK-NEXT: }
+
+ .text
+main:
+ nop