[llvm] 42e3f97 - [MC] Change ELFOSABI_NONE to ELFOSABI_GNU for SHF_GNU_RETAIN

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 9 09:59:52 PST 2021


Author: Fangrui Song
Date: 2021-03-09T09:59:47-08:00
New Revision: 42e3f97a9dd3a439f63a733c4ee909cba6b77e49

URL: https://github.com/llvm/llvm-project/commit/42e3f97a9dd3a439f63a733c4ee909cba6b77e49
DIFF: https://github.com/llvm/llvm-project/commit/42e3f97a9dd3a439f63a733c4ee909cba6b77e49.diff

LOG: [MC] Change ELFOSABI_NONE to ELFOSABI_GNU for SHF_GNU_RETAIN

GNU ld does not give SHF_GNU_RETAIN GC root semantics for ELFOSABI_NONE.
(https://sourceware.org/pipermail/binutils/2021-March/115581.html)

This allows GNU ld to interpret SHF_GNU_RETAIN and avoids a gold quirk
https://sourceware.org/bugzilla/show_bug.cgi?id=27490

Because ELFObjectWriter is in an anonymous namespace, I have to place
`markGnuAbi` in the parent MCObjectWriter.

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

Added: 
    

Modified: 
    lld/test/ELF/gc-sections-retain.s
    llvm/include/llvm/MC/MCObjectWriter.h
    llvm/lib/MC/ELFObjectWriter.cpp
    llvm/lib/MC/MCELFStreamer.cpp
    llvm/test/MC/ELF/section-gnu.s

Removed: 
    


################################################################################
diff  --git a/lld/test/ELF/gc-sections-retain.s b/lld/test/ELF/gc-sections-retain.s
index edde321754ab..196fc73fa0d4 100644
--- a/lld/test/ELF/gc-sections-retain.s
+++ b/lld/test/ELF/gc-sections-retain.s
@@ -8,11 +8,6 @@
 # RUN: ld.lld -r -e _start --gc-sections --print-gc-sections %t.o -o %t.ro | count 0
 # RUN: llvm-readobj -hS %t.ro | FileCheck %s
 
-## SHF_GNU_RETAIN has no significance in executables/shared objects. Multiple
-## OSABI values can benefit from this flag. Test that we don't change EI_OSABI,
-## even for relocatable output.
-# CHECK:       OS/ABI: SystemV (0x0)
-
 # CHECK:      Name: .retain
 # CHECK-NEXT: Type: SHT_PROGBITS
 # CHECK-NEXT: Flags [

diff  --git a/llvm/include/llvm/MC/MCObjectWriter.h b/llvm/include/llvm/MC/MCObjectWriter.h
index ddc2301c04c1..d2a2f1a13ff5 100644
--- a/llvm/include/llvm/MC/MCObjectWriter.h
+++ b/llvm/include/llvm/MC/MCObjectWriter.h
@@ -85,6 +85,9 @@ class MCObjectWriter {
                                                       bool InSet,
                                                       bool IsPCRel) const;
 
+  /// ELF only. Mark that we have seen GNU ABI usage (e.g. SHF_GNU_RETAIN).
+  virtual void markGnuAbi() {}
+
   /// Tell the object writer to emit an address-significance table during
   /// writeObject(). If this function is not called, all symbols are treated as
   /// address-significant.

diff  --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp
index e635a47680da..b837e6e53305 100644
--- a/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/llvm/lib/MC/ELFObjectWriter.cpp
@@ -222,6 +222,7 @@ class ELFObjectWriter : public MCObjectWriter {
 
   DenseMap<const MCSymbolELF *, const MCSymbolELF *> Renames;
 
+  bool SeenGnuAbi = false;
   bool EmitAddrsigSection = false;
   std::vector<const MCSymbol *> AddrsigSyms;
 
@@ -237,6 +238,7 @@ class ELFObjectWriter : public MCObjectWriter {
       : TargetObjectWriter(std::move(MOTW)) {}
 
   void reset() override {
+    SeenGnuAbi = false;
     Relocations.clear();
     Renames.clear();
     MCObjectWriter::reset();
@@ -260,6 +262,8 @@ class ELFObjectWriter : public MCObjectWriter {
   void executePostLayoutBinding(MCAssembler &Asm,
                                 const MCAsmLayout &Layout) override;
 
+  void markGnuAbi() override { SeenGnuAbi = true; }
+  bool seenGnuAbi() const { return SeenGnuAbi; }
   void emitAddrsigSection() override { EmitAddrsigSection = true; }
   void addAddrsigSymbol(const MCSymbol *Sym) override {
     AddrsigSyms.push_back(Sym);
@@ -412,7 +416,10 @@ void ELFWriter::writeHeader(const MCAssembler &Asm) {
 
   W.OS << char(ELF::EV_CURRENT);        // e_ident[EI_VERSION]
   // e_ident[EI_OSABI]
-  W.OS << char(OWriter.TargetObjectWriter->getOSABI());
+  uint8_t OSABI = OWriter.TargetObjectWriter->getOSABI();
+  W.OS << char(OSABI == ELF::ELFOSABI_NONE && OWriter.seenGnuAbi()
+                   ? ELF::ELFOSABI_GNU
+                   : OSABI);
   // e_ident[EI_ABIVERSION]
   W.OS << char(OWriter.TargetObjectWriter->getABIVersion());
 

diff  --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index 12a8575a5f72..5a6c042333dc 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -156,6 +156,8 @@ void MCELFStreamer::changeSection(MCSection *Section,
   const MCSymbol *Grp = SectionELF->getGroup();
   if (Grp)
     Asm.registerSymbol(*Grp);
+  if (SectionELF->getFlags() & ELF::SHF_GNU_RETAIN)
+    Asm.getWriter().markGnuAbi();
 
   changeSectionImpl(Section, Subsection);
   Asm.registerSymbol(*Section->getBeginSymbol());

diff  --git a/llvm/test/MC/ELF/section-gnu.s b/llvm/test/MC/ELF/section-gnu.s
index 5fc72d99a971..67a09a62d485 100644
--- a/llvm/test/MC/ELF/section-gnu.s
+++ b/llvm/test/MC/ELF/section-gnu.s
@@ -1,10 +1,12 @@
 # RUN: llvm-mc -triple=x86_64 %s | FileCheck %s --check-prefix=ASM
-# RUN: llvm-mc -filetype=obj -triple=x86_64 %s | llvm-readobj -hS - | FileCheck %s --check-prefix=OBJ
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %s | llvm-readobj -hS - | FileCheck %s --check-prefixes=GNU,OBJ
+# RUN: llvm-mc -filetype=obj -triple=aarch64-freebsd %s | llvm-readobj -hS - | FileCheck %s --check-prefixes=FREEBSD,OBJ
 
 # ASM: .section retain,"aR", at progbits
 
-## Note: GNU as sets OSABI to GNU.
-# OBJ:      OS/ABI: SystemV (0x0)
+## ELFOSABI_NONE is changed to ELFOSABI_GNU. Other OSABI values are unchanged.
+# GNU:      OS/ABI: GNU/Linux
+# FREEBSD:  OS/ABI: FreeBSD
 
 # OBJ:      Name: retain
 # OBJ-NEXT: Type: SHT_PROGBITS


        


More information about the llvm-commits mailing list