diff options
author | monster <monster@ydb.tech> | 2022-07-07 14:41:37 +0300 |
---|---|---|
committer | monster <monster@ydb.tech> | 2022-07-07 14:41:37 +0300 |
commit | 06e5c21a835c0e923506c4ff27929f34e00761c2 (patch) | |
tree | 75efcbc6854ef9bd476eb8bf00cc5c900da436a2 /contrib/libs/llvm12/lib/DebugInfo/GSYM/ObjectFileTransformer.cpp | |
parent | 03f024c4412e3aa613bb543cf1660176320ba8f4 (diff) | |
download | ydb-06e5c21a835c0e923506c4ff27929f34e00761c2.tar.gz |
fix ya.make
Diffstat (limited to 'contrib/libs/llvm12/lib/DebugInfo/GSYM/ObjectFileTransformer.cpp')
-rw-r--r-- | contrib/libs/llvm12/lib/DebugInfo/GSYM/ObjectFileTransformer.cpp | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/contrib/libs/llvm12/lib/DebugInfo/GSYM/ObjectFileTransformer.cpp b/contrib/libs/llvm12/lib/DebugInfo/GSYM/ObjectFileTransformer.cpp new file mode 100644 index 0000000000..ad35aefe77 --- /dev/null +++ b/contrib/libs/llvm12/lib/DebugInfo/GSYM/ObjectFileTransformer.cpp @@ -0,0 +1,116 @@ +//===- ObjectFileTransformer.cpp --------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include <unordered_set> + +#include "llvm/Object/ELFObjectFile.h" +#include "llvm/Object/MachOUniversal.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/Support/DataExtractor.h" +#include "llvm/Support/raw_ostream.h" + +#include "llvm/DebugInfo/GSYM/ObjectFileTransformer.h" +#include "llvm/DebugInfo/GSYM/GsymCreator.h" + +using namespace llvm; +using namespace gsym; + +constexpr uint32_t NT_GNU_BUILD_ID_TAG = 0x03; + +static std::vector<uint8_t> getUUID(const object::ObjectFile &Obj) { + // Extract the UUID from the object file + std::vector<uint8_t> UUID; + if (auto *MachO = dyn_cast<object::MachOObjectFile>(&Obj)) { + const ArrayRef<uint8_t> MachUUID = MachO->getUuid(); + if (!MachUUID.empty()) + UUID.assign(MachUUID.data(), MachUUID.data() + MachUUID.size()); + } else if (isa<object::ELFObjectFileBase>(&Obj)) { + const StringRef GNUBuildID(".note.gnu.build-id"); + for (const object::SectionRef &Sect : Obj.sections()) { + Expected<StringRef> SectNameOrErr = Sect.getName(); + if (!SectNameOrErr) { + consumeError(SectNameOrErr.takeError()); + continue; + } + StringRef SectName(*SectNameOrErr); + if (SectName != GNUBuildID) + continue; + StringRef BuildIDData; + Expected<StringRef> E = Sect.getContents(); + if (E) + BuildIDData = *E; + else { + consumeError(E.takeError()); + continue; + } + DataExtractor Decoder(BuildIDData, Obj.makeTriple().isLittleEndian(), 8); + uint64_t Offset = 0; + const uint32_t NameSize = Decoder.getU32(&Offset); + const uint32_t PayloadSize = Decoder.getU32(&Offset); + const uint32_t PayloadType = Decoder.getU32(&Offset); + StringRef Name(Decoder.getFixedLengthString(&Offset, NameSize)); + if (Name == "GNU" && PayloadType == NT_GNU_BUILD_ID_TAG) { + Offset = alignTo(Offset, 4); + StringRef UUIDBytes(Decoder.getBytes(&Offset, PayloadSize)); + if (!UUIDBytes.empty()) { + auto Ptr = reinterpret_cast<const uint8_t *>(UUIDBytes.data()); + UUID.assign(Ptr, Ptr + UUIDBytes.size()); + } + } + } + } + return UUID; +} + +llvm::Error ObjectFileTransformer::convert(const object::ObjectFile &Obj, + raw_ostream &Log, + GsymCreator &Gsym) { + using namespace llvm::object; + + const bool IsMachO = isa<MachOObjectFile>(&Obj); + const bool IsELF = isa<ELFObjectFileBase>(&Obj); + + // Read build ID. + Gsym.setUUID(getUUID(Obj)); + + // Parse the symbol table. + size_t NumBefore = Gsym.getNumFunctionInfos(); + for (const object::SymbolRef &Sym : Obj.symbols()) { + Expected<SymbolRef::Type> SymType = Sym.getType(); + if (!SymType) { + consumeError(SymType.takeError()); + continue; + } + Expected<uint64_t> AddrOrErr = Sym.getValue(); + if (!AddrOrErr) + // TODO: Test this error. + return AddrOrErr.takeError(); + + if (SymType.get() != SymbolRef::Type::ST_Function || + !Gsym.IsValidTextAddress(*AddrOrErr) || + Gsym.hasFunctionInfoForAddress(*AddrOrErr)) + continue; + // Function size for MachO files will be 0 + constexpr bool NoCopy = false; + const uint64_t size = IsELF ? ELFSymbolRef(Sym).getSize() : 0; + Expected<StringRef> Name = Sym.getName(); + if (!Name) { + logAllUnhandledErrors(Name.takeError(), Log, "ObjectFileTransformer: "); + continue; + } + // Remove the leading '_' character in any symbol names if there is one + // for mach-o files. + if (IsMachO) + Name->consume_front("_"); + Gsym.addFunctionInfo( + FunctionInfo(*AddrOrErr, size, Gsym.insertString(*Name, NoCopy))); + } + size_t FunctionsAddedCount = Gsym.getNumFunctionInfos() - NumBefore; + Log << "Loaded " << FunctionsAddedCount << " functions from symbol table.\n"; + return Error::success(); +} |