Files
acceptance-tests
data
debian
docs
external
Newtonsoft.Json
api-doc-tools
api-snapshot
aspnetwebstack
binary-reference-assemblies
bockbuild
boringssl
cecil
cecil-legacy
corefx
corert
helix-binaries
ikdasm
ikvm
illinker-test-assets
linker
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
nuget-buildtasks
nunit-lite
roslyn-binaries
rx
xunit-binaries
how-to-bump-roslyn-binaries.md
ikvm-native
libgc
llvm
m4
man
mcs
mk
mono
msvc
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
linux-packaging-mono/external/llvm/lib/DebugInfo/PDB/Native/PDBStringTable.cpp
Xamarin Public Jenkins (auto-signing) 64ac736ec5 Imported Upstream version 6.0.0.172
Former-commit-id: f3cc9b82f3e5bd8f0fd3ebc098f789556b44e9cd
2019-04-12 14:10:50 +00:00

139 lines
4.4 KiB
C++

//===- PDBStringTable.cpp - PDB String Table ---------------------*- C++-*-===//
//
// 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/PDBStringTable.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/DebugInfo/PDB/Native/Hash.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Endian.h"
using namespace llvm;
using namespace llvm::support;
using namespace llvm::pdb;
uint32_t PDBStringTable::getByteSize() const { return Header->ByteSize; }
uint32_t PDBStringTable::getNameCount() const { return NameCount; }
uint32_t PDBStringTable::getHashVersion() const { return Header->HashVersion; }
uint32_t PDBStringTable::getSignature() const { return Header->Signature; }
Error PDBStringTable::readHeader(BinaryStreamReader &Reader) {
if (auto EC = Reader.readObject(Header))
return EC;
if (Header->Signature != PDBStringTableSignature)
return make_error<RawError>(raw_error_code::corrupt_file,
"Invalid hash table signature");
if (Header->HashVersion != 1 && Header->HashVersion != 2)
return make_error<RawError>(raw_error_code::corrupt_file,
"Unsupported hash version");
assert(Reader.bytesRemaining() == 0);
return Error::success();
}
Error PDBStringTable::readStrings(BinaryStreamReader &Reader) {
BinaryStreamRef Stream;
if (auto EC = Reader.readStreamRef(Stream))
return EC;
if (auto EC = Strings.initialize(Stream)) {
return joinErrors(std::move(EC),
make_error<RawError>(raw_error_code::corrupt_file,
"Invalid hash table byte length"));
}
assert(Reader.bytesRemaining() == 0);
return Error::success();
}
const codeview::DebugStringTableSubsectionRef &
PDBStringTable::getStringTable() const {
return Strings;
}
Error PDBStringTable::readHashTable(BinaryStreamReader &Reader) {
const support::ulittle32_t *HashCount;
if (auto EC = Reader.readObject(HashCount))
return EC;
if (auto EC = Reader.readArray(IDs, *HashCount)) {
return joinErrors(std::move(EC),
make_error<RawError>(raw_error_code::corrupt_file,
"Could not read bucket array"));
}
return Error::success();
}
Error PDBStringTable::readEpilogue(BinaryStreamReader &Reader) {
if (auto EC = Reader.readInteger(NameCount))
return EC;
assert(Reader.bytesRemaining() == 0);
return Error::success();
}
Error PDBStringTable::reload(BinaryStreamReader &Reader) {
BinaryStreamReader SectionReader;
std::tie(SectionReader, Reader) = Reader.split(sizeof(PDBStringTableHeader));
if (auto EC = readHeader(SectionReader))
return EC;
std::tie(SectionReader, Reader) = Reader.split(Header->ByteSize);
if (auto EC = readStrings(SectionReader))
return EC;
// We don't know how long the hash table is until we parse it, so let the
// function responsible for doing that figure it out.
if (auto EC = readHashTable(Reader))
return EC;
std::tie(SectionReader, Reader) = Reader.split(sizeof(uint32_t));
if (auto EC = readEpilogue(SectionReader))
return EC;
assert(Reader.bytesRemaining() == 0);
return Error::success();
}
Expected<StringRef> PDBStringTable::getStringForID(uint32_t ID) const {
return Strings.getString(ID);
}
Expected<uint32_t> PDBStringTable::getIDForString(StringRef Str) const {
uint32_t Hash =
(Header->HashVersion == 1) ? hashStringV1(Str) : hashStringV2(Str);
size_t Count = IDs.size();
uint32_t Start = Hash % Count;
for (size_t I = 0; I < Count; ++I) {
// The hash is just a starting point for the search, but if it
// doesn't work we should find the string no matter what, because
// we iterate the entire array.
uint32_t Index = (Start + I) % Count;
uint32_t ID = IDs[Index];
auto ExpectedStr = getStringForID(ID);
if (!ExpectedStr)
return ExpectedStr.takeError();
if (*ExpectedStr == Str)
return ID;
}
return make_error<RawError>(raw_error_code::no_entry);
}
FixedStreamArray<support::ulittle32_t> PDBStringTable::name_ids() const {
return IDs;
}