[lld] r282714 - [ELF][MIPS] Setup STO_MIPS_PIC flag for PIC symbols when generate a relocatable object
Simon Atanasyan via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 29 05:58:37 PDT 2016
Author: atanasyan
Date: Thu Sep 29 07:58:36 2016
New Revision: 282714
URL: http://llvm.org/viewvc/llvm-project?rev=282714&view=rev
Log:
[ELF][MIPS] Setup STO_MIPS_PIC flag for PIC symbols when generate a relocatable object
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.
Added:
lld/trunk/test/ELF/mips-sto-pic-flag.s
Modified:
lld/trunk/ELF/OutputSections.cpp
lld/trunk/ELF/Symbols.cpp
lld/trunk/ELF/Symbols.h
lld/trunk/ELF/Target.cpp
Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=282714&r1=282713&r2=282714&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Thu Sep 29 07:58:36 2016
@@ -1467,13 +1467,19 @@ void SymbolTableSection<ELFT>::writeGlob
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;
}
}
Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=282714&r1=282713&r2=282714&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Thu Sep 29 07:58:36 2016
@@ -190,6 +190,13 @@ Defined::Defined(Kind K, StringRef Name,
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) {
@@ -315,6 +322,11 @@ template uint32_t SymbolBody::template g
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>;
Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=282714&r1=282713&r2=282714&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Thu Sep 29 07:58:36 2016
@@ -214,6 +214,9 @@ public:
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;
}
Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=282714&r1=282713&r2=282714&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Thu Sep 29 07:58:36 2016
@@ -2054,14 +2054,9 @@ RelExpr MipsTargetInfo<ELFT>::getThunkEx
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>
Added: lld/trunk/test/ELF/mips-sto-pic-flag.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/mips-sto-pic-flag.s?rev=282714&view=auto
==============================================================================
--- lld/trunk/test/ELF/mips-sto-pic-flag.s (added)
+++ lld/trunk/test/ELF/mips-sto-pic-flag.s Thu Sep 29 07:58:36 2016
@@ -0,0 +1,58 @@
+# 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
More information about the llvm-commits
mailing list