Path: blob/main/contrib/llvm-project/llvm/lib/Remarks/RemarkLinker.cpp
35262 views
//===- RemarkLinker.cpp ---------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file provides an implementation of the remark linker.9//10//===----------------------------------------------------------------------===//1112#include "llvm/Remarks/RemarkLinker.h"13#include "llvm/ADT/StringRef.h"14#include "llvm/Object/ObjectFile.h"15#include "llvm/Object/SymbolicFile.h"16#include "llvm/Remarks/RemarkParser.h"17#include "llvm/Remarks/RemarkSerializer.h"18#include "llvm/Support/Error.h"19#include <optional>2021using namespace llvm;22using namespace llvm::remarks;2324namespace llvm {25class raw_ostream;26}2728static Expected<StringRef>29getRemarksSectionName(const object::ObjectFile &Obj) {30if (Obj.isMachO())31return StringRef("__remarks");32// ELF -> .remarks, but there is no ELF support at this point.33return createStringError(std::errc::illegal_byte_sequence,34"Unsupported file format.");35}3637Expected<std::optional<StringRef>>38llvm::remarks::getRemarksSectionContents(const object::ObjectFile &Obj) {39Expected<StringRef> SectionName = getRemarksSectionName(Obj);40if (!SectionName)41return SectionName.takeError();4243for (const object::SectionRef &Section : Obj.sections()) {44Expected<StringRef> MaybeName = Section.getName();45if (!MaybeName)46return MaybeName.takeError();47if (*MaybeName != *SectionName)48continue;4950if (Expected<StringRef> Contents = Section.getContents())51return *Contents;52else53return Contents.takeError();54}55return std::optional<StringRef>{};56}5758Remark &RemarkLinker::keep(std::unique_ptr<Remark> Remark) {59StrTab.internalize(*Remark);60auto Inserted = Remarks.insert(std::move(Remark));61return **Inserted.first;62}6364void RemarkLinker::setExternalFilePrependPath(StringRef PrependPathIn) {65PrependPath = std::string(PrependPathIn);66}6768Error RemarkLinker::link(StringRef Buffer, std::optional<Format> RemarkFormat) {69if (!RemarkFormat) {70Expected<Format> ParserFormat = magicToFormat(Buffer);71if (!ParserFormat)72return ParserFormat.takeError();73RemarkFormat = *ParserFormat;74}7576Expected<std::unique_ptr<RemarkParser>> MaybeParser =77createRemarkParserFromMeta(78*RemarkFormat, Buffer, /*StrTab=*/std::nullopt,79PrependPath ? std::optional<StringRef>(StringRef(*PrependPath))80: std::optional<StringRef>());81if (!MaybeParser)82return MaybeParser.takeError();8384RemarkParser &Parser = **MaybeParser;8586while (true) {87Expected<std::unique_ptr<Remark>> Next = Parser.next();88if (Error E = Next.takeError()) {89if (E.isA<EndOfFileError>()) {90consumeError(std::move(E));91break;92}93return E;94}9596assert(*Next != nullptr);9798if (shouldKeepRemark(**Next))99keep(std::move(*Next));100}101return Error::success();102}103104Error RemarkLinker::link(const object::ObjectFile &Obj,105std::optional<Format> RemarkFormat) {106Expected<std::optional<StringRef>> SectionOrErr =107getRemarksSectionContents(Obj);108if (!SectionOrErr)109return SectionOrErr.takeError();110111if (std::optional<StringRef> Section = *SectionOrErr)112return link(*Section, RemarkFormat);113return Error::success();114}115116Error RemarkLinker::serialize(raw_ostream &OS, Format RemarksFormat) const {117Expected<std::unique_ptr<RemarkSerializer>> MaybeSerializer =118createRemarkSerializer(RemarksFormat, SerializerMode::Standalone, OS,119std::move(const_cast<StringTable &>(StrTab)));120if (!MaybeSerializer)121return MaybeSerializer.takeError();122123std::unique_ptr<remarks::RemarkSerializer> Serializer =124std::move(*MaybeSerializer);125126for (const Remark &R : remarks())127Serializer->emit(R);128return Error::success();129}130131132