LLVM  14.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"
16 
17 using namespace llvm;
18 using namespace object;
19 
20 // Orders increasingly by (SectionID, Address).
22  if (A->SectionID != B->SectionID)
23  return A->SectionID < B->SectionID ? -1 : 1;
24  if (A->Address != B->Address)
25  return A->Address < B->Address ? -1 : 1;
26  return 0;
27 }
28 
29 static unsigned getSectionID(const ObjectFile &O, SectionRef Sec) {
30  if (auto *M = dyn_cast<MachOObjectFile>(&O))
31  return M->getSectionID(Sec);
32  if (isa<WasmObjectFile>(&O))
33  return Sec.getIndex();
34  if (isa<XCOFFObjectFile>(&O))
35  return Sec.getIndex();
36  return cast<COFFObjectFile>(O).getSectionID(Sec);
37 }
38 
39 static unsigned getSymbolSectionID(const ObjectFile &O, SymbolRef Sym) {
40  if (auto *M = dyn_cast<MachOObjectFile>(&O))
41  return M->getSymbolSectionID(Sym);
42  if (const auto *M = dyn_cast<WasmObjectFile>(&O))
43  return M->getSymbolSectionId(Sym);
44  if (const auto *M = dyn_cast<XCOFFObjectFile>(&O))
45  return M->getSymbolSectionID(Sym);
46  return cast<COFFObjectFile>(O).getSymbolSectionID(Sym);
47 }
48 
49 std::vector<std::pair<SymbolRef, uint64_t>>
51  std::vector<std::pair<SymbolRef, uint64_t>> Ret;
52 
53  if (const auto *E = dyn_cast<ELFObjectFileBase>(&O)) {
54  auto Syms = E->symbols();
55  if (Syms.empty())
56  Syms = E->getDynamicSymbolIterators();
57  for (ELFSymbolRef Sym : Syms)
58  Ret.push_back({Sym, Sym.getSize()});
59  return Ret;
60  }
61 
62  // Collect sorted symbol addresses. Include dummy addresses for the end
63  // of each section.
64  std::vector<SymEntry> Addresses;
65  unsigned SymNum = 0;
66  for (symbol_iterator I = O.symbol_begin(), E = O.symbol_end(); I != E; ++I) {
67  SymbolRef Sym = *I;
68  Expected<uint64_t> ValueOrErr = Sym.getValue();
69  if (!ValueOrErr)
70  // TODO: Actually report errors helpfully.
71  report_fatal_error(ValueOrErr.takeError());
72  Addresses.push_back({I, *ValueOrErr, SymNum, getSymbolSectionID(O, Sym)});
73  ++SymNum;
74  }
75  for (SectionRef Sec : O.sections()) {
76  uint64_t Address = Sec.getAddress();
77  uint64_t Size = Sec.getSize();
78  Addresses.push_back(
79  {O.symbol_end(), Address + Size, 0, getSectionID(O, Sec)});
80  }
81 
82  if (Addresses.empty())
83  return Ret;
84 
85  array_pod_sort(Addresses.begin(), Addresses.end(), compareAddress);
86 
87  // Compute the size as the gap to the next symbol
88  for (unsigned I = 0, N = Addresses.size() - 1; I < N; ++I) {
89  auto &P = Addresses[I];
90  if (P.I == O.symbol_end())
91  continue;
92 
93  // If multiple symbol have the same address, give both the same size.
94  unsigned NextI = I + 1;
95  while (NextI < N && Addresses[NextI].Address == P.Address)
96  ++NextI;
97 
98  uint64_t Size = Addresses[NextI].Address - P.Address;
99  P.Address = Size;
100  }
101 
102  // Assign the sorted symbols in the original order.
103  Ret.resize(SymNum);
104  for (SymEntry &P : Addresses) {
105  if (P.I == O.symbol_end())
106  continue;
107  Ret[P.Number] = {*P.I, P.Address};
108  }
109  return Ret;
110 }
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:1450
llvm
---------------------— PointerInfo ------------------------------------—
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")
XCOFFObjectFile.h
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::report_fatal_error
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:21
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:197
object
bar al al movzbl eax ret Missed when stored in a memory object
Definition: README.txt:1411
uint64_t
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:143
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:50
getSectionID
static unsigned getSectionID(const ObjectFile &O, SectionRef Sec)
Definition: SymbolSize.cpp:29
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition: Error.h:589
COFF.h
getSymbolSectionID
static unsigned getSymbolSectionID(const ObjectFile &O, SymbolRef Sym)
Definition: SymbolSize.cpp:39
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