[lld] r370172 - [ELF][RISCV] Assign st_shndx of __global_pointer$ to 1 if .sdata does not exist

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 28 02:01:04 PDT 2019


Author: maskray
Date: Wed Aug 28 02:01:03 2019
New Revision: 370172

URL: http://llvm.org/viewvc/llvm-project?rev=370172&view=rev
Log:
[ELF][RISCV] Assign st_shndx of __global_pointer$ to 1 if .sdata does not exist

This essentially reverts the code change of D63132 and switches to a simpler approach.

In an executable/shared object, st_shndx of a symbol can be:

1) SHN_UNDEF: undefined symbol (or canonical PLT)
2) SHN_ABS: absolute symbol
3) any other value (usually a regular section index) represents a relative symbol.
  The actual value does not matter.

Many ld.so (musl, all archs except MIPS of FreeBSD rtld-elf) even treat 2) and 3)
the same. If .sdata does not exist, it does not matter what value/section
__global_pointer$ has, as long as it is relative (otherwise there will be a pedantic
lld error. See D63132). Just set the st_shndx arbitrarily to 1.

Dummy st_shndx=1 may be used by __rela_iplt_start, linker-script-defined symbols outside a section, __dso_handle, etc.

Reviewed By: ruiu

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

Added:
    lld/trunk/test/ELF/riscv-gp-no-sdata.s
Removed:
    lld/trunk/test/ELF/riscv-gp-dummy-sdata.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=370172&r1=370171&r2=370172&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Wed Aug 28 02:01:03 2019
@@ -3506,23 +3506,6 @@ bool PPC64LongBranchTargetSection::isNee
   return !finalized || !entries.empty();
 }
 
-RISCVSdataSection::RISCVSdataSection()
-    : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, 1, ".sdata") {}
-
-bool RISCVSdataSection::isNeeded() const {
-  if (!ElfSym::riscvGlobalPointer)
-    return false;
-
-  // __global_pointer$ is defined relative to .sdata . If the section does not
-  // exist, create a dummy one.
-  for (BaseCommand *base : getParent()->sectionCommands)
-    if (auto *isd = dyn_cast<InputSectionDescription>(base))
-      for (InputSection *isec : isd->sections)
-        if (isec != this)
-          return false;
-  return true;
-}
-
 static uint8_t getAbiVersion() {
   // MIPS non-PIC executable gets ABI version 1.
   if (config->emachine == EM_MIPS) {

Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=370172&r1=370171&r2=370172&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Wed Aug 28 02:01:03 2019
@@ -1100,15 +1100,6 @@ public:
   void writeTo(uint8_t *buf) override;
 };
 
-// Create a dummy .sdata for __global_pointer$ if .sdata does not exist.
-class RISCVSdataSection final : public SyntheticSection {
-public:
-  RISCVSdataSection();
-  size_t getSize() const override { return 0; }
-  bool isNeeded() const override;
-  void writeTo(uint8_t *buf) override {}
-};
-
 InputSection *createInterpSection();
 MergeInputSection *createCommentSection();
 template <class ELFT> void splitSections();
@@ -1173,7 +1164,6 @@ struct InStruct {
   PltSection *plt;
   PltSection *iplt;
   PPC32Got2Section *ppc32Got2;
-  RISCVSdataSection *riscvSdata;
   RelocationBaseSection *relaPlt;
   RelocationBaseSection *relaIplt;
   StringTableSection *shStrTab;

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=370172&r1=370171&r2=370172&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Aug 28 02:01:03 2019
@@ -474,11 +474,6 @@ template <class ELFT> static void create
     add(in.ppc64LongBranchTarget);
   }
 
-  if (config->emachine == EM_RISCV) {
-    in.riscvSdata = make<RISCVSdataSection>();
-    add(in.riscvSdata);
-  }
-
   in.gotPlt = make<GotPltSection>();
   add(in.gotPlt);
   in.igotPlt = make<IgotPltSection>();
@@ -1701,12 +1696,16 @@ template <class ELFT> void Writer<ELFT>:
   // Define __rel[a]_iplt_{start,end} symbols if needed.
   addRelIpltSymbols();
 
-  // RISC-V's gp can address +/- 2 KiB, set it to .sdata + 0x800 if not defined.
-  // This symbol should only be defined in an executable.
-  if (config->emachine == EM_RISCV && !config->shared)
+  // RISC-V's gp can address +/- 2 KiB, set it to .sdata + 0x800. This symbol
+  // should only be defined in an executable. If .sdata does not exist, its
+  // value/section does not matter but it has to be relative, so set its
+  // st_shndx arbitrarily to 1 (Out::elfHeader).
+  if (config->emachine == EM_RISCV && !config->shared) {
+    OutputSection *sec = findSection(".sdata");
     ElfSym::riscvGlobalPointer =
-        addOptionalRegular("__global_pointer$", findSection(".sdata"), 0x800,
-                           STV_DEFAULT, STB_GLOBAL);
+        addOptionalRegular("__global_pointer$", sec ? sec : Out::elfHeader,
+                           0x800, STV_DEFAULT, STB_GLOBAL);
+  }
 
   if (config->emachine == EM_X86_64) {
     // On targets that support TLSDESC, _TLS_MODULE_BASE_ is defined in such a
@@ -1881,7 +1880,6 @@ template <class ELFT> void Writer<ELFT>:
   finalizeSynthetic(in.plt);
   finalizeSynthetic(in.iplt);
   finalizeSynthetic(in.ppc32Got2);
-  finalizeSynthetic(in.riscvSdata);
   finalizeSynthetic(in.partIndex);
 
   // Dynamic section must be the last one in this list and dynamic

Removed: lld/trunk/test/ELF/riscv-gp-dummy-sdata.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/riscv-gp-dummy-sdata.s?rev=370171&view=auto
==============================================================================
--- lld/trunk/test/ELF/riscv-gp-dummy-sdata.s (original)
+++ lld/trunk/test/ELF/riscv-gp-dummy-sdata.s (removed)
@@ -1,25 +0,0 @@
-# REQUIRES: riscv
-# RUN: llvm-mc -filetype=obj -triple=riscv32 %s -o %t.32.o
-# RUN: ld.lld -pie %t.32.o -o %t.32
-# RUN: llvm-readelf -S %t.32 | FileCheck --check-prefix=SEC %s
-# RUN: llvm-readelf -s %t.32 | FileCheck --check-prefix=SYM %s
-
-# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.64.o
-# RUN: ld.lld -pie %t.64.o -o %t.64
-# RUN: llvm-readelf -S %t.64 | FileCheck --check-prefix=SEC %s
-# RUN: llvm-readelf -s %t.64 | FileCheck --check-prefix=SYM %s
-
-## If there is an undefined reference to __global_pointer$ but .sdata doesn't
-## exist, create a dummy one.
-
-## __global_pointer$ = .sdata+0x800
-# SEC: [ 7] .sdata PROGBITS {{0*}}00003000
-# SYM: {{0*}}00003800 0 NOTYPE GLOBAL DEFAULT 7 __global_pointer$
-
-## If __global_pointer$ is not used, don't create .sdata .
-
-# RUN: llvm-mc -filetype=obj -triple=riscv32 /dev/null -o %t.32.o
-# RUN: ld.lld -pie %t.32.o -o %t.32
-# RUN: llvm-readelf -S %t.32 | FileCheck --implicit-check-not=.sdata /dev/null
-
-lla gp, __global_pointer$

Added: lld/trunk/test/ELF/riscv-gp-no-sdata.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/riscv-gp-no-sdata.s?rev=370172&view=auto
==============================================================================
--- lld/trunk/test/ELF/riscv-gp-no-sdata.s (added)
+++ lld/trunk/test/ELF/riscv-gp-no-sdata.s Wed Aug 28 02:01:03 2019
@@ -0,0 +1,15 @@
+# REQUIRES: riscv
+# RUN: llvm-mc -filetype=obj -triple=riscv32 %s -o %t.32.o
+# RUN: ld.lld -pie %t.32.o -o %t.32
+# RUN: llvm-readelf -s %t.32 | FileCheck --check-prefix=SYM %s
+
+# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.64.o
+# RUN: ld.lld -pie %t.64.o -o %t.64
+# RUN: llvm-readelf -s %t.64 | FileCheck --check-prefix=SYM %s
+
+## If there is an undefined reference to __global_pointer$ but .sdata doesn't
+## exist, define __global_pointer$ and set its st_shndx arbitrarily to 1.
+
+# SYM: {{0*}}00000800 0 NOTYPE GLOBAL DEFAULT 1 __global_pointer$
+
+lla gp, __global_pointer$




More information about the llvm-commits mailing list