12f09f445SMaksim Panchenko //===- bolt/Core/BinaryData.cpp - Objects in a binary file ----------------===// 2a34c753fSRafael Auler // 3a34c753fSRafael Auler // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4a34c753fSRafael Auler // See https://llvm.org/LICENSE.txt for license information. 5a34c753fSRafael Auler // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6a34c753fSRafael Auler // 7a34c753fSRafael Auler //===----------------------------------------------------------------------===// 8a34c753fSRafael Auler // 92f09f445SMaksim Panchenko // This file implements the BinaryData class. 102f09f445SMaksim Panchenko // 11a34c753fSRafael Auler //===----------------------------------------------------------------------===// 12a34c753fSRafael Auler 13a34c753fSRafael Auler #include "bolt/Core/BinaryData.h" 14a34c753fSRafael Auler #include "bolt/Core/BinarySection.h" 15a34c753fSRafael Auler #include "llvm/Support/CommandLine.h" 16a34c753fSRafael Auler #include "llvm/Support/Regex.h" 17a34c753fSRafael Auler 18a34c753fSRafael Auler using namespace llvm; 19a34c753fSRafael Auler using namespace bolt; 20a34c753fSRafael Auler 21a34c753fSRafael Auler #define DEBUG_TYPE "bolt" 22a34c753fSRafael Auler 23a34c753fSRafael Auler namespace opts { 24a34c753fSRafael Auler extern cl::OptionCategory BoltCategory; 25a34c753fSRafael Auler extern cl::opt<unsigned> Verbosity; 26a34c753fSRafael Auler 27a34c753fSRafael Auler cl::opt<bool> 28a34c753fSRafael Auler PrintSymbolAliases("print-aliases", 29a34c753fSRafael Auler cl::desc("print aliases when printing objects"), 30*b92436efSFangrui Song cl::Hidden, cl::cat(BoltCategory)); 31a34c753fSRafael Auler } 32a34c753fSRafael Auler 3340c2e0faSMaksim Panchenko bool BinaryData::isAbsolute() const { return Flags & SymbolRef::SF_Absolute; } 34a34c753fSRafael Auler 35a34c753fSRafael Auler bool BinaryData::isMoveable() const { 3640c2e0faSMaksim Panchenko return (!isAbsolute() && (IsMoveable && (!Parent || isTopLevelJumpTable()))); 37a34c753fSRafael Auler } 38a34c753fSRafael Auler 39a34c753fSRafael Auler void BinaryData::merge(const BinaryData *Other) { 40a34c753fSRafael Auler assert(!Size || !Other->Size || Size == Other->Size); 41a34c753fSRafael Auler assert(Address == Other->Address); 42a34c753fSRafael Auler assert(*Section == *Other->Section); 43a34c753fSRafael Auler assert(OutputOffset == Other->OutputOffset); 44a34c753fSRafael Auler assert(OutputSection == Other->OutputSection); 45a34c753fSRafael Auler Symbols.insert(Symbols.end(), Other->Symbols.begin(), Other->Symbols.end()); 46a34c753fSRafael Auler Flags |= Other->Flags; 47a34c753fSRafael Auler if (!Size) 48a34c753fSRafael Auler Size = Other->Size; 49a34c753fSRafael Auler } 50a34c753fSRafael Auler 51a34c753fSRafael Auler bool BinaryData::hasName(StringRef Name) const { 523652483cSRafael Auler for (const MCSymbol *Symbol : Symbols) 53a34c753fSRafael Auler if (Name == Symbol->getName()) 54a34c753fSRafael Auler return true; 55a34c753fSRafael Auler return false; 56a34c753fSRafael Auler } 57a34c753fSRafael Auler 58a34c753fSRafael Auler bool BinaryData::hasNameRegex(StringRef NameRegex) const { 59a34c753fSRafael Auler Regex MatchName(NameRegex); 603652483cSRafael Auler for (const MCSymbol *Symbol : Symbols) 61a34c753fSRafael Auler if (MatchName.match(Symbol->getName())) 62a34c753fSRafael Auler return true; 63a34c753fSRafael Auler return false; 64a34c753fSRafael Auler } 65a34c753fSRafael Auler 66a34c753fSRafael Auler bool BinaryData::nameStartsWith(StringRef Prefix) const { 673652483cSRafael Auler for (const MCSymbol *Symbol : Symbols) 68a34c753fSRafael Auler if (Symbol->getName().startswith(Prefix)) 69a34c753fSRafael Auler return true; 70a34c753fSRafael Auler return false; 71a34c753fSRafael Auler } 72a34c753fSRafael Auler 7340c2e0faSMaksim Panchenko StringRef BinaryData::getSectionName() const { return getSection().getName(); } 74a34c753fSRafael Auler 75a34c753fSRafael Auler StringRef BinaryData::getOutputSectionName() const { 76a34c753fSRafael Auler return getOutputSection().getName(); 77a34c753fSRafael Auler } 78a34c753fSRafael Auler 79a34c753fSRafael Auler uint64_t BinaryData::getOutputAddress() const { 80a34c753fSRafael Auler assert(OutputSection->getOutputAddress()); 81a34c753fSRafael Auler return OutputSection->getOutputAddress() + OutputOffset; 82a34c753fSRafael Auler } 83a34c753fSRafael Auler 84a34c753fSRafael Auler uint64_t BinaryData::getOffset() const { 85a34c753fSRafael Auler return Address - getSection().getAddress(); 86a34c753fSRafael Auler } 87a34c753fSRafael Auler 88a34c753fSRafael Auler void BinaryData::setSection(BinarySection &NewSection) { 89a34c753fSRafael Auler if (OutputSection == Section) 90a34c753fSRafael Auler OutputSection = &NewSection; 91a34c753fSRafael Auler Section = &NewSection; 92a34c753fSRafael Auler } 93a34c753fSRafael Auler 94a34c753fSRafael Auler bool BinaryData::isMoved() const { 95a34c753fSRafael Auler return (getOffset() != OutputOffset || OutputSection != Section); 96a34c753fSRafael Auler } 97a34c753fSRafael Auler 9840c2e0faSMaksim Panchenko void BinaryData::print(raw_ostream &OS) const { printBrief(OS); } 99a34c753fSRafael Auler 100a34c753fSRafael Auler void BinaryData::printBrief(raw_ostream &OS) const { 101a34c753fSRafael Auler OS << "("; 102a34c753fSRafael Auler 103a34c753fSRafael Auler if (isJumpTable()) 104a34c753fSRafael Auler OS << "jump-table: "; 105a34c753fSRafael Auler else 106a34c753fSRafael Auler OS << "object: "; 107a34c753fSRafael Auler 108a34c753fSRafael Auler OS << getName(); 109a34c753fSRafael Auler 110a34c753fSRafael Auler if ((opts::PrintSymbolAliases || opts::Verbosity > 1) && Symbols.size() > 1) { 111a34c753fSRafael Auler OS << ", aliases:"; 112a34c753fSRafael Auler for (unsigned I = 1u; I < Symbols.size(); ++I) { 113a34c753fSRafael Auler OS << (I == 1 ? " (" : ", ") << Symbols[I]->getName(); 114a34c753fSRafael Auler } 115a34c753fSRafael Auler OS << ")"; 116a34c753fSRafael Auler } 117a34c753fSRafael Auler 118a34c753fSRafael Auler if (Parent) { 119a34c753fSRafael Auler OS << " (parent: "; 120a34c753fSRafael Auler Parent->printBrief(OS); 121a34c753fSRafael Auler OS << ")"; 122a34c753fSRafael Auler } 123a34c753fSRafael Auler 12440c2e0faSMaksim Panchenko OS << ", 0x" << Twine::utohexstr(getAddress()) << ":0x" 12540c2e0faSMaksim Panchenko << Twine::utohexstr(getEndAddress()) << "/" << getSize() << "/" 12640c2e0faSMaksim Panchenko << getAlignment() << "/0x" << Twine::utohexstr(Flags); 127a34c753fSRafael Auler 128a34c753fSRafael Auler OS << ")"; 129a34c753fSRafael Auler } 130a34c753fSRafael Auler 13140c2e0faSMaksim Panchenko BinaryData::BinaryData(MCSymbol &Symbol, uint64_t Address, uint64_t Size, 13240c2e0faSMaksim Panchenko uint16_t Alignment, BinarySection &Section, 133a34c753fSRafael Auler unsigned Flags) 13440c2e0faSMaksim Panchenko : Section(&Section), Address(Address), Size(Size), Alignment(Alignment), 13540c2e0faSMaksim Panchenko Flags(Flags), OutputSection(&Section), OutputOffset(getOffset()) { 136a34c753fSRafael Auler Symbols.push_back(&Symbol); 137a34c753fSRafael Auler } 138