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, 31 cl::ZeroOrMore, 32 cl::cat(BoltCategory)); 33 } 34 35 bool BinaryData::isAbsolute() const { return Flags & SymbolRef::SF_Absolute; } 36 37 bool BinaryData::isMoveable() const { 38 return (!isAbsolute() && (IsMoveable && (!Parent || isTopLevelJumpTable()))); 39 } 40 41 void BinaryData::merge(const BinaryData *Other) { 42 assert(!Size || !Other->Size || Size == Other->Size); 43 assert(Address == Other->Address); 44 assert(*Section == *Other->Section); 45 assert(OutputOffset == Other->OutputOffset); 46 assert(OutputSection == Other->OutputSection); 47 Symbols.insert(Symbols.end(), Other->Symbols.begin(), Other->Symbols.end()); 48 Flags |= Other->Flags; 49 if (!Size) 50 Size = Other->Size; 51 } 52 53 bool BinaryData::hasName(StringRef Name) const { 54 for (const MCSymbol *Symbol : Symbols) { 55 if (Name == Symbol->getName()) 56 return true; 57 } 58 return false; 59 } 60 61 bool BinaryData::hasNameRegex(StringRef NameRegex) const { 62 Regex MatchName(NameRegex); 63 for (const MCSymbol *Symbol : Symbols) { 64 if (MatchName.match(Symbol->getName())) 65 return true; 66 } 67 return false; 68 } 69 70 bool BinaryData::nameStartsWith(StringRef Prefix) const { 71 for (const MCSymbol *Symbol : Symbols) { 72 if (Symbol->getName().startswith(Prefix)) 73 return true; 74 } 75 return false; 76 } 77 78 StringRef BinaryData::getSectionName() const { return getSection().getName(); } 79 80 StringRef BinaryData::getOutputSectionName() const { 81 return getOutputSection().getName(); 82 } 83 84 uint64_t BinaryData::getOutputAddress() const { 85 assert(OutputSection->getOutputAddress()); 86 return OutputSection->getOutputAddress() + OutputOffset; 87 } 88 89 uint64_t BinaryData::getOffset() const { 90 return Address - getSection().getAddress(); 91 } 92 93 void BinaryData::setSection(BinarySection &NewSection) { 94 if (OutputSection == Section) 95 OutputSection = &NewSection; 96 Section = &NewSection; 97 } 98 99 bool BinaryData::isMoved() const { 100 return (getOffset() != OutputOffset || OutputSection != Section); 101 } 102 103 void BinaryData::print(raw_ostream &OS) const { printBrief(OS); } 104 105 void BinaryData::printBrief(raw_ostream &OS) const { 106 OS << "("; 107 108 if (isJumpTable()) 109 OS << "jump-table: "; 110 else 111 OS << "object: "; 112 113 OS << getName(); 114 115 if ((opts::PrintSymbolAliases || opts::Verbosity > 1) && Symbols.size() > 1) { 116 OS << ", aliases:"; 117 for (unsigned I = 1u; I < Symbols.size(); ++I) { 118 OS << (I == 1 ? " (" : ", ") << Symbols[I]->getName(); 119 } 120 OS << ")"; 121 } 122 123 if (Parent) { 124 OS << " (parent: "; 125 Parent->printBrief(OS); 126 OS << ")"; 127 } 128 129 OS << ", 0x" << Twine::utohexstr(getAddress()) << ":0x" 130 << Twine::utohexstr(getEndAddress()) << "/" << getSize() << "/" 131 << getAlignment() << "/0x" << Twine::utohexstr(Flags); 132 133 OS << ")"; 134 } 135 136 BinaryData::BinaryData(MCSymbol &Symbol, uint64_t Address, uint64_t Size, 137 uint16_t Alignment, BinarySection &Section, 138 unsigned Flags) 139 : Section(&Section), Address(Address), Size(Size), Alignment(Alignment), 140 Flags(Flags), OutputSection(&Section), OutputOffset(getOffset()) { 141 Symbols.push_back(&Symbol); 142 } 143