Path: blob/main/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
35269 views
//===- DWARFDebugInfoEntry.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 "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"9#include "llvm/DebugInfo/DWARF/DWARFContext.h"10#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"11#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"12#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"13#include "llvm/DebugInfo/DWARF/DWARFUnit.h"14#include "llvm/Support/Errc.h"15#include <cstddef>16#include <cstdint>1718using namespace llvm;19using namespace dwarf;2021bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U, uint64_t *OffsetPtr,22const DWARFDataExtractor &DebugInfoData,23uint64_t UEndOffset, uint32_t ParentIdx) {24Offset = *OffsetPtr;25this->ParentIdx = ParentIdx;26if (Offset >= UEndOffset) {27U.getContext().getWarningHandler()(28createStringError(errc::invalid_argument,29"DWARF unit from offset 0x%8.8" PRIx64 " incl. "30"to offset 0x%8.8" PRIx64 " excl. "31"tries to read DIEs at offset 0x%8.8" PRIx64,32U.getOffset(), U.getNextUnitOffset(), *OffsetPtr));33return false;34}35assert(DebugInfoData.isValidOffset(UEndOffset - 1));36uint64_t AbbrCode = DebugInfoData.getULEB128(OffsetPtr);37if (0 == AbbrCode) {38// NULL debug tag entry.39AbbrevDecl = nullptr;40return true;41}42const auto *AbbrevSet = U.getAbbreviations();43if (!AbbrevSet) {44U.getContext().getWarningHandler()(45createStringError(errc::invalid_argument,46"DWARF unit at offset 0x%8.8" PRIx64 " "47"contains invalid abbreviation set offset 0x%" PRIx64,48U.getOffset(), U.getAbbreviationsOffset()));49// Restore the original offset.50*OffsetPtr = Offset;51return false;52}53AbbrevDecl = AbbrevSet->getAbbreviationDeclaration(AbbrCode);54if (!AbbrevDecl) {55U.getContext().getWarningHandler()(56createStringError(errc::invalid_argument,57"DWARF unit at offset 0x%8.8" PRIx64 " "58"contains invalid abbreviation %" PRIu64 " at "59"offset 0x%8.8" PRIx64 ", valid abbreviations are %s",60U.getOffset(), AbbrCode, *OffsetPtr,61AbbrevSet->getCodeRange().c_str()));62// Restore the original offset.63*OffsetPtr = Offset;64return false;65}66// See if all attributes in this DIE have fixed byte sizes. If so, we can67// just add this size to the offset to skip to the next DIE.68if (std::optional<size_t> FixedSize =69AbbrevDecl->getFixedAttributesByteSize(U)) {70*OffsetPtr += *FixedSize;71return true;72}7374// Skip all data in the .debug_info for the attributes75for (const auto &AttrSpec : AbbrevDecl->attributes()) {76// Check if this attribute has a fixed byte size.77if (auto FixedSize = AttrSpec.getByteSize(U)) {78// Attribute byte size if fixed, just add the size to the offset.79*OffsetPtr += *FixedSize;80} else if (!DWARFFormValue::skipValue(AttrSpec.Form, DebugInfoData,81OffsetPtr, U.getFormParams())) {82// We failed to skip this attribute's value, restore the original offset83// and return the failure status.84U.getContext().getWarningHandler()(createStringError(85errc::invalid_argument,86"DWARF unit at offset 0x%8.8" PRIx64 " "87"contains invalid FORM_* 0x%" PRIx16 " at offset 0x%8.8" PRIx64,88U.getOffset(), AttrSpec.Form, *OffsetPtr));89*OffsetPtr = Offset;90return false;91}92}93return true;94}959697