llvm::Error DWARFDebugNames::Header::extract(const DWARFDataExtractor &AS, uint32_t *Offset) { // Check that we can read the fixed-size part. if (!AS.isValidOffset(*Offset + sizeof(HeaderPOD) - 1)) return make_error<StringError>("Section too small: cannot read header.", inconvertibleErrorCode()); UnitLength = AS.getU32(Offset); Version = AS.getU16(Offset); Padding = AS.getU16(Offset); CompUnitCount = AS.getU32(Offset); LocalTypeUnitCount = AS.getU32(Offset); ForeignTypeUnitCount = AS.getU32(Offset); BucketCount = AS.getU32(Offset); NameCount = AS.getU32(Offset); AbbrevTableSize = AS.getU32(Offset); AugmentationStringSize = AS.getU32(Offset); if (!AS.isValidOffsetForDataOfSize(*Offset, AugmentationStringSize)) return make_error<StringError>( "Section too small: cannot read header augmentation.", inconvertibleErrorCode()); AugmentationString.resize(AugmentationStringSize); AS.getU8(Offset, reinterpret_cast<uint8_t *>(AugmentationString.data()), AugmentationStringSize); *Offset = alignTo(*Offset, 4); return Error::success(); }
Optional<DWARFDebugLoc::LocationList> DWARFDebugLoc::parseOneLocationList(DWARFDataExtractor Data, unsigned *Offset) { LocationList LL; LL.Offset = *Offset; // 2.6.2 Location Lists // A location list entry consists of: while (true) { Entry E; if (!Data.isValidOffsetForDataOfSize(*Offset, 2 * Data.getAddressSize())) { llvm::errs() << "Location list overflows the debug_loc section.\n"; return None; } // 1. A beginning address offset. ... E.Begin = Data.getRelocatedAddress(Offset); // 2. An ending address offset. ... E.End = Data.getRelocatedAddress(Offset); // The end of any given location list is marked by an end of list entry, // which consists of a 0 for the beginning address offset and a 0 for the // ending address offset. if (E.Begin == 0 && E.End == 0) return LL; if (!Data.isValidOffsetForDataOfSize(*Offset, 2)) { llvm::errs() << "Location list overflows the debug_loc section.\n"; return None; } unsigned Bytes = Data.getU16(Offset); if (!Data.isValidOffsetForDataOfSize(*Offset, Bytes)) { llvm::errs() << "Location list overflows the debug_loc section.\n"; return None; } // A single location description describing the location of the object... StringRef str = Data.getData().substr(*Offset, Bytes); *Offset += Bytes; E.Loc.reserve(str.size()); std::copy(str.begin(), str.end(), std::back_inserter(E.Loc)); LL.Entries.push_back(std::move(E)); } }
Optional<StrOffsetsContributionDescriptor> StrOffsetsContributionDescriptor::validateContributionSize( DWARFDataExtractor &DA) { uint8_t EntrySize = getDwarfOffsetByteSize(); // In order to ensure that we don't read a partial record at the end of // the section we validate for a multiple of the entry size. uint64_t ValidationSize = alignTo(Size, EntrySize); // Guard against overflow. if (ValidationSize >= Size) if (DA.isValidOffsetForDataOfSize((uint32_t)Base, ValidationSize)) return *this; return Optional<StrOffsetsContributionDescriptor>(); }
// Look for a DWARF32-formatted contribution to the string offsets table // starting at a given offset and record it in a descriptor. static Optional<StrOffsetsContributionDescriptor> parseDWARF32StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset) { if (!DA.isValidOffsetForDataOfSize(Offset, 8)) return None; uint32_t ContributionSize = DA.getU32(&Offset); if (ContributionSize >= 0xfffffff0) return None; uint8_t Version = DA.getU16(&Offset); (void)DA.getU16(&Offset); // padding // The encoded length includes the 2-byte version field and the 2-byte // padding, so we need to subtract them out when we populate the descriptor. return {{Offset, ContributionSize - 4, Version, DWARF32}}; }
// Look for a DWARF64-formatted contribution to the string offsets table // starting at a given offset and record it in a descriptor. static Optional<StrOffsetsContributionDescriptor> parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset) { if (!DA.isValidOffsetForDataOfSize(Offset, 16)) return Optional<StrOffsetsContributionDescriptor>(); if (DA.getU32(&Offset) != 0xffffffff) return Optional<StrOffsetsContributionDescriptor>(); uint64_t Size = DA.getU64(&Offset); uint8_t Version = DA.getU16(&Offset); (void)DA.getU16(&Offset); // padding // The encoded length includes the 2-byte version field and the 2-byte // padding, so we need to subtract them out when we populate the descriptor. return StrOffsetsContributionDescriptor(Offset, Size - 4, Version, DWARF64); //return Optional<StrOffsetsContributionDescriptor>(Descriptor); }