[lld] r322362 - [ELF] - Do not use HeaderSize for conditions in PltSection.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 12 01:35:57 PST 2018


Author: grimar
Date: Fri Jan 12 01:35:57 2018
New Revision: 322362

URL: http://llvm.org/viewvc/llvm-project?rev=322362&view=rev
Log:
[ELF] - Do not use HeaderSize for conditions in PltSection.

Previously we checked (HeaderSize == 0) to find out if
PltSection section is IPLT or PLT. Some targets does not set
HeaderSize though. For example PPC64 has no lazy binding implemented
and does not set PltHeaderSize constant.

Because of that using of both IPLT and PLT relocations worked
incorrectly there (testcase is provided).

Patch fixes the issue.

Differential revision: https://reviews.llvm.org/D41613

Added:
    lld/trunk/test/ELF/ppc64-ifunc.s
Modified:
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/ELF/SyntheticSections.h
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=322362&r1=322361&r2=322362&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Fri Jan 12 01:35:57 2018
@@ -1858,9 +1858,9 @@ void HashTableSection::writeTo(uint8_t *
   }
 }
 
-PltSection::PltSection(size_t S)
+PltSection::PltSection(size_t HeaderSize, bool IsIplt)
     : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16, ".plt"),
-      HeaderSize(S) {
+      HeaderSize(HeaderSize), IsIplt(IsIplt) {
   // The PLT needs to be writable on SPARC as the dynamic linker will
   // modify the instructions in the PLT entries.
   if (Config->EMachine == EM_SPARCV9)
@@ -1870,7 +1870,7 @@ PltSection::PltSection(size_t S)
 void PltSection::writeTo(uint8_t *Buf) {
   // At beginning of PLT but not the IPLT, we have code to call the dynamic
   // linker to resolve dynsyms at runtime. Write such code.
-  if (HeaderSize != 0)
+  if (!IsIplt)
     Target->writePltHeader(Buf);
   size_t Off = HeaderSize;
   // The IPlt is immediately after the Plt, account for this in RelOff
@@ -1889,7 +1889,7 @@ void PltSection::writeTo(uint8_t *Buf) {
 template <class ELFT> void PltSection::addEntry(Symbol &Sym) {
   Sym.PltIndex = Entries.size();
   RelocationBaseSection *PltRelocSection = InX::RelaPlt;
-  if (HeaderSize == 0) {
+  if (IsIplt) {
     PltRelocSection = InX::RelaIplt;
     Sym.IsInIplt = true;
   }
@@ -1906,7 +1906,7 @@ size_t PltSection::getSize() const {
 // example ARM uses mapping symbols to aid disassembly
 void PltSection::addSymbols() {
   // The PLT may have symbols defined for the Header, the IPLT has no header
-  if (HeaderSize != 0)
+  if (!IsIplt)
     Target->addPltHeaderSymbols(*this);
   size_t Off = HeaderSize;
   for (size_t I = 0; I < Entries.size(); ++I) {
@@ -1916,7 +1916,7 @@ void PltSection::addSymbols() {
 }
 
 unsigned PltSection::getPltRelocOff() const {
-  return (HeaderSize == 0) ? InX::Plt->getSize() : 0;
+  return IsIplt ? InX::Plt->getSize() : 0;
 }
 
 // The string hash function for .gdb_index.

Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=322362&r1=322361&r2=322362&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Fri Jan 12 01:35:57 2018
@@ -487,13 +487,13 @@ private:
   size_t Size = 0;
 };
 
-// The PltSection is used for both the Plt and Iplt. The former always has a
+// The PltSection is used for both the Plt and Iplt. The former usually has a
 // header as its first entry that is used at run-time to resolve lazy binding.
 // The latter is used for GNU Ifunc symbols, that will be subject to a
 // Target->IRelativeRel.
 class PltSection : public SyntheticSection {
 public:
-  PltSection(size_t HeaderSize);
+  PltSection(size_t HeaderSize, bool IsIplt);
   void writeTo(uint8_t *Buf) override;
   size_t getSize() const override;
   bool empty() const override { return Entries.empty(); }
@@ -504,8 +504,8 @@ public:
 private:
   unsigned getPltRelocOff() const;
   std::vector<std::pair<const Symbol *, unsigned>> Entries;
-  // Iplt always has HeaderSize of 0, the Plt HeaderSize is always non-zero
   size_t HeaderSize;
+  bool IsIplt;
 };
 
 // GdbIndexChunk is created for each .debug_info section and contains

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=322362&r1=322361&r2=322362&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Jan 12 01:35:57 2018
@@ -369,9 +369,9 @@ template <class ELFT> static void create
       false /*Sort*/);
   Add(InX::RelaIplt);
 
-  InX::Plt = make<PltSection>(Target->PltHeaderSize);
+  InX::Plt = make<PltSection>(Target->PltHeaderSize, false /*IsIplt*/);
   Add(InX::Plt);
-  InX::Iplt = make<PltSection>(0);
+  InX::Iplt = make<PltSection>(0 /*HeaderSize*/, true /*IsIplt*/);
   Add(InX::Iplt);
 
   if (!Config->Relocatable) {

Added: lld/trunk/test/ELF/ppc64-ifunc.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/ppc64-ifunc.s?rev=322362&view=auto
==============================================================================
--- lld/trunk/test/ELF/ppc64-ifunc.s (added)
+++ lld/trunk/test/ELF/ppc64-ifunc.s Fri Jan 12 01:35:57 2018
@@ -0,0 +1,41 @@
+# REQUIRES: ppc
+# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
+# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
+# RUN: ld.lld -shared %t2.o -o %t2.so
+# RUN: ld.lld %t.o %t2.so -o %t
+# RUN: llvm-objdump -d %t | FileCheck %s
+
+# CHECK:      _start:
+# CHECK-NEXT:  10010004: {{.*}} bl .+12
+# CHECK-NEXT:  10010008: {{.*}} bl .+40
+
+# 0x10010004 + 12 = 0x10010010 (PLT entry 0)
+# 0x10010008 + 40 = 0x10010030 (PLT entry 1)
+
+# CHECK:     Disassembly of section .plt:
+# CHECK:       10010010: {{.*}} std 2, 40(1)
+# CHECK-NEXT:  10010014: {{.*}} addis 11, 2, 4098
+# CHECK-NEXT:  10010018: {{.*}} ld 12, -32744(11)
+# CHECK-NEXT:  1001001c: {{.*}} ld 11, 0(12)
+# CHECK-NEXT:  10010020: {{.*}} mtctr 11
+# CHECK-NEXT:  10010024: {{.*}} ld 2, 8(12)
+# CHECK-NEXT:  10010028: {{.*}} ld 11, 16(12)
+# CHECK-NEXT:  1001002c: {{.*}} bctr
+# CHECK-NEXT:  10010030: {{.*}} std 2, 40(1)
+# CHECK-NEXT:  10010034: {{.*}} addis 11, 2, 4098
+# CHECK-NEXT:  10010038: {{.*}} ld 12, -32736(11)
+# CHECK-NEXT:  1001003c: {{.*}} ld 11, 0(12)
+# CHECK-NEXT:  10010040: {{.*}} mtctr 11
+# CHECK-NEXT:  10010044: {{.*}} ld 2, 8(12)
+# CHECK-NEXT:  10010048: {{.*}} ld 11, 16(12)
+# CHECK-NEXT:  1001004c: {{.*}} bctr
+
+.type ifunc STT_GNU_IFUNC
+.globl ifunc
+ifunc:
+ nop
+
+.global _start
+_start:
+  bl bar
+  bl ifunc




More information about the llvm-commits mailing list