LCOV - code coverage report
Current view: top level - lib/Object - SymbolSize.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 40 40 100.0 %
Date: 2018-10-20 13:21:21 Functions: 4 4 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- SymbolSize.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/SymbolSize.h"
      11             : #include "llvm/ADT/STLExtras.h"
      12             : #include "llvm/Object/COFF.h"
      13             : #include "llvm/Object/ELFObjectFile.h"
      14             : #include "llvm/Object/MachO.h"
      15             : 
      16             : using namespace llvm;
      17             : using namespace object;
      18             : 
      19             : // Orders increasingly by (SectionID, Address).
      20        1900 : int llvm::object::compareAddress(const SymEntry *A, const SymEntry *B) {
      21        1900 :   if (A->SectionID != B->SectionID)
      22        1836 :     return A->SectionID < B->SectionID ? -1 : 1;
      23         537 :   if (A->Address != B->Address)
      24         427 :     return A->Address < B->Address ? -1 : 1;
      25             :   return 0;
      26             : }
      27             : 
      28         255 : static unsigned getSectionID(const ObjectFile &O, SectionRef Sec) {
      29             :   if (auto *M = dyn_cast<MachOObjectFile>(&O))
      30         165 :     return M->getSectionID(Sec);
      31          90 :   return cast<COFFObjectFile>(O).getSectionID(Sec);
      32             : }
      33             : 
      34         338 : static unsigned getSymbolSectionID(const ObjectFile &O, SymbolRef Sym) {
      35             :   if (auto *M = dyn_cast<MachOObjectFile>(&O))
      36         128 :     return M->getSymbolSectionID(Sym);
      37         210 :   return cast<COFFObjectFile>(O).getSymbolSectionID(Sym);
      38             : }
      39             : 
      40             : std::vector<std::pair<SymbolRef, uint64_t>>
      41         217 : llvm::object::computeSymbolSizes(const ObjectFile &O) {
      42             :   std::vector<std::pair<SymbolRef, uint64_t>> Ret;
      43             : 
      44             :   if (const auto *E = dyn_cast<ELFObjectFileBase>(&O)) {
      45         185 :     auto Syms = E->symbols();
      46         740 :     if (Syms.begin() == Syms.end())
      47          16 :       Syms = E->getDynamicSymbolIterators();
      48    13172289 :     for (ELFSymbolRef Sym : Syms)
      49    13171919 :       Ret.push_back({Sym, Sym.getSize()});
      50             :     return Ret;
      51             :   }
      52             : 
      53             :   // Collect sorted symbol addresses. Include dummy addresses for the end
      54             :   // of each section.
      55             :   std::vector<SymEntry> Addresses;
      56             :   unsigned SymNum = 0;
      57         370 :   for (symbol_iterator I = O.symbol_begin(), E = O.symbol_end(); I != E; ++I) {
      58         338 :     SymbolRef Sym = *I;
      59         338 :     uint64_t Value = Sym.getValue();
      60         338 :     Addresses.push_back({I, Value, SymNum, getSymbolSectionID(O, Sym)});
      61         338 :     ++SymNum;
      62             :   }
      63         287 :   for (SectionRef Sec : O.sections()) {
      64         255 :     uint64_t Address = Sec.getAddress();
      65         255 :     uint64_t Size = Sec.getSize();
      66         510 :     Addresses.push_back(
      67         765 :         {O.symbol_end(), Address + Size, 0, getSectionID(O, Sec)});
      68             :   }
      69             : 
      70          32 :   if (Addresses.empty())
      71             :     return Ret;
      72             : 
      73             :   array_pod_sort(Addresses.begin(), Addresses.end(), compareAddress);
      74             : 
      75             :   // Compute the size as the gap to the next symbol
      76         625 :   for (unsigned I = 0, N = Addresses.size() - 1; I < N; ++I) {
      77         561 :     auto &P = Addresses[I];
      78         561 :     if (P.I == O.symbol_end())
      79             :       continue;
      80             : 
      81             :     // If multiple symbol have the same address, give both the same size.
      82         318 :     unsigned NextI = I + 1;
      83         553 :     while (NextI < N && Addresses[NextI].Address == P.Address)
      84         235 :       ++NextI;
      85             : 
      86         318 :     uint64_t Size = Addresses[NextI].Address - P.Address;
      87         318 :     P.Address = Size;
      88             :   }
      89             : 
      90             :   // Assign the sorted symbols in the original order.
      91          32 :   Ret.resize(SymNum);
      92         625 :   for (SymEntry &P : Addresses) {
      93         593 :     if (P.I == O.symbol_end())
      94             :       continue;
      95         676 :     Ret[P.Number] = {*P.I, P.Address};
      96             :   }
      97             :   return Ret;
      98             : }

Generated by: LCOV version 1.13