[llvm] 70c52b6 - [MC] Export llvm::ELFObjectWriter

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 22 16:18:30 PDT 2024


Author: Fangrui Song
Date: 2024-07-22T16:18:25-07:00
New Revision: 70c52b62c5669993e341664a63bfbe5245e32884

URL: https://github.com/llvm/llvm-project/commit/70c52b62c5669993e341664a63bfbe5245e32884
DIFF: https://github.com/llvm/llvm-project/commit/70c52b62c5669993e341664a63bfbe5245e32884.diff

LOG: [MC] Export llvm::ELFObjectWriter

Similar to commit 28fcafb50274be2520117eacb0a886adafefe59d (2011) for
MachObjectWriter and commit 9539a7796094ff5fb59d9c685140ea2e214b945c for
WinCOFFObjectWriter.

MCELFStreamer can now access ELFObjectWriter directly without adding
ELF-specific markGnuAbi (https://reviews.llvm.org/D97976) and
setOverrideABIVersion to MCObjectWriter.

A few member variables have to be made public since we cannot use a
friend declaration for ELFWriter.

Added: 
    

Modified: 
    llvm/include/llvm/MC/MCELFObjectWriter.h
    llvm/include/llvm/MC/MCELFStreamer.h
    llvm/include/llvm/MC/MCObjectWriter.h
    llvm/lib/MC/ELFObjectWriter.cpp
    llvm/lib/MC/MCELFStreamer.cpp
    llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/MC/MCELFObjectWriter.h b/llvm/include/llvm/MC/MCELFObjectWriter.h
index 12237094ad86a..6b39dbf2b243f 100644
--- a/llvm/include/llvm/MC/MCELFObjectWriter.h
+++ b/llvm/include/llvm/MC/MCELFObjectWriter.h
@@ -9,6 +9,7 @@
 #ifndef LLVM_MC_MCELFOBJECTWRITER_H
 #define LLVM_MC_MCELFOBJECTWRITER_H
 
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/BinaryFormat/ELF.h"
 #include "llvm/MC/MCObjectWriter.h"
 #include "llvm/MC/MCSectionELF.h"
@@ -16,6 +17,8 @@
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/TargetParser/Triple.h"
 #include <cstdint>
+#include <memory>
+#include <optional>
 #include <vector>
 
 namespace llvm {
@@ -25,6 +28,7 @@ class MCContext;
 class MCFixup;
 class MCSymbol;
 class MCSymbolELF;
+class MCTargetOptions;
 class MCValue;
 
 struct ELFRelocationEntry {
@@ -149,6 +153,48 @@ class MCELFObjectTargetWriter : public MCObjectTargetWriter {
   }
 };
 
+class ELFObjectWriter : public MCObjectWriter {
+public:
+  std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter;
+  DenseMap<const MCSectionELF *, std::vector<ELFRelocationEntry>> Relocations;
+  DenseMap<const MCSymbolELF *, const MCSymbolELF *> Renames;
+  bool SeenGnuAbi = false;
+  std::optional<uint8_t> OverrideABIVersion;
+
+  ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW)
+      : TargetObjectWriter(std::move(MOTW)) {}
+
+  void reset() override;
+  void executePostLayoutBinding(MCAssembler &Asm) override;
+  void recordRelocation(MCAssembler &Asm, const MCFragment *Fragment,
+                        const MCFixup &Fixup, MCValue Target,
+                        uint64_t &FixedValue) override;
+  bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+                                              const MCSymbol &SymA,
+                                              const MCFragment &FB, bool InSet,
+                                              bool IsPCRel) const override;
+
+  bool hasRelocationAddend() const;
+  bool usesRela(const MCTargetOptions *TO, const MCSectionELF &Sec) const;
+
+  bool shouldRelocateWithSymbol(const MCAssembler &Asm, const MCValue &Val,
+                                const MCSymbolELF *Sym, uint64_t C,
+                                unsigned Type) const;
+
+  virtual bool checkRelocation(MCContext &Ctx, SMLoc Loc,
+                               const MCSectionELF *From,
+                               const MCSectionELF *To) {
+    return true;
+  }
+
+  // Mark that we have seen GNU ABI usage (e.g. SHF_GNU_RETAIN, STB_GNU_UNIQUE).
+  void markGnuAbi() { SeenGnuAbi = true; }
+  bool seenGnuAbi() const { return SeenGnuAbi; }
+
+  // Override the default e_ident[EI_ABIVERSION] in the ELF header.
+  void setOverrideABIVersion(uint8_t V) { OverrideABIVersion = V; }
+};
+
 /// Construct a new ELF writer instance.
 ///
 /// \param MOTW - The target specific ELF writer subclass.

diff  --git a/llvm/include/llvm/MC/MCELFStreamer.h b/llvm/include/llvm/MC/MCELFStreamer.h
index 1cd64e406d4d0..028bdd1a6bacf 100644
--- a/llvm/include/llvm/MC/MCELFStreamer.h
+++ b/llvm/include/llvm/MC/MCELFStreamer.h
@@ -11,6 +11,7 @@
 
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCELFObjectWriter.h"
 #include "llvm/MC/MCObjectStreamer.h"
 
 namespace llvm {
@@ -42,6 +43,8 @@ class MCELFStreamer : public MCObjectStreamer {
     MCObjectStreamer::reset();
   }
 
+  ELFObjectWriter &getWriter();
+
   /// \name MCStreamer Interface
   /// @{
 

diff  --git a/llvm/include/llvm/MC/MCObjectWriter.h b/llvm/include/llvm/MC/MCObjectWriter.h
index 01114469c241e..f207b823a3ef2 100644
--- a/llvm/include/llvm/MC/MCObjectWriter.h
+++ b/llvm/include/llvm/MC/MCObjectWriter.h
@@ -81,12 +81,6 @@ 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() {}
-
-  /// ELF only, override the default ABIVersion in the ELF header.
-  virtual void setOverrideABIVersion(uint8_t ABIVersion) {}
-
   /// 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 59d796b419b35..21f481de5b005 100644
--- a/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/llvm/lib/MC/ELFObjectWriter.cpp
@@ -67,7 +67,6 @@ using namespace llvm;
 
 namespace {
 
-class ELFObjectWriter;
 struct ELFWriter;
 
 bool isDwoSection(const MCSectionELF &Sec) {
@@ -200,64 +199,6 @@ struct ELFWriter {
                     const MCSectionELF &Section);
 };
 
-class ELFObjectWriter : public MCObjectWriter {
-  /// The target specific ELF writer instance.
-  std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter;
-
-  DenseMap<const MCSectionELF *, std::vector<ELFRelocationEntry>> Relocations;
-
-  DenseMap<const MCSymbolELF *, const MCSymbolELF *> Renames;
-
-  bool SeenGnuAbi = false;
-
-  std::optional<uint8_t> OverrideABIVersion;
-
-  bool hasRelocationAddend() const;
-
-  bool shouldRelocateWithSymbol(const MCAssembler &Asm, const MCValue &Val,
-                                const MCSymbolELF *Sym, uint64_t C,
-                                unsigned Type) const;
-
-public:
-  ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW)
-      : TargetObjectWriter(std::move(MOTW)) {}
-
-  void reset() override {
-    SeenGnuAbi = false;
-    OverrideABIVersion.reset();
-    Relocations.clear();
-    Renames.clear();
-    MCObjectWriter::reset();
-  }
-
-  bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
-                                              const MCSymbol &SymA,
-                                              const MCFragment &FB, bool InSet,
-                                              bool IsPCRel) const override;
-
-  virtual bool checkRelocation(MCContext &Ctx, SMLoc Loc,
-                               const MCSectionELF *From,
-                               const MCSectionELF *To) {
-    return true;
-  }
-
-  void recordRelocation(MCAssembler &Asm, const MCFragment *Fragment,
-                        const MCFixup &Fixup, MCValue Target,
-                        uint64_t &FixedValue) override;
-  bool usesRela(const MCTargetOptions *TO, const MCSectionELF &Sec) const;
-
-  void executePostLayoutBinding(MCAssembler &Asm) override;
-
-  void markGnuAbi() override { SeenGnuAbi = true; }
-  bool seenGnuAbi() const { return SeenGnuAbi; }
-
-  bool seenOverrideABIVersion() const { return OverrideABIVersion.has_value(); }
-  uint8_t getOverrideABIVersion() const { return OverrideABIVersion.value(); }
-  void setOverrideABIVersion(uint8_t V) override { OverrideABIVersion = V; }
-
-  friend struct ELFWriter;
-};
-
 class ELFSingleObjectWriter : public ELFObjectWriter {
   raw_pwrite_stream &OS;
   bool IsLittleEndian;
@@ -403,8 +344,8 @@ void ELFWriter::writeHeader(const MCAssembler &Asm) {
                    ? int(ELF::ELFOSABI_GNU)
                    : OSABI);
   // e_ident[EI_ABIVERSION]
-  W.OS << char(OWriter.seenOverrideABIVersion()
-                   ? OWriter.getOverrideABIVersion()
+  W.OS << char(OWriter.OverrideABIVersion
+                   ? *OWriter.OverrideABIVersion
                    : OWriter.TargetObjectWriter->getABIVersion());
 
   W.OS.write_zeros(ELF::EI_NIDENT - ELF::EI_PAD);
@@ -779,7 +720,7 @@ void ELFWriter::computeSymbolTable(MCAssembler &Asm,
 }
 
 void ELFWriter::writeAddrsigSection() {
-  for (const MCSymbol *Sym : OWriter.AddrsigSyms)
+  for (const MCSymbol *Sym : OWriter.getAddrsigSyms())
     if (Sym->getIndex() != 0)
       encodeULEB128(Sym->getIndex(), W.OS);
 }
@@ -1150,7 +1091,7 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm) {
     StrTabBuilder.finalize();
   } else {
     MCSectionELF *AddrsigSection;
-    if (OWriter.EmitAddrsigSection) {
+    if (OWriter.getEmitAddrsigSection()) {
       AddrsigSection = Ctx.getELFSection(".llvm_addrsig", ELF::SHT_LLVM_ADDRSIG,
                                          ELF::SHF_EXCLUDE);
       addToSectionTable(AddrsigSection);
@@ -1170,7 +1111,7 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm) {
       RelSection->setOffsets(SecStart, SecEnd);
     }
 
-    if (OWriter.EmitAddrsigSection) {
+    if (OWriter.getEmitAddrsigSection()) {
       uint64_t SecStart = W.OS.tell();
       writeAddrsigSection();
       uint64_t SecEnd = W.OS.tell();
@@ -1215,6 +1156,14 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm) {
   return W.OS.tell() - StartOffset;
 }
 
+void ELFObjectWriter::reset() {
+  SeenGnuAbi = false;
+  OverrideABIVersion.reset();
+  Relocations.clear();
+  Renames.clear();
+  MCObjectWriter::reset();
+}
+
 bool ELFObjectWriter::hasRelocationAddend() const {
   return TargetObjectWriter->hasRelocationAddend();
 }

diff  --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index 38ebaccf3b6ff..3ac0398c4a859 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -46,6 +46,10 @@ MCELFStreamer::MCELFStreamer(MCContext &Context,
     : MCObjectStreamer(Context, std::move(TAB), std::move(OW),
                        std::move(Emitter)) {}
 
+ELFObjectWriter &MCELFStreamer::getWriter() {
+  return static_cast<ELFObjectWriter &>(getAssembler().getWriter());
+}
+
 bool MCELFStreamer::isBundleLocked() const {
   return getCurrentSectionOnly()->isBundleLocked();
 }
@@ -120,7 +124,7 @@ void MCELFStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
   if (Grp)
     Asm.registerSymbol(*Grp);
   if (SectionELF->getFlags() & ELF::SHF_GNU_RETAIN)
-    Asm.getWriter().markGnuAbi();
+    getWriter().markGnuAbi();
 
   changeSectionImpl(Section, Subsection);
   Asm.registerSymbol(*Section->getBeginSymbol());
@@ -188,7 +192,7 @@ bool MCELFStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
   case MCSA_ELF_TypeGnuUniqueObject:
     Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_OBJECT));
     Symbol->setBinding(ELF::STB_GNU_UNIQUE);
-    getAssembler().getWriter().markGnuAbi();
+    getWriter().markGnuAbi();
     break;
 
   case MCSA_Global:
@@ -226,7 +230,7 @@ bool MCELFStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
 
   case MCSA_ELF_TypeIndFunction:
     Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_GNU_IFUNC));
-    getAssembler().getWriter().markGnuAbi();
+    getWriter().markGnuAbi();
     break;
 
   case MCSA_ELF_TypeObject:

diff  --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
index edc645103135b..2a1a4ba054c79 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
@@ -607,7 +607,7 @@ MCELFStreamer &AMDGPUTargetELFStreamer::getStreamer() {
 void AMDGPUTargetELFStreamer::finish() {
   MCAssembler &MCA = getStreamer().getAssembler();
   MCA.setELFHeaderEFlags(getEFlags());
-  MCA.getWriter().setOverrideABIVersion(
+  getStreamer().getWriter().setOverrideABIVersion(
       getELFABIVersion(STI.getTargetTriple(), CodeObjectVersion));
 
   std::string Blob;


        


More information about the llvm-commits mailing list