OLD | NEW |
1 //===-- NaClObjDumpStream.cpp --------------------------------------------===// | 1 //===-- NaClObjDumpStream.cpp --------------------------------------------===// |
2 // Implements an objdump stream (bitcode records/assembly code). | 2 // Implements an objdump stream (bitcode records/assembly code). |
3 // | 3 // |
4 // The LLVM Compiler Infrastructure | 4 // The LLVM Compiler Infrastructure |
5 // | 5 // |
6 // This file is distributed under the University of Illinois Open Source | 6 // This file is distributed under the University of Illinois Open Source |
7 // License. See LICENSE.TXT for details. | 7 // License. See LICENSE.TXT for details. |
8 // | 8 // |
9 //===----------------------------------------------------------------------===// | 9 //===----------------------------------------------------------------------===// |
10 | 10 |
11 #include "llvm/ADT/STLExtras.h" | 11 #include "llvm/ADT/STLExtras.h" |
12 #include "llvm/Bitcode/NaCl/NaClObjDumpStream.h" | 12 #include "llvm/Bitcode/NaCl/NaClObjDumpStream.h" |
13 #include "llvm/Support/DataTypes.h" | 13 #include "llvm/Support/DataTypes.h" |
14 #include "llvm/Support/ErrorHandling.h" | 14 #include "llvm/Support/ErrorHandling.h" |
15 #include "llvm/Support/Format.h" | |
16 | 15 |
17 namespace llvm { | 16 namespace llvm { |
18 namespace naclbitc { | 17 namespace naclbitc { |
19 | 18 |
20 TextFormatter::TextFormatter(raw_ostream &BaseStream, | 19 TextFormatter::TextFormatter(raw_ostream &BaseStream, |
21 unsigned LineWidth, | 20 unsigned LineWidth, |
22 const char *Tab) | 21 const char *Tab) |
23 : TextIndenter(Tab), | 22 : TextIndenter(Tab), |
24 BaseStream(BaseStream), | 23 BaseStream(BaseStream), |
25 TextStream(TextBuffer), | 24 TextStream(TextBuffer), |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 | 147 |
149 TextFormatter::Directive *TextFormatter::GetTokenDirective:: | 148 TextFormatter::Directive *TextFormatter::GetTokenDirective:: |
150 Allocate(TextFormatter *Formatter, const std::string &Text) { | 149 Allocate(TextFormatter *Formatter, const std::string &Text) { |
151 GetTokenDirective *Dir = Formatter->GetTokenFreeList.Allocate(Formatter); | 150 GetTokenDirective *Dir = Formatter->GetTokenFreeList.Allocate(Formatter); |
152 Dir->Text = Text; | 151 Dir->Text = Text; |
153 return Dir; | 152 return Dir; |
154 } | 153 } |
155 | 154 |
156 RecordTextFormatter::RecordTextFormatter(ObjDumpStream *ObjDump) | 155 RecordTextFormatter::RecordTextFormatter(ObjDumpStream *ObjDump) |
157 : TextFormatter(ObjDump->Records(), 0, " "), | 156 : TextFormatter(ObjDump->Records(), 0, " "), |
158 ObjDump(ObjDump), | |
159 OpenBrace(this, "<"), | 157 OpenBrace(this, "<"), |
160 CloseBrace(this, ">"), | 158 CloseBrace(this, ">"), |
161 Comma(this, ","), | 159 Comma(this, ","), |
162 Space(this), | 160 Space(this), |
163 Endline(this), | 161 Endline(this), |
164 StartCluster(this), | 162 StartCluster(this), |
165 FinishCluster(this) { | 163 FinishCluster(this) { |
166 // Handle fact that 64-bit values can take up to 21 characters. | 164 // Handle fact that 64-bit values can take up to 21 characters. |
167 MinLineWidth = 21; | 165 MinLineWidth = 21; |
168 Label = RecordAddress(0); | 166 Label = NaClBitstreamReader::getBitAddress(0, AddressWriteWidth); |
169 } | |
170 | |
171 std::string RecordTextFormatter::RecordAddress(uint64_t Bit, | |
172 unsigned MinByteWidth) { | |
173 std::string Buffer; | |
174 raw_string_ostream Stream(Buffer); | |
175 Stream << '%' << MinByteWidth << PRIu64 << ":%u"; | |
176 Stream.flush(); | |
177 std::string FormatString(Buffer); | |
178 Buffer.clear(); | |
179 Stream << format(FormatString.c_str(), | |
180 (Bit / 8), | |
181 static_cast<unsigned>(Bit % 8)); | |
182 return Stream.str(); | |
183 } | 167 } |
184 | 168 |
185 std::string RecordTextFormatter::GetEmptyLabelColumn() { | 169 std::string RecordTextFormatter::GetEmptyLabelColumn() { |
186 std::string Buffer; | 170 std::string Buffer; |
187 raw_string_ostream StrmBuffer(Buffer); | 171 raw_string_ostream StrmBuffer(Buffer); |
188 for (size_t i = 0; i < Label.size(); ++i) { | 172 for (size_t i = 0; i < Label.size(); ++i) { |
189 StrmBuffer << ' '; | 173 StrmBuffer << ' '; |
190 } | 174 } |
191 StrmBuffer << '|'; | 175 StrmBuffer << '|'; |
192 return StrmBuffer.str(); | 176 return StrmBuffer.str(); |
193 } | 177 } |
194 | 178 |
195 void RecordTextFormatter::WriteLineIndents() { | 179 void RecordTextFormatter::WriteLineIndents() { |
196 if (AtInstructionBeginning) { | 180 if (AtInstructionBeginning) { |
197 BaseStream << Label << '|'; | 181 BaseStream << Label << '|'; |
198 } else { | 182 } else { |
199 BaseStream << GetEmptyLabelColumn(); | 183 BaseStream << GetEmptyLabelColumn(); |
200 } | 184 } |
201 LinePosition += Label.size() + 1; | 185 LinePosition += Label.size() + 1; |
202 TextFormatter::WriteLineIndents(); | 186 TextFormatter::WriteLineIndents(); |
203 } | 187 } |
204 | 188 |
205 void RecordTextFormatter::WriteValues(uint64_t Bit, | 189 void RecordTextFormatter::WriteValues(uint64_t Bit, |
206 const llvm::NaClBitcodeValues &Values, | 190 const llvm::NaClBitcodeValues &Values, |
207 int32_t AbbrevIndex) { | 191 int32_t AbbrevIndex) { |
208 Label = ObjDump->RecordAddress(Bit); | 192 Label = NaClBitstreamReader::getBitAddress( |
| 193 Bit, RecordTextFormatter::AddressWriteWidth); |
209 if (AbbrevIndex != ABBREV_INDEX_NOT_SPECIFIED) { | 194 if (AbbrevIndex != ABBREV_INDEX_NOT_SPECIFIED) { |
210 TextStream << AbbrevIndex << ":" << Space; | 195 TextStream << AbbrevIndex << ":" << Space; |
211 } | 196 } |
212 TextStream << OpenBrace; | 197 TextStream << OpenBrace; |
213 for (size_t i = 0; i < Values.size(); ++i) { | 198 for (size_t i = 0; i < Values.size(); ++i) { |
214 if (i > 0) { | 199 if (i > 0) { |
215 TextStream << Comma << FinishCluster << Space; | 200 TextStream << Comma << FinishCluster << Space; |
216 } | 201 } |
217 TextStream << StartCluster << Values[i]; | 202 TextStream << StartCluster << Values[i]; |
218 } | 203 } |
219 // Note: Because of record codes, Values are never empty. Hence we | 204 // Note: Because of record codes, Values are never empty. Hence we |
220 // always need to finish the cluster for the last number printed. | 205 // always need to finish the cluster for the last number printed. |
221 TextStream << FinishCluster << CloseBrace << Endline; | 206 TextStream << FinishCluster << CloseBrace << Endline; |
222 } | 207 } |
223 | 208 |
224 unsigned ObjDumpStream::DefaultMaxErrors = 20; | 209 unsigned ObjDumpStream::DefaultMaxErrors = 20; |
225 | 210 |
226 unsigned ObjDumpStream::ComboObjDumpSeparatorColumn = 40; | 211 unsigned ObjDumpStream::ComboObjDumpSeparatorColumn = 40; |
227 | 212 |
228 unsigned ObjDumpStream::RecordObjectDumpLength = 80; | 213 unsigned ObjDumpStream::RecordObjectDumpLength = 80; |
229 | 214 |
230 ObjDumpStream::ObjDumpStream(raw_ostream &Stream, | 215 ObjDumpStream::ObjDumpStream(raw_ostream &Stream, |
231 bool DumpRecords, bool DumpAssembly) | 216 bool DumpRecords, bool DumpAssembly) |
232 : Stream(Stream), | 217 : Stream(Stream), |
233 DumpRecords(DumpRecords), | 218 DumpRecords(DumpRecords), |
234 DumpAssembly(DumpAssembly), | 219 DumpAssembly(DumpAssembly), |
235 NumErrors(0), | 220 NumErrors(0), |
236 MaxErrors(DefaultMaxErrors), | 221 MaxErrors(DefaultMaxErrors), |
237 RecordWidth(0), | 222 RecordWidth(0), |
238 StartOffset(0), | |
239 AssemblyBuffer(), | 223 AssemblyBuffer(), |
240 AssemblyStream(AssemblyBuffer), | 224 AssemblyStream(AssemblyBuffer), |
241 MessageBuffer(), | 225 MessageBuffer(), |
242 MessageStream(MessageBuffer), | 226 MessageStream(MessageBuffer), |
243 ColumnSeparator('|'), | 227 ColumnSeparator('|'), |
244 LastKnownBit(0), | 228 LastKnownBit(0), |
245 RecordBuffer(), | 229 RecordBuffer(), |
246 RecordStream(RecordBuffer), | 230 RecordStream(RecordBuffer), |
247 RecordFormatter(this) { | 231 RecordFormatter(this) { |
248 if (DumpRecords) { | 232 if (DumpRecords) { |
(...skipping 19 matching lines...) Expand all Loading... |
268 Flush(); | 252 Flush(); |
269 llvm::report_fatal_error("Unable to continue"); | 253 llvm::report_fatal_error("Unable to continue"); |
270 } | 254 } |
271 | 255 |
272 void ObjDumpStream::Fatal(uint64_t Bit, | 256 void ObjDumpStream::Fatal(uint64_t Bit, |
273 const llvm::NaClBitcodeRecordData &Record, | 257 const llvm::NaClBitcodeRecordData &Record, |
274 const std::string &Message) { | 258 const std::string &Message) { |
275 LastKnownBit = Bit; | 259 LastKnownBit = Bit; |
276 PrintMessagePrefix("Error", Bit) << Message; | 260 PrintMessagePrefix("Error", Bit) << Message; |
277 Write(Bit, Record); | 261 Write(Bit, Record); |
| 262 Flush(); |
278 llvm::report_fatal_error("Unable to continue"); | 263 llvm::report_fatal_error("Unable to continue"); |
279 } | 264 } |
280 | 265 |
281 // Dumps the next line of text in the buffer. Returns the number of characters | 266 // Dumps the next line of text in the buffer. Returns the number of characters |
282 // printed. | 267 // printed. |
283 static size_t DumpLine(raw_ostream &Stream, | 268 static size_t DumpLine(raw_ostream &Stream, |
284 const std::string &Buffer, | 269 const std::string &Buffer, |
285 size_t &Index, | 270 size_t &Index, |
286 size_t Size) { | 271 size_t Size) { |
287 size_t Count = 0; | 272 size_t Count = 0; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 Stream << '\n'; | 321 Stream << '\n'; |
337 } | 322 } |
338 } | 323 } |
339 | 324 |
340 // Print out messages and reset buffers. | 325 // Print out messages and reset buffers. |
341 Stream << MessageBuffer; | 326 Stream << MessageBuffer; |
342 ResetBuffers(); | 327 ResetBuffers(); |
343 if (NumErrors >= MaxErrors) { | 328 if (NumErrors >= MaxErrors) { |
344 // Note: we don't call Fatal here because that will call Flush, causing | 329 // Note: we don't call Fatal here because that will call Flush, causing |
345 // an infinite loop. | 330 // an infinite loop. |
346 Stream << "Error(" << ObjDumpAddress(LastKnownBit) | 331 Stream << "Error(" << NaClBitstreamReader::getBitAddress(LastKnownBit) |
347 << "): Too many errors\n"; | 332 << "): Too many errors\n"; |
348 llvm::report_fatal_error("Unable to continue"); | 333 llvm::report_fatal_error("Unable to continue"); |
349 } | 334 } |
350 Stream.flush(); | 335 Stream.flush(); |
351 } | 336 } |
352 | 337 |
353 } | 338 } |
354 } | 339 } |
OLD | NEW |