summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/MC/MCObjectStreamer.h2
-rw-r--r--llvm/include/llvm/Support/TargetRegistry.h20
-rw-r--r--llvm/lib/CodeGen/LLVMTargetMachine.cpp6
-rw-r--r--llvm/lib/MC/MCMachOStreamer.cpp49
-rw-r--r--llvm/lib/MC/MCObjectStreamer.cpp9
-rw-r--r--llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp4
-rw-r--r--llvm/lib/Target/ARM/ARMAsmPrinter.cpp59
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp6
-rw-r--r--llvm/test/CodeGen/ARM/darwin-section-order.ll21
-rw-r--r--llvm/test/CodeGen/ARM/none-macho.ll5
-rw-r--r--llvm/test/DebugInfo/ARM/header.ll30
-rw-r--r--llvm/test/DebugInfo/ARM/sectionorder.ll18
-rw-r--r--llvm/tools/dsymutil/DwarfLinker.cpp3
-rw-r--r--llvm/tools/llvm-mc/llvm-mc.cpp3
14 files changed, 108 insertions, 127 deletions
diff --git a/llvm/include/llvm/MC/MCObjectStreamer.h b/llvm/include/llvm/MC/MCObjectStreamer.h
index 100029f3aae..24200724c62 100644
--- a/llvm/include/llvm/MC/MCObjectStreamer.h
+++ b/llvm/include/llvm/MC/MCObjectStreamer.h
@@ -85,6 +85,8 @@ protected:
/// fragment is not a data fragment.
MCDataFragment *getOrCreateDataFragment();
+ bool changeSectionImpl(const MCSection *Section, const MCExpr *Subsection);
+
public:
void visitUsedSymbol(const MCSymbol &Sym) override;
diff --git a/llvm/include/llvm/Support/TargetRegistry.h b/llvm/include/llvm/Support/TargetRegistry.h
index bad1e5146b1..26134e4eecb 100644
--- a/llvm/include/llvm/Support/TargetRegistry.h
+++ b/llvm/include/llvm/Support/TargetRegistry.h
@@ -65,7 +65,8 @@ namespace llvm {
bool RelaxAll);
MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *CE,
- bool RelaxAll, bool LabelSections = false);
+ bool RelaxAll, bool DWARFMustBeAtTheEnd,
+ bool LabelSections = false);
MCRelocationInfo *createMCRelocationInfo(StringRef TT, MCContext &Ctx);
@@ -138,11 +139,9 @@ namespace llvm {
MCAsmBackend &TAB, raw_ostream &OS,
MCCodeEmitter *Emitter,
bool RelaxAll);
- typedef MCStreamer *(*MachOStreamerCtorTy)(MCContext &Ctx,
- MCAsmBackend &TAB,
- raw_ostream &OS,
- MCCodeEmitter *Emitter,
- bool RelaxAll);
+ typedef MCStreamer *(*MachOStreamerCtorTy)(
+ MCContext &Ctx, MCAsmBackend &TAB, raw_ostream &OS,
+ MCCodeEmitter *Emitter, bool RelaxAll, bool DWARFMustBeAtTheEnd);
typedef MCStreamer *(*COFFStreamerCtorTy)(MCContext &Ctx, MCAsmBackend &TAB,
raw_ostream &OS,
MCCodeEmitter *Emitter,
@@ -444,7 +443,8 @@ namespace llvm {
MCAsmBackend &TAB, raw_ostream &OS,
MCCodeEmitter *Emitter,
const MCSubtargetInfo &STI,
- bool RelaxAll) const {
+ bool RelaxAll,
+ bool DWARFMustBeAtTheEnd) const {
MCStreamer *S;
switch (T.getObjectFormat()) {
default:
@@ -455,9 +455,11 @@ namespace llvm {
break;
case Triple::MachO:
if (MachOStreamerCtorFn)
- S = MachOStreamerCtorFn(Ctx, TAB, OS, Emitter, RelaxAll);
+ S = MachOStreamerCtorFn(Ctx, TAB, OS, Emitter, RelaxAll,
+ DWARFMustBeAtTheEnd);
else
- S = createMachOStreamer(Ctx, TAB, OS, Emitter, RelaxAll);
+ S = createMachOStreamer(Ctx, TAB, OS, Emitter, RelaxAll,
+ DWARFMustBeAtTheEnd);
break;
case Triple::ELF:
if (ELFStreamerCtorFn)
diff --git a/llvm/lib/CodeGen/LLVMTargetMachine.cpp b/llvm/lib/CodeGen/LLVMTargetMachine.cpp
index f463f70d3e6..0fb0c46ddb1 100644
--- a/llvm/lib/CodeGen/LLVMTargetMachine.cpp
+++ b/llvm/lib/CodeGen/LLVMTargetMachine.cpp
@@ -202,7 +202,8 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
Triple T(getTargetTriple());
AsmStreamer.reset(getTarget().createMCObjectStreamer(
- T, *Context, *MAB, Out, MCE, STI, Options.MCOptions.MCRelaxAll));
+ T, *Context, *MAB, Out, MCE, STI, Options.MCOptions.MCRelaxAll,
+ /*DWARFMustBeAtTheEnd*/ true));
break;
}
case CGFT_Null:
@@ -253,7 +254,8 @@ bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM,
Triple T(getTargetTriple());
const MCSubtargetInfo &STI = *getMCSubtargetInfo();
std::unique_ptr<MCStreamer> AsmStreamer(getTarget().createMCObjectStreamer(
- T, *Ctx, *MAB, Out, MCE, STI, Options.MCOptions.MCRelaxAll));
+ T, *Ctx, *MAB, Out, MCE, STI, Options.MCOptions.MCRelaxAll,
+ /*DWARFMustBeAtTheEnd*/ true));
// Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
FunctionPass *Printer =
diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp
index 6246ed01ab7..d5c7101d0d5 100644
--- a/llvm/lib/MC/MCMachOStreamer.cpp
+++ b/llvm/lib/MC/MCMachOStreamer.cpp
@@ -40,6 +40,9 @@ private:
/// need for local relocations. False by default.
bool LabelSections;
+ bool DWARFMustBeAtTheEnd;
+ bool CreatedADWARFSection;
+
/// 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.
@@ -52,9 +55,9 @@ private:
public:
MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS,
- MCCodeEmitter *Emitter, bool label)
- : MCObjectStreamer(Context, MAB, OS, Emitter),
- LabelSections(label) {}
+ MCCodeEmitter *Emitter, bool DWARFMustBeAtTheEnd, bool label)
+ : MCObjectStreamer(Context, MAB, OS, Emitter), LabelSections(label),
+ DWARFMustBeAtTheEnd(DWARFMustBeAtTheEnd), CreatedADWARFSection(false) {}
/// state management
void reset() override {
@@ -120,10 +123,43 @@ public:
} // end anonymous namespace.
+static bool canGoAfterDWARF(const MCSectionMachO &MSec) {
+ // These sections are created by the assembler itself after the end of
+ // the .s file.
+ StringRef SegName = MSec.getSegmentName();
+ StringRef SecName = MSec.getSectionName();
+
+ if (SegName == "__LD" && SecName == "__compact_unwind")
+ return true;
+
+ if (SegName == "__IMPORT") {
+ if (SecName == "__jump_table")
+ return true;
+
+ if (SecName == "__pointers")
+ return true;
+ }
+
+ if (SegName == "__TEXT" && SecName == "__eh_frame")
+ return true;
+
+ if (SegName == "__DATA" && SecName == "__nl_symbol_ptr")
+ return true;
+
+ return false;
+}
+
void MCMachOStreamer::ChangeSection(const MCSection *Section,
const MCExpr *Subsection) {
// Change the section normally.
- MCObjectStreamer::ChangeSection(Section, Subsection);
+ bool Created = MCObjectStreamer::changeSectionImpl(Section, Subsection);
+ const MCSectionMachO &MSec = *cast<MCSectionMachO>(Section);
+ StringRef SegName = MSec.getSegmentName();
+ if (SegName == "__DWARF")
+ CreatedADWARFSection = true;
+ else if (Created && DWARFMustBeAtTheEnd && !canGoAfterDWARF(MSec))
+ assert(!CreatedADWARFSection && "Creating regular section after DWARF");
+
// 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]) {
@@ -456,9 +492,10 @@ void MCMachOStreamer::FinishImpl() {
MCStreamer *llvm::createMachOStreamer(MCContext &Context, MCAsmBackend &MAB,
raw_ostream &OS, MCCodeEmitter *CE,
- bool RelaxAll,
+ bool RelaxAll, bool DWARFMustBeAtTheEnd,
bool LabelSections) {
- MCMachOStreamer *S = new MCMachOStreamer(Context, MAB, OS, CE, LabelSections);
+ MCMachOStreamer *S = new MCMachOStreamer(Context, MAB, OS, CE,
+ DWARFMustBeAtTheEnd, LabelSections);
if (RelaxAll)
S->getAssembler().setRelaxAll(true);
return S;
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index 5b6b6b5facf..6aa2de36db6 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -182,10 +182,16 @@ void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
void MCObjectStreamer::ChangeSection(const MCSection *Section,
const MCExpr *Subsection) {
+ changeSectionImpl(Section, Subsection);
+}
+
+bool MCObjectStreamer::changeSectionImpl(const MCSection *Section,
+ const MCExpr *Subsection) {
assert(Section && "Cannot switch to a null section!");
flushPendingLabels(nullptr);
- CurSectionData = &getAssembler().getOrCreateSectionData(*Section);
+ bool Created;
+ CurSectionData = &getAssembler().getOrCreateSectionData(*Section, &Created);
int64_t IntSubsection = 0;
if (Subsection &&
@@ -195,6 +201,7 @@ void MCObjectStreamer::ChangeSection(const MCSection *Section,
report_fatal_error("Subsection number out of range");
CurInsertionPoint =
CurSectionData->getSubsectionInsertionPoint(unsigned(IntSubsection));
+ return Created;
}
void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp
index 1a72b79a291..38b399d5da4 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp
@@ -131,8 +131,10 @@ static MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx,
static MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *Emitter,
- bool RelaxAll) {
+ bool RelaxAll,
+ bool DWARFMustBeAtTheEnd) {
return createMachOStreamer(Ctx, TAB, OS, Emitter, RelaxAll,
+ DWARFMustBeAtTheEnd,
/*LabelSections*/ true);
}
diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
index e3c9dcbf72b..971e10df8b9 100644
--- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
+++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
@@ -435,65 +435,6 @@ void ARMAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
Triple TT(TM.getTargetTriple());
- if (TT.isOSBinFormatMachO()) {
- Reloc::Model RelocM = TM.getRelocationModel();
- if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) {
- // Declare all the text sections up front (before the DWARF sections
- // emitted by AsmPrinter::doInitialization) so the assembler will keep
- // them together at the beginning of the object file. This helps
- // avoid out-of-range branches that are due a fundamental limitation of
- // the way symbol offsets are encoded with the current Darwin ARM
- // relocations.
- const TargetLoweringObjectFileMachO &TLOFMacho =
- static_cast<const TargetLoweringObjectFileMachO &>(
- getObjFileLowering());
-
- // Collect the set of sections our functions will go into.
- SetVector<const MCSection *, SmallVector<const MCSection *, 8>,
- SmallPtrSet<const MCSection *, 8> > TextSections;
- // Default text section comes first.
- TextSections.insert(TLOFMacho.getTextSection());
- // Now any user defined text sections from function attributes.
- for (Module::iterator F = M.begin(), e = M.end(); F != e; ++F)
- if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage())
- TextSections.insert(TLOFMacho.SectionForGlobal(F, *Mang, TM));
- // Now the coalescable sections.
- TextSections.insert(TLOFMacho.getTextCoalSection());
- TextSections.insert(TLOFMacho.getConstTextCoalSection());
-
- // Emit the sections in the .s file header to fix the order.
- for (unsigned i = 0, e = TextSections.size(); i != e; ++i)
- OutStreamer.SwitchSection(TextSections[i]);
-
- if (RelocM == Reloc::DynamicNoPIC) {
- const MCSection *sect =
- OutContext.getMachOSection("__TEXT", "__symbol_stub4",
- MachO::S_SYMBOL_STUBS,
- 12, SectionKind::getText());
- OutStreamer.SwitchSection(sect);
- } else {
- const MCSection *sect =
- OutContext.getMachOSection("__TEXT", "__picsymbolstub4",
- MachO::S_SYMBOL_STUBS,
- 16, SectionKind::getText());
- OutStreamer.SwitchSection(sect);
- }
- const MCSection *StaticInitSect =
- OutContext.getMachOSection("__TEXT", "__StaticInit",
- MachO::S_REGULAR |
- MachO::S_ATTR_PURE_INSTRUCTIONS,
- SectionKind::getText());
- OutStreamer.SwitchSection(StaticInitSect);
- }
-
- // Compiling with debug info should not affect the code
- // generation. Ensure the cstring section comes before the
- // optional __DWARF secion. Otherwise, PC-relative loads would
- // have to use different instruction sequences at "-g" in order to
- // reach global data in the same object file.
- OutStreamer.SwitchSection(getObjFileLowering().getCStringSection());
- }
-
// Use unified assembler syntax.
OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified);
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
index 9f75491911c..82dac5c4357 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
@@ -307,9 +307,9 @@ static MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx,
static MCStreamer *createARMMachOStreamer(MCContext &Ctx, MCAsmBackend &MAB,
raw_ostream &OS,
- MCCodeEmitter *Emitter,
- bool RelaxAll) {
- return createMachOStreamer(Ctx, MAB, OS, Emitter, false);
+ MCCodeEmitter *Emitter, bool RelaxAll,
+ bool DWARFMustBeAtTheEnd) {
+ return createMachOStreamer(Ctx, MAB, OS, Emitter, false, DWARFMustBeAtTheEnd);
}
static MCInstPrinter *createARMMCInstPrinter(const Target &T,
diff --git a/llvm/test/CodeGen/ARM/darwin-section-order.ll b/llvm/test/CodeGen/ARM/darwin-section-order.ll
deleted file mode 100644
index 701028c0a53..00000000000
--- a/llvm/test/CodeGen/ARM/darwin-section-order.ll
+++ /dev/null
@@ -1,21 +0,0 @@
-; RUN: llc < %s -mtriple=armv7-apple-darwin | FileCheck %s
-
-; CHECK: .section __TEXT,__text,regular,pure_instructions
-; CHECK: .section __TEXT,myprecious
-; CHECK: .section __TEXT,__textcoal_nt,coalesced,pure_instructions
-; CHECK: .section __TEXT,__const_coal,coalesced
-; CHECK: .section __TEXT,__picsymbolstub4,symbol_stubs,none,16
-; CHECK: .section __TEXT,__StaticInit,regular,pure_instructions
-
-
-define void @normal() nounwind readnone {
-; CHECK: .section __TEXT,__text,regular,pure_instructions
-; CHECK: _normal:
- ret void
-}
-
-define void @special() nounwind readnone section "__TEXT,myprecious" {
-; CHECK: .section __TEXT,myprecious
-; CHECK: _special:
- ret void
-}
diff --git a/llvm/test/CodeGen/ARM/none-macho.ll b/llvm/test/CodeGen/ARM/none-macho.ll
index 23555b3d22c..733ba4ba2d2 100644
--- a/llvm/test/CodeGen/ARM/none-macho.ll
+++ b/llvm/test/CodeGen/ARM/none-macho.ll
@@ -2,11 +2,6 @@
; RUN: llc -mtriple=thumbv7m-none-macho -O0 %s -o - -relocation-model=pic -disable-fp-elim | FileCheck %s
; RUN: llc -mtriple=thumbv7m-none-macho -filetype=obj %s -o /dev/null
- ; Bare-metal should probably "declare" segments just like normal MachO
-; CHECK: __picsymbolstub4
-; CHECK: __StaticInit
-; CHECK: __text
-
@var = external global i32
define i32 @test_litpool() minsize {
diff --git a/llvm/test/DebugInfo/ARM/header.ll b/llvm/test/DebugInfo/ARM/header.ll
new file mode 100644
index 00000000000..d9dd611e127
--- /dev/null
+++ b/llvm/test/DebugInfo/ARM/header.ll
@@ -0,0 +1,30 @@
+; RUN: llc -mtriple armv7-apple-darwin < %s | FileCheck %s
+
+; Test that we don't pollute the start of the file with debug sections.
+; This is particularly important on ARM MachO as a change in section order can
+; cause a change the relaxation of the instructions used.
+
+; CHECK: .section __TEXT,__text,regular,pure_instructions
+; CHECK-NEXT: .syntax unified
+; CHECK-NEXT: .globl _f
+; CHECK-NEXT: .align 2
+; CHECK-NEXT: _f: @ @f
+
+; CHECK: .section __DWARF,__debug_str,regular,debug
+
+define void @f() {
+ ret void, !dbg !9
+}
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!7, !8}
+
+!0 = !MDCompileUnit(language: DW_LANG_C99, file: !1, producer: "foo", isOptimized: true, runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2)
+!1 = !MDFile(filename: "/foo/test.c", directory: "/foo")
+!2 = !{}
+!3 = !{!4}
+!4 = !MDSubprogram(name: "f", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: true, function: void ()* @f, variables: !2)
+!5 = !MDSubroutineType(types: !6)
+!6 = !{null}
+!7 = !{i32 2, !"Dwarf Version", i32 4}
+!8 = !{i32 2, !"Debug Info Version", i32 3}
+!9 = !MDLocation(line: 1, column: 15, scope: !4)
diff --git a/llvm/test/DebugInfo/ARM/sectionorder.ll b/llvm/test/DebugInfo/ARM/sectionorder.ll
deleted file mode 100644
index e6e067a1b58..00000000000
--- a/llvm/test/DebugInfo/ARM/sectionorder.ll
+++ /dev/null
@@ -1,18 +0,0 @@
-; RUN: llc -filetype=asm %s -o - | FileCheck %s
-
-; Verifies that the DWARF* sections come _after_ the __TEXT sections.
-; rdar://problem/15623193
-
-; CHECK: .section __TEXT,__text,
-; CHECK-NOT: __DWARF,__debug
-; CHECK: .section __TEXT,__cstring,cstring_literals
-target triple = "thumbv7-apple-ios"
-
-!llvm.module.flags = !{!3, !4}
-!llvm.dbg.cu = !{!0}
-
-!0 = !MDCompileUnit(language: DW_LANG_C99, producer: "LLVM", isOptimized: true, file: !5, enums: !1, retainedTypes: !1, subprograms: !1, globals: !1)
-!1 = !{}
-!3 = !{i32 2, !"Dwarf Version", i32 2}
-!4 = !{i32 1, !"Debug Info Version", i32 3}
-!5 = !MDFile(filename: "test.c", directory: "/Volumes/Data/radar/15623193")
diff --git a/llvm/tools/dsymutil/DwarfLinker.cpp b/llvm/tools/dsymutil/DwarfLinker.cpp
index 4326be45137..c9c05cd54ac 100644
--- a/llvm/tools/dsymutil/DwarfLinker.cpp
+++ b/llvm/tools/dsymutil/DwarfLinker.cpp
@@ -511,7 +511,8 @@ bool DwarfStreamer::init(Triple TheTriple, StringRef OutputFilename) {
return error(Twine(OutputFilename) + ": " + EC.message(), Context);
MS = TheTarget->createMCObjectStreamer(TheTriple, *MC, *MAB, *OutFile, MCE,
- *MSTI, false);
+ *MSTI, false,
+ /*DWARFMustBeAtTheEnd*/ false);
if (!MS)
return error("no object streamer for target " + TripleName, Context);
diff --git a/llvm/tools/llvm-mc/llvm-mc.cpp b/llvm/tools/llvm-mc/llvm-mc.cpp
index eb0df78c48d..4f9b6fc99e3 100644
--- a/llvm/tools/llvm-mc/llvm-mc.cpp
+++ b/llvm/tools/llvm-mc/llvm-mc.cpp
@@ -472,7 +472,8 @@ int main(int argc, char **argv) {
MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
Str.reset(TheTarget->createMCObjectStreamer(TheTriple, Ctx, *MAB, FOS, CE,
- *STI, RelaxAll));
+ *STI, RelaxAll,
+ /*DWARFMustBeAtTheEnd*/ false));
if (NoExecStack)
Str->InitSections(true);
}
OpenPOWER on IntegriCloud