| //===- 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); |
| } |