[lld] r305218 - Allow the GNU gold-style nonstandard SHT_GROUP section.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 12 11:46:33 PDT 2017


Author: ruiu
Date: Mon Jun 12 13:46:33 2017
New Revision: 305218

URL: http://llvm.org/viewvc/llvm-project?rev=305218&view=rev
Log:
Allow the GNU gold-style nonstandard SHT_GROUP section.

The ELF standard defines that the SHT_GROUP section as follows:

 - its sh_link has the symbol index, and
 - the symbol name is used to uniquify section groups.

Object files created by GNU gold does not seem to comply with the
standard. They have this additional rule:

 - if the symbol has no name and a STT_SECTION symbol, a section
   name is used instead of a symbol name.

If we don't do anything for this, the linker fails with a mysterious
error message if input files are generated by gas. It is unfortunate
but I think we need to support it.

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

Added:
    lld/trunk/test/ELF/Inputs/sht-group-gold-r.elf   (with props)
    lld/trunk/test/ELF/Inputs/sht-group-gold-r.s
    lld/trunk/test/ELF/sht-group-gold-r.test
Modified:
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/InputFiles.h

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=305218&r1=305217&r2=305218&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Mon Jun 12 13:46:33 2017
@@ -205,13 +205,27 @@ template <class ELFT>
 StringRef
 elf::ObjectFile<ELFT>::getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,
                                             const Elf_Shdr &Sec) {
+  // Group signatures are stored as symbol names in object files.
+  // sh_info contains a symbol index, so we fetch a symbol and read its name.
   if (this->Symbols.empty())
     this->initSymtab(
         Sections,
         check(object::getSection<ELFT>(Sections, Sec.sh_link), toString(this)));
+
   const Elf_Sym *Sym = check(
       object::getSymbol<ELFT>(this->Symbols, Sec.sh_info), toString(this));
-  return check(Sym->getName(this->StringTable), toString(this));
+  StringRef Signature = check(Sym->getName(this->StringTable), toString(this));
+
+  // As a special case, if a symbol is a section symbol and has no name,
+  // we use a section name as a signature.
+  //
+  // Such SHT_GROUP sections are invalid from the perspective of the ELF
+  // standard, but GNU gold 1.14 (the neweset version as of July 2017) or
+  // older produce such sections as outputs for the -r option, so we need
+  // a bug-compatibility.
+  if (Signature.empty() && Sym->getType() == STT_SECTION)
+    return getSectionName(Sec);
+  return Signature;
 }
 
 template <class ELFT>
@@ -287,8 +301,7 @@ void elf::ObjectFile<ELFT>::initializeSe
       check(this->getObj().sections(), toString(this));
   uint64_t Size = ObjSections.size();
   this->Sections.resize(Size);
-
-  StringRef SectionStringTable =
+  this->SectionStringTable =
       check(Obj.getSectionStringTable(ObjSections), toString(this));
 
   for (size_t I = 0, E = ObjSections.size(); I < E; I++) {
@@ -318,7 +331,7 @@ void elf::ObjectFile<ELFT>::initializeSe
       // object files, we want to pass through basically everything.
       if (IsNew) {
         if (Config->Relocatable)
-          this->Sections[I] = createInputSection(Sec, SectionStringTable);
+          this->Sections[I] = createInputSection(Sec);
         continue;
       }
 
@@ -342,7 +355,7 @@ void elf::ObjectFile<ELFT>::initializeSe
     case SHT_NULL:
       break;
     default:
-      this->Sections[I] = createInputSection(Sec, SectionStringTable);
+      this->Sections[I] = createInputSection(Sec);
     }
 
     // .ARM.exidx sections have a reverse dependency on the InputSection they
@@ -386,10 +399,8 @@ InputSectionBase *toRegularSection(Merge
 
 template <class ELFT>
 InputSectionBase *
-elf::ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec,
-                                          StringRef SectionStringTable) {
-  StringRef Name = check(
-      this->getObj().getSectionName(&Sec, SectionStringTable), toString(this));
+elf::ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
+  StringRef Name = getSectionName(Sec);
 
   switch (Sec.sh_type) {
   case SHT_ARM_ATTRIBUTES:
@@ -521,6 +532,12 @@ elf::ObjectFile<ELFT>::createInputSectio
   return make<InputSection>(this, &Sec, Name);
 }
 
+template <class ELFT>
+StringRef elf::ObjectFile<ELFT>::getSectionName(const Elf_Shdr &Sec) {
+  return check(this->getObj().getSectionName(&Sec, SectionStringTable),
+               toString(this));
+}
+
 template <class ELFT> void elf::ObjectFile<ELFT>::initializeSymbols() {
   SymbolBodies.reserve(this->Symbols.size());
   for (const Elf_Sym &Sym : this->Symbols)

Modified: lld/trunk/ELF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=305218&r1=305217&r2=305218&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.h (original)
+++ lld/trunk/ELF/InputFiles.h Mon Jun 12 13:46:33 2017
@@ -194,8 +194,8 @@ private:
   void initializeSymbols();
   void initializeDwarfLine();
   InputSectionBase *getRelocTarget(const Elf_Shdr &Sec);
-  InputSectionBase *createInputSection(const Elf_Shdr &Sec,
-                                       StringRef SectionStringTable);
+  InputSectionBase *createInputSection(const Elf_Shdr &Sec);
+  StringRef getSectionName(const Elf_Shdr &Sec);
 
   bool shouldMerge(const Elf_Shdr &Sec);
   SymbolBody *createSymbolBody(const Elf_Sym *Sym);
@@ -203,6 +203,9 @@ private:
   // List of all symbols referenced or defined by this file.
   std::vector<SymbolBody *> SymbolBodies;
 
+  // .shstrtab contents.
+  StringRef SectionStringTable;
+
   // Debugging information to retrieve source file and line for error
   // reporting. Linker may find reasonable number of errors in a
   // single object file, so we cache debugging information in order to

Added: lld/trunk/test/ELF/Inputs/sht-group-gold-r.elf
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/sht-group-gold-r.elf?rev=305218&view=auto
==============================================================================
Binary file - no diff available.

Propchange: lld/trunk/test/ELF/Inputs/sht-group-gold-r.elf
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: lld/trunk/test/ELF/Inputs/sht-group-gold-r.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/sht-group-gold-r.s?rev=305218&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/sht-group-gold-r.s (added)
+++ lld/trunk/test/ELF/Inputs/sht-group-gold-r.s Mon Jun 12 13:46:33 2017
@@ -0,0 +1,14 @@
+# sht-group-gold-r.elf is produced by
+#
+#   llvm-mc -filetype=obj -triple=x86_64-pc-linux sht-group-gold-r.s -o sht-group-gold-r.o
+#   ld.gold -o sht-group-gold-r.elf -r sht-group-gold-r.o
+
+.global foo, bar
+
+.section .text.foo,"aG", at progbits,group_foo,comdat
+foo:
+  nop
+
+.section .text.bar,"aG", at progbits,group_bar,comdat
+bar:
+  nop

Added: lld/trunk/test/ELF/sht-group-gold-r.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/sht-group-gold-r.test?rev=305218&view=auto
==============================================================================
--- lld/trunk/test/ELF/sht-group-gold-r.test (added)
+++ lld/trunk/test/ELF/sht-group-gold-r.test Mon Jun 12 13:46:33 2017
@@ -0,0 +1,17 @@
+# GNU gold 1.14 (the newest version as of July 2017) seems to create
+# non-standard-compliant SHT_GROUP sections when the -r option is given.
+#
+# Such SHT_GROUP sections use section names as their signatures
+# instead of symbols pointed by sh_link field. Since it is prevalent,
+# we accept such nonstandard sections.
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld %p/Inputs/sht-group-gold-r.elf %t.o -o %t.exe
+# RUN: llvm-objdump -t %t.exe | FileCheck %s
+
+# CHECK: .text 00000000 bar
+# CHECK: .text 00000000 foo
+
+.globl _start
+_start:
+  ret




More information about the llvm-commits mailing list