xref: /llvm-project/bolt/lib/Core/BinaryData.cpp (revision b92436efcb7813fc481b30f2593a4907568d917a)
12f09f445SMaksim Panchenko //===- bolt/Core/BinaryData.cpp - Objects in a binary file ----------------===//
2a34c753fSRafael Auler //
3a34c753fSRafael Auler // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4a34c753fSRafael Auler // See https://llvm.org/LICENSE.txt for license information.
5a34c753fSRafael Auler // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6a34c753fSRafael Auler //
7a34c753fSRafael Auler //===----------------------------------------------------------------------===//
8a34c753fSRafael Auler //
92f09f445SMaksim Panchenko // This file implements the BinaryData class.
102f09f445SMaksim Panchenko //
11a34c753fSRafael Auler //===----------------------------------------------------------------------===//
12a34c753fSRafael Auler 
13a34c753fSRafael Auler #include "bolt/Core/BinaryData.h"
14a34c753fSRafael Auler #include "bolt/Core/BinarySection.h"
15a34c753fSRafael Auler #include "llvm/Support/CommandLine.h"
16a34c753fSRafael Auler #include "llvm/Support/Regex.h"
17a34c753fSRafael Auler 
18a34c753fSRafael Auler using namespace llvm;
19a34c753fSRafael Auler using namespace bolt;
20a34c753fSRafael Auler 
21a34c753fSRafael Auler #define DEBUG_TYPE "bolt"
22a34c753fSRafael Auler 
23a34c753fSRafael Auler namespace opts {
24a34c753fSRafael Auler extern cl::OptionCategory BoltCategory;
25a34c753fSRafael Auler extern cl::opt<unsigned> Verbosity;
26a34c753fSRafael Auler 
27a34c753fSRafael Auler cl::opt<bool>
28a34c753fSRafael Auler     PrintSymbolAliases("print-aliases",
29a34c753fSRafael Auler                        cl::desc("print aliases when printing objects"),
30*b92436efSFangrui Song                        cl::Hidden, cl::cat(BoltCategory));
31a34c753fSRafael Auler }
32a34c753fSRafael Auler 
3340c2e0faSMaksim Panchenko bool BinaryData::isAbsolute() const { return Flags & SymbolRef::SF_Absolute; }
34a34c753fSRafael Auler 
35a34c753fSRafael Auler bool BinaryData::isMoveable() const {
3640c2e0faSMaksim Panchenko   return (!isAbsolute() && (IsMoveable && (!Parent || isTopLevelJumpTable())));
37a34c753fSRafael Auler }
38a34c753fSRafael Auler 
39a34c753fSRafael Auler void BinaryData::merge(const BinaryData *Other) {
40a34c753fSRafael Auler   assert(!Size || !Other->Size || Size == Other->Size);
41a34c753fSRafael Auler   assert(Address == Other->Address);
42a34c753fSRafael Auler   assert(*Section == *Other->Section);
43a34c753fSRafael Auler   assert(OutputOffset == Other->OutputOffset);
44a34c753fSRafael Auler   assert(OutputSection == Other->OutputSection);
45a34c753fSRafael Auler   Symbols.insert(Symbols.end(), Other->Symbols.begin(), Other->Symbols.end());
46a34c753fSRafael Auler   Flags |= Other->Flags;
47a34c753fSRafael Auler   if (!Size)
48a34c753fSRafael Auler     Size = Other->Size;
49a34c753fSRafael Auler }
50a34c753fSRafael Auler 
51a34c753fSRafael Auler bool BinaryData::hasName(StringRef Name) const {
523652483cSRafael Auler   for (const MCSymbol *Symbol : Symbols)
53a34c753fSRafael Auler     if (Name == Symbol->getName())
54a34c753fSRafael Auler       return true;
55a34c753fSRafael Auler   return false;
56a34c753fSRafael Auler }
57a34c753fSRafael Auler 
58a34c753fSRafael Auler bool BinaryData::hasNameRegex(StringRef NameRegex) const {
59a34c753fSRafael Auler   Regex MatchName(NameRegex);
603652483cSRafael Auler   for (const MCSymbol *Symbol : Symbols)
61a34c753fSRafael Auler     if (MatchName.match(Symbol->getName()))
62a34c753fSRafael Auler       return true;
63a34c753fSRafael Auler   return false;
64a34c753fSRafael Auler }
65a34c753fSRafael Auler 
66a34c753fSRafael Auler bool BinaryData::nameStartsWith(StringRef Prefix) const {
673652483cSRafael Auler   for (const MCSymbol *Symbol : Symbols)
68a34c753fSRafael Auler     if (Symbol->getName().startswith(Prefix))
69a34c753fSRafael Auler       return true;
70a34c753fSRafael Auler   return false;
71a34c753fSRafael Auler }
72a34c753fSRafael Auler 
7340c2e0faSMaksim Panchenko StringRef BinaryData::getSectionName() const { return getSection().getName(); }
74a34c753fSRafael Auler 
75a34c753fSRafael Auler StringRef BinaryData::getOutputSectionName() const {
76a34c753fSRafael Auler   return getOutputSection().getName();
77a34c753fSRafael Auler }
78a34c753fSRafael Auler 
79a34c753fSRafael Auler uint64_t BinaryData::getOutputAddress() const {
80a34c753fSRafael Auler   assert(OutputSection->getOutputAddress());
81a34c753fSRafael Auler   return OutputSection->getOutputAddress() + OutputOffset;
82a34c753fSRafael Auler }
83a34c753fSRafael Auler 
84a34c753fSRafael Auler uint64_t BinaryData::getOffset() const {
85a34c753fSRafael Auler   return Address - getSection().getAddress();
86a34c753fSRafael Auler }
87a34c753fSRafael Auler 
88a34c753fSRafael Auler void BinaryData::setSection(BinarySection &NewSection) {
89a34c753fSRafael Auler   if (OutputSection == Section)
90a34c753fSRafael Auler     OutputSection = &NewSection;
91a34c753fSRafael Auler   Section = &NewSection;
92a34c753fSRafael Auler }
93a34c753fSRafael Auler 
94a34c753fSRafael Auler bool BinaryData::isMoved() const {
95a34c753fSRafael Auler   return (getOffset() != OutputOffset || OutputSection != Section);
96a34c753fSRafael Auler }
97a34c753fSRafael Auler 
9840c2e0faSMaksim Panchenko void BinaryData::print(raw_ostream &OS) const { printBrief(OS); }
99a34c753fSRafael Auler 
100a34c753fSRafael Auler void BinaryData::printBrief(raw_ostream &OS) const {
101a34c753fSRafael Auler   OS << "(";
102a34c753fSRafael Auler 
103a34c753fSRafael Auler   if (isJumpTable())
104a34c753fSRafael Auler     OS << "jump-table: ";
105a34c753fSRafael Auler   else
106a34c753fSRafael Auler     OS << "object: ";
107a34c753fSRafael Auler 
108a34c753fSRafael Auler   OS << getName();
109a34c753fSRafael Auler 
110a34c753fSRafael Auler   if ((opts::PrintSymbolAliases || opts::Verbosity > 1) && Symbols.size() > 1) {
111a34c753fSRafael Auler     OS << ", aliases:";
112a34c753fSRafael Auler     for (unsigned I = 1u; I < Symbols.size(); ++I) {
113a34c753fSRafael Auler       OS << (I == 1 ? " (" : ", ") << Symbols[I]->getName();
114a34c753fSRafael Auler     }
115a34c753fSRafael Auler     OS << ")";
116a34c753fSRafael Auler   }
117a34c753fSRafael Auler 
118a34c753fSRafael Auler   if (Parent) {
119a34c753fSRafael Auler     OS << " (parent: ";
120a34c753fSRafael Auler     Parent->printBrief(OS);
121a34c753fSRafael Auler     OS << ")";
122a34c753fSRafael Auler   }
123a34c753fSRafael Auler 
12440c2e0faSMaksim Panchenko   OS << ", 0x" << Twine::utohexstr(getAddress()) << ":0x"
12540c2e0faSMaksim Panchenko      << Twine::utohexstr(getEndAddress()) << "/" << getSize() << "/"
12640c2e0faSMaksim Panchenko      << getAlignment() << "/0x" << Twine::utohexstr(Flags);
127a34c753fSRafael Auler 
128a34c753fSRafael Auler   OS << ")";
129a34c753fSRafael Auler }
130a34c753fSRafael Auler 
13140c2e0faSMaksim Panchenko BinaryData::BinaryData(MCSymbol &Symbol, uint64_t Address, uint64_t Size,
13240c2e0faSMaksim Panchenko                        uint16_t Alignment, BinarySection &Section,
133a34c753fSRafael Auler                        unsigned Flags)
13440c2e0faSMaksim Panchenko     : Section(&Section), Address(Address), Size(Size), Alignment(Alignment),
13540c2e0faSMaksim Panchenko       Flags(Flags), OutputSection(&Section), OutputOffset(getOffset()) {
136a34c753fSRafael Auler   Symbols.push_back(&Symbol);
137a34c753fSRafael Auler }
138