130 lines · cpp
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-exception6//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 18using namespace llvm;19using namespace bolt;20 21#define DEBUG_TYPE "bolt"22 23namespace opts {24extern cl::OptionCategory BoltCategory;25extern cl::opt<unsigned> Verbosity;26 27static cl::opt<bool>28 PrintSymbolAliases("print-aliases",29 cl::desc("print aliases when printing objects"),30 cl::Hidden, cl::cat(BoltCategory));31}32 33bool BinaryData::isAbsolute() const { return Flags & SymbolRef::SF_Absolute; }34 35bool BinaryData::isMoveable() const {36 return (!isAbsolute() && (IsMoveable && (!Parent || isTopLevelJumpTable())));37}38 39void 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 51bool BinaryData::hasName(StringRef Name) const {52 for (const MCSymbol *Symbol : Symbols)53 if (Name == Symbol->getName())54 return true;55 return false;56}57 58bool BinaryData::nameStartsWith(StringRef Prefix) const {59 for (const MCSymbol *Symbol : Symbols)60 if (Symbol->getName().starts_with(Prefix))61 return true;62 return false;63}64 65StringRef BinaryData::getSectionName() const { return getSection().getName(); }66 67StringRef BinaryData::getOutputSectionName() const {68 return getOutputSection().getName();69}70 71uint64_t BinaryData::getOutputAddress() const {72 assert(OutputSection->getOutputAddress());73 return OutputSection->getOutputAddress() + OutputOffset;74}75 76uint64_t BinaryData::getOffset() const {77 return Address - getSection().getAddress();78}79 80void BinaryData::setSection(BinarySection &NewSection) {81 if (OutputSection == Section)82 OutputSection = &NewSection;83 Section = &NewSection;84}85 86bool BinaryData::isMoved() const {87 return (getOffset() != OutputOffset || OutputSection != Section);88}89 90void BinaryData::print(raw_ostream &OS) const { printBrief(OS); }91 92void BinaryData::printBrief(raw_ostream &OS) const {93 OS << "(";94 95 if (isJumpTable())96 OS << "jump-table: ";97 else98 OS << "object: ";99 100 OS << getName();101 102 if ((opts::PrintSymbolAliases || opts::Verbosity > 1) && Symbols.size() > 1) {103 OS << ", aliases:";104 for (unsigned I = 1u; I < Symbols.size(); ++I) {105 OS << (I == 1 ? " (" : ", ") << Symbols[I]->getName();106 }107 OS << ")";108 }109 110 if (Parent) {111 OS << " (parent: ";112 Parent->printBrief(OS);113 OS << ")";114 }115 116 OS << ", 0x" << Twine::utohexstr(getAddress()) << ":0x"117 << Twine::utohexstr(getEndAddress()) << "/" << getSize() << "/"118 << getAlignment() << "/0x" << Twine::utohexstr(Flags);119 120 OS << ")";121}122 123BinaryData::BinaryData(MCSymbol &Symbol, uint64_t Address, uint64_t Size,124 uint16_t Alignment, BinarySection &Section,125 unsigned Flags)126 : Section(&Section), Address(Address), Size(Size), Alignment(Alignment),127 Flags(Flags), OutputSection(&Section), OutputOffset(getOffset()) {128 Symbols.push_back(&Symbol);129}130