Skip to content

Commit f5d49c7

Browse files
authored
Revert "MCFragment: Use trailing data for fixed-size part" (#151383)
Reverts #150846 due to unsigned underflow identifier by UBSan in several tests
1 parent 82f00ea commit f5d49c7

File tree

7 files changed

+55
-139
lines changed

7 files changed

+55
-139
lines changed

llvm/include/llvm/MC/MCObjectStreamer.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,6 @@ class MCObjectStreamer : public MCStreamer {
5252
DenseMap<const MCSymbol *, SmallVector<PendingAssignment, 1>>
5353
pendingAssignments;
5454

55-
SmallVector<std::unique_ptr<char[]>, 0> FragStorage;
56-
// Available bytes in the current block for trailing data or new fragments.
57-
size_t FragSpace = 0;
58-
5955
void emitInstToData(const MCInst &Inst, const MCSubtargetInfo &);
6056
void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
6157
void emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
@@ -88,18 +84,11 @@ class MCObjectStreamer : public MCStreamer {
8884
// Add a fragment with a variable-size tail and start a new empty fragment.
8985
void insert(MCFragment *F);
9086

91-
char *getCurFragEnd() const {
92-
return reinterpret_cast<char *>(CurFrag + 1) + CurFrag->getFixedSize();
93-
}
94-
MCFragment *allocFragSpace(size_t Headroom);
9587
// Add a new fragment to the current section without a variable-size tail.
9688
void newFragment();
9789

98-
void ensureHeadroom(size_t Headroom);
9990
void appendContents(ArrayRef<char> Contents);
10091
void appendContents(size_t Num, char Elt);
101-
// Add a fixup to the current fragment. Call ensureHeadroom beforehand to
102-
// ensure the fixup and appended content apply to the same fragment.
10392
void addFixup(const MCExpr *Value, MCFixupKind Kind);
10493

10594
void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;

llvm/include/llvm/MC/MCSection.h

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ class MCFragment {
9393
// Track content and fixups for the fixed-size part as fragments are
9494
// appended to the section. The content remains immutable, except when
9595
// modified by applyFixup.
96-
uint32_t FixedSize = 0;
96+
uint32_t ContentStart = 0;
97+
uint32_t ContentEnd = 0;
9798
uint32_t FixupStart = 0;
9899
uint32_t FixupEnd = 0;
99100

@@ -187,6 +188,18 @@ class MCFragment {
187188
//== Content-related functions manage parent's storage using ContentStart and
188189
// ContentSize.
189190

191+
// Get a SmallVector reference. The caller should call doneAppending to update
192+
// `ContentEnd`.
193+
SmallVectorImpl<char> &getContentsForAppending();
194+
void doneAppending();
195+
void appendContents(ArrayRef<char> Contents) {
196+
getContentsForAppending().append(Contents.begin(), Contents.end());
197+
doneAppending();
198+
}
199+
void appendContents(size_t Num, char Elt) {
200+
getContentsForAppending().append(Num, Elt);
201+
doneAppending();
202+
}
190203
MutableArrayRef<char> getContents();
191204
ArrayRef<char> getContents() const;
192205

@@ -195,10 +208,10 @@ class MCFragment {
195208
MutableArrayRef<char> getVarContents();
196209
ArrayRef<char> getVarContents() const;
197210

198-
size_t getFixedSize() const { return FixedSize; }
211+
size_t getFixedSize() const { return ContentEnd - ContentStart; }
199212
size_t getVarSize() const { return VarContentEnd - VarContentStart; }
200213
size_t getSize() const {
201-
return FixedSize + (VarContentEnd - VarContentStart);
214+
return ContentEnd - ContentStart + (VarContentEnd - VarContentStart);
202215
}
203216

204217
//== Fixup-related functions manage parent's storage using FixupStart and
@@ -621,11 +634,28 @@ class LLVM_ABI MCSection {
621634
bool isBssSection() const { return IsBss; }
622635
};
623636

637+
inline SmallVectorImpl<char> &MCFragment::getContentsForAppending() {
638+
SmallVectorImpl<char> &S = getParent()->ContentStorage;
639+
if (LLVM_UNLIKELY(ContentEnd != S.size())) {
640+
// Move the elements to the end. Reserve space to avoid invalidating
641+
// S.begin()+I for `append`.
642+
auto Size = ContentEnd - ContentStart;
643+
auto I = std::exchange(ContentStart, S.size());
644+
S.reserve(S.size() + Size);
645+
S.append(S.begin() + I, S.begin() + I + Size);
646+
}
647+
return S;
648+
}
649+
inline void MCFragment::doneAppending() {
650+
ContentEnd = getParent()->ContentStorage.size();
651+
}
624652
inline MutableArrayRef<char> MCFragment::getContents() {
625-
return {reinterpret_cast<char *>(this + 1), FixedSize};
653+
return MutableArrayRef(getParent()->ContentStorage)
654+
.slice(ContentStart, ContentEnd - ContentStart);
626655
}
627656
inline ArrayRef<char> MCFragment::getContents() const {
628-
return {reinterpret_cast<const char *>(this + 1), FixedSize};
657+
return ArrayRef(getParent()->ContentStorage)
658+
.slice(ContentStart, ContentEnd - ContentStart);
629659
}
630660

631661
inline MutableArrayRef<char> MCFragment::getVarContents() {

llvm/lib/MC/MCObjectStreamer.cpp

Lines changed: 20 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -46,83 +46,27 @@ MCAssembler *MCObjectStreamer::getAssemblerPtr() {
4646
return nullptr;
4747
}
4848

49-
constexpr size_t FragBlockSize = 16384;
50-
// Ensure the new fragment can at least store a few bytes.
51-
constexpr size_t NewFragHeadroom = 8;
52-
53-
static_assert(NewFragHeadroom >= alignof(MCFragment));
54-
static_assert(FragBlockSize >= sizeof(MCFragment) + NewFragHeadroom);
55-
56-
MCFragment *MCObjectStreamer::allocFragSpace(size_t Headroom) {
57-
auto Size = std::max(FragBlockSize, sizeof(MCFragment) + Headroom);
58-
FragSpace = Size - sizeof(MCFragment);
59-
auto Chunk = std::unique_ptr<char[]>(new char[Size]);
60-
auto *F = reinterpret_cast<MCFragment *>(Chunk.get());
61-
FragStorage.push_back(std::move(Chunk));
62-
return F;
63-
}
64-
6549
void MCObjectStreamer::newFragment() {
66-
MCFragment *F;
67-
if (LLVM_LIKELY(sizeof(MCFragment) + NewFragHeadroom <= FragSpace)) {
68-
auto End = reinterpret_cast<size_t>(getCurFragEnd());
69-
F = reinterpret_cast<MCFragment *>(
70-
alignToPowerOf2(End, alignof(MCFragment)));
71-
FragSpace -= size_t(F) - End + sizeof(MCFragment);
72-
} else {
73-
F = allocFragSpace(0);
74-
}
75-
new (F) MCFragment();
76-
addFragment(F);
77-
}
78-
79-
void MCObjectStreamer::ensureHeadroom(size_t Headroom) {
80-
if (Headroom <= FragSpace)
81-
return;
82-
auto *F = allocFragSpace(Headroom);
83-
new (F) MCFragment();
84-
addFragment(F);
50+
addFragment(getContext().allocFragment<MCFragment>());
8551
}
8652

87-
void MCObjectStreamer::insert(MCFragment *Frag) {
88-
assert(Frag->getKind() != MCFragment::FT_Data &&
53+
void MCObjectStreamer::insert(MCFragment *F) {
54+
assert(F->getKind() != MCFragment::FT_Data &&
8955
"F should have a variable-size tail");
90-
// Frag is not connected to FragSpace. Before modifying CurFrag with
91-
// addFragment(Frag), allocate an empty fragment to maintain FragSpace
92-
// connectivity, potentially reusing CurFrag's associated space.
93-
MCFragment *F;
94-
if (LLVM_LIKELY(sizeof(MCFragment) + NewFragHeadroom <= FragSpace)) {
95-
auto End = reinterpret_cast<size_t>(getCurFragEnd());
96-
F = reinterpret_cast<MCFragment *>(
97-
alignToPowerOf2(End, alignof(MCFragment)));
98-
FragSpace -= size_t(F) - End + sizeof(MCFragment);
99-
} else {
100-
F = allocFragSpace(0);
101-
}
102-
new (F) MCFragment();
103-
104-
addFragment(Frag);
10556
addFragment(F);
57+
newFragment();
10658
}
10759

10860
void MCObjectStreamer::appendContents(ArrayRef<char> Contents) {
109-
ensureHeadroom(Contents.size());
110-
assert(FragSpace >= Contents.size());
111-
llvm::copy(Contents, getCurFragEnd());
112-
CurFrag->FixedSize += Contents.size();
113-
FragSpace -= Contents.size();
61+
CurFrag->appendContents(Contents);
11462
}
11563

11664
void MCObjectStreamer::appendContents(size_t Num, char Elt) {
117-
ensureHeadroom(Num);
118-
MutableArrayRef<char> Data(getCurFragEnd(), Num);
119-
llvm::fill(Data, Elt);
120-
CurFrag->FixedSize += Num;
121-
FragSpace -= Num;
65+
CurFrag->appendContents(Num, Elt);
12266
}
12367

12468
void MCObjectStreamer::addFixup(const MCExpr *Value, MCFixupKind Kind) {
125-
CurFrag->addFixup(MCFixup::create(getCurFragSize(), Value, Kind));
69+
CurFrag->addFixup(MCFixup::create(CurFrag->getFixedSize(), Value, Kind));
12670
}
12771

12872
// As a compile-time optimization, avoid allocating and evaluating an MCExpr
@@ -171,8 +115,6 @@ void MCObjectStreamer::reset() {
171115
}
172116
EmitEHFrame = true;
173117
EmitDebugFrame = false;
174-
FragStorage.clear();
175-
FragSpace = 0;
176118
MCStreamer::reset();
177119
}
178120

@@ -201,6 +143,7 @@ void MCObjectStreamer::emitCFISections(bool EH, bool Debug, bool SFrame) {
201143
void MCObjectStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
202144
SMLoc Loc) {
203145
MCStreamer::emitValueImpl(Value, Size, Loc);
146+
MCFragment *DF = getCurrentFragment();
204147

205148
MCDwarfLineEntry::make(this, getCurrentSectionOnly());
206149

@@ -215,9 +158,9 @@ void MCObjectStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
215158
emitIntValue(AbsValue, Size);
216159
return;
217160
}
218-
ensureHeadroom(Size);
219-
addFixup(Value, MCFixup::getDataKindForSize(Size));
220-
appendContents(Size, 0);
161+
DF->addFixup(MCFixup::create(DF->getContents().size(), Value,
162+
MCFixup::getDataKindForSize(Size)));
163+
DF->appendContents(Size, 0);
221164
}
222165

223166
MCSymbol *MCObjectStreamer::emitCFILabel() {
@@ -251,7 +194,7 @@ void MCObjectStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
251194
// section.
252195
MCFragment *F = CurFrag;
253196
Symbol->setFragment(F);
254-
Symbol->setOffset(F->getFixedSize());
197+
Symbol->setOffset(F->getContents().size());
255198

256199
emitPendingAssignments(Symbol);
257200
}
@@ -317,38 +260,20 @@ void MCObjectStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
317260
F0 = CurFrag;
318261
}
319262

320-
// To maintain connectivity between CurFrag and FragSpace when CurFrag is
321-
// modified, allocate an empty fragment and append it to the fragment list.
322-
// (Subsections[I].second.Tail is not connected to FragSpace.)
323-
MCFragment *F;
324-
if (LLVM_LIKELY(sizeof(MCFragment) + NewFragHeadroom <= FragSpace)) {
325-
auto End = reinterpret_cast<size_t>(getCurFragEnd());
326-
F = reinterpret_cast<MCFragment *>(
327-
alignToPowerOf2(End, alignof(MCFragment)));
328-
FragSpace -= size_t(F) - End + sizeof(MCFragment);
329-
} else {
330-
F = allocFragSpace(0);
331-
}
332-
new (F) MCFragment();
333-
F->setParent(Section);
334-
335263
auto &Subsections = Section->Subsections;
336264
size_t I = 0, E = Subsections.size();
337265
while (I != E && Subsections[I].first < Subsection)
338266
++I;
339267
// If the subsection number is not in the sorted Subsections list, create a
340268
// new fragment list.
341269
if (I == E || Subsections[I].first != Subsection) {
270+
auto *F = getContext().allocFragment<MCFragment>();
271+
F->setParent(Section);
342272
Subsections.insert(Subsections.begin() + I,
343273
{Subsection, MCSection::FragList{F, F}});
344-
Section->CurFragList = &Subsections[I].second;
345-
CurFrag = F;
346-
} else {
347-
Section->CurFragList = &Subsections[I].second;
348-
CurFrag = Subsections[I].second.Tail;
349-
// Ensure CurFrag is associated with FragSpace.
350-
addFragment(F);
351274
}
275+
Section->CurFragList = &Subsections[I].second;
276+
CurFrag = Section->CurFragList->Tail;
352277

353278
// Define the section symbol at subsection 0's initial fragment if required.
354279
if (!NewSec)
@@ -419,15 +344,11 @@ void MCObjectStreamer::emitInstToData(const MCInst &Inst,
419344
MCFragment *F = getCurrentFragment();
420345

421346
// Append the instruction to the data fragment.
422-
size_t CodeOffset = getCurFragSize();
423-
SmallString<16> Content;
347+
size_t CodeOffset = F->getContents().size();
424348
SmallVector<MCFixup, 1> Fixups;
425-
getAssembler().getEmitter().encodeInstruction(Inst, Content, Fixups, STI);
426-
appendContents(Content);
427-
if (CurFrag != F) {
428-
F = CurFrag;
429-
CodeOffset = 0;
430-
}
349+
getAssembler().getEmitter().encodeInstruction(
350+
Inst, F->getContentsForAppending(), Fixups, STI);
351+
F->doneAppending();
431352
F->setHasInstructions(STI);
432353

433354
if (Fixups.empty())

llvm/lib/MC/MCWin64EH.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -318,9 +318,6 @@ static void EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info) {
318318

319319
// Emit the epilog instructions.
320320
if (EnableUnwindV2) {
321-
// Ensure the fixups and appended content apply to the same fragment.
322-
OS->ensureHeadroom(info->EpilogMap.size() * 2);
323-
324321
bool IsLast = true;
325322
for (const auto &Epilog : llvm::reverse(info->EpilogMap)) {
326323
if (IsLast) {

llvm/lib/MC/MCWinCOFFStreamer.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,6 @@ void MCWinCOFFStreamer::emitCOFFSymbolIndex(MCSymbol const *Symbol) {
280280
void MCWinCOFFStreamer::emitCOFFSectionIndex(const MCSymbol *Symbol) {
281281
visitUsedSymbol(*Symbol);
282282
const MCSymbolRefExpr *SRE = MCSymbolRefExpr::create(Symbol, getContext());
283-
ensureHeadroom(2);
284283
addFixup(SRE, FK_SecRel_2);
285284
appendContents(2, 0);
286285
}
@@ -294,7 +293,6 @@ void MCWinCOFFStreamer::emitCOFFSecRel32(const MCSymbol *Symbol,
294293
if (Offset)
295294
MCE = MCBinaryExpr::createAdd(
296295
MCE, MCConstantExpr::create(Offset, getContext()), getContext());
297-
ensureHeadroom(4);
298296
addFixup(MCE, FK_SecRel_4);
299297
// Emit 4 bytes (zeros) to the object file.
300298
appendContents(4, 0);
@@ -310,7 +308,6 @@ void MCWinCOFFStreamer::emitCOFFImgRel32(const MCSymbol *Symbol,
310308
if (Offset)
311309
MCE = MCBinaryExpr::createAdd(
312310
MCE, MCConstantExpr::create(Offset, getContext()), getContext());
313-
ensureHeadroom(4);
314311
addFixup(MCE, FK_Data_4);
315312
// Emit 4 bytes (zeros) to the object file.
316313
appendContents(4, 0);
@@ -321,7 +318,6 @@ void MCWinCOFFStreamer::emitCOFFSecNumber(MCSymbol const *Symbol) {
321318
// Create Symbol for section number.
322319
const MCExpr *MCE = MCCOFFSectionNumberTargetExpr::create(
323320
*Symbol, this->getWriter(), getContext());
324-
ensureHeadroom(4);
325321
addFixup(MCE, FK_Data_4);
326322
// Emit 4 bytes (zeros) to the object file.
327323
appendContents(4, 0);
@@ -332,7 +328,6 @@ void MCWinCOFFStreamer::emitCOFFSecOffset(MCSymbol const *Symbol) {
332328
// Create Symbol for section offset.
333329
const MCExpr *MCE =
334330
MCCOFFSectionOffsetTargetExpr::create(*Symbol, getContext());
335-
ensureHeadroom(4);
336331
addFixup(MCE, FK_Data_4);
337332
// Emit 4 bytes (zeros) to the object file.
338333
appendContents(4, 0);

llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,43 +1034,37 @@ MCELFStreamer &MipsTargetELFStreamer::getStreamer() {
10341034

10351035
void MipsTargetELFStreamer::emitGPRel32Value(const MCExpr *Value) {
10361036
auto &S = getStreamer();
1037-
S.ensureHeadroom(4);
10381037
S.addFixup(Value, Mips::fixup_Mips_GPREL32);
10391038
S.appendContents(4, 0);
10401039
}
10411040

10421041
void MipsTargetELFStreamer::emitGPRel64Value(const MCExpr *Value) {
10431042
auto &S = getStreamer();
1044-
S.ensureHeadroom(8);
10451043
// fixup_Mips_GPREL32 desginates R_MIPS_GPREL32+R_MIPS_64 on MIPS64.
10461044
S.addFixup(Value, Mips::fixup_Mips_GPREL32);
10471045
S.appendContents(8, 0);
10481046
}
10491047

10501048
void MipsTargetELFStreamer::emitDTPRel32Value(const MCExpr *Value) {
10511049
auto &S = getStreamer();
1052-
S.ensureHeadroom(4);
10531050
S.addFixup(Value, Mips::fixup_Mips_DTPREL32);
10541051
S.appendContents(4, 0);
10551052
}
10561053

10571054
void MipsTargetELFStreamer::emitDTPRel64Value(const MCExpr *Value) {
10581055
auto &S = getStreamer();
1059-
S.ensureHeadroom(8);
10601056
S.addFixup(Value, Mips::fixup_Mips_DTPREL64);
10611057
S.appendContents(8, 0);
10621058
}
10631059

10641060
void MipsTargetELFStreamer::emitTPRel32Value(const MCExpr *Value) {
10651061
auto &S = getStreamer();
1066-
S.ensureHeadroom(4);
10671062
S.addFixup(Value, Mips::fixup_Mips_TPREL32);
10681063
S.appendContents(4, 0);
10691064
}
10701065

10711066
void MipsTargetELFStreamer::emitTPRel64Value(const MCExpr *Value) {
10721067
auto &S = getStreamer();
1073-
S.ensureHeadroom(8);
10741068
S.addFixup(Value, Mips::fixup_Mips_TPREL64);
10751069
S.appendContents(8, 0);
10761070
}

0 commit comments

Comments
 (0)