96 lines · cpp
1//===- DWARFDebugInfoEntry.cpp --------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"10#include "llvm/DebugInfo/DWARF/DWARFContext.h"11#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"12#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"13#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"14#include "llvm/DebugInfo/DWARF/DWARFUnit.h"15#include "llvm/Support/Errc.h"16#include <cstddef>17#include <cstdint>18 19using namespace llvm;20using namespace dwarf;21 22bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U, uint64_t *OffsetPtr,23 const DWARFDataExtractor &DebugInfoData,24 uint64_t UEndOffset, uint32_t ParentIdx) {25 Offset = *OffsetPtr;26 this->ParentIdx = ParentIdx;27 if (Offset >= UEndOffset) {28 U.getContext().getWarningHandler()(29 createStringError(errc::invalid_argument,30 "DWARF unit from offset 0x%8.8" PRIx64 " incl. "31 "to offset 0x%8.8" PRIx64 " excl. "32 "tries to read DIEs at offset 0x%8.8" PRIx64,33 U.getOffset(), U.getNextUnitOffset(), *OffsetPtr));34 return false;35 }36 assert(DebugInfoData.isValidOffset(UEndOffset - 1));37 uint64_t AbbrCode = DebugInfoData.getULEB128(OffsetPtr);38 if (0 == AbbrCode) {39 // NULL debug tag entry.40 AbbrevDecl = nullptr;41 return true;42 }43 const auto *AbbrevSet = U.getAbbreviations();44 if (!AbbrevSet) {45 U.getContext().getWarningHandler()(46 createStringError(errc::invalid_argument,47 "DWARF unit at offset 0x%8.8" PRIx64 " "48 "contains invalid abbreviation set offset 0x%" PRIx64,49 U.getOffset(), U.getAbbreviationsOffset()));50 // Restore the original offset.51 *OffsetPtr = Offset;52 return false;53 }54 AbbrevDecl = AbbrevSet->getAbbreviationDeclaration(AbbrCode);55 if (!AbbrevDecl) {56 U.getContext().getWarningHandler()(57 createStringError(errc::invalid_argument,58 "DWARF unit at offset 0x%8.8" PRIx64 " "59 "contains invalid abbreviation %" PRIu64 " at "60 "offset 0x%8.8" PRIx64 ", valid abbreviations are %s",61 U.getOffset(), AbbrCode, *OffsetPtr,62 AbbrevSet->getCodeRange().c_str()));63 // Restore the original offset.64 *OffsetPtr = Offset;65 return false;66 }67 // See if all attributes in this DIE have fixed byte sizes. If so, we can68 // just add this size to the offset to skip to the next DIE.69 if (std::optional<size_t> FixedSize =70 AbbrevDecl->getFixedAttributesByteSize(U)) {71 *OffsetPtr += *FixedSize;72 return true;73 }74 75 // Skip all data in the .debug_info for the attributes76 for (const auto &AttrSpec : AbbrevDecl->attributes()) {77 // Check if this attribute has a fixed byte size.78 if (auto FixedSize = AttrSpec.getByteSize(U)) {79 // Attribute byte size if fixed, just add the size to the offset.80 *OffsetPtr += *FixedSize;81 } else if (!DWARFFormValue::skipValue(AttrSpec.Form, DebugInfoData,82 OffsetPtr, U.getFormParams())) {83 // We failed to skip this attribute's value, restore the original offset84 // and return the failure status.85 U.getContext().getWarningHandler()(createStringError(86 errc::invalid_argument,87 "DWARF unit at offset 0x%8.8" PRIx64 " "88 "contains invalid FORM_* 0x%" PRIx16 " at offset 0x%8.8" PRIx64,89 U.getOffset(), AttrSpec.Form, *OffsetPtr));90 *OffsetPtr = Offset;91 return false;92 }93 }94 return true;95}96