brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.9 KiB · 30aa60b Raw
116 lines · cpp
1//===- DebugChecksumsSubsection.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/CodeView/DebugChecksumsSubsection.h"10#include "llvm/ADT/ArrayRef.h"11#include "llvm/DebugInfo/CodeView/CodeView.h"12#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"13#include "llvm/Support/BinaryStreamReader.h"14#include "llvm/Support/BinaryStreamWriter.h"15#include "llvm/Support/Endian.h"16#include "llvm/Support/Error.h"17#include "llvm/Support/MathExtras.h"18#include <cassert>19#include <cstdint>20#include <cstring>21 22using namespace llvm;23using namespace llvm::codeview;24 25struct FileChecksumEntryHeader {26  using ulittle32_t = support::ulittle32_t;27 28  ulittle32_t FileNameOffset; // Byte offset of filename in global string table.29  uint8_t ChecksumSize;       // Number of bytes of checksum.30  uint8_t ChecksumKind;       // FileChecksumKind31                              // Checksum bytes follow.32};33 34Error VarStreamArrayExtractor<FileChecksumEntry>::35operator()(BinaryStreamRef Stream, uint32_t &Len, FileChecksumEntry &Item) {36  BinaryStreamReader Reader(Stream);37 38  const FileChecksumEntryHeader *Header;39  if (auto EC = Reader.readObject(Header))40    return EC;41 42  Item.FileNameOffset = Header->FileNameOffset;43  Item.Kind = static_cast<FileChecksumKind>(Header->ChecksumKind);44  if (auto EC = Reader.readBytes(Item.Checksum, Header->ChecksumSize))45    return EC;46 47  Len = alignTo(Header->ChecksumSize + sizeof(FileChecksumEntryHeader), 4);48  return Error::success();49}50 51Error DebugChecksumsSubsectionRef::initialize(BinaryStreamReader Reader) {52  if (auto EC = Reader.readArray(Checksums, Reader.bytesRemaining()))53    return EC;54 55  return Error::success();56}57 58Error DebugChecksumsSubsectionRef::initialize(BinaryStreamRef Section) {59  BinaryStreamReader Reader(Section);60  return initialize(Reader);61}62 63DebugChecksumsSubsection::DebugChecksumsSubsection(64    DebugStringTableSubsection &Strings)65    : DebugSubsection(DebugSubsectionKind::FileChecksums), Strings(Strings) {}66 67void DebugChecksumsSubsection::addChecksum(StringRef FileName,68                                           FileChecksumKind Kind,69                                           ArrayRef<uint8_t> Bytes) {70  FileChecksumEntry Entry;71  if (!Bytes.empty()) {72    uint8_t *Copy = Storage.Allocate<uint8_t>(Bytes.size());73    ::memcpy(Copy, Bytes.data(), Bytes.size());74    Entry.Checksum = ArrayRef(Copy, Bytes.size());75  }76 77  Entry.FileNameOffset = Strings.insert(FileName);78  Entry.Kind = Kind;79  Checksums.push_back(Entry);80 81  // This maps the offset of this string in the string table to the offset82  // of this checksum entry in the checksum buffer.83  OffsetMap[Entry.FileNameOffset] = SerializedSize;84  assert(SerializedSize % 4 == 0);85 86  uint32_t Len = alignTo(sizeof(FileChecksumEntryHeader) + Bytes.size(), 4);87  SerializedSize += Len;88}89 90uint32_t DebugChecksumsSubsection::calculateSerializedSize() const {91  return SerializedSize;92}93 94Error DebugChecksumsSubsection::commit(BinaryStreamWriter &Writer) const {95  for (const auto &FC : Checksums) {96    FileChecksumEntryHeader Header;97    Header.ChecksumKind = uint8_t(FC.Kind);98    Header.ChecksumSize = FC.Checksum.size();99    Header.FileNameOffset = FC.FileNameOffset;100    if (auto EC = Writer.writeObject(Header))101      return EC;102    if (auto EC = Writer.writeArray(ArrayRef(FC.Checksum)))103      return EC;104    if (auto EC = Writer.padToAlignment(4))105      return EC;106  }107  return Error::success();108}109 110uint32_t DebugChecksumsSubsection::mapChecksumOffset(StringRef FileName) const {111  uint32_t Offset = Strings.getIdForString(FileName);112  auto Iter = OffsetMap.find(Offset);113  assert(Iter != OffsetMap.end());114  return Iter->second;115}116