Path: blob/main/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp
35269 views
//===- DWARFListTable.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/DWARFListTable.h"9#include "llvm/BinaryFormat/Dwarf.h"10#include "llvm/DebugInfo/DWARF/DWARFContext.h"11#include "llvm/Support/Errc.h"12#include "llvm/Support/Error.h"13#include "llvm/Support/Format.h"14#include "llvm/Support/raw_ostream.h"1516using namespace llvm;1718Error DWARFListTableHeader::extract(DWARFDataExtractor Data,19uint64_t *OffsetPtr) {20HeaderOffset = *OffsetPtr;21Error Err = Error::success();2223std::tie(HeaderData.Length, Format) = Data.getInitialLength(OffsetPtr, &Err);24if (Err)25return createStringError(26errc::invalid_argument, "parsing %s table at offset 0x%" PRIx64 ": %s",27SectionName.data(), HeaderOffset, toString(std::move(Err)).c_str());2829uint8_t OffsetByteSize = Format == dwarf::DWARF64 ? 8 : 4;30uint64_t FullLength =31HeaderData.Length + dwarf::getUnitLengthFieldByteSize(Format);32if (FullLength < getHeaderSize(Format))33return createStringError(errc::invalid_argument,34"%s table at offset 0x%" PRIx6435" has too small length (0x%" PRIx6436") to contain a complete header",37SectionName.data(), HeaderOffset, FullLength);38assert(FullLength == length() && "Inconsistent calculation of length.");39uint64_t End = HeaderOffset + FullLength;40if (!Data.isValidOffsetForDataOfSize(HeaderOffset, FullLength))41return createStringError(errc::invalid_argument,42"section is not large enough to contain a %s table "43"of length 0x%" PRIx64 " at offset 0x%" PRIx64,44SectionName.data(), FullLength, HeaderOffset);4546HeaderData.Version = Data.getU16(OffsetPtr);47HeaderData.AddrSize = Data.getU8(OffsetPtr);48HeaderData.SegSize = Data.getU8(OffsetPtr);49HeaderData.OffsetEntryCount = Data.getU32(OffsetPtr);5051// Perform basic validation of the remaining header fields.52if (HeaderData.Version != 5)53return createStringError(errc::invalid_argument,54"unrecognised %s table version %" PRIu1655" in table at offset 0x%" PRIx64,56SectionName.data(), HeaderData.Version, HeaderOffset);57if (Error SizeErr = DWARFContext::checkAddressSizeSupported(58HeaderData.AddrSize, errc::not_supported,59"%s table at offset 0x%" PRIx64, SectionName.data(), HeaderOffset))60return SizeErr;61if (HeaderData.SegSize != 0)62return createStringError(errc::not_supported,63"%s table at offset 0x%" PRIx6464" has unsupported segment selector size %" PRIu8,65SectionName.data(), HeaderOffset, HeaderData.SegSize);66if (End < HeaderOffset + getHeaderSize(Format) +67HeaderData.OffsetEntryCount * OffsetByteSize)68return createStringError(errc::invalid_argument,69"%s table at offset 0x%" PRIx64 " has more offset entries (%" PRIu3270") than there is space for",71SectionName.data(), HeaderOffset, HeaderData.OffsetEntryCount);72Data.setAddressSize(HeaderData.AddrSize);73*OffsetPtr += HeaderData.OffsetEntryCount * OffsetByteSize;74return Error::success();75}7677void DWARFListTableHeader::dump(DataExtractor Data, raw_ostream &OS,78DIDumpOptions DumpOpts) const {79if (DumpOpts.Verbose)80OS << format("0x%8.8" PRIx64 ": ", HeaderOffset);81int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(Format);82OS << format("%s list header: length = 0x%0*" PRIx64, ListTypeString.data(),83OffsetDumpWidth, HeaderData.Length)84<< ", format = " << dwarf::FormatString(Format)85<< format(", version = 0x%4.4" PRIx16 ", addr_size = 0x%2.2" PRIx886", seg_size = 0x%2.2" PRIx887", offset_entry_count = 0x%8.8" PRIx32 "\n",88HeaderData.Version, HeaderData.AddrSize, HeaderData.SegSize,89HeaderData.OffsetEntryCount);9091if (HeaderData.OffsetEntryCount > 0) {92OS << "offsets: [";93for (uint32_t I = 0; I < HeaderData.OffsetEntryCount; ++I) {94auto Off = *getOffsetEntry(Data, I);95OS << format("\n0x%0*" PRIx64, OffsetDumpWidth, Off);96if (DumpOpts.Verbose)97OS << format(" => 0x%08" PRIx64,98Off + HeaderOffset + getHeaderSize(Format));99}100OS << "\n]\n";101}102}103104uint64_t DWARFListTableHeader::length() const {105if (HeaderData.Length == 0)106return 0;107return HeaderData.Length + dwarf::getUnitLengthFieldByteSize(Format);108}109110111