| //===- bolt/Core/BinaryData.cpp - Objects in a binary file ----------------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // | |
| // This file implements the BinaryData class. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "bolt/Core/BinaryData.h" | |
| #include "bolt/Core/BinarySection.h" | |
| #include "llvm/Support/CommandLine.h" | |
| #include "llvm/Support/Regex.h" | |
| using namespace llvm; | |
| using namespace bolt; | |
| #define DEBUG_TYPE "bolt" | |
| namespace opts { | |
| extern cl::OptionCategory BoltCategory; | |
| extern cl::opt<unsigned> Verbosity; | |
| static cl::opt<bool> | |
| PrintSymbolAliases("print-aliases", | |
| cl::desc("print aliases when printing objects"), | |
| cl::Hidden, cl::cat(BoltCategory)); | |
| } | |
| bool BinaryData::isAbsolute() const { return Flags & SymbolRef::SF_Absolute; } | |
| bool BinaryData::isMoveable() const { | |
| return (!isAbsolute() && (IsMoveable && (!Parent || isTopLevelJumpTable()))); | |
| } | |
| void BinaryData::merge(const BinaryData *Other) { | |
| assert(!Size || !Other->Size || Size == Other->Size); | |
| assert(Address == Other->Address); | |
| assert(*Section == *Other->Section); | |
| assert(OutputOffset == Other->OutputOffset); | |
| assert(OutputSection == Other->OutputSection); | |
| Symbols.insert(Symbols.end(), Other->Symbols.begin(), Other->Symbols.end()); | |
| Flags |= Other->Flags; | |
| if (!Size) | |
| Size = Other->Size; | |
| } | |
| bool BinaryData::hasName(StringRef Name) const { | |
| for (const MCSymbol *Symbol : Symbols) | |
| if (Name == Symbol->getName()) | |
| return true; | |
| return false; | |
| } | |
| bool BinaryData::nameStartsWith(StringRef Prefix) const { | |
| for (const MCSymbol *Symbol : Symbols) | |
| if (Symbol->getName().starts_with(Prefix)) | |
| return true; | |
| return false; | |
| } | |
| StringRef BinaryData::getSectionName() const { return getSection().getName(); } | |
| StringRef BinaryData::getOutputSectionName() const { | |
| return getOutputSection().getName(); | |
| } | |
| uint64_t BinaryData::getOutputAddress() const { | |
| assert(OutputSection->getOutputAddress()); | |
| return OutputSection->getOutputAddress() + OutputOffset; | |
| } | |
| uint64_t BinaryData::getOffset() const { | |
| return Address - getSection().getAddress(); | |
| } | |
| void BinaryData::setSection(BinarySection &NewSection) { | |
| if (OutputSection == Section) | |
| OutputSection = &NewSection; | |
| Section = &NewSection; | |
| } | |
| bool BinaryData::isMoved() const { | |
| return (getOffset() != OutputOffset || OutputSection != Section); | |
| } | |
| void BinaryData::print(raw_ostream &OS) const { printBrief(OS); } | |
| void BinaryData::printBrief(raw_ostream &OS) const { | |
| OS << "("; | |
| if (isJumpTable()) | |
| OS << "jump-table: "; | |
| else | |
| OS << "object: "; | |
| OS << getName(); | |
| if ((opts::PrintSymbolAliases || opts::Verbosity > 1) && Symbols.size() > 1) { | |
| OS << ", aliases:"; | |
| for (unsigned I = 1u; I < Symbols.size(); ++I) { | |
| OS << (I == 1 ? " (" : ", ") << Symbols[I]->getName(); | |
| } | |
| OS << ")"; | |
| } | |
| if (Parent) { | |
| OS << " (parent: "; | |
| Parent->printBrief(OS); | |
| OS << ")"; | |
| } | |
| OS << ", 0x" << Twine::utohexstr(getAddress()) << ":0x" | |
| << Twine::utohexstr(getEndAddress()) << "/" << getSize() << "/" | |
| << getAlignment() << "/0x" << Twine::utohexstr(Flags); | |
| OS << ")"; | |
| } | |
| BinaryData::BinaryData(MCSymbol &Symbol, uint64_t Address, uint64_t Size, | |
| uint16_t Alignment, BinarySection &Section, | |
| unsigned Flags) | |
| : Section(&Section), Address(Address), Size(Size), Alignment(Alignment), | |
| Flags(Flags), OutputSection(&Section), OutputOffset(getOffset()) { | |
| Symbols.push_back(&Symbol); | |
| } |