summaryrefslogtreecommitdiff
path: root/lib/MC/MCMachOStreamer.cpp
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2014-03-29 07:05:06 +0000
committerTim Northover <tnorthover@apple.com>2014-03-29 07:05:06 +0000
commitc5d592d5d250ee39fda0fe48899e952328995472 (patch)
tree9b4a285e816eff59e8aaa5475b02107b641925ce /lib/MC/MCMachOStreamer.cpp
parent42529ad33a84c64876a7f9a6eacf2905cbdcdc35 (diff)
downloadllvm-c5d592d5d250ee39fda0fe48899e952328995472.tar.gz
llvm-c5d592d5d250ee39fda0fe48899e952328995472.tar.bz2
llvm-c5d592d5d250ee39fda0fe48899e952328995472.tar.xz
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
Diffstat (limited to 'lib/MC/MCMachOStreamer.cpp')
-rw-r--r--lib/MC/MCMachOStreamer.cpp37
1 files changed, 33 insertions, 4 deletions
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<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;