From c5d592d5d250ee39fda0fe48899e952328995472 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Sat, 29 Mar 2014 07:05:06 +0000 Subject: 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205081 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/MC/MCMachOStreamer.cpp | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) (limited to 'lib/MC/MCMachOStreamer.cpp') diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index c932c3c375..742f784649 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -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 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; -- cgit v1.2.3