[lld] r252854 - [ELF2] Sort dynamic symbols according to the MIPS requirements.

Igor Kudrin via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 11 20:08:13 PST 2015


Author: ikudrin
Date: Wed Nov 11 22:08:12 2015
New Revision: 252854

URL: http://llvm.org/viewvc/llvm-project?rev=252854&view=rev
Log:
[ELF2] Sort dynamic symbols according to the MIPS requirements.

The MIPS ABI has requirements to sort the entries in the .dyn.sym section.
Symbols which are not in the GOT have to precede the symbols which are added to
the GOT. The latter must have the same order as the corresponding GOT entries.

Since these sorting requirements contradict those of the GNU hash section,
they cannot be used together.

Differential revision: http://reviews.llvm.org/D14281

Added:
    lld/trunk/test/elf2/mips-dynsym-sort.s
    lld/trunk/test/elf2/mips-gnu-hash.s
Modified:
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/OutputSections.cpp

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=252854&r1=252853&r2=252854&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Wed Nov 11 22:08:12 2015
@@ -220,6 +220,9 @@ void LinkerDriver::createFiles(opt::Inpu
 
   if (Files.empty())
     error("no input files.");
+
+  if (Config->GnuHash && Config->EMachine == EM_MIPS)
+    error("The .gnu.hash section is not compatible with the MIPS target.");
 }
 
 template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=252854&r1=252853&r2=252854&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Wed Nov 11 22:08:12 2015
@@ -1081,6 +1081,17 @@ SymbolTableSection<ELFT>::SymbolTableSec
   Header.sh_addralign = ELFT::Is64Bits ? 8 : 4;
 }
 
+// Orders symbols according to their positions in the GOT,
+// in compliance with MIPS ABI rules.
+// See "Global Offset Table" in Chapter 5 in the following document
+// for detailed description:
+// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
+static bool sortMipsSymbols(SymbolBody *L, SymbolBody *R) {
+  if (!L->isInGot() || !R->isInGot())
+    return R->isInGot();
+  return L->GotIndex < R->GotIndex;
+}
+
 template <class ELFT> void SymbolTableSection<ELFT>::finalize() {
   if (this->Header.sh_size)
     return; // Already finalized.
@@ -1100,6 +1111,8 @@ template <class ELFT> void SymbolTableSe
   if (Out<ELFT>::GnuHashTab)
     // NB: It also sorts Symbols to meet the GNU hash table requirements.
     Out<ELFT>::GnuHashTab->addSymbols(Symbols);
+  else if (Config->EMachine == EM_MIPS)
+    std::stable_sort(Symbols.begin(), Symbols.end(), sortMipsSymbols);
   size_t I = 0;
   for (SymbolBody *B : Symbols)
     B->setDynamicSymbolTableIndex(++I);

Added: lld/trunk/test/elf2/mips-dynsym-sort.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/mips-dynsym-sort.s?rev=252854&view=auto
==============================================================================
--- lld/trunk/test/elf2/mips-dynsym-sort.s (added)
+++ lld/trunk/test/elf2/mips-dynsym-sort.s Wed Nov 11 22:08:12 2015
@@ -0,0 +1,43 @@
+# Check the order of dynamic symbols for the MIPS target.
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-be.o
+# RUN: ld.lld2 -shared %t-be.o -o %t-be.so
+# RUN: llvm-readobj -symbols -dyn-symbols %t-be.so | FileCheck %s
+
+# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t-el.o
+# RUN: ld.lld2 -shared %t-el.o -o %t-el.so
+# RUN: llvm-readobj -symbols -dyn-symbols %t-el.so | FileCheck %s
+
+# REQUIRES: mips
+
+  .data
+  .globl v1,v2,v3
+v1:
+  .space 4
+v2:
+  .space 4
+v3:
+  .space 4
+
+  .text
+  .globl  __start
+__start:
+  lui $2, %got(v3) # v3 will precede v1 in the GOT
+  lui $2, %got(v1)
+
+# Since all these symbols have global binding,
+# the Symbols section contains them in the original order.
+# CHECK: Symbols [
+# CHECK:     Name: v1
+# CHECK:     Name: v2
+# CHECK:     Name: v3
+# CHECK: ]
+
+# The symbols in the DynamicSymbols section are sorted in compliance with
+# the MIPS rules. v2 comes first as it is not in the GOT.
+# v1 and v3 are sorted according to their order in the GOT.
+# CHECK: DynamicSymbols [
+# CHECK:     Name: v2@
+# CHECK:     Name: v3@
+# CHECK:     Name: v1@
+# CHECK: ]

Added: lld/trunk/test/elf2/mips-gnu-hash.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/mips-gnu-hash.s?rev=252854&view=auto
==============================================================================
--- lld/trunk/test/elf2/mips-gnu-hash.s (added)
+++ lld/trunk/test/elf2/mips-gnu-hash.s Wed Nov 11 22:08:12 2015
@@ -0,0 +1,15 @@
+# Shouldn't allow the GNU hash style to be selected with the MIPS target.
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-be.o
+# RUN: not ld.lld2 -shared -hash-style=gnu %t-be.o -o %t-be.so 2>&1 | FileCheck %s
+
+# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t-el.o
+# RUN: not ld.lld2 -shared -hash-style=gnu %t-el.o -o %t-el.so 2>&1 | FileCheck %s
+
+# CHECK: The .gnu.hash section is not compatible with the MIPS target.
+
+# REQUIRES: mips
+
+  .globl  __start
+__start:
+  nop




More information about the llvm-commits mailing list