You've already forked linux-packaging-mono
acceptance-tests
data
docs
external
Newtonsoft.Json
api-doc-tools
api-snapshot
aspnetwebstack
bdwgc
binary-reference-assemblies
bockbuild
boringssl
cecil
cecil-legacy
corefx
corert
helix-binaries
ikdasm
ikvm
illinker-test-assets
linker
llvm-project
clang
clang-tools-extra
compiler-rt
eng
libcxx
libcxxabi
libunwind
lld
lldb
llvm
bindings
cmake
docs
examples
include
lib
Analysis
AsmParser
BinaryFormat
Bitcode
CodeGen
DebugInfo
CodeView
DWARF
MSF
PDB
DIA
Native
DbiModuleDescriptor.cpp
DbiModuleDescriptorBuilder.cpp
DbiModuleList.cpp
DbiStream.cpp
DbiStreamBuilder.cpp
EnumTables.cpp
GSIStreamBuilder.cpp
GlobalsStream.cpp
Hash.cpp
HashTable.cpp
InfoStream.cpp
InfoStreamBuilder.cpp
ModuleDebugStream.cpp
NamedStreamMap.cpp
NativeBuiltinSymbol.cpp
NativeCompilandSymbol.cpp
NativeEnumModules.cpp
NativeEnumSymbol.cpp
NativeEnumTypes.cpp
NativeExeSymbol.cpp
NativeRawSymbol.cpp
NativeSession.cpp
PDBFile.cpp
PDBFileBuilder.cpp
PDBStringTable.cpp
PDBStringTableBuilder.cpp
PublicsStream.cpp
RawError.cpp
SymbolStream.cpp
TpiHashing.cpp
TpiStream.cpp
TpiStreamBuilder.cpp
CMakeLists.txt
GenericError.cpp
IPDBSourceFile.cpp
LLVMBuild.txt
PDB.cpp
PDBContext.cpp
PDBExtras.cpp
PDBInterfaceAnchors.cpp
PDBSymDumper.cpp
PDBSymbol.cpp
PDBSymbolAnnotation.cpp
PDBSymbolBlock.cpp
PDBSymbolCompiland.cpp
PDBSymbolCompilandDetails.cpp
PDBSymbolCompilandEnv.cpp
PDBSymbolCustom.cpp
PDBSymbolData.cpp
PDBSymbolExe.cpp
PDBSymbolFunc.cpp
PDBSymbolFuncDebugEnd.cpp
PDBSymbolFuncDebugStart.cpp
PDBSymbolLabel.cpp
PDBSymbolPublicSymbol.cpp
PDBSymbolThunk.cpp
PDBSymbolTypeArray.cpp
PDBSymbolTypeBaseClass.cpp
PDBSymbolTypeBuiltin.cpp
PDBSymbolTypeCustom.cpp
PDBSymbolTypeDimension.cpp
PDBSymbolTypeEnum.cpp
PDBSymbolTypeFriend.cpp
PDBSymbolTypeFunctionArg.cpp
PDBSymbolTypeFunctionSig.cpp
PDBSymbolTypeManaged.cpp
PDBSymbolTypePointer.cpp
PDBSymbolTypeTypedef.cpp
PDBSymbolTypeUDT.cpp
PDBSymbolTypeVTable.cpp
PDBSymbolTypeVTableShape.cpp
PDBSymbolUnknown.cpp
PDBSymbolUsingNamespace.cpp
UDTLayout.cpp
Symbolize
CMakeLists.txt
LLVMBuild.txt
Demangle
ExecutionEngine
FuzzMutate
Fuzzer
IR
IRReader
LTO
LineEditor
Linker
MC
Object
ObjectYAML
Option
Passes
ProfileData
Support
TableGen
Target
Testing
ToolDrivers
Transforms
WindowsManifest
XRay
CMakeLists.txt
LLVMBuild.txt
projects
resources
runtimes
scripts
test
tools
unittests
utils
.arcconfig
.clang-format
.clang-tidy
.gitattributes
.gitignore
CMakeLists.txt
CODE_OWNERS.TXT
CREDITS.TXT
LICENSE.TXT
LLVMBuild.txt
README.txt
RELEASE_TESTERS.TXT
configure
llvm.spec.in
version.txt.in
nuget
openmp
polly
Directory.Build.props
Directory.Build.targets
NuGet.config
azure-pipelines.yml
build.cmd
build.sh
dir.common.props
global.json
llvm.proj
mxe-Win64.cmake.in
nuget-buildtasks
nunit-lite
roslyn-binaries
rx
xunit-binaries
how-to-bump-roslyn-binaries.md
ikvm-native
llvm
m4
man
mcs
mono
msvc
netcore
po
runtime
samples
scripts
support
tools
COPYING.LIB
LICENSE
Makefile.am
Makefile.in
NEWS
README.md
acinclude.m4
aclocal.m4
autogen.sh
code_of_conduct.md
compile
config.guess
config.h.in
config.rpath
config.sub
configure.REMOVED.git-id
configure.ac.REMOVED.git-id
depcomp
install-sh
ltmain.sh.REMOVED.git-id
missing
mkinstalldirs
mono-uninstalled.pc.in
test-driver
winconfig.h
153 lines
4.9 KiB
C++
153 lines
4.9 KiB
C++
![]() |
//===- NamedStreamMap.cpp - PDB Named Stream Map --------------------------===//
|
||
|
//
|
||
|
// The LLVM Compiler Infrastructure
|
||
|
//
|
||
|
// This file is distributed under the University of Illinois Open Source
|
||
|
// License. See LICENSE.TXT for details.
|
||
|
//
|
||
|
//===----------------------------------------------------------------------===//
|
||
|
|
||
|
#include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h"
|
||
|
#include "llvm/ADT/StringMap.h"
|
||
|
#include "llvm/ADT/StringRef.h"
|
||
|
#include "llvm/ADT/iterator_range.h"
|
||
|
#include "llvm/DebugInfo/PDB/Native/HashTable.h"
|
||
|
#include "llvm/DebugInfo/PDB/Native/RawError.h"
|
||
|
#include "llvm/Support/BinaryStreamReader.h"
|
||
|
#include "llvm/Support/BinaryStreamRef.h"
|
||
|
#include "llvm/Support/BinaryStreamWriter.h"
|
||
|
#include "llvm/Support/Endian.h"
|
||
|
#include "llvm/Support/Error.h"
|
||
|
#include <algorithm>
|
||
|
#include <cassert>
|
||
|
#include <cstdint>
|
||
|
#include <tuple>
|
||
|
|
||
|
using namespace llvm;
|
||
|
using namespace llvm::pdb;
|
||
|
|
||
|
// FIXME: This shouldn't be necessary, but if we insert the strings in any
|
||
|
// other order, cvdump cannot read the generated name map. This suggests that
|
||
|
// we may be using the wrong hash function. A closer inspection of the cvdump
|
||
|
// source code may reveal something, but for now this at least makes us work,
|
||
|
// even if only by accident.
|
||
|
static constexpr const char *OrderedStreamNames[] = {"/LinkInfo", "/names",
|
||
|
"/src/headerblock"};
|
||
|
|
||
|
NamedStreamMap::NamedStreamMap() = default;
|
||
|
|
||
|
Error NamedStreamMap::load(BinaryStreamReader &Stream) {
|
||
|
Mapping.clear();
|
||
|
FinalizedHashTable.clear();
|
||
|
FinalizedInfo.reset();
|
||
|
|
||
|
uint32_t StringBufferSize;
|
||
|
if (auto EC = Stream.readInteger(StringBufferSize))
|
||
|
return joinErrors(std::move(EC),
|
||
|
make_error<RawError>(raw_error_code::corrupt_file,
|
||
|
"Expected string buffer size"));
|
||
|
|
||
|
BinaryStreamRef StringsBuffer;
|
||
|
if (auto EC = Stream.readStreamRef(StringsBuffer, StringBufferSize))
|
||
|
return EC;
|
||
|
|
||
|
HashTable OffsetIndexMap;
|
||
|
if (auto EC = OffsetIndexMap.load(Stream))
|
||
|
return EC;
|
||
|
|
||
|
uint32_t NameOffset;
|
||
|
uint32_t NameIndex;
|
||
|
for (const auto &Entry : OffsetIndexMap) {
|
||
|
std::tie(NameOffset, NameIndex) = Entry;
|
||
|
|
||
|
// Compute the offset of the start of the string relative to the stream.
|
||
|
BinaryStreamReader NameReader(StringsBuffer);
|
||
|
NameReader.setOffset(NameOffset);
|
||
|
// Pump out our c-string from the stream.
|
||
|
StringRef Str;
|
||
|
if (auto EC = NameReader.readCString(Str))
|
||
|
return joinErrors(std::move(EC),
|
||
|
make_error<RawError>(raw_error_code::corrupt_file,
|
||
|
"Expected name map name"));
|
||
|
|
||
|
// Add this to a string-map from name to stream number.
|
||
|
Mapping.insert({Str, NameIndex});
|
||
|
}
|
||
|
|
||
|
return Error::success();
|
||
|
}
|
||
|
|
||
|
Error NamedStreamMap::commit(BinaryStreamWriter &Writer) const {
|
||
|
assert(FinalizedInfo.hasValue());
|
||
|
|
||
|
// The first field is the number of bytes of string data.
|
||
|
if (auto EC = Writer.writeInteger(FinalizedInfo->StringDataBytes))
|
||
|
return EC;
|
||
|
|
||
|
for (const auto &Name : OrderedStreamNames) {
|
||
|
auto Item = Mapping.find(Name);
|
||
|
if (Item == Mapping.end())
|
||
|
continue;
|
||
|
if (auto EC = Writer.writeCString(Item->getKey()))
|
||
|
return EC;
|
||
|
}
|
||
|
|
||
|
// And finally the Offset Index map.
|
||
|
if (auto EC = FinalizedHashTable.commit(Writer))
|
||
|
return EC;
|
||
|
|
||
|
return Error::success();
|
||
|
}
|
||
|
|
||
|
uint32_t NamedStreamMap::finalize() {
|
||
|
if (FinalizedInfo.hasValue())
|
||
|
return FinalizedInfo->SerializedLength;
|
||
|
|
||
|
// Build the finalized hash table.
|
||
|
FinalizedHashTable.clear();
|
||
|
FinalizedInfo.emplace();
|
||
|
|
||
|
for (const auto &Name : OrderedStreamNames) {
|
||
|
auto Item = Mapping.find(Name);
|
||
|
if (Item == Mapping.end())
|
||
|
continue;
|
||
|
FinalizedHashTable.set(FinalizedInfo->StringDataBytes, Item->getValue());
|
||
|
FinalizedInfo->StringDataBytes += Item->getKeyLength() + 1;
|
||
|
}
|
||
|
|
||
|
// Number of bytes of string data.
|
||
|
FinalizedInfo->SerializedLength += sizeof(support::ulittle32_t);
|
||
|
// Followed by that many actual bytes of string data.
|
||
|
FinalizedInfo->SerializedLength += FinalizedInfo->StringDataBytes;
|
||
|
// Followed by the mapping from Offset to Index.
|
||
|
FinalizedInfo->SerializedLength +=
|
||
|
FinalizedHashTable.calculateSerializedLength();
|
||
|
return FinalizedInfo->SerializedLength;
|
||
|
}
|
||
|
|
||
|
iterator_range<StringMapConstIterator<uint32_t>>
|
||
|
NamedStreamMap::entries() const {
|
||
|
return make_range<StringMapConstIterator<uint32_t>>(Mapping.begin(),
|
||
|
Mapping.end());
|
||
|
}
|
||
|
|
||
|
uint32_t NamedStreamMap::size() const { return Mapping.size(); }
|
||
|
|
||
|
bool NamedStreamMap::get(StringRef Stream, uint32_t &StreamNo) const {
|
||
|
auto Iter = Mapping.find(Stream);
|
||
|
if (Iter == Mapping.end())
|
||
|
return false;
|
||
|
StreamNo = Iter->second;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void NamedStreamMap::set(StringRef Stream, uint32_t StreamNo) {
|
||
|
FinalizedInfo.reset();
|
||
|
Mapping[Stream] = StreamNo;
|
||
|
}
|
||
|
|
||
|
void NamedStreamMap::remove(StringRef Stream) {
|
||
|
FinalizedInfo.reset();
|
||
|
Mapping.erase(Stream);
|
||
|
}
|