Skip to content

Commit 1955a01

Browse files
authored
MC: Allocate initial fragment and define section symbol in changeSection
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. * 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 84dc97e commit 1955a01

15 files changed

+80
-89
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/MCSection.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,8 @@ class LLVM_ABI MCSection {
589589
/// offset between two locations may not be fully resolved.
590590
bool LinkerRelaxable : 1;
591591

592+
MCFragment DummyFragment;
593+
592594
// Mapping from subsection number to fragment list. At layout time, the
593595
// subsection 0 list is replaced with concatenated fragments from all
594596
// subsections.
@@ -650,7 +652,7 @@ class LLVM_ABI MCSection {
650652
bool isLinkerRelaxable() const { return LinkerRelaxable; }
651653
void setLinkerRelaxable() { LinkerRelaxable = true; }
652654

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

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

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

llvm/lib/MC/MCObjectStreamer.cpp

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,10 @@ void MCObjectStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
185185

186186
getAssembler().registerSymbol(*Symbol);
187187

188-
// If there is a current fragment, mark the symbol as pointing into it.
189-
// Otherwise queue the label and set its fragment pointer when we emit the
190-
// next fragment.
191-
MCFragment *F = getCurrentFragment();
188+
// Set the fragment and offset. This function might be called by
189+
// changeSection, when the section stack top hasn't been changed to the new
190+
// section.
191+
MCFragment *F = CurFrag;
192192
Symbol->setFragment(F);
193193
Symbol->setOffset(F->getContents().size());
194194

@@ -247,6 +247,15 @@ void MCObjectStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
247247
assert(Section && "Cannot switch to a null section!");
248248
getContext().clearDwarfLocSeen();
249249

250+
// Register the section and create an initial fragment for subsection 0
251+
// if `Subsection` is non-zero.
252+
bool NewSec = getAssembler().registerSection(*Section);
253+
MCFragment *F0 = nullptr;
254+
if (NewSec && Subsection) {
255+
changeSection(Section, 0);
256+
F0 = CurFrag;
257+
}
258+
250259
auto &Subsections = Section->Subsections;
251260
size_t I = 0, E = Subsections.size();
252261
while (I != E && Subsections[I].first < Subsection)
@@ -262,7 +271,13 @@ void MCObjectStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
262271
Section->CurFragList = &Subsections[I].second;
263272
CurFrag = Section->CurFragList->Tail;
264273

265-
getAssembler().registerSection(*Section);
274+
// Define the section symbol at subsection 0's initial fragment if required.
275+
if (!NewSec)
276+
return;
277+
if (auto *Sym = Section->getBeginSymbol()) {
278+
Sym->setFragment(Subsection ? F0 : CurFrag);
279+
getAssembler().registerSymbol(*Sym);
280+
}
266281
}
267282

268283
void MCObjectStreamer::switchSectionNoPrint(MCSection *Section) {

llvm/lib/MC/MCSection.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ MCSection::MCSection(SectionVariant V, StringRef Name, bool IsText, bool IsBss,
2222
MCSymbol *Begin)
2323
: Begin(Begin), HasInstructions(false), IsRegistered(false), IsText(IsText),
2424
IsBss(IsBss), LinkerRelaxable(false), Name(Name), Variant(V) {
25-
// The initial subsection number is 0. Create a fragment list.
26-
CurFragList = &Subsections.emplace_back(0u, FragList{}).second;
25+
DummyFragment.setParent(this);
2726
}
2827

2928
MCSymbol *MCSection::getEndSymbol(MCContext &Ctx) {

0 commit comments

Comments
 (0)