LCOV - code coverage report
Current view: top level - lib/Object - Decompressor.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 33 38 86.8 %
Date: 2018-10-20 13:21:21 Functions: 7 8 87.5 %
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          46 : Expected<Decompressor> Decompressor::create(StringRef Name, StringRef Data,
      22             :                                             bool IsLE, bool Is64Bit) {
      23          46 :   if (!zlib::isAvailable())
      24           0 :     return createError("zlib is not available");
      25             : 
      26          46 :   Decompressor D(Data);
      27          46 :   Error Err = isGnuStyle(Name) ? D.consumeCompressedGnuHeader()
      28          46 :                                : D.consumeCompressedZLibHeader(Is64Bit, IsLE);
      29          46 :   if (Err)
      30             :     return std::move(Err);
      31             :   return D;
      32             : }
      33             : 
      34          46 : Decompressor::Decompressor(StringRef Data)
      35          46 :     : SectionData(Data), DecompressedSize(0) {}
      36             : 
      37          27 : Error Decompressor::consumeCompressedGnuHeader() {
      38             :   if (!SectionData.startswith("ZLIB"))
      39           5 :     return createError("corrupted compressed section header");
      40             : 
      41          22 :   SectionData = SectionData.substr(4);
      42             : 
      43             :   // Consume uncompressed section size (big-endian 8 bytes).
      44          22 :   if (SectionData.size() < 8)
      45           0 :     return createError("corrupted uncompressed section size");
      46          22 :   DecompressedSize = read64be(SectionData.data());
      47          22 :   SectionData = SectionData.substr(8);
      48             : 
      49             :   return Error::success();
      50             : }
      51             : 
      52          19 : Error Decompressor::consumeCompressedZLibHeader(bool Is64Bit,
      53             :                                                 bool IsLittleEndian) {
      54             :   using namespace ELF;
      55          19 :   uint64_t HdrSize = Is64Bit ? sizeof(Elf64_Chdr) : sizeof(Elf32_Chdr);
      56          19 :   if (SectionData.size() < HdrSize)
      57           1 :     return createError("corrupted compressed section header");
      58             : 
      59             :   DataExtractor Extractor(SectionData, IsLittleEndian, 0);
      60          18 :   uint32_t Offset = 0;
      61          18 :   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          18 :   if (Is64Bit)
      68          18 :     Offset += sizeof(Elf64_Word);
      69             : 
      70          18 :   DecompressedSize = Extractor.getUnsigned(
      71             :       &Offset, Is64Bit ? sizeof(Elf64_Xword) : sizeof(Elf32_Word));
      72          18 :   SectionData = SectionData.substr(HdrSize);
      73             :   return Error::success();
      74             : }
      75             : 
      76       22101 : bool Decompressor::isGnuStyle(StringRef Name) {
      77       22101 :   return Name.startswith(".zdebug");
      78             : }
      79             : 
      80       21688 : bool Decompressor::isCompressed(const object::SectionRef &Section) {
      81       21688 :   StringRef Name;
      82       21688 :   if (Section.getName(Name))
      83             :     return false;
      84       21674 :   return Section.isCompressed() || isGnuStyle(Name);
      85             : }
      86             : 
      87           0 : bool Decompressor::isCompressedELFSection(uint64_t Flags, StringRef Name) {
      88           0 :   return (Flags & ELF::SHF_COMPRESSED) || isGnuStyle(Name);
      89             : }
      90             : 
      91          40 : Error Decompressor::decompress(MutableArrayRef<char> Buffer) {
      92          40 :   size_t Size = Buffer.size();
      93          40 :   return zlib::uncompress(SectionData, Buffer.data(), Size);
      94             : }

Generated by: LCOV version 1.13