Changeset View
Changeset View
Standalone View
Standalone View
llvm/tools/llvm-pdbutil/LinePrinter.cpp
Show First 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | bool LinePrinter::IsClassExcluded(const ClassLayout &Class) { | ||||
if (IsTypeExcluded(Class.getName(), Class.getSize())) | if (IsTypeExcluded(Class.getName(), Class.getSize())) | ||||
return true; | return true; | ||||
if (Class.deepPaddingSize() < opts::pretty::PaddingThreshold) | if (Class.deepPaddingSize() < opts::pretty::PaddingThreshold) | ||||
return true; | return true; | ||||
return false; | return false; | ||||
} | } | ||||
void LinePrinter::formatBinary(StringRef Label, ArrayRef<uint8_t> Data, | void LinePrinter::formatBinary(StringRef Label, ArrayRef<uint8_t> Data, | ||||
uint32_t StartOffset) { | uint64_t StartOffset) { | ||||
NewLine(); | NewLine(); | ||||
OS << Label << " ("; | OS << Label << " ("; | ||||
if (!Data.empty()) { | if (!Data.empty()) { | ||||
OS << "\n"; | OS << "\n"; | ||||
OS << format_bytes_with_ascii(Data, StartOffset, 32, 4, | OS << format_bytes_with_ascii(Data, StartOffset, 32, 4, | ||||
CurrentIndent + IndentSpaces, true); | CurrentIndent + IndentSpaces, true); | ||||
NewLine(); | NewLine(); | ||||
} | } | ||||
OS << ")"; | OS << ")"; | ||||
} | } | ||||
void LinePrinter::formatBinary(StringRef Label, ArrayRef<uint8_t> Data, | void LinePrinter::formatBinary(StringRef Label, ArrayRef<uint8_t> Data, | ||||
uint64_t Base, uint32_t StartOffset) { | uint64_t Base, uint64_t StartOffset) { | ||||
NewLine(); | NewLine(); | ||||
OS << Label << " ("; | OS << Label << " ("; | ||||
if (!Data.empty()) { | if (!Data.empty()) { | ||||
OS << "\n"; | OS << "\n"; | ||||
Base += StartOffset; | Base += StartOffset; | ||||
OS << format_bytes_with_ascii(Data, Base, 32, 4, | OS << format_bytes_with_ascii(Data, Base, 32, 4, | ||||
CurrentIndent + IndentSpaces, true); | CurrentIndent + IndentSpaces, true); | ||||
NewLine(); | NewLine(); | ||||
} | } | ||||
OS << ")"; | OS << ")"; | ||||
} | } | ||||
namespace { | namespace { | ||||
struct Run { | struct Run { | ||||
Run() = default; | Run() = default; | ||||
explicit Run(uint32_t Block) : Block(Block) {} | explicit Run(uint32_t Block) : Block(Block) {} | ||||
uint32_t Block = 0; | uint32_t Block = 0; | ||||
uint32_t ByteLen = 0; | uint64_t ByteLen = 0; | ||||
}; | }; | ||||
} // namespace | } // namespace | ||||
static std::vector<Run> computeBlockRuns(uint32_t BlockSize, | static std::vector<Run> computeBlockRuns(uint32_t BlockSize, | ||||
const msf::MSFStreamLayout &Layout) { | const msf::MSFStreamLayout &Layout) { | ||||
std::vector<Run> Runs; | std::vector<Run> Runs; | ||||
if (Layout.Length == 0) | if (Layout.Length == 0) | ||||
return Runs; | return Runs; | ||||
ArrayRef<support::ulittle32_t> Blocks = Layout.Blocks; | ArrayRef<support::ulittle32_t> Blocks = Layout.Blocks; | ||||
assert(!Blocks.empty()); | assert(!Blocks.empty()); | ||||
uint32_t StreamBytesRemaining = Layout.Length; | uint64_t StreamBytesRemaining = Layout.Length; | ||||
uint32_t CurrentBlock = Blocks[0]; | uint32_t CurrentBlock = Blocks[0]; | ||||
Runs.emplace_back(CurrentBlock); | Runs.emplace_back(CurrentBlock); | ||||
while (!Blocks.empty()) { | while (!Blocks.empty()) { | ||||
Run *CurrentRun = &Runs.back(); | Run *CurrentRun = &Runs.back(); | ||||
uint32_t NextBlock = Blocks.front(); | uint32_t NextBlock = Blocks.front(); | ||||
if (NextBlock < CurrentBlock || (NextBlock - CurrentBlock > 1)) { | if (NextBlock < CurrentBlock || (NextBlock - CurrentBlock > 1)) { | ||||
Runs.emplace_back(NextBlock); | Runs.emplace_back(NextBlock); | ||||
CurrentRun = &Runs.back(); | CurrentRun = &Runs.back(); | ||||
} | } | ||||
uint32_t Used = std::min(BlockSize, StreamBytesRemaining); | uint64_t Used = | ||||
std::min(static_cast<uint64_t>(BlockSize), StreamBytesRemaining); | |||||
CurrentRun->ByteLen += Used; | CurrentRun->ByteLen += Used; | ||||
StreamBytesRemaining -= Used; | StreamBytesRemaining -= Used; | ||||
CurrentBlock = NextBlock; | CurrentBlock = NextBlock; | ||||
Blocks = Blocks.drop_front(); | Blocks = Blocks.drop_front(); | ||||
} | } | ||||
return Runs; | return Runs; | ||||
} | } | ||||
static std::pair<Run, uint32_t> findRun(uint32_t Offset, ArrayRef<Run> Runs) { | static std::pair<Run, uint64_t> findRun(uint64_t Offset, ArrayRef<Run> Runs) { | ||||
for (const auto &R : Runs) { | for (const auto &R : Runs) { | ||||
if (Offset < R.ByteLen) | if (Offset < R.ByteLen) | ||||
return std::make_pair(R, Offset); | return std::make_pair(R, Offset); | ||||
Offset -= R.ByteLen; | Offset -= R.ByteLen; | ||||
} | } | ||||
llvm_unreachable("Invalid offset!"); | llvm_unreachable("Invalid offset!"); | ||||
} | } | ||||
void LinePrinter::formatMsfStreamData(StringRef Label, PDBFile &File, | void LinePrinter::formatMsfStreamData(StringRef Label, PDBFile &File, | ||||
uint32_t StreamIdx, | uint32_t StreamIdx, | ||||
StringRef StreamPurpose, uint32_t Offset, | StringRef StreamPurpose, uint64_t Offset, | ||||
uint32_t Size) { | uint64_t Size) { | ||||
if (StreamIdx >= File.getNumStreams()) { | if (StreamIdx >= File.getNumStreams()) { | ||||
formatLine("Stream {0}: Not present", StreamIdx); | formatLine("Stream {0}: Not present", StreamIdx); | ||||
return; | return; | ||||
} | } | ||||
if (Size + Offset > File.getStreamByteSize(StreamIdx)) { | if (Size + Offset > File.getStreamByteSize(StreamIdx)) { | ||||
formatLine( | formatLine( | ||||
"Stream {0}: Invalid offset and size, range out of stream bounds", | "Stream {0}: Invalid offset and size, range out of stream bounds", | ||||
StreamIdx); | StreamIdx); | ||||
return; | return; | ||||
} | } | ||||
auto S = File.createIndexedStream(StreamIdx); | auto S = File.createIndexedStream(StreamIdx); | ||||
if (!S) { | if (!S) { | ||||
NewLine(); | NewLine(); | ||||
formatLine("Stream {0}: Not present", StreamIdx); | formatLine("Stream {0}: Not present", StreamIdx); | ||||
return; | return; | ||||
} | } | ||||
uint32_t End = | uint64_t End = | ||||
(Size == 0) ? S->getLength() : std::min(Offset + Size, S->getLength()); | (Size == 0) ? S->getLength() : std::min(Offset + Size, S->getLength()); | ||||
Size = End - Offset; | Size = End - Offset; | ||||
formatLine("Stream {0}: {1} (dumping {2:N} / {3:N} bytes)", StreamIdx, | formatLine("Stream {0}: {1} (dumping {2:N} / {3:N} bytes)", StreamIdx, | ||||
StreamPurpose, Size, S->getLength()); | StreamPurpose, Size, S->getLength()); | ||||
AutoIndent Indent(*this); | AutoIndent Indent(*this); | ||||
BinaryStreamRef Slice(*S); | BinaryStreamRef Slice(*S); | ||||
BinarySubstreamRef Substream; | BinarySubstreamRef Substream; | ||||
Show All 12 Lines | void LinePrinter::formatMsfStreamData(StringRef Label, PDBFile &File, | ||||
auto Runs = computeBlockRuns(File.getBlockSize(), Stream); | auto Runs = computeBlockRuns(File.getBlockSize(), Stream); | ||||
NewLine(); | NewLine(); | ||||
OS << Label << " ("; | OS << Label << " ("; | ||||
while (Reader.bytesRemaining() > 0) { | while (Reader.bytesRemaining() > 0) { | ||||
OS << "\n"; | OS << "\n"; | ||||
Run FoundRun; | Run FoundRun; | ||||
uint32_t RunOffset; | uint64_t RunOffset; | ||||
std::tie(FoundRun, RunOffset) = findRun(Substream.Offset, Runs); | std::tie(FoundRun, RunOffset) = findRun(Substream.Offset, Runs); | ||||
assert(FoundRun.ByteLen >= RunOffset); | assert(FoundRun.ByteLen >= RunOffset); | ||||
uint32_t Len = FoundRun.ByteLen - RunOffset; | uint64_t Len = FoundRun.ByteLen - RunOffset; | ||||
Len = std::min(Len, Reader.bytesRemaining()); | Len = std::min(Len, Reader.bytesRemaining()); | ||||
uint64_t Base = FoundRun.Block * File.getBlockSize() + RunOffset; | uint64_t Base = FoundRun.Block * File.getBlockSize() + RunOffset; | ||||
ArrayRef<uint8_t> Data; | ArrayRef<uint8_t> Data; | ||||
consumeError(Reader.readBytes(Data, Len)); | consumeError(Reader.readBytes(Data, Len)); | ||||
OS << format_bytes_with_ascii(Data, Base, 32, 4, | OS << format_bytes_with_ascii(Data, Base, 32, 4, | ||||
CurrentIndent + IndentSpaces, true); | CurrentIndent + IndentSpaces, true); | ||||
if (Reader.bytesRemaining() > 0) { | if (Reader.bytesRemaining() > 0) { | ||||
NewLine(); | NewLine(); | ||||
OS << formatv(" {0}", | OS << formatv(" {0}", | ||||
fmt_align("<discontinuity>", AlignStyle::Center, 114, '-')); | fmt_align("<discontinuity>", AlignStyle::Center, 114, '-')); | ||||
} | } | ||||
Substream.Offset += Len; | Substream.Offset += Len; | ||||
} | } | ||||
NewLine(); | NewLine(); | ||||
OS << ")"; | OS << ")"; | ||||
} | } | ||||
void LinePrinter::formatMsfStreamBlocks( | void LinePrinter::formatMsfStreamBlocks( | ||||
PDBFile &File, const msf::MSFStreamLayout &StreamLayout) { | PDBFile &File, const msf::MSFStreamLayout &StreamLayout) { | ||||
auto Blocks = makeArrayRef(StreamLayout.Blocks); | auto Blocks = makeArrayRef(StreamLayout.Blocks); | ||||
uint32_t L = StreamLayout.Length; | uint64_t L = StreamLayout.Length; | ||||
while (L > 0) { | while (L > 0) { | ||||
NewLine(); | NewLine(); | ||||
assert(!Blocks.empty()); | assert(!Blocks.empty()); | ||||
OS << formatv("Block {0} (\n", uint32_t(Blocks.front())); | OS << formatv("Block {0} (\n", uint32_t(Blocks.front())); | ||||
uint32_t UsedBytes = std::min(L, File.getBlockSize()); | uint64_t UsedBytes = | ||||
std::min(L, static_cast<uint64_t>(File.getBlockSize())); | |||||
ArrayRef<uint8_t> BlockData = | ArrayRef<uint8_t> BlockData = | ||||
cantFail(File.getBlockData(Blocks.front(), File.getBlockSize())); | cantFail(File.getBlockData(Blocks.front(), File.getBlockSize())); | ||||
uint64_t BaseOffset = Blocks.front(); | uint64_t BaseOffset = Blocks.front(); | ||||
BaseOffset *= File.getBlockSize(); | BaseOffset *= File.getBlockSize(); | ||||
OS << format_bytes_with_ascii(BlockData, BaseOffset, 32, 4, | OS << format_bytes_with_ascii(BlockData, BaseOffset, 32, 4, | ||||
CurrentIndent + IndentSpaces, true); | CurrentIndent + IndentSpaces, true); | ||||
NewLine(); | NewLine(); | ||||
OS << ")"; | OS << ")"; | ||||
NewLine(); | NewLine(); | ||||
L -= UsedBytes; | L -= UsedBytes; | ||||
Blocks = Blocks.drop_front(); | Blocks = Blocks.drop_front(); | ||||
} | } | ||||
} | } | ||||
bool LinePrinter::IsTypeExcluded(llvm::StringRef TypeName, uint32_t Size) { | bool LinePrinter::IsTypeExcluded(llvm::StringRef TypeName, uint64_t Size) { | ||||
if (IsItemExcluded(TypeName, IncludeTypeFilters, ExcludeTypeFilters)) | if (IsItemExcluded(TypeName, IncludeTypeFilters, ExcludeTypeFilters)) | ||||
return true; | return true; | ||||
if (Size < opts::pretty::SizeThreshold) | if (Size < opts::pretty::SizeThreshold) | ||||
return true; | return true; | ||||
return false; | return false; | ||||
} | } | ||||
bool LinePrinter::IsSymbolExcluded(llvm::StringRef SymbolName) { | bool LinePrinter::IsSymbolExcluded(llvm::StringRef SymbolName) { | ||||
▲ Show 20 Lines • Show All 55 Lines • Show Last 20 Lines |