Path: blob/main/contrib/llvm-project/llvm/lib/ObjectYAML/DWARFYAML.cpp
35233 views
//===- DWARFYAML.cpp - DWARF YAMLIO implementation ------------------------===//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 defines classes for handling the YAML representation of DWARF Debug9// Info.10//11//===----------------------------------------------------------------------===//1213#include "llvm/ObjectYAML/DWARFYAML.h"14#include "llvm/BinaryFormat/Dwarf.h"15#include "llvm/Support/Errc.h"16#include "llvm/Support/Error.h"1718namespace llvm {1920bool DWARFYAML::Data::isEmpty() const {21return getNonEmptySectionNames().empty();22}2324SetVector<StringRef> DWARFYAML::Data::getNonEmptySectionNames() const {25SetVector<StringRef> SecNames;26if (DebugStrings)27SecNames.insert("debug_str");28if (DebugAranges)29SecNames.insert("debug_aranges");30if (DebugRanges)31SecNames.insert("debug_ranges");32if (!DebugLines.empty())33SecNames.insert("debug_line");34if (DebugAddr)35SecNames.insert("debug_addr");36if (!DebugAbbrev.empty())37SecNames.insert("debug_abbrev");38if (!CompileUnits.empty())39SecNames.insert("debug_info");40if (PubNames)41SecNames.insert("debug_pubnames");42if (PubTypes)43SecNames.insert("debug_pubtypes");44if (GNUPubNames)45SecNames.insert("debug_gnu_pubnames");46if (GNUPubTypes)47SecNames.insert("debug_gnu_pubtypes");48if (DebugStrOffsets)49SecNames.insert("debug_str_offsets");50if (DebugRnglists)51SecNames.insert("debug_rnglists");52if (DebugLoclists)53SecNames.insert("debug_loclists");54if (DebugNames)55SecNames.insert("debug_names");56return SecNames;57}5859Expected<DWARFYAML::Data::AbbrevTableInfo>60DWARFYAML::Data::getAbbrevTableInfoByID(uint64_t ID) const {61if (AbbrevTableInfoMap.empty()) {62uint64_t AbbrevTableOffset = 0;63for (const auto &[Index, AbbrevTable] : enumerate(DebugAbbrev)) {64// If the abbrev table's ID isn't specified, we use the index as its ID.65uint64_t AbbrevTableID = AbbrevTable.ID.value_or(Index);66auto It = AbbrevTableInfoMap.insert(67{AbbrevTableID, AbbrevTableInfo{/*Index=*/Index,68/*Offset=*/AbbrevTableOffset}});69if (!It.second)70return createStringError(71errc::invalid_argument,72"the ID (%" PRIu64 ") of abbrev table with index %zu has been used "73"by abbrev table with index %" PRIu64,74AbbrevTableID, Index, It.first->second.Index);7576AbbrevTableOffset += getAbbrevTableContentByIndex(Index).size();77}78}7980auto It = AbbrevTableInfoMap.find(ID);81if (It == AbbrevTableInfoMap.end())82return createStringError(errc::invalid_argument,83"cannot find abbrev table whose ID is %" PRIu64,84ID);85return It->second;86}8788namespace yaml {8990void MappingTraits<DWARFYAML::Data>::mapping(IO &IO, DWARFYAML::Data &DWARF) {91void *OldContext = IO.getContext();92DWARFYAML::DWARFContext DWARFCtx;93IO.setContext(&DWARFCtx);94IO.mapOptional("debug_str", DWARF.DebugStrings);95IO.mapOptional("debug_abbrev", DWARF.DebugAbbrev);96IO.mapOptional("debug_aranges", DWARF.DebugAranges);97IO.mapOptional("debug_ranges", DWARF.DebugRanges);98IO.mapOptional("debug_pubnames", DWARF.PubNames);99IO.mapOptional("debug_pubtypes", DWARF.PubTypes);100DWARFCtx.IsGNUPubSec = true;101IO.mapOptional("debug_gnu_pubnames", DWARF.GNUPubNames);102IO.mapOptional("debug_gnu_pubtypes", DWARF.GNUPubTypes);103IO.mapOptional("debug_info", DWARF.CompileUnits);104IO.mapOptional("debug_line", DWARF.DebugLines);105IO.mapOptional("debug_addr", DWARF.DebugAddr);106IO.mapOptional("debug_str_offsets", DWARF.DebugStrOffsets);107IO.mapOptional("debug_rnglists", DWARF.DebugRnglists);108IO.mapOptional("debug_loclists", DWARF.DebugLoclists);109IO.mapOptional("debug_names", DWARF.DebugNames);110IO.setContext(OldContext);111}112113void MappingTraits<DWARFYAML::AbbrevTable>::mapping(114IO &IO, DWARFYAML::AbbrevTable &AbbrevTable) {115IO.mapOptional("ID", AbbrevTable.ID);116IO.mapOptional("Table", AbbrevTable.Table);117}118119void MappingTraits<DWARFYAML::Abbrev>::mapping(IO &IO,120DWARFYAML::Abbrev &Abbrev) {121IO.mapOptional("Code", Abbrev.Code);122IO.mapRequired("Tag", Abbrev.Tag);123IO.mapRequired("Children", Abbrev.Children);124IO.mapOptional("Attributes", Abbrev.Attributes);125}126127void MappingTraits<DWARFYAML::IdxForm>::mapping(IO &IO,128DWARFYAML::IdxForm &IdxForm) {129IO.mapRequired("Idx", IdxForm.Idx);130IO.mapRequired("Form", IdxForm.Form);131}132133void MappingTraits<DWARFYAML::DebugNameAbbreviation>::mapping(134IO &IO, DWARFYAML::DebugNameAbbreviation &DebugNameAbbreviation) {135IO.mapRequired("Code", DebugNameAbbreviation.Code);136IO.mapRequired("Tag", DebugNameAbbreviation.Tag);137IO.mapRequired("Indices", DebugNameAbbreviation.Indices);138}139140void MappingTraits<DWARFYAML::DebugNameEntry>::mapping(141IO &IO, DWARFYAML::DebugNameEntry &DebugNameEntry) {142IO.mapRequired("Name", DebugNameEntry.NameStrp);143IO.mapRequired("Code", DebugNameEntry.Code);144IO.mapOptional("Values", DebugNameEntry.Values);145}146147void MappingTraits<DWARFYAML::DebugNamesSection>::mapping(148IO &IO, DWARFYAML::DebugNamesSection &DebugNames) {149IO.mapRequired("Abbreviations", DebugNames.Abbrevs);150IO.mapRequired("Entries", DebugNames.Entries);151}152153void MappingTraits<DWARFYAML::AttributeAbbrev>::mapping(154IO &IO, DWARFYAML::AttributeAbbrev &AttAbbrev) {155IO.mapRequired("Attribute", AttAbbrev.Attribute);156IO.mapRequired("Form", AttAbbrev.Form);157if(AttAbbrev.Form == dwarf::DW_FORM_implicit_const)158IO.mapRequired("Value", AttAbbrev.Value);159}160161void MappingTraits<DWARFYAML::ARangeDescriptor>::mapping(162IO &IO, DWARFYAML::ARangeDescriptor &Descriptor) {163IO.mapRequired("Address", Descriptor.Address);164IO.mapRequired("Length", Descriptor.Length);165}166167void MappingTraits<DWARFYAML::ARange>::mapping(IO &IO,168DWARFYAML::ARange &ARange) {169IO.mapOptional("Format", ARange.Format, dwarf::DWARF32);170IO.mapOptional("Length", ARange.Length);171IO.mapRequired("Version", ARange.Version);172IO.mapRequired("CuOffset", ARange.CuOffset);173IO.mapOptional("AddressSize", ARange.AddrSize);174IO.mapOptional("SegmentSelectorSize", ARange.SegSize, 0);175IO.mapOptional("Descriptors", ARange.Descriptors);176}177178void MappingTraits<DWARFYAML::RangeEntry>::mapping(179IO &IO, DWARFYAML::RangeEntry &Descriptor) {180IO.mapRequired("LowOffset", Descriptor.LowOffset);181IO.mapRequired("HighOffset", Descriptor.HighOffset);182}183184void MappingTraits<DWARFYAML::Ranges>::mapping(IO &IO,185DWARFYAML::Ranges &DebugRanges) {186IO.mapOptional("Offset", DebugRanges.Offset);187IO.mapOptional("AddrSize", DebugRanges.AddrSize);188IO.mapRequired("Entries", DebugRanges.Entries);189}190191void MappingTraits<DWARFYAML::PubEntry>::mapping(IO &IO,192DWARFYAML::PubEntry &Entry) {193IO.mapRequired("DieOffset", Entry.DieOffset);194if (static_cast<DWARFYAML::DWARFContext *>(IO.getContext())->IsGNUPubSec)195IO.mapRequired("Descriptor", Entry.Descriptor);196IO.mapRequired("Name", Entry.Name);197}198199void MappingTraits<DWARFYAML::PubSection>::mapping(200IO &IO, DWARFYAML::PubSection &Section) {201IO.mapOptional("Format", Section.Format, dwarf::DWARF32);202IO.mapRequired("Length", Section.Length);203IO.mapRequired("Version", Section.Version);204IO.mapRequired("UnitOffset", Section.UnitOffset);205IO.mapRequired("UnitSize", Section.UnitSize);206IO.mapRequired("Entries", Section.Entries);207}208209void MappingTraits<DWARFYAML::Unit>::mapping(IO &IO, DWARFYAML::Unit &Unit) {210IO.mapOptional("Format", Unit.Format, dwarf::DWARF32);211IO.mapOptional("Length", Unit.Length);212IO.mapRequired("Version", Unit.Version);213if (Unit.Version >= 5)214IO.mapRequired("UnitType", Unit.Type);215IO.mapOptional("AbbrevTableID", Unit.AbbrevTableID);216IO.mapOptional("AbbrOffset", Unit.AbbrOffset);217IO.mapOptional("AddrSize", Unit.AddrSize);218IO.mapOptional("Entries", Unit.Entries);219}220221void MappingTraits<DWARFYAML::Entry>::mapping(IO &IO, DWARFYAML::Entry &Entry) {222IO.mapRequired("AbbrCode", Entry.AbbrCode);223IO.mapOptional("Values", Entry.Values);224}225226void MappingTraits<DWARFYAML::FormValue>::mapping(227IO &IO, DWARFYAML::FormValue &FormValue) {228IO.mapOptional("Value", FormValue.Value);229if (!FormValue.CStr.empty() || !IO.outputting())230IO.mapOptional("CStr", FormValue.CStr);231if (!FormValue.BlockData.empty() || !IO.outputting())232IO.mapOptional("BlockData", FormValue.BlockData);233}234235void MappingTraits<DWARFYAML::File>::mapping(IO &IO, DWARFYAML::File &File) {236IO.mapRequired("Name", File.Name);237IO.mapRequired("DirIdx", File.DirIdx);238IO.mapRequired("ModTime", File.ModTime);239IO.mapRequired("Length", File.Length);240}241242void MappingTraits<DWARFYAML::LineTableOpcode>::mapping(243IO &IO, DWARFYAML::LineTableOpcode &LineTableOpcode) {244IO.mapRequired("Opcode", LineTableOpcode.Opcode);245if (LineTableOpcode.Opcode == dwarf::DW_LNS_extended_op) {246IO.mapOptional("ExtLen", LineTableOpcode.ExtLen);247IO.mapRequired("SubOpcode", LineTableOpcode.SubOpcode);248}249250if (!LineTableOpcode.UnknownOpcodeData.empty() || !IO.outputting())251IO.mapOptional("UnknownOpcodeData", LineTableOpcode.UnknownOpcodeData);252if (!LineTableOpcode.UnknownOpcodeData.empty() || !IO.outputting())253IO.mapOptional("StandardOpcodeData", LineTableOpcode.StandardOpcodeData);254if (!LineTableOpcode.FileEntry.Name.empty() || !IO.outputting())255IO.mapOptional("FileEntry", LineTableOpcode.FileEntry);256if (LineTableOpcode.Opcode == dwarf::DW_LNS_advance_line || !IO.outputting())257IO.mapOptional("SData", LineTableOpcode.SData);258IO.mapOptional("Data", LineTableOpcode.Data);259}260261void MappingTraits<DWARFYAML::LineTable>::mapping(262IO &IO, DWARFYAML::LineTable &LineTable) {263IO.mapOptional("Format", LineTable.Format, dwarf::DWARF32);264IO.mapOptional("Length", LineTable.Length);265IO.mapRequired("Version", LineTable.Version);266IO.mapOptional("PrologueLength", LineTable.PrologueLength);267IO.mapRequired("MinInstLength", LineTable.MinInstLength);268if(LineTable.Version >= 4)269IO.mapRequired("MaxOpsPerInst", LineTable.MaxOpsPerInst);270IO.mapRequired("DefaultIsStmt", LineTable.DefaultIsStmt);271IO.mapRequired("LineBase", LineTable.LineBase);272IO.mapRequired("LineRange", LineTable.LineRange);273IO.mapOptional("OpcodeBase", LineTable.OpcodeBase);274IO.mapOptional("StandardOpcodeLengths", LineTable.StandardOpcodeLengths);275IO.mapOptional("IncludeDirs", LineTable.IncludeDirs);276IO.mapOptional("Files", LineTable.Files);277IO.mapOptional("Opcodes", LineTable.Opcodes);278}279280void MappingTraits<DWARFYAML::SegAddrPair>::mapping(281IO &IO, DWARFYAML::SegAddrPair &SegAddrPair) {282IO.mapOptional("Segment", SegAddrPair.Segment, 0);283IO.mapOptional("Address", SegAddrPair.Address, 0);284}285286void MappingTraits<DWARFYAML::AddrTableEntry>::mapping(287IO &IO, DWARFYAML::AddrTableEntry &AddrTable) {288IO.mapOptional("Format", AddrTable.Format, dwarf::DWARF32);289IO.mapOptional("Length", AddrTable.Length);290IO.mapRequired("Version", AddrTable.Version);291IO.mapOptional("AddressSize", AddrTable.AddrSize);292IO.mapOptional("SegmentSelectorSize", AddrTable.SegSelectorSize, 0);293IO.mapOptional("Entries", AddrTable.SegAddrPairs);294}295296void MappingTraits<DWARFYAML::StringOffsetsTable>::mapping(297IO &IO, DWARFYAML::StringOffsetsTable &StrOffsetsTable) {298IO.mapOptional("Format", StrOffsetsTable.Format, dwarf::DWARF32);299IO.mapOptional("Length", StrOffsetsTable.Length);300IO.mapOptional("Version", StrOffsetsTable.Version, 5);301IO.mapOptional("Padding", StrOffsetsTable.Padding, 0);302IO.mapOptional("Offsets", StrOffsetsTable.Offsets);303}304305void MappingTraits<DWARFYAML::DWARFOperation>::mapping(306IO &IO, DWARFYAML::DWARFOperation &DWARFOperation) {307IO.mapRequired("Operator", DWARFOperation.Operator);308IO.mapOptional("Values", DWARFOperation.Values);309}310311void MappingTraits<DWARFYAML::RnglistEntry>::mapping(312IO &IO, DWARFYAML::RnglistEntry &RnglistEntry) {313IO.mapRequired("Operator", RnglistEntry.Operator);314IO.mapOptional("Values", RnglistEntry.Values);315}316317void MappingTraits<DWARFYAML::LoclistEntry>::mapping(318IO &IO, DWARFYAML::LoclistEntry &LoclistEntry) {319IO.mapRequired("Operator", LoclistEntry.Operator);320IO.mapOptional("Values", LoclistEntry.Values);321IO.mapOptional("DescriptionsLength", LoclistEntry.DescriptionsLength);322IO.mapOptional("Descriptions", LoclistEntry.Descriptions);323}324325template <typename EntryType>326void MappingTraits<DWARFYAML::ListEntries<EntryType>>::mapping(327IO &IO, DWARFYAML::ListEntries<EntryType> &ListEntries) {328IO.mapOptional("Entries", ListEntries.Entries);329IO.mapOptional("Content", ListEntries.Content);330}331332template <typename EntryType>333std::string MappingTraits<DWARFYAML::ListEntries<EntryType>>::validate(334IO &IO, DWARFYAML::ListEntries<EntryType> &ListEntries) {335if (ListEntries.Entries && ListEntries.Content)336return "Entries and Content can't be used together";337return "";338}339340template <typename EntryType>341void MappingTraits<DWARFYAML::ListTable<EntryType>>::mapping(342IO &IO, DWARFYAML::ListTable<EntryType> &ListTable) {343IO.mapOptional("Format", ListTable.Format, dwarf::DWARF32);344IO.mapOptional("Length", ListTable.Length);345IO.mapOptional("Version", ListTable.Version, 5);346IO.mapOptional("AddressSize", ListTable.AddrSize);347IO.mapOptional("SegmentSelectorSize", ListTable.SegSelectorSize, 0);348IO.mapOptional("OffsetEntryCount", ListTable.OffsetEntryCount);349IO.mapOptional("Offsets", ListTable.Offsets);350IO.mapOptional("Lists", ListTable.Lists);351}352353} // end namespace yaml354355} // end namespace llvm356357358