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