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