diff options
Diffstat (limited to 'lib/MC')
-rw-r--r-- | lib/MC/MCAsmInfo.cpp | 2 | ||||
-rw-r--r-- | lib/MC/MCAssembler.cpp | 47 | ||||
-rw-r--r-- | lib/MC/MCContext.cpp | 19 | ||||
-rw-r--r-- | lib/MC/MCObjectStreamer.cpp | 7 |
4 files changed, 67 insertions, 8 deletions
diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp index f09bbd1a66..c78d3d574a 100644 --- a/lib/MC/MCAsmInfo.cpp +++ b/lib/MC/MCAsmInfo.cpp @@ -100,6 +100,8 @@ MCAsmInfo::MCAsmInfo() { // architecture basis. // - The target subclasses for AArch64, ARM, and X86 handle these cases UseIntegratedAssembler = false; + + CompressDebugSections = false; } MCAsmInfo::~MCAsmInfo() { diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 910295c5d2..fcf1b50a4f 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -28,6 +28,9 @@ #include "llvm/Support/LEB128.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Compression.h" +#include "llvm/Support/Host.h" using namespace llvm; @@ -230,6 +233,39 @@ MCEncodedFragmentWithFixups::~MCEncodedFragmentWithFixups() { /* *** */ +const SmallVectorImpl<char> &MCCompressedFragment::getCompressedContents() const { + assert(getParent()->size() == 1 && + "Only compress sections containing a single fragment"); + if (CompressedContents.empty()) { + std::unique_ptr<MemoryBuffer> CompressedSection; + zlib::Status Success = + zlib::compress(StringRef(getContents().data(), getContents().size()), + CompressedSection); + (void)Success; + assert(Success == zlib::StatusOK); + CompressedContents.push_back('Z'); + CompressedContents.push_back('L'); + CompressedContents.push_back('I'); + CompressedContents.push_back('B'); + uint64_t Size = getContents().size(); + if (sys::IsLittleEndianHost) + Size = sys::SwapByteOrder(Size); + CompressedContents.append(reinterpret_cast<char *>(&Size), + reinterpret_cast<char *>(&Size + 1)); + CompressedContents.append(CompressedSection->getBuffer().begin(), + CompressedSection->getBuffer().end()); + } + return CompressedContents; +} + +SmallVectorImpl<char> &MCCompressedFragment::getContents() { + assert(CompressedContents.empty() && + "Fragment contents should not be altered after compression"); + return MCDataFragment::getContents(); +} + +/* *** */ + MCSectionData::MCSectionData() : Section(0) {} MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A) @@ -430,6 +466,8 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout, case MCFragment::FT_Relaxable: case MCFragment::FT_CompactEncodedInst: return cast<MCEncodedFragment>(F).getContents().size(); + case MCFragment::FT_Compressed: + return cast<MCCompressedFragment>(F).getCompressedContents().size(); case MCFragment::FT_Fill: return cast<MCFillFragment>(F).getSize(); @@ -618,6 +656,11 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, break; } + case MCFragment::FT_Compressed: + ++stats::EmittedDataFragments; + OW->WriteBytes(cast<MCCompressedFragment>(F).getCompressedContents()); + break; + case MCFragment::FT_Data: ++stats::EmittedDataFragments; writeFragmentContents(F, OW); @@ -694,6 +737,7 @@ void MCAssembler::writeSectionData(const MCSectionData *SD, ie = SD->end(); it != ie; ++it) { switch (it->getKind()) { default: llvm_unreachable("Invalid fragment in virtual section!"); + case MCFragment::FT_Compressed: case MCFragment::FT_Data: { // Check that we aren't trying to write a non-zero contents (or fixups) // into a virtual section. This is to support clients which use standard @@ -1021,6 +1065,8 @@ void MCFragment::dump() { switch (getKind()) { case MCFragment::FT_Align: OS << "MCAlignFragment"; break; case MCFragment::FT_Data: OS << "MCDataFragment"; break; + case MCFragment::FT_Compressed: + OS << "MCCompressedFragment"; break; case MCFragment::FT_CompactEncodedInst: OS << "MCCompactEncodedInstFragment"; break; case MCFragment::FT_Fill: OS << "MCFillFragment"; break; @@ -1047,6 +1093,7 @@ void MCFragment::dump() { << " MaxBytesToEmit:" << AF->getMaxBytesToEmit() << ">"; break; } + case MCFragment::FT_Compressed: case MCFragment::FT_Data: { const MCDataFragment *DF = cast<MCDataFragment>(this); OS << "\n "; diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp index ede3b3cd23..b228d18ba7 100644 --- a/lib/MC/MCContext.cpp +++ b/lib/MC/MCContext.cpp @@ -37,13 +37,13 @@ typedef std::map<SectionGroupPair, const MCSectionCOFF *> COFFUniqueMapTy; MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri, const MCObjectFileInfo *mofi, const SourceMgr *mgr, - bool DoAutoReset) : - SrcMgr(mgr), MAI(mai), MRI(mri), MOFI(mofi), - Allocator(), Symbols(Allocator), UsedNames(Allocator), - NextUniqueID(0), - CurrentDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0), - DwarfLocSeen(false), GenDwarfForAssembly(false), GenDwarfFileNumber(0), - AllowTemporaryLabels(true), DwarfCompileUnitID(0), AutoReset(DoAutoReset) { + bool DoAutoReset) + : SrcMgr(mgr), MAI(mai), MRI(mri), MOFI(mofi), Allocator(), + Symbols(Allocator), UsedNames(Allocator), NextUniqueID(0), + CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0), DwarfLocSeen(false), + GenDwarfForAssembly(false), GenDwarfFileNumber(0), + AllowTemporaryLabels(true), DwarfCompileUnitID(0), + AutoReset(DoAutoReset) { error_code EC = llvm::sys::fs::current_path(CompilationDir); if (EC) @@ -251,6 +251,11 @@ getELFSection(StringRef Section, unsigned Type, unsigned Flags, ELFUniquingMap = new ELFUniqueMapTy(); ELFUniqueMapTy &Map = *(ELFUniqueMapTy*)ELFUniquingMap; + SmallString<32> ZDebugName; + if (MAI->compressDebugSections() && Section.startswith(".debug_") && + Section != ".debug_frame") + Section = (".z" + Section.drop_front(1)).toStringRef(ZDebugName); + // Do the lookup, if we have a hit, return it. std::pair<ELFUniqueMapTy::iterator, bool> Entry = Map.insert( std::make_pair(SectionGroupPair(Section, Group), (MCSectionELF *)0)); diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp index 809cb11e36..35786accb4 100644 --- a/lib/MC/MCObjectStreamer.cpp +++ b/lib/MC/MCObjectStreamer.cpp @@ -20,6 +20,7 @@ #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/MC/MCSectionELF.h" using namespace llvm; MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, @@ -63,7 +64,11 @@ MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const { // When bundling is enabled, we don't want to add data to a fragment that // already has instructions (see MCELFStreamer::EmitInstToData for details) if (!F || (Assembler->isBundlingEnabled() && F->hasInstructions())) { - F = new MCDataFragment(); + const auto *Sec = dyn_cast<MCSectionELF>(&getCurrentSectionData()->getSection()); + if (Sec && Sec->getSectionName().startswith(".zdebug_")) + F = new MCCompressedFragment(); + else + F = new MCDataFragment(); insert(F); } return F; |