summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/MC/MCAsmInfo.h15
-rw-r--r--include/llvm/MC/MCContext.h4
-rw-r--r--include/llvm/MC/MCStreamer.h3
-rw-r--r--lib/MC/MCAsmInfo.cpp1
-rw-r--r--lib/MC/MCContext.cpp7
-rw-r--r--lib/MC/MCMachOStreamer.cpp37
6 files changed, 62 insertions, 5 deletions
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h
index 724c3d7f38..037a24f85b 100644
--- a/include/llvm/MC/MCAsmInfo.h
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -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;
}
diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h
index afb94f07bd..b276b1f83e 100644
--- a/include/llvm/MC/MCContext.h
+++ b/include/llvm/MC/MCContext.h
@@ -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();
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index 37d586b8f1..9fe6da96b6 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -758,7 +758,8 @@ MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
/// 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.
diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp
index c78d3d574a..966714592a 100644
--- a/lib/MC/MCAsmInfo.cpp
+++ b/lib/MC/MCAsmInfo.cpp
@@ -41,6 +41,7 @@ MCAsmInfo::MCAsmInfo() {
LabelSuffix = ":";
DebugLabelSuffix = ":";
PrivateGlobalPrefix = "L";
+ LinkerPrivateGlobalPrefix = "";
InlineAsmStart = "APP";
InlineAsmEnd = "NO_APP";
Code16Directive = ".code16";
diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp
index fdedec1031..73ffdc0a4b 100644
--- a/lib/MC/MCContext.cpp
+++ b/lib/MC/MCContext.cpp
@@ -153,6 +153,13 @@ MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) {
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)
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;