forked from OSchip/llvm-project
MC: Change MCAssembler::writeSectionData and writeFragmentPadding to take a raw_ostream. NFCI.
Also clean up a couple of hacks where we were writing the section contents to another stream by setting the object writer's stream, writing and setting it back. Part of PR37466. Differential Revision: https://reviews.llvm.org/D47038 llvm-svn: 332858
This commit is contained in:
parent
571a3301ae
commit
147db3e628
|
@ -238,8 +238,8 @@ public:
|
|||
/// defining a separate atom.
|
||||
bool isSymbolLinkerVisible(const MCSymbol &SD) const;
|
||||
|
||||
/// Emit the section contents using the given object writer.
|
||||
void writeSectionData(const MCSection *Section,
|
||||
/// Emit the section contents to \p OS.
|
||||
void writeSectionData(raw_ostream &OS, const MCSection *Section,
|
||||
const MCAsmLayout &Layout) const;
|
||||
|
||||
/// Check whether a given symbol has been flagged with .thumb_func.
|
||||
|
@ -433,10 +433,10 @@ public:
|
|||
FileNames.push_back(FileName);
|
||||
}
|
||||
|
||||
/// Write the necessary bundle padding to the given object writer.
|
||||
/// Write the necessary bundle padding to \p OS.
|
||||
/// Expects a fragment \p F containing instructions and its size \p FSize.
|
||||
void writeFragmentPadding(const MCFragment &F, uint64_t FSize,
|
||||
MCObjectWriter *OW) const;
|
||||
void writeFragmentPadding(raw_ostream &OS, const MCFragment &F,
|
||||
uint64_t FSize) const;
|
||||
|
||||
/// @}
|
||||
|
||||
|
|
|
@ -996,7 +996,7 @@ void ELFObjectWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
|
|||
MAI->compressDebugSections() != DebugCompressionType::None;
|
||||
if (!CompressionEnabled || !SectionName.startswith(".debug_") ||
|
||||
SectionName == ".debug_frame") {
|
||||
Asm.writeSectionData(&Section, Layout);
|
||||
Asm.writeSectionData(getStream(), &Section, Layout);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1006,10 +1006,7 @@ void ELFObjectWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
|
|||
|
||||
SmallVector<char, 128> UncompressedData;
|
||||
raw_svector_ostream VecOS(UncompressedData);
|
||||
raw_pwrite_stream &OldStream = getStream();
|
||||
setStream(VecOS);
|
||||
Asm.writeSectionData(&Section, Layout);
|
||||
setStream(OldStream);
|
||||
Asm.writeSectionData(VecOS, &Section, Layout);
|
||||
|
||||
SmallVector<char, 128> CompressedContents;
|
||||
if (Error E = zlib::compress(
|
||||
|
|
|
@ -450,8 +450,8 @@ void MCAssembler::registerSymbol(const MCSymbol &Symbol, bool *Created) {
|
|||
}
|
||||
}
|
||||
|
||||
void MCAssembler::writeFragmentPadding(const MCFragment &F, uint64_t FSize,
|
||||
MCObjectWriter *OW) const {
|
||||
void MCAssembler::writeFragmentPadding(raw_ostream &OS, const MCFragment &F,
|
||||
uint64_t FSize) const {
|
||||
assert(getBackendPtr() && "Expected assembler backend");
|
||||
// Should NOP padding be written out before this fragment?
|
||||
unsigned BundlePadding = F.getBundlePadding();
|
||||
|
@ -472,31 +472,30 @@ void MCAssembler::writeFragmentPadding(const MCFragment &F, uint64_t FSize,
|
|||
// ----------------------------
|
||||
// ^-------------------^ <- TotalLength
|
||||
unsigned DistanceToBoundary = TotalLength - getBundleAlignSize();
|
||||
if (!getBackend().writeNopData(OW->getStream(), DistanceToBoundary))
|
||||
if (!getBackend().writeNopData(OS, DistanceToBoundary))
|
||||
report_fatal_error("unable to write NOP sequence of " +
|
||||
Twine(DistanceToBoundary) + " bytes");
|
||||
BundlePadding -= DistanceToBoundary;
|
||||
}
|
||||
if (!getBackend().writeNopData(OW->getStream(), BundlePadding))
|
||||
if (!getBackend().writeNopData(OS, BundlePadding))
|
||||
report_fatal_error("unable to write NOP sequence of " +
|
||||
Twine(BundlePadding) + " bytes");
|
||||
}
|
||||
}
|
||||
|
||||
/// Write the fragment \p F to the output file.
|
||||
static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
|
||||
const MCFragment &F) {
|
||||
MCObjectWriter *OW = Asm.getWriterPtr();
|
||||
assert(OW && "Need ObjectWriter to write fragment");
|
||||
|
||||
static void writeFragment(raw_ostream &OS, const MCAssembler &Asm,
|
||||
const MCAsmLayout &Layout, const MCFragment &F) {
|
||||
// FIXME: Embed in fragments instead?
|
||||
uint64_t FragmentSize = Asm.computeFragmentSize(Layout, F);
|
||||
|
||||
Asm.writeFragmentPadding(F, FragmentSize, OW);
|
||||
support::endianness Endian = Asm.getBackend().Endian;
|
||||
|
||||
Asm.writeFragmentPadding(OS, F, FragmentSize);
|
||||
|
||||
// This variable (and its dummy usage) is to participate in the assert at
|
||||
// the end of the function.
|
||||
uint64_t Start = OW->getStream().tell();
|
||||
uint64_t Start = OS.tell();
|
||||
(void) Start;
|
||||
|
||||
++stats::EmittedFragments;
|
||||
|
@ -523,7 +522,7 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
|
|||
// bytes left to fill use the Value and ValueSize to fill the rest.
|
||||
// If we are aligning with nops, ask that target to emit the right data.
|
||||
if (AF.hasEmitNops()) {
|
||||
if (!Asm.getBackend().writeNopData(OW->getStream(), Count))
|
||||
if (!Asm.getBackend().writeNopData(OS, Count))
|
||||
report_fatal_error("unable to write nop sequence of " +
|
||||
Twine(Count) + " bytes");
|
||||
break;
|
||||
|
@ -533,10 +532,16 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
|
|||
for (uint64_t i = 0; i != Count; ++i) {
|
||||
switch (AF.getValueSize()) {
|
||||
default: llvm_unreachable("Invalid size!");
|
||||
case 1: OW->write8 (uint8_t (AF.getValue())); break;
|
||||
case 2: OW->write16(uint16_t(AF.getValue())); break;
|
||||
case 4: OW->write32(uint32_t(AF.getValue())); break;
|
||||
case 8: OW->write64(uint64_t(AF.getValue())); break;
|
||||
case 1: OS << char(AF.getValue()); break;
|
||||
case 2:
|
||||
support::endian::write<uint16_t>(OS, AF.getValue(), Endian);
|
||||
break;
|
||||
case 4:
|
||||
support::endian::write<uint32_t>(OS, AF.getValue(), Endian);
|
||||
break;
|
||||
case 8:
|
||||
support::endian::write<uint64_t>(OS, AF.getValue(), Endian);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -544,17 +549,17 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
|
|||
|
||||
case MCFragment::FT_Data:
|
||||
++stats::EmittedDataFragments;
|
||||
OW->writeBytes(cast<MCDataFragment>(F).getContents());
|
||||
OS << cast<MCDataFragment>(F).getContents();
|
||||
break;
|
||||
|
||||
case MCFragment::FT_Relaxable:
|
||||
++stats::EmittedRelaxableFragments;
|
||||
OW->writeBytes(cast<MCRelaxableFragment>(F).getContents());
|
||||
OS << cast<MCRelaxableFragment>(F).getContents();
|
||||
break;
|
||||
|
||||
case MCFragment::FT_CompactEncodedInst:
|
||||
++stats::EmittedCompactEncodedInstFragments;
|
||||
OW->writeBytes(cast<MCCompactEncodedInstFragment>(F).getContents());
|
||||
OS << cast<MCCompactEncodedInstFragment>(F).getContents();
|
||||
break;
|
||||
|
||||
case MCFragment::FT_Fill: {
|
||||
|
@ -565,10 +570,9 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
|
|||
const unsigned MaxChunkSize = 16;
|
||||
char Data[MaxChunkSize];
|
||||
// Duplicate V into Data as byte vector to reduce number of
|
||||
// writes done. As such, do endian conversion here, not in OW.
|
||||
const bool isLittleEndian = Asm.getContext().getAsmInfo()->isLittleEndian();
|
||||
// writes done. As such, do endian conversion here.
|
||||
for (unsigned I = 0; I != VSize; ++I) {
|
||||
unsigned index = isLittleEndian ? I : (VSize - I - 1);
|
||||
unsigned index = Endian == support::little ? I : (VSize - I - 1);
|
||||
Data[I] = uint8_t(V >> (index * 8));
|
||||
}
|
||||
for (unsigned I = VSize; I < MaxChunkSize; ++I)
|
||||
|
@ -582,25 +586,23 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
|
|||
// Do copies by chunk.
|
||||
StringRef Ref(Data, ChunkSize);
|
||||
for (uint64_t I = 0, E = FragmentSize / ChunkSize; I != E; ++I)
|
||||
OW->writeBytes(Ref);
|
||||
OS << Ref;
|
||||
|
||||
// do remainder if needed.
|
||||
unsigned TrailingCount = FragmentSize % ChunkSize;
|
||||
if (TrailingCount) {
|
||||
StringRef RefTail(Data, TrailingCount);
|
||||
OW->writeBytes(RefTail);
|
||||
}
|
||||
if (TrailingCount)
|
||||
OS.write(Data, TrailingCount);
|
||||
break;
|
||||
}
|
||||
|
||||
case MCFragment::FT_LEB: {
|
||||
const MCLEBFragment &LF = cast<MCLEBFragment>(F);
|
||||
OW->writeBytes(LF.getContents());
|
||||
OS << LF.getContents();
|
||||
break;
|
||||
}
|
||||
|
||||
case MCFragment::FT_Padding: {
|
||||
if (!Asm.getBackend().writeNopData(OW->getStream(), FragmentSize))
|
||||
if (!Asm.getBackend().writeNopData(OS, FragmentSize))
|
||||
report_fatal_error("unable to write nop sequence of " +
|
||||
Twine(FragmentSize) + " bytes");
|
||||
break;
|
||||
|
@ -608,7 +610,7 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
|
|||
|
||||
case MCFragment::FT_SymbolId: {
|
||||
const MCSymbolIdFragment &SF = cast<MCSymbolIdFragment>(F);
|
||||
OW->write32(SF.getSymbol()->getIndex());
|
||||
support::endian::write<uint32_t>(OS, SF.getSymbol()->getIndex(), Endian);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -617,40 +619,40 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
|
|||
const MCOrgFragment &OF = cast<MCOrgFragment>(F);
|
||||
|
||||
for (uint64_t i = 0, e = FragmentSize; i != e; ++i)
|
||||
OW->write8(uint8_t(OF.getValue()));
|
||||
OS << char(OF.getValue());
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case MCFragment::FT_Dwarf: {
|
||||
const MCDwarfLineAddrFragment &OF = cast<MCDwarfLineAddrFragment>(F);
|
||||
OW->writeBytes(OF.getContents());
|
||||
OS << OF.getContents();
|
||||
break;
|
||||
}
|
||||
case MCFragment::FT_DwarfFrame: {
|
||||
const MCDwarfCallFrameFragment &CF = cast<MCDwarfCallFrameFragment>(F);
|
||||
OW->writeBytes(CF.getContents());
|
||||
OS << CF.getContents();
|
||||
break;
|
||||
}
|
||||
case MCFragment::FT_CVInlineLines: {
|
||||
const auto &OF = cast<MCCVInlineLineTableFragment>(F);
|
||||
OW->writeBytes(OF.getContents());
|
||||
OS << OF.getContents();
|
||||
break;
|
||||
}
|
||||
case MCFragment::FT_CVDefRange: {
|
||||
const auto &DRF = cast<MCCVDefRangeFragment>(F);
|
||||
OW->writeBytes(DRF.getContents());
|
||||
OS << DRF.getContents();
|
||||
break;
|
||||
}
|
||||
case MCFragment::FT_Dummy:
|
||||
llvm_unreachable("Should not have been added");
|
||||
}
|
||||
|
||||
assert(OW->getStream().tell() - Start == FragmentSize &&
|
||||
assert(OS.tell() - Start == FragmentSize &&
|
||||
"The stream should advance by fragment size");
|
||||
}
|
||||
|
||||
void MCAssembler::writeSectionData(const MCSection *Sec,
|
||||
void MCAssembler::writeSectionData(raw_ostream &OS, const MCSection *Sec,
|
||||
const MCAsmLayout &Layout) const {
|
||||
assert(getBackendPtr() && "Expected assembler backend");
|
||||
|
||||
|
@ -696,14 +698,13 @@ void MCAssembler::writeSectionData(const MCSection *Sec,
|
|||
return;
|
||||
}
|
||||
|
||||
uint64_t Start = getWriter().getStream().tell();
|
||||
uint64_t Start = OS.tell();
|
||||
(void)Start;
|
||||
|
||||
for (const MCFragment &F : *Sec)
|
||||
writeFragment(*this, Layout, F);
|
||||
writeFragment(OS, *this, Layout, F);
|
||||
|
||||
assert(getWriter().getStream().tell() - Start ==
|
||||
Layout.getSectionAddressSize(Sec));
|
||||
assert(OS.tell() - Start == Layout.getSectionAddressSize(Sec));
|
||||
}
|
||||
|
||||
std::tuple<MCValue, uint64_t, bool>
|
||||
|
|
|
@ -69,13 +69,8 @@ void MCELFStreamer::mergeFragment(MCDataFragment *DF,
|
|||
if (RequiredBundlePadding > 0) {
|
||||
SmallString<256> Code;
|
||||
raw_svector_ostream VecOS(Code);
|
||||
{
|
||||
auto OW = Assembler.getBackend().createObjectWriter(VecOS);
|
||||
|
||||
EF->setBundlePadding(static_cast<uint8_t>(RequiredBundlePadding));
|
||||
|
||||
Assembler.writeFragmentPadding(*EF, FSize, OW.get());
|
||||
}
|
||||
EF->setBundlePadding(static_cast<uint8_t>(RequiredBundlePadding));
|
||||
Assembler.writeFragmentPadding(VecOS, *EF, FSize);
|
||||
|
||||
DF->getContents().append(Code.begin(), Code.end());
|
||||
}
|
||||
|
|
|
@ -919,7 +919,7 @@ void MachObjectWriter::writeObject(MCAssembler &Asm,
|
|||
|
||||
// Write the actual section data.
|
||||
for (const MCSection &Sec : Asm) {
|
||||
Asm.writeSectionData(&Sec, Layout);
|
||||
Asm.writeSectionData(getStream(), &Sec, Layout);
|
||||
|
||||
uint64_t Pad = getPaddingSize(&Sec, Layout);
|
||||
WriteZeros(Pad);
|
||||
|
|
|
@ -853,7 +853,7 @@ void WasmObjectWriter::writeCodeSection(const MCAssembler &Asm,
|
|||
|
||||
encodeULEB128(Size, getStream());
|
||||
FuncSection.setSectionOffset(getStream().tell() - Section.ContentsOffset);
|
||||
Asm.writeSectionData(&FuncSection, Layout);
|
||||
Asm.writeSectionData(getStream(), &FuncSection, Layout);
|
||||
}
|
||||
|
||||
// Apply fixups.
|
||||
|
@ -1016,7 +1016,7 @@ void WasmObjectWriter::writeCustomSections(const MCAssembler &Asm,
|
|||
startCustomSection(Section, CustomSection.Name);
|
||||
|
||||
Sec->setSectionOffset(getStream().tell() - Section.ContentsOffset);
|
||||
Asm.writeSectionData(Sec, Layout);
|
||||
Asm.writeSectionData(getStream(), Sec, Layout);
|
||||
|
||||
CustomSection.OutputContentsOffset = Section.ContentsOffset;
|
||||
CustomSection.OutputIndex = Section.Index;
|
||||
|
|
|
@ -608,15 +608,7 @@ uint32_t WinCOFFObjectWriter::writeSectionContents(MCAssembler &Asm,
|
|||
// to CRC the data before we dump it into the object file.
|
||||
SmallVector<char, 128> Buf;
|
||||
raw_svector_ostream VecOS(Buf);
|
||||
raw_pwrite_stream &OldStream = getStream();
|
||||
|
||||
// Redirect the output stream to our buffer and fill our buffer with
|
||||
// the section data.
|
||||
setStream(VecOS);
|
||||
Asm.writeSectionData(&MCSec, Layout);
|
||||
|
||||
// Reset the stream back to what it was before.
|
||||
setStream(OldStream);
|
||||
Asm.writeSectionData(VecOS, &MCSec, Layout);
|
||||
|
||||
// Write the section contents to the object file.
|
||||
getStream() << Buf;
|
||||
|
|
|
@ -516,7 +516,7 @@ bool generateDsymCompanion(const DebugMap &DM, MCStreamer &MS,
|
|||
|
||||
uint64_t Pos = OutFile.tell();
|
||||
Writer.WriteZeros(alignTo(Pos, Sec.getAlignment()) - Pos);
|
||||
MCAsm.writeSectionData(&Sec, Layout);
|
||||
MCAsm.writeSectionData(OutFile, &Sec, Layout);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
Loading…
Reference in New Issue