LLVM  13.0.0git
SymbolSize.cpp
Go to the documentation of this file.
1 //===- SymbolSize.cpp -----------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/Object/COFF.h"
13 #include "llvm/Object/MachO.h"
14 #include "llvm/Object/Wasm.h"
15 
16 using namespace llvm;
17 using namespace object;
18 
19 // Orders increasingly by (SectionID, Address).
21  if (A->SectionID != B->SectionID)
22  return A->SectionID < B->SectionID ? -1 : 1;
23  if (A->Address != B->Address)
24  return A->Address < B->Address ? -1 : 1;
25  return 0;
26 }
27 
28 static unsigned getSectionID(const ObjectFile &O, SectionRef Sec) {
29  if (auto *M = dyn_cast<MachOObjectFile>(&O))
30  return M->getSectionID(Sec);
31  if (isa<WasmObjectFile>(&O))
32  return Sec.getIndex();
33 
34  return cast<COFFObjectFile>(O).getSectionID(Sec);
35 }
36 
37 static unsigned getSymbolSectionID(const ObjectFile &O, SymbolRef Sym) {
38  if (auto *M = dyn_cast<MachOObjectFile>(&O))
39  return M->getSymbolSectionID(Sym);
40  if (const auto *M = dyn_cast<WasmObjectFile>(&O))
41  return M->getSymbolSectionId(Sym);
42  return cast<COFFObjectFile>(O).getSymbolSectionID(Sym);
43 }
44 
45 std::vector<std::pair<SymbolRef, uint64_t>>
47  std::vector<std::pair<SymbolRef, uint64_t>> Ret;
48 
49  if (const auto *E = dyn_cast<ELFObjectFileBase>(&O)) {
50  auto Syms = E->symbols();
51  if (Syms.empty())
52  Syms = E->getDynamicSymbolIterators();
53  for (ELFSymbolRef Sym : Syms)
54  Ret.push_back({Sym, Sym.getSize()});
55  return Ret;
56  }
57 
58  // Collect sorted symbol addresses. Include dummy addresses for the end
59  // of each section.
60  std::vector<SymEntry> Addresses;
61  unsigned SymNum = 0;
62  for (symbol_iterator I = O.symbol_begin(), E = O.symbol_end(); I != E; ++I) {
63  SymbolRef Sym = *I;
64  Expected<uint64_t> ValueOrErr = Sym.getValue();
65  if (!ValueOrErr)
66  // TODO: Actually report errors helpfully.
67  report_fatal_error(ValueOrErr.takeError());
68  Addresses.push_back({I, *ValueOrErr, SymNum, getSymbolSectionID(O, Sym)});
69  ++SymNum;
70  }
71  for (SectionRef Sec : O.sections()) {
72  uint64_t Address = Sec.getAddress();
73  uint64_t Size = Sec.getSize();
74  Addresses.push_back(
75  {O.symbol_end(), Address + Size, 0, getSectionID(O, Sec)});
76  }
77 
78  if (Addresses.empty())
79  return Ret;
80 
81  array_pod_sort(Addresses.begin(), Addresses.end(), compareAddress);
82 
83  // Compute the size as the gap to the next symbol
84  for (unsigned I = 0, N = Addresses.size() - 1; I < N; ++I) {
85  auto &P = Addresses[I];
86  if (P.I == O.symbol_end())
87  continue;
88 
89  // If multiple symbol have the same address, give both the same size.
90  unsigned NextI = I + 1;
91  while (NextI < N && Addresses[NextI].Address == P.Address)
92  ++NextI;
93 
94  uint64_t Size = Addresses[NextI].Address - P.Address;
95  P.Address = Size;
96  }
97 
98  // Assign the sorted symbols in the original order.
99  Ret.resize(SymNum);
100  for (SymEntry &P : Addresses) {
101  if (P.I == O.symbol_end())
102  continue;
103  Ret[P.Number] = {*P.I, P.Address};
104  }
105  return Ret;
106 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
llvm::array_pod_sort
void array_pod_sort(IteratorTy Start, IteratorTy End)
array_pod_sort - This sorts an array with the specified start and end extent.
Definition: STLExtras.h:1381
llvm
Definition: AllocatorList.h:23
llvm::object::SymbolRef::getValue
Expected< uint64_t > getValue() const
Return the value of the symbol depending on the object this can be an offset or a virtual address.
Definition: ObjectFile.h:397
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::object::SymEntry
Definition: SymbolSize.h:18
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
SymbolSize.h
llvm::MipsISD::Ret
@ Ret
Definition: MipsISelLowering.h:116
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
STLExtras.h
MachO.h
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::report_fatal_error
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:140
Wasm.h
llvm::object::SectionRef
This is a value type class that represents a single section in the list of sections in the object fil...
Definition: ObjectFile.h:80
llvm::object::compareAddress
int compareAddress(const SymEntry *A, const SymEntry *B)
Definition: SymbolSize.cpp:20
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:179
object
bar al al movzbl eax ret Missed when stored in a memory object
Definition: README.txt:1411
llvm::object::symbol_iterator
Definition: ObjectFile.h:207
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::HighlightColor::Address
@ Address
llvm::object::ELFSymbolRef
Definition: ELFObjectFile.h:139
llvm::object::ObjectFile
This class is the base class for all object file types.
Definition: ObjectFile.h:228
ELFObjectFile.h
llvm::object::computeSymbolSizes
std::vector< std::pair< SymbolRef, uint64_t > > computeSymbolSizes(const ObjectFile &O)
Definition: SymbolSize.cpp:46
getSectionID
static unsigned getSectionID(const ObjectFile &O, SectionRef Sec)
Definition: SymbolSize.cpp:28
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition: Error.h:557
COFF.h
getSymbolSectionID
static unsigned getSymbolSectionID(const ObjectFile &O, SymbolRef Sym)
Definition: SymbolSize.cpp:37
N
#define N
llvm::object::SymbolRef
This is a value type class that represents a single symbol in the list of symbols in the object file.
Definition: ObjectFile.h:167