llvm.org GIT mirror llvm / 32cfa0e
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@348499 91177308-0d34-0410-b5e6-96231b3b80d8 Zachary Turner 1 year, 5 months ago
5 changed file(s) with 52 addition(s) and 49 deletion(s). Raw diff Collapse all Expand all
9595
9696 explicit VarStreamArray(const Extractor &E) : E(E) {}
9797
98 explicit VarStreamArray(BinaryStreamRef Stream) : Stream(Stream) {}
99
100 VarStreamArray(BinaryStreamRef Stream, const Extractor &E)
101 : Stream(Stream), E(E) {}
98 explicit VarStreamArray(BinaryStreamRef Stream, uint32_t Skew = 0)
99 : Stream(Stream), Skew(Skew) {}
100
101 VarStreamArray(BinaryStreamRef Stream, const Extractor &E, uint32_t Skew = 0)
102 : Stream(Stream), E(E), Skew(Skew) {}
102103
103104 Iterator begin(bool *HadError = nullptr) const {
104 return Iterator(*this, E, HadError);
105 return Iterator(*this, E, Skew, nullptr);
105106 }
106107
107108 bool valid() const { return Stream.valid(); }
108109
110 uint32_t skew() const { return Skew; }
109111 Iterator end() const { return Iterator(E); }
110112
111113 bool empty() const { return Stream.getLength() == 0; }
122124 Extractor &getExtractor() { return E; }
123125
124126 BinaryStreamRef getUnderlyingStream() const { return Stream; }
125 void setUnderlyingStream(BinaryStreamRef S) { Stream = S; }
127 void setUnderlyingStream(BinaryStreamRef S, uint32_t Skew = 0) {
128 Stream = S;
129 this->Skew = Skew;
130 }
126131
127132 void drop_front() { Stream = Stream.drop_front(begin()->length()); }
128133
129134 private:
130135 BinaryStreamRef Stream;
131136 Extractor E;
137 uint32_t Skew;
132138 };
133139
134140 template
139145 typedef VarStreamArray ArrayType;
140146
141147 public:
142 VarStreamArrayIterator(const ArrayType &Array, const Extractor &E,
143 bool *HadError)
144 : VarStreamArrayIterator(Array, E, 0, HadError) {}
145
146148 VarStreamArrayIterator(const ArrayType &Array, const Extractor &E,
147149 uint32_t Offset, bool *HadError)
148150 : IterRef(Array.Stream.drop_front(Offset)), Extract(E),
202202 /// \returns a success error code if the data was successfully read, otherwise
203203 /// returns an appropriate error code.
204204 template
205 Error readArray(VarStreamArray &Array, uint32_t Size) {
205 Error readArray(VarStreamArray &Array, uint32_t Size,
206 uint32_t Skew = 0) {
206207 BinaryStreamRef S;
207208 if (auto EC = readStreamRef(S, Size))
208209 return EC;
209 Array.setUnderlyingStream(S);
210 Array.setUnderlyingStream(S, Skew);
210211 return Error::success();
211212 }
212213
7474 Error CVSymbolVisitor::visitSymbolStream(const CVSymbolArray &Symbols,
7575 uint32_t InitialOffset) {
7676 for (auto I : Symbols) {
77 if (auto EC = visitSymbolRecord(I, InitialOffset))
77 if (auto EC = visitSymbolRecord(I, InitialOffset + Symbols.skew()))
7878 return EC;
7979 InitialOffset += I.length();
8080 }
4646
4747 if (auto EC = Reader.readInteger(Signature))
4848 return EC;
49 if (auto EC = Reader.readSubstream(SymbolsSubstream, SymbolSize - 4))
49 Reader.setOffset(0);
50 if (auto EC = Reader.readSubstream(SymbolsSubstream, SymbolSize))
5051 return EC;
5152 if (auto EC = Reader.readSubstream(C11LinesSubstream, C11Size))
5253 return EC;
5455 return EC;
5556
5657 BinaryStreamReader SymbolReader(SymbolsSubstream.StreamData);
57 if (auto EC =
58 SymbolReader.readArray(SymbolArray, SymbolReader.bytesRemaining()))
58 if (auto EC = SymbolReader.readArray(
59 SymbolArray, SymbolReader.bytesRemaining(), sizeof(uint32_t)))
5960 return EC;
6061
6162 BinaryStreamReader SubsectionsReader(C13LinesSubstream.StreamData);
9798 }
9899
99100 CVSymbol ModuleDebugStreamRef::readSymbolAtOffset(uint32_t Offset) const {
100 // Offsets include the size of the 4-byte magic at the beginning, but lookup
101 // doesn't take that into account, so subtract it here.
102 auto Iter = SymbolArray.at(Offset - 4);
101 auto Iter = SymbolArray.at(Offset);
103102 assert(Iter != SymbolArray.end());
104103 return *Iter;
105104 }
4141 SYMS-NEXT: ============================================================
4242 SYMS-NEXT: Mod 0000 | `d:\src\llvm\test\DebugInfo\PDB\Inputs\empty.obj`:
4343 SYMS-NEXT: Symbols (
44 SYMS-NEXT: 6004: 36000111 00000000 643A5C73 72635C6C 6C766D5C 74657374 5C446562 7567496E |6.......d:\src\llvm\test\DebugIn|
45 SYMS-NEXT: 6024: 666F5C50 44425C49 6E707574 735C656D 7074792E 6F626A00 3A003C11 01200000 |fo\PDB\Inputs\empty.obj.:.<.. ..|
46 SYMS-NEXT: 6044: 07001200 00007D79 00001200 00007D79 00004D69 63726F73 6F667420 28522920 |......}y......}y..Microsoft (R) |
47 SYMS-NEXT: 6064: 4F707469 6D697A69 6E672043 6F6D7069 6C657200 2A001011 00000000 C4000000 |Optimizing Compiler.*...........|
48 SYMS-NEXT: 6084: 00000000 0A000000 03000000 08000000 01100000 10000000 0100016D 61696E00 |...........................main.|
49 SYMS-NEXT: 60A4: 1E001210 00000000 00000000 00000000 00000000 00000000 00000082 12000000 |................................|
50 SYMS-NEXT: 60C4: 02000600 06004C11 0E100000 |......L.....|
44 SYMS-NEXT: 6000: 04000000 36000111 00000000 643A5C73 72635C6C 6C766D5C 74657374 5C446562 |....6.......d:\src\llvm\test\Deb|
45 SYMS-NEXT: 6020: 7567496E 666F5C50 44425C49 6E707574 735C656D 7074792E 6F626A00 3A003C11 |ugInfo\PDB\Inputs\empty.obj.:.<.|
46 SYMS-NEXT: 6040: 01200000 07001200 00007D79 00001200 00007D79 00004D69 63726F73 6F667420 |. ........}y......}y..Microsoft |
47 SYMS-NEXT: 6060: 28522920 4F707469 6D697A69 6E672043 6F6D7069 6C657200 2A001011 00000000 |(R) Optimizing Compiler.*.......|
48 SYMS-NEXT: 6080: C4000000 00000000 0A000000 03000000 08000000 01100000 10000000 0100016D |...............................m|
49 SYMS-NEXT: 60A0: 61696E00 1E001210 00000000 00000000 00000000 00000000 00000000 00000082 |ain.............................|
50 SYMS-NEXT: 60C0: 12000000 02000600 06004C11 0E100000 |..........L.....|
5151 SYMS-NEXT: )
5252 SYMS-NEXT: Mod 0001 | `* Linker *`:
5353 SYMS-NEXT: Symbols (
54 SYMS-NEXT: 7004: 12000111 00000000 2A204C69 6E6B6572 202A0000 2E003C11 07000000 03000000 |........* Linker *....<.........|
55 SYMS-NEXT: 7024: 00000000 00000C00 00007D79 00004D69 63726F73 6F667420 28522920 4C494E4B |..........}y..Microsoft (R) LINK|
56 SYMS-NEXT: 7044: 00000000 AA003D11 00637764 00643A5C 7372635C 6C6C766D 5C746573 745C4465 |......=..cwd.d:\src\llvm\test\De|
57 SYMS-NEXT: 7064: 62756749 6E666F5C 5044425C 496E7075 74730065 78650043 3A5C5072 6F677261 |bugInfo\PDB\Inputs.exe.C:\Progra|
58 SYMS-NEXT: 7084: 6D204669 6C657320 28783836 295C4D69 63726F73 6F667420 56697375 616C2053 |m Files (x86)\Microsoft Visual S|
59 SYMS-NEXT: 70A4: 74756469 6F203132 2E305C56 435C4249 4E5C6C69 6E6B2E65 78650070 64620064 |tudio 12.0\VC\BIN\link.exe.pdb.d|
60 SYMS-NEXT: 70C4: 3A5C7372 635C6C6C 766D5C74 6573745C 44656275 67496E66 6F5C5044 425C496E |:\src\llvm\test\DebugInfo\PDB\In|
61 SYMS-NEXT: 70E4: 70757473 5C656D70 74792E70 64620000 12002C11 00000500 05000000 10000000 |puts\empty.pdb....,.............|
62 SYMS-NEXT: 7104: 01000100 1A003611 01000C00 00100000 1A100000 20000060 2E746578 74000000 |......6............. ..`.text...|
63 SYMS-NEXT: 7124: 1A003711 1A100000 20000060 00000000 01002E74 65787424 6D6E0000 1A003611 |..7..... ..`.......text$mn....6.|
64 SYMS-NEXT: 7144: 02000C00 00300000 B2020000 40000040 2E726461 74610000 1A003711 43010000 |.....0......@..@.rdata....7.C...|
65 SYMS-NEXT: 7164: 40000040 00000000 02002E72 64617461 00000000 1A003711 00000000 40000040 |@..@.......rdata......7.....@..@|
66 SYMS-NEXT: 7184: 43010000 02002E65 64617461 00000000 1E003711 6E010000 40000040 44010000 |C......edata......7.n...@..@D...|
67 SYMS-NEXT: 71A4: 02002E72 64617461 24646562 75670000 1A003611 03000C00 00400000 04000000 |...rdata$debug....6......@......|
68 SYMS-NEXT: 71C4: 400000C0 2E646174 61000000 16003711 04000000 800000C0 00000000 03002E62 |@....data.....7................b|
69 SYMS-NEXT: 71E4: 73730000 1A003611 04000C00 00500000 08000000 40000042 2E72656C 6F630000 |ss....6......P......@..B.reloc..|
54 SYMS-NEXT: 7000: 04000000 12000111 00000000 2A204C69 6E6B6572 202A0000 2E003C11 07000000 |............* Linker *....<.....|
55 SYMS-NEXT: 7020: 03000000 00000000 00000C00 00007D79 00004D69 63726F73 6F667420 28522920 |..............}y..Microsoft (R) |
56 SYMS-NEXT: 7040: 4C494E4B 00000000 AA003D11 00637764 00643A5C 7372635C 6C6C766D 5C746573 |LINK......=..cwd.d:\src\llvm\tes|
57 SYMS-NEXT: 7060: 745C4465 62756749 6E666F5C 5044425C 496E7075 74730065 78650043 3A5C5072 |t\DebugInfo\PDB\Inputs.exe.C:\Pr|
58 SYMS-NEXT: 7080: 6F677261 6D204669 6C657320 28783836 295C4D69 63726F73 6F667420 56697375 |ogram Files (x86)\Microsoft Visu|
59 SYMS-NEXT: 70A0: 616C2053 74756469 6F203132 2E305C56 435C4249 4E5C6C69 6E6B2E65 78650070 |al Studio 12.0\VC\BIN\link.exe.p|
60 SYMS-NEXT: 70C0: 64620064 3A5C7372 635C6C6C 766D5C74 6573745C 44656275 67496E66 6F5C5044 |db.d:\src\llvm\test\DebugInfo\PD|
61 SYMS-NEXT: 70E0: 425C496E 70757473 5C656D70 74792E70 64620000 12002C11 00000500 05000000 |B\Inputs\empty.pdb....,.........|
62 SYMS-NEXT: 7100: 10000000 01000100 1A003611 01000C00 00100000 1A100000 20000060 2E746578 |..........6............. ..`.tex|
63 SYMS-NEXT: 7120: 74000000 1A003711 1A100000 20000060 00000000 01002E74 65787424 6D6E0000 |t.....7..... ..`.......text$mn..|
64 SYMS-NEXT: 7140: 1A003611 02000C00 00300000 B2020000 40000040 2E726461 74610000 1A003711 |..6......0......@..@.rdata....7.|
65 SYMS-NEXT: 7160: 43010000 40000040 00000000 02002E72 64617461 00000000 1A003711 00000000 |C...@..@.......rdata......7.....|
66 SYMS-NEXT: 7180: 40000040 43010000 02002E65 64617461 00000000 1E003711 6E010000 40000040 |@..@C......edata......7.n...@..@|
67 SYMS-NEXT: 71A0: 44010000 02002E72 64617461 24646562 75670000 1A003611 03000C00 00400000 |D......rdata$debug....6......@..|
68 SYMS-NEXT: 71C0: 04000000 400000C0 2E646174 61000000 16003711 04000000 800000C0 00000000 |....@....data.....7.............|
69 SYMS-NEXT: 71E0: 03002E62 73730000 1A003611 04000C00 00500000 08000000 40000042 2E72656C |...bss....6......P......@..B.rel|
70 SYMS-NEXT: 7200: 6F630000 |oc..|
7071 SYMS-NEXT: )
7172
7273 FILTERED-SYMS: Module Symbols
7374 FILTERED-SYMS-NEXT: ============================================================
7475 FILTERED-SYMS-NEXT: Mod 0000 | `d:\src\llvm\test\DebugInfo\PDB\Inputs\empty.obj`:
7576 FILTERED-SYMS-NEXT: Symbols (
76 FILTERED-SYMS-NEXT: 6004: 36000111 00000000 643A5C73 72635C6C 6C766D5C 74657374 5C446562 7567496E |6.......d:\src\llvm\test\DebugIn|
77 FILTERED-SYMS-NEXT: 6024: 666F5C50 44425C49 6E707574 735C656D 7074792E 6F626A00 3A003C11 01200000 |fo\PDB\Inputs\empty.obj.:.<.. ..|
78 FILTERED-SYMS-NEXT: 6044: 07001200 00007D79 00001200 00007D79 00004D69 63726F73 6F667420 28522920 |......}y......}y..Microsoft (R) |
79 FILTERED-SYMS-NEXT: 6064: 4F707469 6D697A69 6E672043 6F6D7069 6C657200 2A001011 00000000 C4000000 |Optimizing Compiler.*...........|
80 FILTERED-SYMS-NEXT: 6084: 00000000 0A000000 03000000 08000000 01100000 10000000 0100016D 61696E00 |...........................main.|
81 FILTERED-SYMS-NEXT: 60A4: 1E001210 00000000 00000000 00000000 00000000 00000000 00000082 12000000 |................................|
82 FILTERED-SYMS-NEXT: 60C4: 02000600 06004C11 0E100000 |......L.....|
77 FILTERED-SYMS-NEXT: 6000: 04000000 36000111 00000000 643A5C73 72635C6C 6C766D5C 74657374 5C446562 |....6.......d:\src\llvm\test\Deb|
78 FILTERED-SYMS-NEXT: 6020: 7567496E 666F5C50 44425C49 6E707574 735C656D 7074792E 6F626A00 3A003C11 |ugInfo\PDB\Inputs\empty.obj.:.<.|
79 FILTERED-SYMS-NEXT: 6040: 01200000 07001200 00007D79 00001200 00007D79 00004D69 63726F73 6F667420 |. ........}y......}y..Microsoft |
80 FILTERED-SYMS-NEXT: 6060: 28522920 4F707469 6D697A69 6E672043 6F6D7069 6C657200 2A001011 00000000 |(R) Optimizing Compiler.*.......|
81 FILTERED-SYMS-NEXT: 6080: C4000000 00000000 0A000000 03000000 08000000 01100000 10000000 0100016D |...............................m|
82 FILTERED-SYMS-NEXT: 60A0: 61696E00 1E001210 00000000 00000000 00000000 00000000 00000000 00000082 |ain.............................|
83 FILTERED-SYMS-NEXT: 60C0: 12000000 02000600 06004C11 0E100000 |..........L.....|
8384 FILTERED-SYMS-NEXT: )
8485 FILTERED-SYMS-NOT: Mod 0001