[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