xref: /llvm-project/bolt/lib/Core/BinaryData.cpp (revision a34c753fe709a624f5b087397fb05adeac2311e4)
1 //===--- BinaryData.cpp - Representation of section data objects ----------===//
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 //
9 //===----------------------------------------------------------------------===//
10 
11 #include "bolt/Core/BinaryData.h"
12 #include "bolt/Core/BinarySection.h"
13 #include "llvm/Support/CommandLine.h"
14 #include "llvm/Support/Regex.h"
15 
16 using namespace llvm;
17 using namespace bolt;
18 
19 #undef  DEBUG_TYPE
20 #define DEBUG_TYPE "bolt"
21 
22 namespace opts {
23 extern cl::OptionCategory BoltCategory;
24 extern cl::opt<unsigned> Verbosity;
25 
26 cl::opt<bool>
27 PrintSymbolAliases("print-aliases",
28   cl::desc("print aliases when printing objects"),
29   cl::Hidden,
30   cl::ZeroOrMore,
31   cl::cat(BoltCategory));
32 }
33 
34 bool BinaryData::isAbsolute() const {
35   return Flags & SymbolRef::SF_Absolute;
36 }
37 
38 bool BinaryData::isMoveable() const {
39   return (!isAbsolute() &&
40           (IsMoveable &&
41            (!Parent || isTopLevelJumpTable())));
42 }
43 
44 void BinaryData::merge(const BinaryData *Other) {
45   assert(!Size || !Other->Size || Size == Other->Size);
46   assert(Address == Other->Address);
47   assert(*Section == *Other->Section);
48   assert(OutputOffset == Other->OutputOffset);
49   assert(OutputSection == Other->OutputSection);
50   Symbols.insert(Symbols.end(), Other->Symbols.begin(), Other->Symbols.end());
51   Flags |= Other->Flags;
52   if (!Size)
53     Size = Other->Size;
54 }
55 
56 bool BinaryData::hasName(StringRef Name) const {
57   for (const MCSymbol *Symbol : Symbols) {
58     if (Name == Symbol->getName())
59       return true;
60   }
61   return false;
62 }
63 
64 bool BinaryData::hasNameRegex(StringRef NameRegex) const {
65   Regex MatchName(NameRegex);
66   for (const MCSymbol *Symbol : Symbols) {
67     if (MatchName.match(Symbol->getName()))
68       return true;
69   }
70   return false;
71 }
72 
73 bool BinaryData::nameStartsWith(StringRef Prefix) const {
74   for (const MCSymbol *Symbol : Symbols) {
75     if (Symbol->getName().startswith(Prefix))
76       return true;
77   }
78   return false;
79 }
80 
81 StringRef BinaryData::getSectionName() const {
82   return getSection().getName();
83 }
84 
85 StringRef BinaryData::getOutputSectionName() const {
86   return getOutputSection().getName();
87 }
88 
89 uint64_t BinaryData::getOutputAddress() const {
90   assert(OutputSection->getOutputAddress());
91   return OutputSection->getOutputAddress() + OutputOffset;
92 }
93 
94 uint64_t BinaryData::getOffset() const {
95   return Address - getSection().getAddress();
96 }
97 
98 void BinaryData::setSection(BinarySection &NewSection) {
99   if (OutputSection == Section)
100     OutputSection = &NewSection;
101   Section = &NewSection;
102 }
103 
104 bool BinaryData::isMoved() const {
105   return (getOffset() != OutputOffset || OutputSection != Section);
106 }
107 
108 void BinaryData::print(raw_ostream &OS) const {
109   printBrief(OS);
110 }
111 
112 void BinaryData::printBrief(raw_ostream &OS) const {
113   OS << "(";
114 
115   if (isJumpTable())
116     OS << "jump-table: ";
117   else
118     OS << "object: ";
119 
120   OS << getName();
121 
122   if ((opts::PrintSymbolAliases || opts::Verbosity > 1) && Symbols.size() > 1) {
123     OS << ", aliases:";
124     for (unsigned I = 1u; I < Symbols.size(); ++I) {
125       OS << (I == 1 ? " (" : ", ") << Symbols[I]->getName();
126     }
127     OS << ")";
128   }
129 
130   if (Parent) {
131     OS << " (parent: ";
132     Parent->printBrief(OS);
133     OS << ")";
134   }
135 
136   OS << ", 0x" << Twine::utohexstr(getAddress())
137      << ":0x" << Twine::utohexstr(getEndAddress())
138      << "/" << getSize() << "/" << getAlignment()
139      << "/0x" << Twine::utohexstr(Flags);
140 
141   OS << ")";
142 }
143 
144 BinaryData::BinaryData(MCSymbol &Symbol,
145                        uint64_t Address,
146                        uint64_t Size,
147                        uint16_t Alignment,
148                        BinarySection &Section,
149                        unsigned Flags)
150 : Section(&Section),
151   Address(Address),
152   Size(Size),
153   Alignment(Alignment),
154   Flags(Flags),
155   OutputSection(&Section),
156   OutputOffset(getOffset())
157 {
158   Symbols.push_back(&Symbol);
159 }
160