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