Skip to content

Commit ea92ff1

Browse files
MaskRaymahesh-attarde
authored andcommitted
MC: Allocate initial fragment and define section symbol in changeSection
Reland llvm#150574 with a MCStreamer::changeSection change: In Mach-O, DWARF sections use Begin as a temporary label, requiring a label definition, unlike section symbols in other file formats. (Tested by dec9780) --- 13a79bb (2017) introduced fragment creation in MCContext for createELFSectionImpl, which was inappropriate. Fragments should only be created when using MCSteramer, not during `MCContext::get*Section` calls. `initMachOMCObjectFileInfo` defines multiple sections, some of which may not be used by the code generator. This caused symbol names matching these sections to be incorrectly marked as undefined (see https://reviews.llvm.org/D55173). The fragment code was later replicated in other file formats, such as WebAssembly (see https://reviews.llvm.org/D46561), XCOFF, and GOFF. This patch fixes the problem by moving initial fragment allocation from MCContext::createSection to MCStreamer::changeSection. While MCContext still creates a section symbol, the symbol is not attached to the initial fragment. In addition, * Move `emitLabel`/`setFragment` from `switchSection*` and overridden changeSection to `MCObjectStreamer::changeSection` for consistency. * De-virtualize `switchSectionNoPrint`. * test/CodeGen/XCore/section-name.ll now passes. XCore doesn't support MCObjectStreamer. I don't think the MCAsmStreamer output behavior change matters. Pull Request: llvm#150574
1 parent 7b78c1e commit ea92ff1

17 files changed

+92
-96
lines changed

llvm/include/llvm/MC/MCContext.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,6 @@ class MCContext {
333333
void reportCommon(SMLoc Loc,
334334
std::function<void(SMDiagnostic &, const SourceMgr *)>);
335335

336-
MCFragment *allocInitialFragment(MCSection &Sec);
337-
338336
MCSymbolTableEntry &getSymbolTableEntry(StringRef Name);
339337

340338
MCSymbol *createSymbolImpl(const MCSymbolTableEntry *Name, bool IsTemporary);

llvm/include/llvm/MC/MCObjectStreamer.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ class MCObjectStreamer : public MCStreamer {
102102
void emitSLEB128Value(const MCExpr *Value) override;
103103
void emitWeakReference(MCSymbol *Alias, const MCSymbol *Target) override;
104104
void changeSection(MCSection *Section, uint32_t Subsection = 0) override;
105-
void switchSectionNoPrint(MCSection *Section) override;
106105
void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
107106

108107
/// Emit an instruction to a special fragment, because this instruction

llvm/include/llvm/MC/MCSection.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,8 @@ class LLVM_ABI MCSection {
570570
// At parse time, this holds the fragment list of the current subsection. At
571571
// layout time, this holds the concatenated fragment lists of all subsections.
572572
FragList *CurFragList;
573+
// In many object file formats, this denotes the section symbol. In Mach-O,
574+
// this denotes an optional temporary label at the section start.
573575
MCSymbol *Begin;
574576
MCSymbol *End = nullptr;
575577
/// The alignment requirement of this section.
@@ -589,6 +591,8 @@ class LLVM_ABI MCSection {
589591
/// offset between two locations may not be fully resolved.
590592
bool LinkerRelaxable : 1;
591593

594+
MCFragment DummyFragment;
595+
592596
// Mapping from subsection number to fragment list. At layout time, the
593597
// subsection 0 list is replaced with concatenated fragments from all
594598
// subsections.
@@ -650,7 +654,7 @@ class LLVM_ABI MCSection {
650654
bool isLinkerRelaxable() const { return LinkerRelaxable; }
651655
void setLinkerRelaxable() { LinkerRelaxable = true; }
652656

653-
MCFragment &getDummyFragment() { return *Subsections[0].second.Head; }
657+
MCFragment &getDummyFragment() { return DummyFragment; }
654658

655659
FragList *curFragList() const { return CurFragList; }
656660
iterator begin() const { return iterator(CurFragList->Head); }

llvm/include/llvm/MC/MCStreamer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ class LLVM_ABI MCStreamer {
459459
bool switchSection(MCSection *Section, const MCExpr *);
460460

461461
/// Similar to switchSection, but does not print the section directive.
462-
virtual void switchSectionNoPrint(MCSection *Section);
462+
void switchSectionNoPrint(MCSection *Section);
463463

464464
/// Create the default sections and set the initial one.
465465
virtual void initSections(bool NoExecStack, const MCSubtargetInfo &STI);

llvm/include/llvm/MC/MCXCOFFStreamer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class MCXCOFFStreamer : public MCObjectStreamer {
2222

2323
XCOFFObjectWriter &getWriter();
2424

25+
void changeSection(MCSection *Section, uint32_t Subsection = 0) override;
2526
bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
2627
void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
2728
Align ByteAlignment) override;

llvm/lib/MC/ELFObjectWriter.cpp

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -559,20 +559,7 @@ void ELFWriter::computeSymbolTable(const RevGroupMapTy &RevGroupMap) {
559559
} else {
560560
const MCSectionELF &Section =
561561
static_cast<const MCSectionELF &>(Symbol.getSection());
562-
563-
// We may end up with a situation when section symbol is technically
564-
// defined, but should not be. That happens because we explicitly
565-
// pre-create few .debug_* sections to have accessors.
566-
// And if these sections were not really defined in the code, but were
567-
// referenced, we simply error out.
568-
if (!Section.isRegistered()) {
569-
assert(static_cast<const MCSymbolELF &>(Symbol).getType() ==
570-
ELF::STT_SECTION);
571-
Ctx.reportError(SMLoc(),
572-
"Undefined section reference: " + Symbol.getName());
573-
continue;
574-
}
575-
562+
assert(Section.isRegistered());
576563
if (Mode == NonDwoOnly && isDwoSection(Section))
577564
continue;
578565
MSD.SectionIndex = Section.getOrdinal();

llvm/lib/MC/MCAssembler.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ void MCAssembler::reset() {
106106
bool MCAssembler::registerSection(MCSection &Section) {
107107
if (Section.isRegistered())
108108
return false;
109-
assert(Section.curFragList()->Head && "allocInitialFragment not called");
110109
Sections.push_back(&Section);
111110
Section.setIsRegistered(true);
112111
return true;

llvm/lib/MC/MCContext.cpp

Lines changed: 9 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -200,16 +200,6 @@ MCInst *MCContext::createMCInst() {
200200
return new (MCInstAllocator.Allocate()) MCInst;
201201
}
202202

203-
// Allocate the initial MCFragment for the begin symbol.
204-
MCFragment *MCContext::allocInitialFragment(MCSection &Sec) {
205-
assert(!Sec.curFragList()->Head);
206-
auto *F = allocFragment<MCFragment>();
207-
F->setParent(&Sec);
208-
Sec.curFragList()->Head = F;
209-
Sec.curFragList()->Tail = F;
210-
return F;
211-
}
212-
213203
//===----------------------------------------------------------------------===//
214204
// Symbol Manipulation
215205
//===----------------------------------------------------------------------===//
@@ -443,24 +433,28 @@ MCSymbol *MCContext::getDirectionalLocalSymbol(unsigned LocalLabelVal,
443433
return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);
444434
}
445435

436+
// Create a section symbol, with a distinct one for each section of the same.
437+
// The first symbol is used for assembly code references.
446438
template <typename Symbol>
447439
Symbol *MCContext::getOrCreateSectionSymbol(StringRef Section) {
448440
Symbol *R;
449441
auto &SymEntry = getSymbolTableEntry(Section);
450442
MCSymbol *Sym = SymEntry.second.Symbol;
451-
// A section symbol can not redefine regular symbols. There may be multiple
452-
// sections with the same name, in which case the first such section wins.
453443
if (Sym && Sym->isDefined() &&
454444
(!Sym->isInSection() || Sym->getSection().getBeginSymbol() != Sym))
455445
reportError(SMLoc(), "invalid symbol redefinition");
456-
if (Sym && Sym->isUndefined()) {
446+
// Use the symbol's index to track if it has been used as a section symbol.
447+
// Set to -1 to catch potential bugs if misused as a symbol index.
448+
if (Sym && Sym->getIndex() != -1u) {
457449
R = cast<Symbol>(Sym);
458450
} else {
459451
SymEntry.second.Used = true;
460452
R = new (&SymEntry, *this) Symbol(&SymEntry, /*isTemporary=*/false);
461453
if (!Sym)
462454
SymEntry.second.Symbol = R;
463455
}
456+
// Mark as section symbol.
457+
R->setIndex(-1u);
464458
return R;
465459
}
466460

@@ -568,7 +562,6 @@ MCSectionMachO *MCContext::getMachOSection(StringRef Segment, StringRef Section,
568562
MCSectionMachO(Segment, Name.substr(Name.size() - Section.size()),
569563
TypeAndAttributes, Reserved2, Kind, Begin);
570564
R.first->second = Ret;
571-
allocInitialFragment(*Ret);
572565
return Ret;
573566
}
574567

@@ -579,15 +572,8 @@ MCSectionELF *MCContext::createELFSectionImpl(StringRef Section, unsigned Type,
579572
bool Comdat, unsigned UniqueID,
580573
const MCSymbolELF *LinkedToSym) {
581574
auto *R = getOrCreateSectionSymbol<MCSymbolELF>(Section);
582-
R->setBinding(ELF::STB_LOCAL);
583-
R->setType(ELF::STT_SECTION);
584-
585-
auto *Ret = new (ELFAllocator.Allocate()) MCSectionELF(
575+
return new (ELFAllocator.Allocate()) MCSectionELF(
586576
Section, Type, Flags, EntrySize, Group, Comdat, UniqueID, R, LinkedToSym);
587-
588-
auto *F = allocInitialFragment(*Ret);
589-
R->setFragment(F);
590-
return Ret;
591577
}
592578

593579
MCSectionELF *
@@ -743,7 +729,6 @@ MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
743729
MCSectionGOFF(CachedName, Kind, IsVirtual, Attributes,
744730
static_cast<MCSectionGOFF *>(Parent));
745731
Iter->second = GOFFSection;
746-
allocInitialFragment(*GOFFSection);
747732
return GOFFSection;
748733
}
749734

@@ -798,8 +783,7 @@ MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
798783
MCSectionCOFF *Result = new (COFFAllocator.Allocate()) MCSectionCOFF(
799784
CachedName, Characteristics, COMDATSymbol, Selection, UniqueID, Begin);
800785
Iter->second = Result;
801-
auto *F = allocInitialFragment(*Result);
802-
Begin->setFragment(F);
786+
Begin->setFragment(&Result->getDummyFragment());
803787
return Result;
804788
}
805789

@@ -870,8 +854,6 @@ MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind Kind,
870854
MCSectionWasm(CachedName, Kind, Flags, GroupSym, UniqueID, Begin);
871855
Entry.second = Result;
872856

873-
auto *F = allocInitialFragment(*Result);
874-
Begin->setFragment(F);
875857
return Result;
876858
}
877859

@@ -927,24 +909,11 @@ MCSectionXCOFF *MCContext::getXCOFFSection(
927909
MultiSymbolsAllowed);
928910

929911
Entry.second = Result;
930-
931-
auto *F = allocInitialFragment(*Result);
932-
933-
// We might miss calculating the symbols difference as absolute value before
934-
// adding fixups when symbol_A without the fragment set is the csect itself
935-
// and symbol_B is in it.
936-
// TODO: Currently we only set the fragment for XMC_PR csects and DWARF
937-
// sections because we don't have other cases that hit this problem yet.
938-
if (IsDwarfSec || CsectProp->MappingClass == XCOFF::XMC_PR)
939-
QualName->setFragment(F);
940-
941912
return Result;
942913
}
943914

944915
MCSectionSPIRV *MCContext::getSPIRVSection() {
945916
MCSectionSPIRV *Result = new (SPIRVAllocator.Allocate()) MCSectionSPIRV();
946-
947-
allocInitialFragment(*Result);
948917
return Result;
949918
}
950919

@@ -964,7 +933,6 @@ MCSectionDXContainer *MCContext::getDXContainerSection(StringRef Section,
964933
new (DXCAllocator.Allocate()) MCSectionDXContainer(Name, K, nullptr);
965934

966935
// The first fragment will store the header
967-
allocInitialFragment(*MapIt->second);
968936
return MapIt->second;
969937
}
970938

llvm/lib/MC/MCELFStreamer.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@ void MCELFStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
8989
getWriter().markGnuAbi();
9090

9191
MCObjectStreamer::changeSection(Section, Subsection);
92-
Asm.registerSymbol(*Section->getBeginSymbol());
92+
auto *Sym = static_cast<MCSymbolELF *>(Section->getBeginSymbol());
93+
Sym->setBinding(ELF::STB_LOCAL);
94+
Sym->setType(ELF::STT_SECTION);
9395
}
9496

9597
void MCELFStreamer::emitWeakReference(MCSymbol *Alias, const MCSymbol *Target) {

llvm/lib/MC/MCMachOStreamer.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ void MCMachOStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
140140
MCSymbol *Label = getContext().createLinkerPrivateTempSymbol();
141141
Section->setBeginSymbol(Label);
142142
HasSectionLabel[Section] = true;
143+
if (!Label->isInSection())
144+
emitLabel(Label);
143145
}
144146
}
145147

0 commit comments

Comments
 (0)