summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-dwp/llvm-dwp.cpp
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2016-02-19 01:51:44 +0000
committerDavid Blaikie <dblaikie@gmail.com>2016-02-19 01:51:44 +0000
commit74f5b282110eb6a548f93738e67b707d654b0882 (patch)
tree1cc154d2782eb63db2b086ddb522c45dafacfba9 /llvm/tools/llvm-dwp/llvm-dwp.cpp
parent5f1c2851ccc865072ecf3a097a91483eec7d8766 (diff)
downloadbcm5719-llvm-74f5b282110eb6a548f93738e67b707d654b0882.tar.gz
bcm5719-llvm-74f5b282110eb6a548f93738e67b707d654b0882.zip
llvm-dwp: Support compressed input
llvm-svn: 261296
Diffstat (limited to 'llvm/tools/llvm-dwp/llvm-dwp.cpp')
-rw-r--r--llvm/tools/llvm-dwp/llvm-dwp.cpp50
1 files changed, 45 insertions, 5 deletions
diff --git a/llvm/tools/llvm-dwp/llvm-dwp.cpp b/llvm/tools/llvm-dwp/llvm-dwp.cpp
index 9bc32760591..52dee3add48 100644
--- a/llvm/tools/llvm-dwp/llvm-dwp.cpp
+++ b/llvm/tools/llvm-dwp/llvm-dwp.cpp
@@ -12,6 +12,7 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCTargetOptionsCommandFlags.h"
#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Compression.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MathExtras.h"
@@ -237,7 +238,7 @@ static void writeIndex(MCStreamer &Out, MCSection *Section,
auto H = S & Mask;
while (Buckets[H]) {
assert(S != IndexEntries[Buckets[H] - 1].Signature &&
- "Duplicate type unit");
+ "Duplicate unit");
H = (H + (((S >> 32) & Mask) | 1)) % Buckets.size();
}
Buckets[H] = i + 1;
@@ -270,6 +271,22 @@ static void writeIndex(MCStreamer &Out, MCSection *Section,
writeIndexTable(Out, ContributionOffsets, IndexEntries,
&DWARFUnitIndex::Entry::SectionContribution::Length);
}
+static bool consumeCompressedDebugSectionHeader(StringRef &data,
+ uint64_t &OriginalSize) {
+ // Consume "ZLIB" prefix.
+ if (!data.startswith("ZLIB"))
+ return false;
+ data = data.substr(4);
+ // Consume uncompressed section size (big-endian 8 bytes).
+ DataExtractor extractor(data, false, 8);
+ uint32_t Offset = 0;
+ OriginalSize = extractor.getU64(&Offset);
+ if (Offset == 0)
+ return false;
+ data = data.substr(Offset);
+ return true;
+}
+
static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
const auto &MCOFI = *Out.getContext().getObjectFileInfo();
MCSection *const StrSection = MCOFI.getDwarfStrDWOSection();
@@ -311,20 +328,43 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
StringRef CurCUIndexSection;
StringRef CurTUIndexSection;
+ SmallVector<SmallString<32>, 4> UncompressedSections;
+
for (const auto &Section : ErrOrObj->getBinary()->sections()) {
+ if (Section.isBSS())
+ continue;
+ if (Section.isVirtual())
+ continue;
+
StringRef Name;
if (std::error_code Err = Section.getName(Name))
return Err;
- auto SectionPair =
- KnownSections.find(Name.substr(Name.find_first_not_of("._")));
- if (SectionPair == KnownSections.end())
- continue;
+ Name = Name.substr(Name.find_first_not_of("._"));
StringRef Contents;
if (auto Err = Section.getContents(Contents))
return Err;
+ if (Name.startswith("zdebug_")) {
+ uint64_t OriginalSize;
+ if (!zlib::isAvailable() ||
+ !consumeCompressedDebugSectionHeader(Contents, OriginalSize))
+ continue;
+ UncompressedSections.resize(UncompressedSections.size() + 1);
+ if (zlib::uncompress(Contents, UncompressedSections.back(), OriginalSize) !=
+ zlib::StatusOK) {
+ UncompressedSections.pop_back();
+ continue;
+ }
+ Name = Name.substr(1);
+ Contents = UncompressedSections.back();
+ }
+
+ auto SectionPair = KnownSections.find(Name);
+ if (SectionPair == KnownSections.end())
+ continue;
+
if (DWARFSectionKind Kind = SectionPair->second.second) {
auto Index = Kind - DW_SECT_INFO;
if (Kind != DW_SECT_TYPES) {
OpenPOWER on IntegriCloud