123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- //===- RemarkLinker.cpp ---------------------------------------------------===//
- //
- // 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 provides an implementation of the remark linker.
- //
- //===----------------------------------------------------------------------===//
- #include "llvm/Remarks/RemarkLinker.h"
- #include "llvm/ADT/StringRef.h"
- #include "llvm/Object/ObjectFile.h"
- #include "llvm/Object/SymbolicFile.h"
- #include "llvm/Remarks/RemarkParser.h"
- #include "llvm/Remarks/RemarkSerializer.h"
- #include "llvm/Support/Error.h"
- #include "llvm/Support/raw_ostream.h"
- using namespace llvm;
- using namespace llvm::remarks;
- static Expected<StringRef>
- getRemarksSectionName(const object::ObjectFile &Obj) {
- if (Obj.isMachO())
- return StringRef("__remarks");
- // ELF -> .remarks, but there is no ELF support at this point.
- return createStringError(std::errc::illegal_byte_sequence,
- "Unsupported file format.");
- }
- Expected<Optional<StringRef>>
- llvm::remarks::getRemarksSectionContents(const object::ObjectFile &Obj) {
- Expected<StringRef> SectionName = getRemarksSectionName(Obj);
- if (!SectionName)
- return SectionName.takeError();
- for (const object::SectionRef &Section : Obj.sections()) {
- Expected<StringRef> MaybeName = Section.getName();
- if (!MaybeName)
- return MaybeName.takeError();
- if (*MaybeName != *SectionName)
- continue;
- if (Expected<StringRef> Contents = Section.getContents())
- return *Contents;
- else
- return Contents.takeError();
- }
- return Optional<StringRef>{};
- }
- Remark &RemarkLinker::keep(std::unique_ptr<Remark> Remark) {
- StrTab.internalize(*Remark);
- auto Inserted = Remarks.insert(std::move(Remark));
- return **Inserted.first;
- }
- void RemarkLinker::setExternalFilePrependPath(StringRef PrependPathIn) {
- PrependPath = std::string(PrependPathIn);
- }
- // Discard remarks with no source location.
- static bool shouldKeepRemark(const Remark &R) { return R.Loc.hasValue(); }
- Error RemarkLinker::link(StringRef Buffer, Optional<Format> RemarkFormat) {
- if (!RemarkFormat) {
- Expected<Format> ParserFormat = magicToFormat(Buffer);
- if (!ParserFormat)
- return ParserFormat.takeError();
- RemarkFormat = *ParserFormat;
- }
- Expected<std::unique_ptr<RemarkParser>> MaybeParser =
- createRemarkParserFromMeta(
- *RemarkFormat, Buffer, /*StrTab=*/None,
- PrependPath ? Optional<StringRef>(StringRef(*PrependPath))
- : Optional<StringRef>(None));
- if (!MaybeParser)
- return MaybeParser.takeError();
- RemarkParser &Parser = **MaybeParser;
- while (true) {
- Expected<std::unique_ptr<Remark>> Next = Parser.next();
- if (Error E = Next.takeError()) {
- if (E.isA<EndOfFileError>()) {
- consumeError(std::move(E));
- break;
- }
- return E;
- }
- assert(*Next != nullptr);
- if (shouldKeepRemark(**Next))
- keep(std::move(*Next));
- }
- return Error::success();
- }
- Error RemarkLinker::link(const object::ObjectFile &Obj,
- Optional<Format> RemarkFormat) {
- Expected<Optional<StringRef>> SectionOrErr = getRemarksSectionContents(Obj);
- if (!SectionOrErr)
- return SectionOrErr.takeError();
- if (Optional<StringRef> Section = *SectionOrErr)
- return link(*Section, RemarkFormat);
- return Error::success();
- }
- Error RemarkLinker::serialize(raw_ostream &OS, Format RemarksFormat) const {
- Expected<std::unique_ptr<RemarkSerializer>> MaybeSerializer =
- createRemarkSerializer(RemarksFormat, SerializerMode::Standalone, OS,
- std::move(const_cast<StringTable &>(StrTab)));
- if (!MaybeSerializer)
- return MaybeSerializer.takeError();
- std::unique_ptr<remarks::RemarkSerializer> Serializer =
- std::move(*MaybeSerializer);
- for (const Remark &R : remarks())
- Serializer->emit(R);
- return Error::success();
- }
|