Skip to content

Commit d347d13

Browse files
committed
MC: Allocate initial fragment 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. * test/CodeGen/XCore/section-name.ll now passes. XCore doesn't support MCObjectStreamer. I don't think the MCAsmStreamer output behavior change matters.
1 parent b0dea47 commit d347d13

16 files changed

+94
-67
lines changed

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: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -566,8 +566,6 @@ void ELFWriter::computeSymbolTable(const RevGroupMapTy &RevGroupMap) {
566566
// And if these sections were not really defined in the code, but were
567567
// referenced, we simply error out.
568568
if (!Section.isRegistered()) {
569-
assert(static_cast<const MCSymbolELF &>(Symbol).getType() ==
570-
ELF::STT_SECTION);
571569
Ctx.reportError(SMLoc(),
572570
"Undefined section reference: " + Symbol.getName());
573571
continue;

llvm/lib/MC/MCAsmStreamer.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class MCAsmStreamer final : public MCStreamer {
6060
bool ShowInst = false;
6161
bool UseDwarfDirectory = false;
6262

63+
void changeSection(MCSection *, uint32_t) override;
6364
void EmitRegisterName(int64_t Register);
6465
void PrintQuotedString(StringRef Data, raw_ostream &OS) const;
6566
void printDwarfFileDirective(unsigned FileNo, StringRef Directory,
@@ -2429,6 +2430,12 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst,
24292430
}
24302431
}
24312432

2433+
void MCAsmStreamer::changeSection(MCSection *Sec, uint32_t) {
2434+
CurFrag = &Sec->getDummyFragment();
2435+
if (auto *Sym = Sec->getBeginSymbol())
2436+
Sym->setFragment(&Sec->getDummyFragment());
2437+
}
2438+
24322439
void MCAsmStreamer::emitInstruction(const MCInst &Inst,
24332440
const MCSubtargetInfo &STI) {
24342441
if (MAI->isAIX() && CurFrag)

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 & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -443,24 +443,28 @@ MCSymbol *MCContext::getDirectionalLocalSymbol(unsigned LocalLabelVal,
443443
return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);
444444
}
445445

446+
// Create a section symbol, with a distinct one for each section of the same.
447+
// The first symbol is used for assembly code references.
446448
template <typename Symbol>
447449
Symbol *MCContext::getOrCreateSectionSymbol(StringRef Section) {
448450
Symbol *R;
449451
auto &SymEntry = getSymbolTableEntry(Section);
450452
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.
453453
if (Sym && Sym->isDefined() &&
454454
(!Sym->isInSection() || Sym->getSection().getBeginSymbol() != Sym))
455455
reportError(SMLoc(), "invalid symbol redefinition");
456-
if (Sym && Sym->isUndefined()) {
456+
// Use the symbol's index to track if it has been used as a section symbol.
457+
// Set to -1 to catch potential bugs if misused as a symbol index.
458+
if (Sym && Sym->getIndex() != -1u) {
457459
R = cast<Symbol>(Sym);
458460
} else {
459461
SymEntry.second.Used = true;
460462
R = new (&SymEntry, *this) Symbol(&SymEntry, /*isTemporary=*/false);
461463
if (!Sym)
462464
SymEntry.second.Symbol = R;
463465
}
466+
// Mark as section symbol.
467+
R->setIndex(-1u);
464468
return R;
465469
}
466470

@@ -568,7 +572,6 @@ MCSectionMachO *MCContext::getMachOSection(StringRef Segment, StringRef Section,
568572
MCSectionMachO(Segment, Name.substr(Name.size() - Section.size()),
569573
TypeAndAttributes, Reserved2, Kind, Begin);
570574
R.first->second = Ret;
571-
allocInitialFragment(*Ret);
572575
return Ret;
573576
}
574577

@@ -579,15 +582,8 @@ MCSectionELF *MCContext::createELFSectionImpl(StringRef Section, unsigned Type,
579582
bool Comdat, unsigned UniqueID,
580583
const MCSymbolELF *LinkedToSym) {
581584
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(
585+
return new (ELFAllocator.Allocate()) MCSectionELF(
586586
Section, Type, Flags, EntrySize, Group, Comdat, UniqueID, R, LinkedToSym);
587-
588-
auto *F = allocInitialFragment(*Ret);
589-
R->setFragment(F);
590-
return Ret;
591587
}
592588

593589
MCSectionELF *
@@ -743,7 +739,6 @@ MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
743739
MCSectionGOFF(CachedName, Kind, IsVirtual, Attributes,
744740
static_cast<MCSectionGOFF *>(Parent));
745741
Iter->second = GOFFSection;
746-
allocInitialFragment(*GOFFSection);
747742
return GOFFSection;
748743
}
749744

@@ -798,8 +793,7 @@ MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
798793
MCSectionCOFF *Result = new (COFFAllocator.Allocate()) MCSectionCOFF(
799794
CachedName, Characteristics, COMDATSymbol, Selection, UniqueID, Begin);
800795
Iter->second = Result;
801-
auto *F = allocInitialFragment(*Result);
802-
Begin->setFragment(F);
796+
Begin->setFragment(&Result->getDummyFragment());
803797
return Result;
804798
}
805799

@@ -870,8 +864,6 @@ MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind Kind,
870864
MCSectionWasm(CachedName, Kind, Flags, GroupSym, UniqueID, Begin);
871865
Entry.second = Result;
872866

873-
auto *F = allocInitialFragment(*Result);
874-
Begin->setFragment(F);
875867
return Result;
876868
}
877869

@@ -927,24 +919,11 @@ MCSectionXCOFF *MCContext::getXCOFFSection(
927919
MultiSymbolsAllowed);
928920

929921
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-
941922
return Result;
942923
}
943924

944925
MCSectionSPIRV *MCContext::getSPIRVSection() {
945926
MCSectionSPIRV *Result = new (SPIRVAllocator.Allocate()) MCSectionSPIRV();
946-
947-
allocInitialFragment(*Result);
948927
return Result;
949928
}
950929

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

966945
// The first fragment will store the header
967-
allocInitialFragment(*MapIt->second);
968946
return MapIt->second;
969947
}
970948

llvm/lib/MC/MCELFStreamer.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,10 @@ 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);
95+
Asm.registerSymbol(*Sym);
9396
}
9497

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

llvm/lib/MC/MCGOFFStreamer.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,19 @@ GOFFObjectWriter &MCGOFFStreamer::getWriter() {
2929
void MCGOFFStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
3030
// Make sure that all section are registered in the correct order.
3131
SmallVector<MCSectionGOFF *> Sections;
32-
for (auto *S = static_cast<MCSectionGOFF *>(Section); S; S = S->getParent())
32+
for (auto *S = static_cast<MCSectionGOFF *>(Section); (S = S->getParent());)
3333
Sections.push_back(S);
34-
while (!Sections.empty()) {
35-
auto *S = Sections.pop_back_val();
36-
MCObjectStreamer::changeSection(S, Sections.empty() ? Subsection : 0);
34+
while (!Sections.empty())
35+
MCObjectStreamer::changeSection(Sections.pop_back_val(), 0);
36+
37+
bool Registered = Section->isRegistered();
38+
MCObjectStreamer::changeSection(Section, Subsection);
39+
if (!Registered) {
40+
MCSymbol *Sym = Section->getBeginSymbol();
41+
if (Sym) {
42+
Sym->setFragment(nullptr);
43+
emitLabel(Sym);
44+
}
3745
}
3846
}
3947

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: 19 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+
// If the section was not registered before and Subsection is not zero,
251+
// allocate the initial fragment for subsection 0 for the section symbol.
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,12 @@ 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+
if (NewSec) {
275+
if (!Subsection)
276+
F0 = CurFrag;
277+
if (auto *Sym = Section->getBeginSymbol())
278+
Sym->setFragment(F0);
279+
}
266280
}
267281

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

0 commit comments

Comments
 (0)