LCOV - code coverage report
Current view: top level - lib/Object - SymbolSize.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 48 48 100.0 %
Date: 2017-09-14 15:23:50 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        1824 : int llvm::object::compareAddress(const SymEntry *A, const SymEntry *B) {
      21        1824 :   if (A->SectionID != B->SectionID)
      22        1334 :     return A->SectionID < B->SectionID ? -1 : 1;
      23         490 :   if (A->Address != B->Address)
      24         362 :     return A->Address < B->Address ? -1 : 1;
      25             :   return 0;
      26             : }
      27             : 
      28         249 : static unsigned getSectionID(const ObjectFile &O, SectionRef Sec) {
      29         249 :   if (auto *M = dyn_cast<MachOObjectFile>(&O))
      30         159 :     return M->getSectionID(Sec);
      31          90 :   return cast<COFFObjectFile>(O).getSectionID(Sec);
      32             : }
      33             : 
      34         318 : static unsigned getSymbolSectionID(const ObjectFile &O, SymbolRef Sym) {
      35         318 :   if (auto *M = dyn_cast<MachOObjectFile>(&O))
      36         108 :     return M->getSymbolSectionID(Sym);
      37         210 :   return cast<COFFObjectFile>(O).getSymbolSectionID(Sym);
      38             : }
      39             : 
      40             : std::vector<std::pair<SymbolRef, uint64_t>>
      41         178 : llvm::object::computeSymbolSizes(const ObjectFile &O) {
      42         178 :   std::vector<std::pair<SymbolRef, uint64_t>> Ret;
      43             : 
      44         178 :   if (const auto *E = dyn_cast<ELFObjectFileBase>(&O)) {
      45         147 :     auto Syms = E->symbols();
      46         441 :     if (Syms.begin() == Syms.end())
      47          12 :       Syms = E->getDynamicSymbolIterators();
      48    16209282 :     for (ELFSymbolRef Sym : Syms)
      49    24313041 :       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          31 :   std::vector<SymEntry> Addresses;
      56          31 :   unsigned SymNum = 0;
      57         380 :   for (symbol_iterator I = O.symbol_begin(), E = O.symbol_end(); I != E; ++I) {
      58         318 :     SymbolRef Sym = *I;
      59         318 :     uint64_t Value = Sym.getValue();
      60         636 :     Addresses.push_back({I, Value, SymNum, getSymbolSectionID(O, Sym)});
      61         318 :     ++SymNum;
      62             :   }
      63         373 :   for (SectionRef Sec : O.sections()) {
      64         249 :     uint64_t Address = Sec.getAddress();
      65         249 :     uint64_t Size = Sec.getSize();
      66         996 :     Addresses.push_back(
      67         996 :         {O.symbol_end(), Address + Size, 0, getSectionID(O, Sec)});
      68             :   }
      69          93 :   array_pod_sort(Addresses.begin(), Addresses.end(), compareAddress);
      70             : 
      71             :   // Compute the size as the gap to the next symbol
      72         598 :   for (unsigned I = 0, N = Addresses.size() - 1; I < N; ++I) {
      73        1072 :     auto &P = Addresses[I];
      74        1072 :     if (P.I == O.symbol_end())
      75         237 :       continue;
      76             : 
      77             :     // If multiple symbol have the same address, give both the same size.
      78         299 :     unsigned NextI = I + 1;
      79        1087 :     while (NextI < N && Addresses[NextI].Address == P.Address)
      80         169 :       ++NextI;
      81             : 
      82         598 :     uint64_t Size = Addresses[NextI].Address - P.Address;
      83         299 :     P.Address = Size;
      84             :   }
      85             : 
      86             :   // Assign the sorted symbols in the original order.
      87          31 :   Ret.resize(SymNum);
      88         691 :   for (SymEntry &P : Addresses) {
      89        1134 :     if (P.I == O.symbol_end())
      90         249 :       continue;
      91        1590 :     Ret[P.Number] = {*P.I, P.Address};
      92             :   }
      93             :   return Ret;
      94             : }

Generated by: LCOV version 1.13