[llvm] r205081 - MachO: allow each section to have a linker-private symbol

Tim Northover tnorthover at apple.com
Sat Mar 29 00:05:07 PDT 2014


Author: tnorthover
Date: Sat Mar 29 02:05:06 2014
New Revision: 205081

URL: http://llvm.org/viewvc/llvm-project?rev=205081&view=rev
Log:
MachO: allow each section to have a linker-private symbol

The upcoming ARM64 backend doesn't have section-relative relocations,
so we give each section its own symbol to provide this functionality.
Of course, it doesn't need to appear in the final executable, so
linker-private is the best kind for this purpose.

Modified:
    llvm/trunk/include/llvm/MC/MCAsmInfo.h
    llvm/trunk/include/llvm/MC/MCContext.h
    llvm/trunk/include/llvm/MC/MCStreamer.h
    llvm/trunk/lib/MC/MCAsmInfo.cpp
    llvm/trunk/lib/MC/MCContext.cpp
    llvm/trunk/lib/MC/MCMachOStreamer.cpp

Modified: llvm/trunk/include/llvm/MC/MCAsmInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAsmInfo.h?rev=205081&r1=205080&r2=205081&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCAsmInfo.h (original)
+++ llvm/trunk/include/llvm/MC/MCAsmInfo.h Sat Mar 29 02:05:06 2014
@@ -116,6 +116,13 @@ namespace llvm {
     /// file.
     const char *PrivateGlobalPrefix;         // Defaults to "L"
 
+    /// This prefix is used for symbols that should be passed through the
+    /// assembler but be removed by the linker.  This is 'l' on Darwin,
+    /// currently used for some ObjC metadata.
+    /// The default of "" meast that for this system a plain private symbol
+    /// should be used.
+    const char *LinkerPrivateGlobalPrefix;    // Defaults to "".
+
     /// InlineAsmStart/End - If these are nonempty, they contain a directive to
     /// emit before and after an inline assembly statement.
     const char *InlineAsmStart;              // Defaults to "#APP\n"
@@ -425,6 +432,14 @@ namespace llvm {
     const char *getPrivateGlobalPrefix() const {
       return PrivateGlobalPrefix;
     }
+    bool hasLinkerPrivateGlobalPrefix() const {
+      return LinkerPrivateGlobalPrefix[0] != '\0';
+    }
+    const char *getLinkerPrivateGlobalPrefix() const {
+      if (hasLinkerPrivateGlobalPrefix())
+        return LinkerPrivateGlobalPrefix;
+      return getPrivateGlobalPrefix();
+    }
     const char *getInlineAsmStart() const {
       return InlineAsmStart;
     }

Modified: llvm/trunk/include/llvm/MC/MCContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCContext.h?rev=205081&r1=205080&r2=205081&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCContext.h (original)
+++ llvm/trunk/include/llvm/MC/MCContext.h Sat Mar 29 02:05:06 2014
@@ -193,6 +193,10 @@ namespace llvm {
     /// @name Symbol Management
     /// @{
 
+    /// CreateLinkerPrivateTempSymbol - Create and return a new linker temporary
+    /// symbol with a unique but unspecified name.
+    MCSymbol *CreateLinkerPrivateTempSymbol();
+
     /// CreateTempSymbol - Create and return a new assembler temporary symbol
     /// with a unique but unspecified name.
     MCSymbol *CreateTempSymbol();

Modified: llvm/trunk/include/llvm/MC/MCStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=205081&r1=205080&r2=205081&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCStreamer.h (original)
+++ llvm/trunk/include/llvm/MC/MCStreamer.h Sat Mar 29 02:05:06 2014
@@ -758,7 +758,8 @@ MCStreamer *createAsmStreamer(MCContext
 /// Takes ownership of \p TAB and \p CE.
 MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB,
                                 raw_ostream &OS, MCCodeEmitter *CE,
-                                bool RelaxAll = false);
+                                bool RelaxAll = false,
+                                bool LabelSections = false);
 
 /// createWinCOFFStreamer - Create a machine code streamer which will
 /// generate Microsoft COFF format object files.

Modified: llvm/trunk/lib/MC/MCAsmInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmInfo.cpp?rev=205081&r1=205080&r2=205081&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAsmInfo.cpp (original)
+++ llvm/trunk/lib/MC/MCAsmInfo.cpp Sat Mar 29 02:05:06 2014
@@ -41,6 +41,7 @@ MCAsmInfo::MCAsmInfo() {
   LabelSuffix = ":";
   DebugLabelSuffix = ":";
   PrivateGlobalPrefix = "L";
+  LinkerPrivateGlobalPrefix = "";
   InlineAsmStart = "APP";
   InlineAsmEnd = "NO_APP";
   Code16Directive = ".code16";

Modified: llvm/trunk/lib/MC/MCContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCContext.cpp?rev=205081&r1=205080&r2=205081&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCContext.cpp (original)
+++ llvm/trunk/lib/MC/MCContext.cpp Sat Mar 29 02:05:06 2014
@@ -153,6 +153,13 @@ MCSymbol *MCContext::GetOrCreateSymbol(c
   return GetOrCreateSymbol(Name.toStringRef(NameSV));
 }
 
+MCSymbol *MCContext::CreateLinkerPrivateTempSymbol() {
+  SmallString<128> NameSV;
+  raw_svector_ostream(NameSV)
+    << MAI->getLinkerPrivateGlobalPrefix() << "tmp" << NextUniqueID++;
+  return CreateSymbol(NameSV);
+}
+
 MCSymbol *MCContext::CreateTempSymbol() {
   SmallString<128> NameSV;
   raw_svector_ostream(NameSV)

Modified: llvm/trunk/lib/MC/MCMachOStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCMachOStreamer.cpp?rev=205081&r1=205080&r2=205081&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCMachOStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCMachOStreamer.cpp Sat Mar 29 02:05:06 2014
@@ -8,6 +8,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/MC/MCStreamer.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/MC/MCAsmBackend.h"
 #include "llvm/MC/MCAssembler.h"
 #include "llvm/MC/MCCodeEmitter.h"
@@ -31,18 +33,31 @@ namespace {
 
 class MCMachOStreamer : public MCObjectStreamer {
 private:
+  /// LabelSections - true if each section change should emit a linker local
+  /// label for use in relocations for assembler local references. Obviates the
+  /// need for local relocations. False by default.
+  bool LabelSections;
+
+  /// HasSectionLabel - map of which sections have already had a non-local
+  /// label emitted to them. Used so we don't emit extraneous linker local
+  /// labels in the middle of the section.
+  DenseMap<const MCSection*, bool> HasSectionLabel;
+
   void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) override;
 
   void EmitDataRegion(DataRegionData::KindTy Kind);
   void EmitDataRegionEnd();
+
 public:
   MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS,
-                  MCCodeEmitter *Emitter)
-      : MCObjectStreamer(Context, MAB, OS, Emitter) {}
+                  MCCodeEmitter *Emitter, bool label)
+      : MCObjectStreamer(Context, MAB, OS, Emitter),
+        LabelSections(label) {}
 
   /// @name MCStreamer Interface
   /// @{
 
+  void ChangeSection(const MCSection *Sect, const MCExpr *Subsect) override;
   void EmitLabel(MCSymbol *Symbol) override;
   void EmitDebugLabel(MCSymbol *Symbol) override;
   void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol) override;
@@ -94,6 +109,19 @@ public:
 
 } // end anonymous namespace.
 
+void MCMachOStreamer::ChangeSection(const MCSection *Section,
+                                    const MCExpr *Subsection) {
+  // Change the section normally.
+  MCObjectStreamer::ChangeSection(Section, Subsection);
+  // Output a linker-local symbol so we don't need section-relative local
+  // relocations. The linker hates us when we do that.
+  if (LabelSections && !HasSectionLabel[Section]) {
+    MCSymbol *Label = getContext().CreateLinkerPrivateTempSymbol();
+    EmitLabel(Label);
+    HasSectionLabel[Section] = true;
+  }
+}
+
 void MCMachOStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
                                           MCSymbol *EHSymbol) {
   MCSymbolData &SD =
@@ -425,8 +453,9 @@ void MCMachOStreamer::FinishImpl() {
 
 MCStreamer *llvm::createMachOStreamer(MCContext &Context, MCAsmBackend &MAB,
                                       raw_ostream &OS, MCCodeEmitter *CE,
-                                      bool RelaxAll) {
-  MCMachOStreamer *S = new MCMachOStreamer(Context, MAB, OS, CE);
+                                      bool RelaxAll,
+                                      bool LabelSections) {
+  MCMachOStreamer *S = new MCMachOStreamer(Context, MAB, OS, CE, LabelSections);
   if (RelaxAll)
     S->getAssembler().setRelaxAll(true);
   return S;





More information about the llvm-commits mailing list