LCOV - code coverage report
Current view: top level - lib/Object - Decompressor.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 40 43 93.0 %
Date: 2017-09-14 15:23:50 Functions: 8 8 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- Decompressor.cpp --------------------------------------------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : 
      10             : #include "llvm/Object/Decompressor.h"
      11             : #include "llvm/BinaryFormat/ELF.h"
      12             : #include "llvm/Object/ELFObjectFile.h"
      13             : #include "llvm/Support/Compression.h"
      14             : #include "llvm/Support/DataExtractor.h"
      15             : #include "llvm/Support/Endian.h"
      16             : 
      17             : using namespace llvm;
      18             : using namespace llvm::support::endian;
      19             : using namespace object;
      20             : 
      21          45 : Expected<Decompressor> Decompressor::create(StringRef Name, StringRef Data,
      22             :                                             bool IsLE, bool Is64Bit) {
      23          45 :   if (!zlib::isAvailable())
      24           0 :     return createError("zlib is not available");
      25             : 
      26          45 :   Decompressor D(Data);
      27          45 :   Error Err = isGnuStyle(Name) ? D.consumeCompressedGnuHeader()
      28          45 :                                : D.consumeCompressedZLibHeader(Is64Bit, IsLE);
      29          45 :   if (Err)
      30          24 :     return std::move(Err);
      31             :   return D;
      32             : }
      33             : 
      34          45 : Decompressor::Decompressor(StringRef Data)
      35          45 :     : SectionData(Data), DecompressedSize(0) {}
      36             : 
      37          29 : Error Decompressor::consumeCompressedGnuHeader() {
      38          53 :   if (!SectionData.startswith("ZLIB"))
      39           5 :     return createError("corrupted compressed section header");
      40             : 
      41          48 :   SectionData = SectionData.substr(4);
      42             : 
      43             :   // Consume uncompressed section size (big-endian 8 bytes).
      44          24 :   if (SectionData.size() < 8)
      45           0 :     return createError("corrupted uncompressed section size");
      46          48 :   DecompressedSize = read64be(SectionData.data());
      47          48 :   SectionData = SectionData.substr(8);
      48             : 
      49          72 :   return Error::success();
      50             : }
      51             : 
      52          16 : Error Decompressor::consumeCompressedZLibHeader(bool Is64Bit,
      53             :                                                 bool IsLittleEndian) {
      54             :   using namespace ELF;
      55          16 :   uint64_t HdrSize = Is64Bit ? sizeof(Elf64_Chdr) : sizeof(Elf32_Chdr);
      56          32 :   if (SectionData.size() < HdrSize)
      57           1 :     return createError("corrupted compressed section header");
      58             : 
      59          30 :   DataExtractor Extractor(SectionData, IsLittleEndian, 0);
      60          15 :   uint32_t Offset = 0;
      61          15 :   if (Extractor.getUnsigned(&Offset, Is64Bit ? sizeof(Elf64_Word)
      62             :                                              : sizeof(Elf32_Word)) !=
      63             :       ELFCOMPRESS_ZLIB)
      64           0 :     return createError("unsupported compression type");
      65             : 
      66             :   // Skip Elf64_Chdr::ch_reserved field.
      67          15 :   if (Is64Bit)
      68          15 :     Offset += sizeof(Elf64_Word);
      69             : 
      70          15 :   DecompressedSize = Extractor.getUnsigned(
      71             :       &Offset, Is64Bit ? sizeof(Elf64_Xword) : sizeof(Elf32_Word));
      72          30 :   SectionData = SectionData.substr(HdrSize);
      73          45 :   return Error::success();
      74             : }
      75             : 
      76      217696 : bool Decompressor::isGnuStyle(StringRef Name) {
      77      435392 :   return Name.startswith(".zdebug");
      78             : }
      79             : 
      80       15529 : bool Decompressor::isCompressed(const object::SectionRef &Section) {
      81       15529 :   StringRef Name;
      82       15529 :   if (Section.getName(Name))
      83             :     return false;
      84       15528 :   return Section.isCompressed() || isGnuStyle(Name);
      85             : }
      86             : 
      87      201761 : bool Decompressor::isCompressedELFSection(uint64_t Flags, StringRef Name) {
      88      201761 :   return (Flags & ELF::SHF_COMPRESSED) || isGnuStyle(Name);
      89             : }
      90             : 
      91          39 : Error Decompressor::decompress(MutableArrayRef<char> Buffer) {
      92          39 :   size_t Size = Buffer.size();
      93          39 :   return zlib::uncompress(SectionData, Buffer.data(), Size);
      94             : }

Generated by: LCOV version 1.13