Skip to content

Commit 36a15cb

Browse files
committed
Don't declare all text sections at the start of the .s
The code this patch removes was there to make sure the text sections went before the dwarf sections. That is necessary because MachO uses offsets relative to the start of the file, so adding a section can change relaxations. The dwarf sections were being printed at the start just to produce symbols pointing at the start of those sections. The underlying issue was fixed in r231898. The dwarf sections are now printed when they are about to be used, which is after we printed the text sections. To make sure we don't regress, the patch makes the MachO streamer assert if CodeGen puts anything unexpected after the DWARF sections. llvm-svn: 232842
1 parent b933fb2 commit 36a15cb

File tree

14 files changed

+108
-127
lines changed

14 files changed

+108
-127
lines changed

llvm/include/llvm/MC/MCObjectStreamer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ class MCObjectStreamer : public MCStreamer {
8585
/// fragment is not a data fragment.
8686
MCDataFragment *getOrCreateDataFragment();
8787

88+
bool changeSectionImpl(const MCSection *Section, const MCExpr *Subsection);
89+
8890
public:
8991
void visitUsedSymbol(const MCSymbol &Sym) override;
9092

llvm/include/llvm/Support/TargetRegistry.h

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ namespace llvm {
6565
bool RelaxAll);
6666
MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB,
6767
raw_ostream &OS, MCCodeEmitter *CE,
68-
bool RelaxAll, bool LabelSections = false);
68+
bool RelaxAll, bool DWARFMustBeAtTheEnd,
69+
bool LabelSections = false);
6970

7071
MCRelocationInfo *createMCRelocationInfo(StringRef TT, MCContext &Ctx);
7172

@@ -138,11 +139,9 @@ namespace llvm {
138139
MCAsmBackend &TAB, raw_ostream &OS,
139140
MCCodeEmitter *Emitter,
140141
bool RelaxAll);
141-
typedef MCStreamer *(*MachOStreamerCtorTy)(MCContext &Ctx,
142-
MCAsmBackend &TAB,
143-
raw_ostream &OS,
144-
MCCodeEmitter *Emitter,
145-
bool RelaxAll);
142+
typedef MCStreamer *(*MachOStreamerCtorTy)(
143+
MCContext &Ctx, MCAsmBackend &TAB, raw_ostream &OS,
144+
MCCodeEmitter *Emitter, bool RelaxAll, bool DWARFMustBeAtTheEnd);
146145
typedef MCStreamer *(*COFFStreamerCtorTy)(MCContext &Ctx, MCAsmBackend &TAB,
147146
raw_ostream &OS,
148147
MCCodeEmitter *Emitter,
@@ -444,7 +443,8 @@ namespace llvm {
444443
MCAsmBackend &TAB, raw_ostream &OS,
445444
MCCodeEmitter *Emitter,
446445
const MCSubtargetInfo &STI,
447-
bool RelaxAll) const {
446+
bool RelaxAll,
447+
bool DWARFMustBeAtTheEnd) const {
448448
MCStreamer *S;
449449
switch (T.getObjectFormat()) {
450450
default:
@@ -455,9 +455,11 @@ namespace llvm {
455455
break;
456456
case Triple::MachO:
457457
if (MachOStreamerCtorFn)
458-
S = MachOStreamerCtorFn(Ctx, TAB, OS, Emitter, RelaxAll);
458+
S = MachOStreamerCtorFn(Ctx, TAB, OS, Emitter, RelaxAll,
459+
DWARFMustBeAtTheEnd);
459460
else
460-
S = createMachOStreamer(Ctx, TAB, OS, Emitter, RelaxAll);
461+
S = createMachOStreamer(Ctx, TAB, OS, Emitter, RelaxAll,
462+
DWARFMustBeAtTheEnd);
461463
break;
462464
case Triple::ELF:
463465
if (ELFStreamerCtorFn)

llvm/lib/CodeGen/LLVMTargetMachine.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
202202

203203
Triple T(getTargetTriple());
204204
AsmStreamer.reset(getTarget().createMCObjectStreamer(
205-
T, *Context, *MAB, Out, MCE, STI, Options.MCOptions.MCRelaxAll));
205+
T, *Context, *MAB, Out, MCE, STI, Options.MCOptions.MCRelaxAll,
206+
/*DWARFMustBeAtTheEnd*/ true));
206207
break;
207208
}
208209
case CGFT_Null:
@@ -253,7 +254,8 @@ bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM,
253254
Triple T(getTargetTriple());
254255
const MCSubtargetInfo &STI = *getMCSubtargetInfo();
255256
std::unique_ptr<MCStreamer> AsmStreamer(getTarget().createMCObjectStreamer(
256-
T, *Ctx, *MAB, Out, MCE, STI, Options.MCOptions.MCRelaxAll));
257+
T, *Ctx, *MAB, Out, MCE, STI, Options.MCOptions.MCRelaxAll,
258+
/*DWARFMustBeAtTheEnd*/ true));
257259

258260
// Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
259261
FunctionPass *Printer =

llvm/lib/MC/MCMachOStreamer.cpp

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ class MCMachOStreamer : public MCObjectStreamer {
4040
/// need for local relocations. False by default.
4141
bool LabelSections;
4242

43+
bool DWARFMustBeAtTheEnd;
44+
bool CreatedADWARFSection;
45+
4346
/// HasSectionLabel - map of which sections have already had a non-local
4447
/// label emitted to them. Used so we don't emit extraneous linker local
4548
/// labels in the middle of the section.
@@ -52,9 +55,9 @@ class MCMachOStreamer : public MCObjectStreamer {
5255

5356
public:
5457
MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS,
55-
MCCodeEmitter *Emitter, bool label)
56-
: MCObjectStreamer(Context, MAB, OS, Emitter),
57-
LabelSections(label) {}
58+
MCCodeEmitter *Emitter, bool DWARFMustBeAtTheEnd, bool label)
59+
: MCObjectStreamer(Context, MAB, OS, Emitter), LabelSections(label),
60+
DWARFMustBeAtTheEnd(DWARFMustBeAtTheEnd), CreatedADWARFSection(false) {}
5861

5962
/// state management
6063
void reset() override {
@@ -120,10 +123,43 @@ class MCMachOStreamer : public MCObjectStreamer {
120123

121124
} // end anonymous namespace.
122125

126+
static bool canGoAfterDWARF(const MCSectionMachO &MSec) {
127+
// These sections are created by the assembler itself after the end of
128+
// the .s file.
129+
StringRef SegName = MSec.getSegmentName();
130+
StringRef SecName = MSec.getSectionName();
131+
132+
if (SegName == "__LD" && SecName == "__compact_unwind")
133+
return true;
134+
135+
if (SegName == "__IMPORT") {
136+
if (SecName == "__jump_table")
137+
return true;
138+
139+
if (SecName == "__pointers")
140+
return true;
141+
}
142+
143+
if (SegName == "__TEXT" && SecName == "__eh_frame")
144+
return true;
145+
146+
if (SegName == "__DATA" && SecName == "__nl_symbol_ptr")
147+
return true;
148+
149+
return false;
150+
}
151+
123152
void MCMachOStreamer::ChangeSection(const MCSection *Section,
124153
const MCExpr *Subsection) {
125154
// Change the section normally.
126-
MCObjectStreamer::ChangeSection(Section, Subsection);
155+
bool Created = MCObjectStreamer::changeSectionImpl(Section, Subsection);
156+
const MCSectionMachO &MSec = *cast<MCSectionMachO>(Section);
157+
StringRef SegName = MSec.getSegmentName();
158+
if (SegName == "__DWARF")
159+
CreatedADWARFSection = true;
160+
else if (Created && DWARFMustBeAtTheEnd && !canGoAfterDWARF(MSec))
161+
assert(!CreatedADWARFSection && "Creating regular section after DWARF");
162+
127163
// Output a linker-local symbol so we don't need section-relative local
128164
// relocations. The linker hates us when we do that.
129165
if (LabelSections && !HasSectionLabel[Section]) {
@@ -456,9 +492,10 @@ void MCMachOStreamer::FinishImpl() {
456492

457493
MCStreamer *llvm::createMachOStreamer(MCContext &Context, MCAsmBackend &MAB,
458494
raw_ostream &OS, MCCodeEmitter *CE,
459-
bool RelaxAll,
495+
bool RelaxAll, bool DWARFMustBeAtTheEnd,
460496
bool LabelSections) {
461-
MCMachOStreamer *S = new MCMachOStreamer(Context, MAB, OS, CE, LabelSections);
497+
MCMachOStreamer *S = new MCMachOStreamer(Context, MAB, OS, CE,
498+
DWARFMustBeAtTheEnd, LabelSections);
462499
if (RelaxAll)
463500
S->getAssembler().setRelaxAll(true);
464501
return S;

llvm/lib/MC/MCObjectStreamer.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,16 @@ void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
182182

183183
void MCObjectStreamer::ChangeSection(const MCSection *Section,
184184
const MCExpr *Subsection) {
185+
changeSectionImpl(Section, Subsection);
186+
}
187+
188+
bool MCObjectStreamer::changeSectionImpl(const MCSection *Section,
189+
const MCExpr *Subsection) {
185190
assert(Section && "Cannot switch to a null section!");
186191
flushPendingLabels(nullptr);
187192

188-
CurSectionData = &getAssembler().getOrCreateSectionData(*Section);
193+
bool Created;
194+
CurSectionData = &getAssembler().getOrCreateSectionData(*Section, &Created);
189195

190196
int64_t IntSubsection = 0;
191197
if (Subsection &&
@@ -195,6 +201,7 @@ void MCObjectStreamer::ChangeSection(const MCSection *Section,
195201
report_fatal_error("Subsection number out of range");
196202
CurInsertionPoint =
197203
CurSectionData->getSubsectionInsertionPoint(unsigned(IntSubsection));
204+
return Created;
198205
}
199206

200207
void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {

llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,10 @@ static MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx,
131131

132132
static MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB,
133133
raw_ostream &OS, MCCodeEmitter *Emitter,
134-
bool RelaxAll) {
134+
bool RelaxAll,
135+
bool DWARFMustBeAtTheEnd) {
135136
return createMachOStreamer(Ctx, TAB, OS, Emitter, RelaxAll,
137+
DWARFMustBeAtTheEnd,
136138
/*LabelSections*/ true);
137139
}
138140

llvm/lib/Target/ARM/ARMAsmPrinter.cpp

Lines changed: 0 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -435,65 +435,6 @@ void ARMAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
435435

436436
void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
437437
Triple TT(TM.getTargetTriple());
438-
if (TT.isOSBinFormatMachO()) {
439-
Reloc::Model RelocM = TM.getRelocationModel();
440-
if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) {
441-
// Declare all the text sections up front (before the DWARF sections
442-
// emitted by AsmPrinter::doInitialization) so the assembler will keep
443-
// them together at the beginning of the object file. This helps
444-
// avoid out-of-range branches that are due a fundamental limitation of
445-
// the way symbol offsets are encoded with the current Darwin ARM
446-
// relocations.
447-
const TargetLoweringObjectFileMachO &TLOFMacho =
448-
static_cast<const TargetLoweringObjectFileMachO &>(
449-
getObjFileLowering());
450-
451-
// Collect the set of sections our functions will go into.
452-
SetVector<const MCSection *, SmallVector<const MCSection *, 8>,
453-
SmallPtrSet<const MCSection *, 8> > TextSections;
454-
// Default text section comes first.
455-
TextSections.insert(TLOFMacho.getTextSection());
456-
// Now any user defined text sections from function attributes.
457-
for (Module::iterator F = M.begin(), e = M.end(); F != e; ++F)
458-
if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage())
459-
TextSections.insert(TLOFMacho.SectionForGlobal(F, *Mang, TM));
460-
// Now the coalescable sections.
461-
TextSections.insert(TLOFMacho.getTextCoalSection());
462-
TextSections.insert(TLOFMacho.getConstTextCoalSection());
463-
464-
// Emit the sections in the .s file header to fix the order.
465-
for (unsigned i = 0, e = TextSections.size(); i != e; ++i)
466-
OutStreamer.SwitchSection(TextSections[i]);
467-
468-
if (RelocM == Reloc::DynamicNoPIC) {
469-
const MCSection *sect =
470-
OutContext.getMachOSection("__TEXT", "__symbol_stub4",
471-
MachO::S_SYMBOL_STUBS,
472-
12, SectionKind::getText());
473-
OutStreamer.SwitchSection(sect);
474-
} else {
475-
const MCSection *sect =
476-
OutContext.getMachOSection("__TEXT", "__picsymbolstub4",
477-
MachO::S_SYMBOL_STUBS,
478-
16, SectionKind::getText());
479-
OutStreamer.SwitchSection(sect);
480-
}
481-
const MCSection *StaticInitSect =
482-
OutContext.getMachOSection("__TEXT", "__StaticInit",
483-
MachO::S_REGULAR |
484-
MachO::S_ATTR_PURE_INSTRUCTIONS,
485-
SectionKind::getText());
486-
OutStreamer.SwitchSection(StaticInitSect);
487-
}
488-
489-
// Compiling with debug info should not affect the code
490-
// generation. Ensure the cstring section comes before the
491-
// optional __DWARF secion. Otherwise, PC-relative loads would
492-
// have to use different instruction sequences at "-g" in order to
493-
// reach global data in the same object file.
494-
OutStreamer.SwitchSection(getObjFileLowering().getCStringSection());
495-
}
496-
497438
// Use unified assembler syntax.
498439
OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified);
499440

llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -307,9 +307,9 @@ static MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx,
307307

308308
static MCStreamer *createARMMachOStreamer(MCContext &Ctx, MCAsmBackend &MAB,
309309
raw_ostream &OS,
310-
MCCodeEmitter *Emitter,
311-
bool RelaxAll) {
312-
return createMachOStreamer(Ctx, MAB, OS, Emitter, false);
310+
MCCodeEmitter *Emitter, bool RelaxAll,
311+
bool DWARFMustBeAtTheEnd) {
312+
return createMachOStreamer(Ctx, MAB, OS, Emitter, false, DWARFMustBeAtTheEnd);
313313
}
314314

315315
static MCInstPrinter *createARMMCInstPrinter(const Target &T,

llvm/test/CodeGen/ARM/darwin-section-order.ll

Lines changed: 0 additions & 21 deletions
This file was deleted.

llvm/test/CodeGen/ARM/none-macho.ll

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@
22
; RUN: llc -mtriple=thumbv7m-none-macho -O0 %s -o - -relocation-model=pic -disable-fp-elim | FileCheck %s
33
; RUN: llc -mtriple=thumbv7m-none-macho -filetype=obj %s -o /dev/null
44

5-
; Bare-metal should probably "declare" segments just like normal MachO
6-
; CHECK: __picsymbolstub4
7-
; CHECK: __StaticInit
8-
; CHECK: __text
9-
105
@var = external global i32
116

127
define i32 @test_litpool() minsize {

llvm/test/DebugInfo/ARM/header.ll

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
; RUN: llc -mtriple armv7-apple-darwin < %s | FileCheck %s
2+
3+
; Test that we don't pollute the start of the file with debug sections.
4+
; This is particularly important on ARM MachO as a change in section order can
5+
; cause a change the relaxation of the instructions used.
6+
7+
; CHECK: .section __TEXT,__text,regular,pure_instructions
8+
; CHECK-NEXT: .syntax unified
9+
; CHECK-NEXT: .globl _f
10+
; CHECK-NEXT: .align 2
11+
; CHECK-NEXT: _f: @ @f
12+
13+
; CHECK: .section __DWARF,__debug_str,regular,debug
14+
15+
define void @f() {
16+
ret void, !dbg !9
17+
}
18+
!llvm.dbg.cu = !{!0}
19+
!llvm.module.flags = !{!7, !8}
20+
21+
!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)
22+
!1 = !MDFile(filename: "/foo/test.c", directory: "/foo")
23+
!2 = !{}
24+
!3 = !{!4}
25+
!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)
26+
!5 = !MDSubroutineType(types: !6)
27+
!6 = !{null}
28+
!7 = !{i32 2, !"Dwarf Version", i32 4}
29+
!8 = !{i32 2, !"Debug Info Version", i32 3}
30+
!9 = !MDLocation(line: 1, column: 15, scope: !4)

llvm/test/DebugInfo/ARM/sectionorder.ll

Lines changed: 0 additions & 18 deletions
This file was deleted.

llvm/tools/dsymutil/DwarfLinker.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,8 @@ bool DwarfStreamer::init(Triple TheTriple, StringRef OutputFilename) {
511511
return error(Twine(OutputFilename) + ": " + EC.message(), Context);
512512

513513
MS = TheTarget->createMCObjectStreamer(TheTriple, *MC, *MAB, *OutFile, MCE,
514-
*MSTI, false);
514+
*MSTI, false,
515+
/*DWARFMustBeAtTheEnd*/ false);
515516
if (!MS)
516517
return error("no object streamer for target " + TripleName, Context);
517518

llvm/tools/llvm-mc/llvm-mc.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,8 @@ int main(int argc, char **argv) {
472472
MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
473473
MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
474474
Str.reset(TheTarget->createMCObjectStreamer(TheTriple, Ctx, *MAB, FOS, CE,
475-
*STI, RelaxAll));
475+
*STI, RelaxAll,
476+
/*DWARFMustBeAtTheEnd*/ false));
476477
if (NoExecStack)
477478
Str->InitSections(true);
478479
}

0 commit comments

Comments
 (0)