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 return false; 58 } 59 60 bool BinaryData::hasNameRegex(StringRef NameRegex) const { 61 Regex MatchName(NameRegex); 62 for (const MCSymbol *Symbol : Symbols) 63 if (MatchName.match(Symbol->getName())) 64 return true; 65 return false; 66 } 67 68 bool BinaryData::nameStartsWith(StringRef Prefix) const { 69 for (const MCSymbol *Symbol : Symbols) 70 if (Symbol->getName().startswith(Prefix)) 71 return true; 72 return false; 73 } 74 75 StringRef BinaryData::getSectionName() const { return getSection().getName(); } 76 77 StringRef BinaryData::getOutputSectionName() const { 78 return getOutputSection().getName(); 79 } 80 81 uint64_t BinaryData::getOutputAddress() const { 82 assert(OutputSection->getOutputAddress()); 83 return OutputSection->getOutputAddress() + OutputOffset; 84 } 85 86 uint64_t BinaryData::getOffset() const { 87 return Address - getSection().getAddress(); 88 } 89 90 void BinaryData::setSection(BinarySection &NewSection) { 91 if (OutputSection == Section) 92 OutputSection = &NewSection; 93 Section = &NewSection; 94 } 95 96 bool BinaryData::isMoved() const { 97 return (getOffset() != OutputOffset || OutputSection != Section); 98 } 99 100 void BinaryData::print(raw_ostream &OS) const { printBrief(OS); } 101 102 void BinaryData::printBrief(raw_ostream &OS) const { 103 OS << "("; 104 105 if (isJumpTable()) 106 OS << "jump-table: "; 107 else 108 OS << "object: "; 109 110 OS << getName(); 111 112 if ((opts::PrintSymbolAliases || opts::Verbosity > 1) && Symbols.size() > 1) { 113 OS << ", aliases:"; 114 for (unsigned I = 1u; I < Symbols.size(); ++I) { 115 OS << (I == 1 ? " (" : ", ") << Symbols[I]->getName(); 116 } 117 OS << ")"; 118 } 119 120 if (Parent) { 121 OS << " (parent: "; 122 Parent->printBrief(OS); 123 OS << ")"; 124 } 125 126 OS << ", 0x" << Twine::utohexstr(getAddress()) << ":0x" 127 << Twine::utohexstr(getEndAddress()) << "/" << getSize() << "/" 128 << getAlignment() << "/0x" << Twine::utohexstr(Flags); 129 130 OS << ")"; 131 } 132 133 BinaryData::BinaryData(MCSymbol &Symbol, uint64_t Address, uint64_t Size, 134 uint16_t Alignment, BinarySection &Section, 135 unsigned Flags) 136 : Section(&Section), Address(Address), Size(Size), Alignment(Alignment), 137 Flags(Flags), OutputSection(&Section), OutputOffset(getOffset()) { 138 Symbols.push_back(&Symbol); 139 } 140