Skip to content

Commit 579264b

Browse files
author
Zachary Turner
committed
Support skewed stream arrays.
VarStreamArray was built on the assumption that it is backed by a StreamRef, and offset 0 of that StreamRef is the first byte of the first record in the array. This is a logical and intuitive assumption, but unfortunately we have use cases where it doesn't hold. Specifically, a PDB module's symbol stream is prefixed by 4 bytes containing a magic value, and the first byte of record data in the array is actually at offset 4 of this byte sequence. Previously, we would just truncate the first 4 bytes and then construct the VarStreamArray with the resulting StreamRef, so that offset 0 of the underlying stream did correspond to the first byte of the first record, but this is problematic, because symbol records reference other symbol records by the absolute offset including that initial magic 4 bytes. So if another record wants to refer to the first record in the array, it would say "the record at offset 4". This led to extremely confusing hacks and semantics in loading code, and after spending 30 minutes trying to get some math right and failing, I decided to fix this in the underlying implementation of VarStreamArray. Now, we can say that a stream is skewed by a particular amount. This way, when we access a record by absolute offset, we can use the same values that the records themselves contain, instead of having to do fixups. Differential Revision: https://reviews.llvm.org/D55344 llvm-svn: 348499
1 parent bb650da commit 579264b

File tree

6 files changed

+53
-53
lines changed

6 files changed

+53
-53
lines changed

lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp

+2-5
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,7 @@ void PdbIndex::BuildAddrToSymbolMap(CompilandIndexItem &cci) {
131131
SegmentOffset so = GetSegmentAndOffset(*iter);
132132
lldb::addr_t va = MakeVirtualAddress(so);
133133

134-
// We need to add 4 here to adjust for the codeview debug magic
135-
// at the beginning of the debug info stream.
136-
uint32_t sym_offset = iter.offset() + 4;
137-
PdbCompilandSymId cu_sym_id(modi, sym_offset);
134+
PdbCompilandSymId cu_sym_id(modi, iter.offset());
138135

139136
// If the debug info is incorrect, we could have multiple symbols with the
140137
// same address. So use try_emplace instead of insert, and the first one
@@ -201,7 +198,7 @@ CVSymbol PdbIndex::ReadSymbolRecord(PdbCompilandSymId cu_sym) const {
201198
// We need to subtract 4 here to adjust for the codeview debug magic
202199
// at the beginning of the debug info stream.
203200
const CompilandIndexItem *cci = compilands().GetCompiland(cu_sym.modi);
204-
auto iter = cci->m_debug_stream.getSymbolArray().at(cu_sym.offset - 4);
201+
auto iter = cci->m_debug_stream.getSymbolArray().at(cu_sym.offset);
205202
lldbassert(iter != cci->m_debug_stream.getSymbolArray().end());
206203
return *iter;
207204
}

llvm/include/llvm/Support/BinaryStreamArray.h

+11-9
Original file line numberDiff line numberDiff line change
@@ -96,17 +96,19 @@ class VarStreamArray {
9696

9797
explicit VarStreamArray(const Extractor &E) : E(E) {}
9898

99-
explicit VarStreamArray(BinaryStreamRef Stream) : Stream(Stream) {}
99+
explicit VarStreamArray(BinaryStreamRef Stream, uint32_t Skew = 0)
100+
: Stream(Stream), Skew(Skew) {}
100101

101-
VarStreamArray(BinaryStreamRef Stream, const Extractor &E)
102-
: Stream(Stream), E(E) {}
102+
VarStreamArray(BinaryStreamRef Stream, const Extractor &E, uint32_t Skew = 0)
103+
: Stream(Stream), E(E), Skew(Skew) {}
103104

104105
Iterator begin(bool *HadError = nullptr) const {
105-
return Iterator(*this, E, HadError);
106+
return Iterator(*this, E, Skew, nullptr);
106107
}
107108

108109
bool valid() const { return Stream.valid(); }
109110

111+
uint32_t skew() const { return Skew; }
110112
Iterator end() const { return Iterator(E); }
111113

112114
bool empty() const { return Stream.getLength() == 0; }
@@ -123,13 +125,17 @@ class VarStreamArray {
123125
Extractor &getExtractor() { return E; }
124126

125127
BinaryStreamRef getUnderlyingStream() const { return Stream; }
126-
void setUnderlyingStream(BinaryStreamRef S) { Stream = S; }
128+
void setUnderlyingStream(BinaryStreamRef S, uint32_t Skew = 0) {
129+
Stream = S;
130+
this->Skew = Skew;
131+
}
127132

128133
void drop_front() { Stream = Stream.drop_front(begin()->length()); }
129134

130135
private:
131136
BinaryStreamRef Stream;
132137
Extractor E;
138+
uint32_t Skew;
133139
};
134140

135141
template <typename ValueType, typename Extractor>
@@ -140,10 +146,6 @@ class VarStreamArrayIterator
140146
typedef VarStreamArray<ValueType, Extractor> ArrayType;
141147

142148
public:
143-
VarStreamArrayIterator(const ArrayType &Array, const Extractor &E,
144-
bool *HadError)
145-
: VarStreamArrayIterator(Array, E, 0, HadError) {}
146-
147149
VarStreamArrayIterator(const ArrayType &Array, const Extractor &E,
148150
uint32_t Offset, bool *HadError)
149151
: IterRef(Array.Stream.drop_front(Offset)), Extract(E),

llvm/include/llvm/Support/BinaryStreamReader.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -203,11 +203,12 @@ class BinaryStreamReader {
203203
/// \returns a success error code if the data was successfully read, otherwise
204204
/// returns an appropriate error code.
205205
template <typename T, typename U>
206-
Error readArray(VarStreamArray<T, U> &Array, uint32_t Size) {
206+
Error readArray(VarStreamArray<T, U> &Array, uint32_t Size,
207+
uint32_t Skew = 0) {
207208
BinaryStreamRef S;
208209
if (auto EC = readStreamRef(S, Size))
209210
return EC;
210-
Array.setUnderlyingStream(S);
211+
Array.setUnderlyingStream(S, Skew);
211212
return Error::success();
212213
}
213214

llvm/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ Error CVSymbolVisitor::visitSymbolStream(const CVSymbolArray &Symbols) {
7575
Error CVSymbolVisitor::visitSymbolStream(const CVSymbolArray &Symbols,
7676
uint32_t InitialOffset) {
7777
for (auto I : Symbols) {
78-
if (auto EC = visitSymbolRecord(I, InitialOffset))
78+
if (auto EC = visitSymbolRecord(I, InitialOffset + Symbols.skew()))
7979
return EC;
8080
InitialOffset += I.length();
8181
}

llvm/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp

+5-6
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,17 @@ Error ModuleDebugStreamRef::reload() {
4747

4848
if (auto EC = Reader.readInteger(Signature))
4949
return EC;
50-
if (auto EC = Reader.readSubstream(SymbolsSubstream, SymbolSize - 4))
50+
Reader.setOffset(0);
51+
if (auto EC = Reader.readSubstream(SymbolsSubstream, SymbolSize))
5152
return EC;
5253
if (auto EC = Reader.readSubstream(C11LinesSubstream, C11Size))
5354
return EC;
5455
if (auto EC = Reader.readSubstream(C13LinesSubstream, C13Size))
5556
return EC;
5657

5758
BinaryStreamReader SymbolReader(SymbolsSubstream.StreamData);
58-
if (auto EC =
59-
SymbolReader.readArray(SymbolArray, SymbolReader.bytesRemaining()))
59+
if (auto EC = SymbolReader.readArray(
60+
SymbolArray, SymbolReader.bytesRemaining(), sizeof(uint32_t)))
6061
return EC;
6162

6263
BinaryStreamReader SubsectionsReader(C13LinesSubstream.StreamData);
@@ -98,9 +99,7 @@ ModuleDebugStreamRef::symbols(bool *HadError) const {
9899
}
99100

100101
CVSymbol ModuleDebugStreamRef::readSymbolAtOffset(uint32_t Offset) const {
101-
// Offsets include the size of the 4-byte magic at the beginning, but lookup
102-
// doesn't take that into account, so subtract it here.
103-
auto Iter = SymbolArray.at(Offset - 4);
102+
auto Iter = SymbolArray.at(Offset);
104103
assert(Iter != SymbolArray.end());
105104
return *Iter;
106105
}

llvm/test/DebugInfo/PDB/module-bytes.test

+31-30
Original file line numberDiff line numberDiff line change
@@ -42,44 +42,45 @@ SYMS: Module Symbols
4242
SYMS-NEXT: ============================================================
4343
SYMS-NEXT: Mod 0000 | `d:\src\llvm\test\DebugInfo\PDB\Inputs\empty.obj`:
4444
SYMS-NEXT: Symbols (
45-
SYMS-NEXT: 6004: 36000111 00000000 643A5C73 72635C6C 6C766D5C 74657374 5C446562 7567496E |6.......d:\src\llvm\test\DebugIn|
46-
SYMS-NEXT: 6024: 666F5C50 44425C49 6E707574 735C656D 7074792E 6F626A00 3A003C11 01200000 |fo\PDB\Inputs\empty.obj.:.<.. ..|
47-
SYMS-NEXT: 6044: 07001200 00007D79 00001200 00007D79 00004D69 63726F73 6F667420 28522920 |......}y......}y..Microsoft (R) |
48-
SYMS-NEXT: 6064: 4F707469 6D697A69 6E672043 6F6D7069 6C657200 2A001011 00000000 C4000000 |Optimizing Compiler.*...........|
49-
SYMS-NEXT: 6084: 00000000 0A000000 03000000 08000000 01100000 10000000 0100016D 61696E00 |...........................main.|
50-
SYMS-NEXT: 60A4: 1E001210 00000000 00000000 00000000 00000000 00000000 00000082 12000000 |................................|
51-
SYMS-NEXT: 60C4: 02000600 06004C11 0E100000 |......L.....|
45+
SYMS-NEXT: 6000: 04000000 36000111 00000000 643A5C73 72635C6C 6C766D5C 74657374 5C446562 |....6.......d:\src\llvm\test\Deb|
46+
SYMS-NEXT: 6020: 7567496E 666F5C50 44425C49 6E707574 735C656D 7074792E 6F626A00 3A003C11 |ugInfo\PDB\Inputs\empty.obj.:.<.|
47+
SYMS-NEXT: 6040: 01200000 07001200 00007D79 00001200 00007D79 00004D69 63726F73 6F667420 |. ........}y......}y..Microsoft |
48+
SYMS-NEXT: 6060: 28522920 4F707469 6D697A69 6E672043 6F6D7069 6C657200 2A001011 00000000 |(R) Optimizing Compiler.*.......|
49+
SYMS-NEXT: 6080: C4000000 00000000 0A000000 03000000 08000000 01100000 10000000 0100016D |...............................m|
50+
SYMS-NEXT: 60A0: 61696E00 1E001210 00000000 00000000 00000000 00000000 00000000 00000082 |ain.............................|
51+
SYMS-NEXT: 60C0: 12000000 02000600 06004C11 0E100000 |..........L.....|
5252
SYMS-NEXT: )
5353
SYMS-NEXT: Mod 0001 | `* Linker *`:
5454
SYMS-NEXT: Symbols (
55-
SYMS-NEXT: 7004: 12000111 00000000 2A204C69 6E6B6572 202A0000 2E003C11 07000000 03000000 |........* Linker *....<.........|
56-
SYMS-NEXT: 7024: 00000000 00000C00 00007D79 00004D69 63726F73 6F667420 28522920 4C494E4B |..........}y..Microsoft (R) LINK|
57-
SYMS-NEXT: 7044: 00000000 AA003D11 00637764 00643A5C 7372635C 6C6C766D 5C746573 745C4465 |......=..cwd.d:\src\llvm\test\De|
58-
SYMS-NEXT: 7064: 62756749 6E666F5C 5044425C 496E7075 74730065 78650043 3A5C5072 6F677261 |bugInfo\PDB\Inputs.exe.C:\Progra|
59-
SYMS-NEXT: 7084: 6D204669 6C657320 28783836 295C4D69 63726F73 6F667420 56697375 616C2053 |m Files (x86)\Microsoft Visual S|
60-
SYMS-NEXT: 70A4: 74756469 6F203132 2E305C56 435C4249 4E5C6C69 6E6B2E65 78650070 64620064 |tudio 12.0\VC\BIN\link.exe.pdb.d|
61-
SYMS-NEXT: 70C4: 3A5C7372 635C6C6C 766D5C74 6573745C 44656275 67496E66 6F5C5044 425C496E |:\src\llvm\test\DebugInfo\PDB\In|
62-
SYMS-NEXT: 70E4: 70757473 5C656D70 74792E70 64620000 12002C11 00000500 05000000 10000000 |puts\empty.pdb....,.............|
63-
SYMS-NEXT: 7104: 01000100 1A003611 01000C00 00100000 1A100000 20000060 2E746578 74000000 |......6............. ..`.text...|
64-
SYMS-NEXT: 7124: 1A003711 1A100000 20000060 00000000 01002E74 65787424 6D6E0000 1A003611 |..7..... ..`.......text$mn....6.|
65-
SYMS-NEXT: 7144: 02000C00 00300000 B2020000 40000040 2E726461 74610000 1A003711 43010000 |.....0......@..@.rdata....7.C...|
66-
SYMS-NEXT: 7164: 40000040 00000000 02002E72 64617461 00000000 1A003711 00000000 40000040 |@..@.......rdata......7.....@..@|
67-
SYMS-NEXT: 7184: 43010000 02002E65 64617461 00000000 1E003711 6E010000 40000040 44010000 |C......edata......7.n...@..@D...|
68-
SYMS-NEXT: 71A4: 02002E72 64617461 24646562 75670000 1A003611 03000C00 00400000 04000000 |...rdata$debug....6......@......|
69-
SYMS-NEXT: 71C4: 400000C0 2E646174 61000000 16003711 04000000 800000C0 00000000 03002E62 |@....data.....7................b|
70-
SYMS-NEXT: 71E4: 73730000 1A003611 04000C00 00500000 08000000 40000042 2E72656C 6F630000 |ss....6......P......@..B.reloc..|
55+
SYMS-NEXT: 7000: 04000000 12000111 00000000 2A204C69 6E6B6572 202A0000 2E003C11 07000000 |............* Linker *....<.....|
56+
SYMS-NEXT: 7020: 03000000 00000000 00000C00 00007D79 00004D69 63726F73 6F667420 28522920 |..............}y..Microsoft (R) |
57+
SYMS-NEXT: 7040: 4C494E4B 00000000 AA003D11 00637764 00643A5C 7372635C 6C6C766D 5C746573 |LINK......=..cwd.d:\src\llvm\tes|
58+
SYMS-NEXT: 7060: 745C4465 62756749 6E666F5C 5044425C 496E7075 74730065 78650043 3A5C5072 |t\DebugInfo\PDB\Inputs.exe.C:\Pr|
59+
SYMS-NEXT: 7080: 6F677261 6D204669 6C657320 28783836 295C4D69 63726F73 6F667420 56697375 |ogram Files (x86)\Microsoft Visu|
60+
SYMS-NEXT: 70A0: 616C2053 74756469 6F203132 2E305C56 435C4249 4E5C6C69 6E6B2E65 78650070 |al Studio 12.0\VC\BIN\link.exe.p|
61+
SYMS-NEXT: 70C0: 64620064 3A5C7372 635C6C6C 766D5C74 6573745C 44656275 67496E66 6F5C5044 |db.d:\src\llvm\test\DebugInfo\PD|
62+
SYMS-NEXT: 70E0: 425C496E 70757473 5C656D70 74792E70 64620000 12002C11 00000500 05000000 |B\Inputs\empty.pdb....,.........|
63+
SYMS-NEXT: 7100: 10000000 01000100 1A003611 01000C00 00100000 1A100000 20000060 2E746578 |..........6............. ..`.tex|
64+
SYMS-NEXT: 7120: 74000000 1A003711 1A100000 20000060 00000000 01002E74 65787424 6D6E0000 |t.....7..... ..`.......text$mn..|
65+
SYMS-NEXT: 7140: 1A003611 02000C00 00300000 B2020000 40000040 2E726461 74610000 1A003711 |..6......0......@..@.rdata....7.|
66+
SYMS-NEXT: 7160: 43010000 40000040 00000000 02002E72 64617461 00000000 1A003711 00000000 |C...@..@.......rdata......7.....|
67+
SYMS-NEXT: 7180: 40000040 43010000 02002E65 64617461 00000000 1E003711 6E010000 40000040 |@..@C......edata......7.n...@..@|
68+
SYMS-NEXT: 71A0: 44010000 02002E72 64617461 24646562 75670000 1A003611 03000C00 00400000 |D......rdata$debug....6......@..|
69+
SYMS-NEXT: 71C0: 04000000 400000C0 2E646174 61000000 16003711 04000000 800000C0 00000000 |....@....data.....7.............|
70+
SYMS-NEXT: 71E0: 03002E62 73730000 1A003611 04000C00 00500000 08000000 40000042 2E72656C |...bss....6......P......@..B.rel|
71+
SYMS-NEXT: 7200: 6F630000 |oc..|
7172
SYMS-NEXT: )
7273

7374
FILTERED-SYMS: Module Symbols
7475
FILTERED-SYMS-NEXT: ============================================================
7576
FILTERED-SYMS-NEXT: Mod 0000 | `d:\src\llvm\test\DebugInfo\PDB\Inputs\empty.obj`:
7677
FILTERED-SYMS-NEXT: Symbols (
77-
FILTERED-SYMS-NEXT: 6004: 36000111 00000000 643A5C73 72635C6C 6C766D5C 74657374 5C446562 7567496E |6.......d:\src\llvm\test\DebugIn|
78-
FILTERED-SYMS-NEXT: 6024: 666F5C50 44425C49 6E707574 735C656D 7074792E 6F626A00 3A003C11 01200000 |fo\PDB\Inputs\empty.obj.:.<.. ..|
79-
FILTERED-SYMS-NEXT: 6044: 07001200 00007D79 00001200 00007D79 00004D69 63726F73 6F667420 28522920 |......}y......}y..Microsoft (R) |
80-
FILTERED-SYMS-NEXT: 6064: 4F707469 6D697A69 6E672043 6F6D7069 6C657200 2A001011 00000000 C4000000 |Optimizing Compiler.*...........|
81-
FILTERED-SYMS-NEXT: 6084: 00000000 0A000000 03000000 08000000 01100000 10000000 0100016D 61696E00 |...........................main.|
82-
FILTERED-SYMS-NEXT: 60A4: 1E001210 00000000 00000000 00000000 00000000 00000000 00000082 12000000 |................................|
83-
FILTERED-SYMS-NEXT: 60C4: 02000600 06004C11 0E100000 |......L.....|
78+
FILTERED-SYMS-NEXT: 6000: 04000000 36000111 00000000 643A5C73 72635C6C 6C766D5C 74657374 5C446562 |....6.......d:\src\llvm\test\Deb|
79+
FILTERED-SYMS-NEXT: 6020: 7567496E 666F5C50 44425C49 6E707574 735C656D 7074792E 6F626A00 3A003C11 |ugInfo\PDB\Inputs\empty.obj.:.<.|
80+
FILTERED-SYMS-NEXT: 6040: 01200000 07001200 00007D79 00001200 00007D79 00004D69 63726F73 6F667420 |. ........}y......}y..Microsoft |
81+
FILTERED-SYMS-NEXT: 6060: 28522920 4F707469 6D697A69 6E672043 6F6D7069 6C657200 2A001011 00000000 |(R) Optimizing Compiler.*.......|
82+
FILTERED-SYMS-NEXT: 6080: C4000000 00000000 0A000000 03000000 08000000 01100000 10000000 0100016D |...............................m|
83+
FILTERED-SYMS-NEXT: 60A0: 61696E00 1E001210 00000000 00000000 00000000 00000000 00000000 00000082 |ain.............................|
84+
FILTERED-SYMS-NEXT: 60C0: 12000000 02000600 06004C11 0E100000 |..........L.....|
8485
FILTERED-SYMS-NEXT: )
8586
FILTERED-SYMS-NOT: Mod 0001

0 commit comments

Comments
 (0)