Path: blob/main/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndexSet.cpp
213845 views
//===-- ManualDWARFIndex.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//===----------------------------------------------------------------------===//78#include "Plugins/SymbolFile/DWARF/ManualDWARFIndexSet.h"9#include "lldb/Core/DataFileCache.h"10#include "lldb/Utility/DataEncoder.h"11#include "lldb/Utility/DataExtractor.h"12#include <cstdint>1314using namespace lldb_private;15using namespace lldb_private::plugin::dwarf;1617namespace {18// Define IDs for the different tables when encoding and decoding the19// ManualDWARFIndex NameToDIE objects so we can avoid saving any empty maps.20enum DataID {21kDataIDFunctionBasenames = 1u,22kDataIDFunctionFullnames,23kDataIDFunctionMethods,24kDataIDFunctionSelectors,25kDataIDFunctionObjcClassSelectors,26kDataIDGlobals,27kDataIDTypes,28kDataIDNamespaces,29kDataIDEnd = 255u,30};31} // namespace3233// Version 2 changes the encoding of DIERef objects used in the DWARF manual34// index name tables. See DIERef class for details.35static constexpr uint32_t CURRENT_CACHE_VERSION = 2;3637static constexpr llvm::StringLiteral kIdentifierManualDWARFIndex("DIDX");3839std::optional<IndexSet<NameToDIE>>40plugin::dwarf::DecodeIndexSet(const DataExtractor &data,41lldb::offset_t *offset_ptr) {42StringTableReader strtab;43// We now decode the string table for all strings in the data cache file.44if (!strtab.Decode(data, offset_ptr))45return std::nullopt;4647llvm::StringRef identifier((const char *)data.GetData(offset_ptr, 4), 4);48if (identifier != kIdentifierManualDWARFIndex)49return std::nullopt;50const uint32_t version = data.GetU32(offset_ptr);51if (version != CURRENT_CACHE_VERSION)52return std::nullopt;5354IndexSet<NameToDIE> result;55while (true) {56switch (data.GetU8(offset_ptr)) {57default:58// If we got here, this is not expected, we expect the data IDs to match59// one of the values from the DataID enumeration.60return std::nullopt;61case kDataIDFunctionBasenames:62if (!result.function_basenames.Decode(data, offset_ptr, strtab))63return std::nullopt;64break;65case kDataIDFunctionFullnames:66if (!result.function_fullnames.Decode(data, offset_ptr, strtab))67return std::nullopt;68break;69case kDataIDFunctionMethods:70if (!result.function_methods.Decode(data, offset_ptr, strtab))71return std::nullopt;72break;73case kDataIDFunctionSelectors:74if (!result.function_selectors.Decode(data, offset_ptr, strtab))75return std::nullopt;76break;77case kDataIDFunctionObjcClassSelectors:78if (!result.objc_class_selectors.Decode(data, offset_ptr, strtab))79return std::nullopt;80break;81case kDataIDGlobals:82if (!result.globals.Decode(data, offset_ptr, strtab))83return std::nullopt;84break;85case kDataIDTypes:86if (!result.types.Decode(data, offset_ptr, strtab))87return std::nullopt;88break;89case kDataIDNamespaces:90if (!result.namespaces.Decode(data, offset_ptr, strtab))91return std::nullopt;92break;93case kDataIDEnd:94// We got to the end of our NameToDIE encodings.95return std::move(result);96break;97}98}99}100101void plugin::dwarf::EncodeIndexSet(const IndexSet<NameToDIE> &set,102DataEncoder &encoder) {103ConstStringTable strtab;104105// Encoder the DWARF index into a separate encoder first. This allows us106// gather all of the strings we willl need in "strtab" as we will need to107// write the string table out before the symbol table.108DataEncoder index_encoder(encoder.GetByteOrder(),109encoder.GetAddressByteSize());110111index_encoder.AppendData(kIdentifierManualDWARFIndex);112// Encode the data version.113index_encoder.AppendU32(CURRENT_CACHE_VERSION);114115if (!set.function_basenames.IsEmpty()) {116index_encoder.AppendU8(kDataIDFunctionBasenames);117set.function_basenames.Encode(index_encoder, strtab);118}119if (!set.function_fullnames.IsEmpty()) {120index_encoder.AppendU8(kDataIDFunctionFullnames);121set.function_fullnames.Encode(index_encoder, strtab);122}123if (!set.function_methods.IsEmpty()) {124index_encoder.AppendU8(kDataIDFunctionMethods);125set.function_methods.Encode(index_encoder, strtab);126}127if (!set.function_selectors.IsEmpty()) {128index_encoder.AppendU8(kDataIDFunctionSelectors);129set.function_selectors.Encode(index_encoder, strtab);130}131if (!set.objc_class_selectors.IsEmpty()) {132index_encoder.AppendU8(kDataIDFunctionObjcClassSelectors);133set.objc_class_selectors.Encode(index_encoder, strtab);134}135if (!set.globals.IsEmpty()) {136index_encoder.AppendU8(kDataIDGlobals);137set.globals.Encode(index_encoder, strtab);138}139if (!set.types.IsEmpty()) {140index_encoder.AppendU8(kDataIDTypes);141set.types.Encode(index_encoder, strtab);142}143if (!set.namespaces.IsEmpty()) {144index_encoder.AppendU8(kDataIDNamespaces);145set.namespaces.Encode(index_encoder, strtab);146}147index_encoder.AppendU8(kDataIDEnd);148149// Now that all strings have been gathered, we will emit the string table.150strtab.Encode(encoder);151// Followed by the symbol table data.152encoder.AppendData(index_encoder.GetData());153}154155156