[ELF][MIPS] Support linking of PIE for MIPS
authorSimon Atanasyan <simon@atanasyan.com>
Fri, 13 Apr 2018 08:15:01 +0000 (08:15 +0000)
committerSimon Atanasyan <simon@atanasyan.com>
Fri, 13 Apr 2018 08:15:01 +0000 (08:15 +0000)
MIPS ABI requires creation of the MIPS_RLD_MAP dynamic tag for non-PIE
executables only and MIPS_RLD_MAP_REL tag for both PIE and non-PIE
executables. The patch skips definition of the MIPS_RLD_MAP for PIE
files and defines MIPS_RLD_MAP_REL.

The MIPS_RLD_MAP_REL tag stores the offset to the .rld_map section
relative to the address of the tag itself.

Differential Revision: https://reviews.llvm.org/D43347

llvm-svn: 329996

lld/ELF/SyntheticSections.cpp
lld/ELF/SyntheticSections.h
lld/test/ELF/mips-dynamic.s

index 45063fd..bd2896e 100644 (file)
@@ -1028,6 +1028,13 @@ void DynamicSection<ELFT>::addInSec(int32_t Tag, InputSection *Sec) {
 }
 
 template <class ELFT>
+void DynamicSection<ELFT>::addInSecRelative(int32_t Tag, InputSection *Sec) {
+  size_t TagOffset = Entries.size() * Entsize;
+  Entries.push_back(
+      {Tag, [=] { return Sec->getVA(0) - (getVA() + TagOffset); }});
+}
+
+template <class ELFT>
 void DynamicSection<ELFT>::addOutSec(int32_t Tag, OutputSection *Sec) {
   Entries.push_back({Tag, [=] { return Sec->Addr; }});
 }
@@ -1180,8 +1187,13 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
     else
       addInt(DT_MIPS_GOTSYM, InX::DynSymTab->getNumSymbols());
     addInSec(DT_PLTGOT, InX::MipsGot);
-    if (InX::MipsRldMap)
-      addInSec(DT_MIPS_RLD_MAP, InX::MipsRldMap);
+    if (InX::MipsRldMap) {
+      if (!Config->Pie)
+        addInSec(DT_MIPS_RLD_MAP, InX::MipsRldMap);
+      // Store the offset to the .rld_map section
+      // relative to the address of the tag.
+      addInSecRelative(DT_MIPS_RLD_MAP_REL, InX::MipsRldMap);
+    }
   }
 
   addInt(DT_NULL, 0);
index b709f4b..c4dc8f9 100644 (file)
@@ -360,6 +360,7 @@ private:
   void add(int32_t Tag, std::function<uint64_t()> Fn);
   void addInt(int32_t Tag, uint64_t Val);
   void addInSec(int32_t Tag, InputSection *Sec);
+  void addInSecRelative(int32_t Tag, InputSection *Sec);
   void addOutSec(int32_t Tag, OutputSection *Sec);
   void addSize(int32_t Tag, OutputSection *Sec);
   void addSym(int32_t Tag, Symbol *Sym);
index 15afb02..820776b 100644 (file)
@@ -6,7 +6,11 @@
 
 # RUN: ld.lld %t.o %td.so -o %t.exe
 # RUN: llvm-readobj -sections -dynamic-table %t.exe \
-# RUN:   | FileCheck -check-prefix=EXE %s
+# RUN:   | FileCheck -check-prefixes=EXE,NOPIE %s
+
+# RUN: ld.lld -pie %t.o %td.so -o %t.so
+# RUN: llvm-readobj -sections -dyn-symbols -dynamic-table %t.so \
+# RUN:   | FileCheck -check-prefixes=EXE,PIE %s
 
 # RUN: ld.lld %t.o --image-base=0x123000 %td.so -o %t.exe
 # RUN: llvm-readobj -sections -dynamic-table %t.exe \
 # EXE-NEXT:     Offset:
 # EXE-NEXT:     Size: 8
 # EXE:      ]
-# EXE:      DynamicSection [
-# EXE-NEXT:   Tag        Type                 Name/Value
-# EXE-DAG:    0x00000003 PLTGOT               [[GOTADDR]]
-# EXE-DAG:    0x70000001 MIPS_RLD_VERSION     1
-# EXE-DAG:    0x70000005 MIPS_FLAGS           NOTPOT
-# EXE-DAG:    0x70000006 MIPS_BASE_ADDRESS    0x10000
-# EXE-DAG:    0x7000000A MIPS_LOCAL_GOTNO     2
-# EXE-DAG:    0x70000011 MIPS_SYMTABNO        2
-# EXE-DAG:    0x70000013 MIPS_GOTSYM          0x2
-# EXE-DAG:    0x70000016 MIPS_RLD_MAP         [[RLDMAPADDR]]
-# EXE:      ]
+
+# PIE:      DynamicSection [
+# PIE-NEXT:   Tag        Type                 Name/Value
+# PIE:        0x00000004 HASH                 0x{{[0-9A-F]+}}
+# PIE-NEXT:   0x70000001 MIPS_RLD_VERSION     1
+# PIE-NEXT:   0x70000005 MIPS_FLAGS           NOTPOT
+# PIE-NEXT:   0x70000006 MIPS_BASE_ADDRESS    0x0
+# PIE-NEXT:   0x70000011 MIPS_SYMTABNO        2
+# PIE-NEXT:   0x7000000A MIPS_LOCAL_GOTNO     2
+# PIE-NEXT:   0x70000013 MIPS_GOTSYM          0x2
+# PIE-NEXT:   0x00000003 PLTGOT               [[GOTADDR]]
+# PIE-NEXT:   0x70000035 MIPS_RLD_MAP_REL     0x{{[0-9A-F]+}}
+# PIE-NEXT:   0x00000000 NULL                 0x0
+# PIE-NEXT: ]
+
+# NOPIE:      DynamicSection [
+# NOPIE-NEXT:   Tag        Type                 Name/Value
+# NOPIE:        0x00000004 HASH                 0x{{[0-9A-F]+}}
+# NOPIE-NEXT:   0x70000001 MIPS_RLD_VERSION     1
+# NOPIE-NEXT:   0x70000005 MIPS_FLAGS           NOTPOT
+# NOPIE-NEXT:   0x70000006 MIPS_BASE_ADDRESS    0x10000
+# NOPIE-NEXT:   0x70000011 MIPS_SYMTABNO        2
+# NOPIE-NEXT:   0x7000000A MIPS_LOCAL_GOTNO     2
+# NOPIE-NEXT:   0x70000013 MIPS_GOTSYM          0x2
+# NOPIE-NEXT:   0x00000003 PLTGOT               [[GOTADDR]]
+# NOPIE-NEXT:   0x70000016 MIPS_RLD_MAP         [[RLDMAPADDR]]
+# NOPIE-NEXT:   0x70000035 MIPS_RLD_MAP_REL     0x{{[0-9A-F]+}}
+# NOPIE-NEXT:   0x00000000 NULL                 0x0
+# NOPIE-NEXT: ]
 
 # IMAGE_BASE: 0x70000006 MIPS_BASE_ADDRESS    0x123000