Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: lib/Bitcode/NaCl/Analysis/NaClObjDump.cpp

Issue 939073008: Rebased PNaCl localmods in LLVM to 223109 (Closed)
Patch Set: undo localmod Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 //===-- NaClObjDump.cpp - Dump PNaCl bitcode contents ---------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/Analysis/NaCl/PNaClABIProps.h"
12 #include "llvm/Analysis/NaCl/PNaClABITypeChecker.h"
13 #include "llvm/Analysis/NaCl/PNaClAllowedIntrinsics.h"
14 #include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h"
15 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h"
16 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h"
17 #include "llvm/Bitcode/NaCl/NaClBitCodes.h"
18 #include "llvm/Bitcode/NaCl/NaClObjDumpStream.h"
19 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h"
20 #include "llvm/IR/Constants.h"
21 #include "llvm/IR/DataLayout.h"
22 #include "llvm/IR/InstrTypes.h"
23 #include "llvm/IR/LLVMContext.h"
24 #include "llvm/IR/Module.h"
25 #include "llvm/Support/CommandLine.h"
26 #include "llvm/Support/MemoryBuffer.h"
27 #include "llvm/Support/Format.h"
28 #include "llvm/Support/raw_ostream.h"
29
30 #include <map>
31
32 namespace {
33
34 using namespace llvm;
35
36 static cl::opt<bool>
37 ReportWarningsAsErrors(
38 "Werror",
39 cl::desc("Report warnings as errors."),
40 cl::init(false));
41
42 static cl::opt<bool>
43 IgnorePNaClABIChecks(
44 "ignore-pnaclabi-checks",
45 cl::desc("Ignore checking bitcode for PNaCl ABI violations"),
46 cl::init(false));
47
48 /// Class to handle sign rotations in a human readable form. That is,
49 /// the sign is in the low bit. The two special cases are:
50 /// 1) -1 is true for i1.
51 /// 2) The representation allows -0 (which is different than 0).
52 class SignRotatedInt {
53 public:
54 SignRotatedInt(uint64_t Value, Type* ValueType)
55 : SignedValue(Value >> 1),
56 IsNegated((Value & 0x1)
57 && !(ValueType->isIntegerTy()
58 && ValueType->getIntegerBitWidth() == 1)) {
59 }
60
61 SignRotatedInt()
62 : SignedValue(0), IsNegated(false) {}
63
64 explicit SignRotatedInt(const SignRotatedInt &V)
65 : SignedValue(V.SignedValue), IsNegated(V.IsNegated) {}
66
67 void operator=(const SignRotatedInt &V) {
68 SignedValue = V.SignedValue;
69 IsNegated = V.IsNegated;
70 }
71
72 void Print(raw_ostream &Strm) const {
73 if (IsNegated) Strm << "-";
74 Strm << SignedValue;
75 }
76
77 private:
78 int64_t SignedValue;
79 bool IsNegated;
80 };
81
82 inline raw_ostream &operator<<(raw_ostream &Strm, const SignRotatedInt &V) {
83 V.Print(Strm);
84 return Strm;
85 }
86
87 /// Convenience class to be able to print value ids to raw_ostream's.
88 /// Kinds of bitcode Ids:
89 /// a : For abbreviations.
90 /// b : For basic blocks.
91 /// c : For local constants.
92 /// f : For function addresses.
93 /// g : For global variable addresses.
94 /// p : For parameter arguments.
95 /// t : For type values.
96 /// v : For values generated by instructions.
97 class BitcodeId {
98 public:
99 BitcodeId(char Kind, uint32_t Index)
100 : Kind(Kind), Index(Index), IsGlobal(IsGlobalKind(Kind)) {
101 }
102
103 BitcodeId(const BitcodeId &Id)
104 : Kind(Id.Kind), Index(Id.Index), IsGlobal(Id.IsGlobal) {}
105
106 BitcodeId(char Kind, uint32_t Index, bool IsGlobal)
107 : Kind(Kind), Index(Index), IsGlobal(IsGlobal) {}
108
109 void operator=(const BitcodeId &Id) {
110 Kind = Id.Kind;
111 Index = Id.Index;
112 IsGlobal = Id.IsGlobal;
113 }
114
115 raw_ostream &Print(raw_ostream &Stream) const {
116 return Stream << Prefix() << Kind << Index;
117 }
118
119 char GetKind() const {
120 return Kind;
121 }
122
123 std::string GetName() const {
124 std::string Buffer;
125 raw_string_ostream StrBuf(Buffer);
126 Print(StrBuf);
127 return StrBuf.str();
128 }
129
130 private:
131 char Kind;
132 uint32_t Index;
133 bool IsGlobal;
134
135 // Returns true if (default) assumption for kind implies global.
136 static bool IsGlobalKind(char Kind);
137
138 // Returns the bitcode prefix character that communicates if the
139 // bitcode Id is lcoal or global.
140 char Prefix() const { return IsGlobal ? '@' : '%'; }
141 };
142
143 bool BitcodeId::IsGlobalKind(char Kind) {
144 switch (Kind) {
145 case 'f':
146 case 'g':
147 case 't':
148 return true;
149 case 'b':
150 case 'c':
151 case 'p':
152 case 'v':
153 return false;
154 default:
155 errs() << "Bad bitcode id, can't determine (statically) if global: "
156 << Kind << "\n";
157 report_fatal_error("Unable to continue");
158 }
159 }
160
161 raw_ostream &operator<<(raw_ostream &Stream, const BitcodeId &Id) {
162 return Id.Print(Stream);
163 }
164
165 class NaClDisBlockParser;
166
167 /// The text formatter for PNaClAsm instructions.
168 class AssemblyTextFormatter : public naclbitc::TextFormatter {
169 public:
170 // Special directive to tokenize type expressions. Used to convert
171 // type signatures into a sequence of tokens.
172 class TypeDirective : public naclbitc::TextFormatter::Directive {
173 public:
174 TypeDirective(TextFormatter *Formatter)
175 : naclbitc::TextFormatter::Directive(Formatter),
176 Typ(0),
177 FcnId(0),
178 AddParams(false) {}
179
180 ~TypeDirective() override {}
181
182 private:
183 /// Calls the corresponding method in AssemblyTextFormatter, with
184 /// the locally stored arguments.
185 void MyApply(bool Replay) const override;
186
187 void MaybeSaveForReplay() const override {}
188
189 // The type to tokenize.
190 Type *Typ;
191 // Pointer to function id, if not NULL.
192 BitcodeId *FcnId;
193 // true if parameter id's should be added to function signature.
194 bool AddParams;
195
196 friend class AssemblyTextFormatter;
197
198 // Internal routine to allow AssemblyTextFormatter::AllocateTypeDirective
199 // to initialize a type directive.
200 void Init(Type *NewTyp, BitcodeId *NewFcnId, bool NewAddParams) {
201 Typ = NewTyp;
202 FcnId = NewFcnId;
203 AddParams = NewAddParams;
204 }
205 };
206
207 // Special directive to tokenize an abbreviation. Used to convert
208 // an abbreviation (pointer) into a sequence of tokens.
209 class AbbreviationDirective : public naclbitc::TextFormatter::Directive {
210 public:
211 AbbreviationDirective(TextFormatter *Formatter)
212 : naclbitc::TextFormatter::Directive(Formatter),
213 Abbrev(0) {}
214
215 ~AbbreviationDirective() override {}
216
217 private:
218 void MyApply(bool Replay) const override;
219
220 void MaybeSaveForReplay() const override {}
221
222 // The abbreviation to tokenize.
223 NaClBitCodeAbbrev *Abbrev;
224
225 friend class AssemblyTextFormatter;
226 };
227
228 // Special directive to tokenize an abbreviation index, if the corresponding
229 // record in the block parser used a user-defined abbreviation.
230 class AbbrevIndexDirective : public naclbitc::TextFormatter::Directive {
231 public:
232 AbbrevIndexDirective(TextFormatter *Formatter)
233 : naclbitc::TextFormatter::Directive(Formatter),
234 Record(0), NumGlobalAbbreviations(0) {}
235
236 ~AbbrevIndexDirective() override {}
237
238 private:
239 void MyApply(bool Replay) const override;
240
241 void MaybeSaveForReplay() const override {}
242
243 // The record containing the associated abbreviation.
244 NaClBitcodeRecord *Record;
245
246 // The number of global abbreviations defined for the block the
247 // record appears in.
248 unsigned NumGlobalAbbreviations;
249
250 friend class AssemblyTextFormatter;
251 };
252
253 public:
254
255 /// Creates an assembly text formatter for the given dump stream.
256 AssemblyTextFormatter(naclbitc::ObjDumpStream &ObjDump)
257 : TextFormatter(ObjDump.Assembly(),
258 std::max(20U, GetAssemblyWidth(ObjDump)),
259 " "),
260 Comma(this, ","),
261 Semicolon(this, ";"),
262 Colon(this, ":"),
263 Space(this),
264 OpenParen(this, "("),
265 CloseParen(this, ")"),
266 OpenAngle(this, "<"),
267 CloseAngle(this, ">"),
268 OpenCurly(this, "{"),
269 CloseCurly(this, "}"),
270 OpenSquare(this, "["),
271 CloseSquare(this, "]"),
272 Endline(this),
273 StartCluster(this),
274 FinishCluster(this)
275 {
276 ContinuationIndent = GetIndent(2);
277 }
278
279 ~AssemblyTextFormatter() override {}
280
281 naclbitc::TokenTextDirective Comma;
282 naclbitc::TokenTextDirective Semicolon;
283 naclbitc::TokenTextDirective Colon;
284 naclbitc::SpaceTextDirective Space;
285 naclbitc::OpenTextDirective OpenParen;
286 naclbitc::CloseTextDirective CloseParen;
287 naclbitc::OpenTextDirective OpenAngle;
288 naclbitc::CloseTextDirective CloseAngle;
289 naclbitc::OpenTextDirective OpenCurly;
290 naclbitc::CloseTextDirective CloseCurly;
291 naclbitc::OpenTextDirective OpenSquare;
292 naclbitc::CloseTextDirective CloseSquare;
293 naclbitc::EndlineTextDirective Endline;
294 naclbitc::StartClusteringDirective StartCluster;
295 naclbitc::FinishClusteringDirective FinishCluster;
296
297 /// Prints the given type as a sequence of tokens.
298 TypeDirective &TokenizeType(Type *Typ) {
299 return AllocateTypeDirective(Typ, 0, false);
300 }
301
302 /// Prints the named function type as a sequence of tokens.
303 /// Typ is the type signature of the function, and FunctionName
304 /// points to the name of the function.
305 TypeDirective &TokenizeFunctionType(FunctionType *Typ,
306 BitcodeId *FunctionName) {
307 return AllocateTypeDirective(Typ, FunctionName, false);
308 }
309
310 /// Prints the function signature of the function type. Typ is
311 /// the type signature of the function. FunctionName points to the
312 /// name of the function. Note: Unlike TokenizeFunctionType, this
313 /// method also adds the parameter names to paramter argumements.
314 TypeDirective &TokenizeFunctionSignature(FunctionType *Typ,
315 BitcodeId *FunctionName) {
316 return AllocateTypeDirective(Typ, FunctionName, true);
317 }
318
319 /// Prints out the abbreviation defined by Abbrev.
320 AbbreviationDirective &TokenizeAbbreviation(NaClBitCodeAbbrev *Abbrev) {
321 AbbreviationDirective *Dir = AbbrevDirMemoryPool.Allocate(this);
322 Dir->Abbrev = Abbrev;
323 return *Dir;
324 }
325
326 /// If the record was read using a user-defined abbreviation,
327 /// generates assembly tokens describing the abbreviation index
328 /// used. Otherwise, no tokens are generated. NumGlobalAbbreviations
329 /// is used to determine if the user-defined abbreviation is local
330 /// or global.
331 AbbrevIndexDirective &TokenizeAbbrevIndex(NaClBitcodeRecord &Record,
332 unsigned NumGlobalAbbreviations) {
333 AbbrevIndexDirective *Dir = AbbrevIndexDirMemoryPool.Allocate(this);
334 Dir->Record = &Record;
335 Dir->NumGlobalAbbreviations = NumGlobalAbbreviations;
336 return *Dir;
337 }
338
339 private:
340 // Converts the given type to tokens, based on the values passed in
341 // by TokenizeType, TokenizeFunctionType, or TokenizeFunctionSignature.
342 void TokenizeTypeInternal(Type *Typ, BitcodeId* FcnName, bool AddParams);
343
344 // The free list of type directives.
345 naclbitc::DirectiveMemoryPool<TypeDirective> TypeDirMemoryPool;
346
347 // Allocates an instance of TypeDirective with the following fields.
348 TypeDirective &AllocateTypeDirective(Type *Typ, BitcodeId *FcnId,
349 bool AddParams);
350
351 // Converts the given abbreviation to tokens.
352 void TokenizeAbbreviationInternal(const NaClBitCodeAbbrev *Abbrev);
353
354 // Helper function that prints out the abbreviation expression
355 // located at Index in the given abbreviation. Updates Index to
356 // next expression in the abbreviation.
357 void TokenizeAbbrevExpression(const NaClBitCodeAbbrev *Abbrev,
358 unsigned &Index);
359
360 // Prints out the given abbreviation operator.
361 void TokenizeAbbrevOp(const NaClBitCodeAbbrevOp &Op);
362
363 // The free list for abbreviation directives.
364 naclbitc::DirectiveMemoryPool<AbbreviationDirective> AbbrevDirMemoryPool;
365
366 // The free list for abbreviation index directives.
367 naclbitc::DirectiveMemoryPool<AbbrevIndexDirective> AbbrevIndexDirMemoryPool;
368
369 // Computes how wide the assembly portion of the dump file should be.
370 static unsigned GetAssemblyWidth(naclbitc::ObjDumpStream &ObjDump) {
371 int Diff = 80 - (ObjDump.GetRecordWidth()+1);
372 // Make sure there is enough room to print out assembly.
373 return Diff < 20 ? 20 : Diff;
374 }
375 };
376
377 void AssemblyTextFormatter::TypeDirective::MyApply(bool Replay) const {
378 assert(!Replay && "Shouldn't have been saved for replay");
379 AssemblyTextFormatter *AssemblyFormatter =
380 reinterpret_cast<AssemblyTextFormatter*>(Formatter);
381 AssemblyFormatter->TokenizeTypeInternal(Typ, FcnId, AddParams);
382 AssemblyFormatter->TypeDirMemoryPool.Free(const_cast<TypeDirective*>(this));
383 }
384
385 void AssemblyTextFormatter::AbbreviationDirective::MyApply(bool Replay) const {
386 assert(!Replay && "Shouldn't have been saved for replay");
387 AssemblyTextFormatter *AssemblyFormatter =
388 reinterpret_cast<AssemblyTextFormatter*>(Formatter);
389 AssemblyFormatter->TokenizeAbbreviationInternal(Abbrev);
390 AssemblyFormatter->AbbrevDirMemoryPool.Free(
391 const_cast<AbbreviationDirective*>(this));
392 }
393
394 AssemblyTextFormatter::TypeDirective &AssemblyTextFormatter::
395 AllocateTypeDirective(Type *Typ, BitcodeId *FcnId, bool AddParams) {
396 TypeDirective *Element = TypeDirMemoryPool.Allocate(this);
397 Element->Init(Typ, FcnId, AddParams);
398 return *Element;
399 }
400
401 void AssemblyTextFormatter::TokenizeTypeInternal(
402 Type *Typ, BitcodeId* FcnName, bool AddParams) {
403 switch (Typ->getTypeID()) {
404 case Type::VoidTyID:
405 TextStream << "void";
406 break;
407 case Type::FloatTyID:
408 TextStream << "float";
409 break;
410 case Type::DoubleTyID:
411 TextStream << "double";
412 break;
413 case Type::IntegerTyID:
414 TextStream << "i" << Typ->getIntegerBitWidth();
415 break;
416 case Type::VectorTyID: {
417 VectorType *VecType = cast<VectorType>(Typ);
418 TextStream << StartCluster << OpenAngle << VecType->getNumElements()
419 << Space << "x" << Space
420 << TokenizeType(VecType->getElementType())
421 << CloseAngle << FinishCluster;
422 break;
423 }
424 case Type::FunctionTyID: {
425 FunctionType *FcnType = cast<FunctionType>(Typ);
426 unsigned NumParams = FcnType->getFunctionNumParams();
427 TextStream << StartCluster
428 << TokenizeType(FcnType->getReturnType())
429 << Space
430 << StartCluster;
431 if (NumParams > 0) TextStream << StartCluster;
432 if (FcnName) TextStream << *FcnName;
433 TextStream << OpenParen << FinishCluster;
434 bool HasParamStartCluster = false;
435 for (unsigned i = 0, NumParams = FcnType->getFunctionNumParams();
436 i < NumParams; ++i) {
437 if (i > 0) {
438 TextStream << Comma << FinishCluster << Space;
439 HasParamStartCluster = false;
440 }
441 TextStream << StartCluster
442 << TokenizeType(FcnType->getFunctionParamType(i));
443 if (AddParams) TextStream << Space << BitcodeId('p', i);
444 HasParamStartCluster = true;
445 }
446 if (FcnType->isFunctionVarArg()) {
447 if (HasParamStartCluster) {
448 TextStream << Comma << FinishCluster << Space;
449 }
450 TextStream << StartCluster << "...";
451 HasParamStartCluster = true;
452 }
453 if (HasParamStartCluster) TextStream << FinishCluster;
454 TextStream << CloseParen << FinishCluster;
455 if (NumParams > 0) TextStream << FinishCluster;
456 break;
457 }
458 default:
459 report_fatal_error("Unsupported PNaCl type found");
460 break;
461 }
462 }
463
464 void AssemblyTextFormatter::TokenizeAbbrevOp(const NaClBitCodeAbbrevOp &Op) {
465 // Note: Mimics NaClBitCodeAbbrevOp::Print in NaClBitCodes.cpp
466 switch (Op.getEncoding()) {
467 case NaClBitCodeAbbrevOp::Literal:
468 Tokens() << Op.getValue();
469 return;
470 case NaClBitCodeAbbrevOp::Fixed:
471 Tokens() << StartCluster << "fixed" << OpenParen << Op.getValue()
472 << CloseParen << FinishCluster;
473 return;
474 case NaClBitCodeAbbrevOp::VBR:
475 Tokens() << StartCluster << "vbr" << OpenParen << Op.getValue()
476 << CloseParen << FinishCluster;
477 return;
478 case NaClBitCodeAbbrevOp::Array:
479 Tokens() << "array";
480 return;
481 case NaClBitCodeAbbrevOp::Char6:
482 Tokens() << "char6";
483 return;
484 }
485 }
486
487 void AssemblyTextFormatter::
488 TokenizeAbbrevExpression(const NaClBitCodeAbbrev *Abbrev, unsigned &Index) {
489 // Note: Mimics PrintExpression in NaClBitCodes.cpp
490 const NaClBitCodeAbbrevOp &Op = Abbrev->getOperandInfo(Index);
491 TokenizeAbbrevOp(Op);
492 if (unsigned NumArgs = Op.NumArguments()) {
493 Tokens() << StartCluster << OpenParen;
494 for (unsigned i = 0; i < NumArgs; ++i) {
495 ++Index;
496 if (i > 0) {
497 Tokens() << Comma << FinishCluster << Space << StartCluster;
498 }
499 TokenizeAbbrevExpression(Abbrev, Index);
500 }
501 Tokens() << CloseParen << FinishCluster;
502 }
503 }
504
505 void AssemblyTextFormatter::
506 TokenizeAbbreviationInternal(const NaClBitCodeAbbrev *Abbrev) {
507 Tokens() << StartCluster << OpenAngle;
508 for (unsigned i = 0; i < Abbrev->getNumOperandInfos(); ++i) {
509 if (i > 0) {
510 Tokens() << Comma << FinishCluster << Space << StartCluster;
511 }
512 TokenizeAbbrevExpression(Abbrev, i);
513 }
514 Tokens() << CloseAngle << FinishCluster;
515 }
516
517 void AssemblyTextFormatter::AbbrevIndexDirective::MyApply(bool Replay) const {
518 assert(!Replay && "Shouldn't have been saved for replay");
519 if (!Record->UsedAnAbbreviation()) return;
520 unsigned Index = Record->GetAbbreviationIndex();
521 if (Index < naclbitc::FIRST_APPLICATION_ABBREV) return;
522 Index -= naclbitc::FIRST_APPLICATION_ABBREV;
523 bool IsGlobal = Index < NumGlobalAbbreviations;
524 if (!IsGlobal) Index -= NumGlobalAbbreviations;
525 BitcodeId AbbrevIndex('a', Index, IsGlobal);
526 AssemblyTextFormatter *Fmtr =
527 reinterpret_cast<AssemblyTextFormatter*>(Formatter);
528 Tokens() << Fmtr->Space << Fmtr->StartCluster << Fmtr->OpenAngle
529 << AbbrevIndex << Fmtr->CloseAngle << Fmtr->FinishCluster;
530 Fmtr->AbbrevIndexDirMemoryPool.Free(const_cast<AbbrevIndexDirective*>(this));
531 }
532
533 // Holds possible alignements for loads/stores etc. Used to extract
534 // expected values.
535 static unsigned NaClPossibleLoadStoreAlignments[] = {
536 1, 2, 4, 8
537 };
538
539 // Finds the expected alignments for the load/store, for type Ty.
540 static void NaClGetExpectedLoadStoreAlignment(
541 const DataLayout &DL, Type *Ty, std::vector<unsigned> &ValidAlignments) {
542 for (size_t i = 0; i < array_lengthof(NaClPossibleLoadStoreAlignments); ++i) {
543 unsigned Alignment = NaClPossibleLoadStoreAlignments[i];
544 if (PNaClABIProps::isAllowedAlignment(&DL, Alignment, Ty)) {
545 ValidAlignments.push_back(Alignment);
546 }
547 }
548 }
549
550 /// Top-level class to parse bitcode file and transform to
551 /// corresponding disassembled code.
552 class NaClDisTopLevelParser : public NaClBitcodeParser {
553 NaClDisTopLevelParser(const NaClDisTopLevelParser&) LLVM_DELETED_FUNCTION;
554 void operator=(const NaClDisTopLevelParser&) LLVM_DELETED_FUNCTION;
555
556 public:
557 NaClDisTopLevelParser(NaClBitcodeHeader &Header,
558 const unsigned char *HeaderBuffer,
559 NaClBitstreamCursor &Cursor,
560 naclbitc::ObjDumpStream &ObjDump)
561 : NaClBitcodeParser(Cursor),
562 Mod("ObjDump", getGlobalContext()),
563 ObjDump(ObjDump),
564 AbbrevListener(this),
565 DL(&Mod),
566 AllowedIntrinsics(&Mod.getContext()),
567 AssemblyFormatter(ObjDump),
568 Header(Header),
569 HeaderBuffer(HeaderBuffer),
570 NumFunctions(0),
571 NumGlobals(0),
572 ExpectedNumGlobals(0),
573 NumParams(0),
574 NumConstants(0),
575 NumValuedInsts(0),
576 UnknownType(Type::getVoidTy(Mod.getContext())),
577 PointerType(Type::getInt32Ty(Mod.getContext())),
578 ComparisonType(Type::getInt1Ty(Mod.getContext())),
579 NumDefinedFunctions(0) {
580 SetListener(&AbbrevListener);
581 }
582
583 ~NaClDisTopLevelParser() override {
584 // Be sure to flush any remaining errors.
585 ObjDump.Flush();
586 }
587
588 // Returns the number of errors that were sent to the ObjDump.
589 unsigned GetNumErrors() {
590 return ObjDump.GetNumErrors();
591 }
592
593 /// Generates an error with the given message.
594 bool Error(const std::string &Message) override {
595 // Use local error routine so that all errors are treated uniformly.
596 ObjDump.Error() << Message << "\n";
597 return true;
598 }
599
600 /// Flushes out objdump and then exits with fatal error.
601 void Fatal() {
602 Fatal("");
603 }
604
605 /// Flushes out objdump and then exits with fatal error, using
606 /// the given message.
607 void Fatal(const std::string &Message) {
608 ObjDump.Fatal(Message);
609 }
610
611 /// Parses the top-level module block.
612 bool ParseBlock(unsigned BlockID) override;
613
614 /// Installs the given type to the next available type index.
615 void InstallType(Type *Ty) {
616 TypeIdType.push_back(Ty);
617 }
618
619 /// Returns the type associated with the given type index.
620 Type *GetType(uint32_t Index) {
621 if (Index >= TypeIdType.size()) {
622 BitcodeId Id('t', Index);
623 Errors() << "Can't find definition for " << Id << "\n";
624 // Recover so that additional errors can be found.
625 return UnknownType;
626 }
627 return TypeIdType[Index];
628 }
629
630 /// Returns the number of types (currently) defined in the bitcode
631 /// file.
632 uint32_t GetNumTypes() const {
633 return TypeIdType.size();
634 }
635
636 /// Returns true if Type represents a (non-zero sized) value.
637 bool isValidValueType(Type *Ty) const {
638 return Ty->isIntegerTy() || Ty->isFloatTy() || Ty->isDoubleTy()
639 || Ty->isVectorTy();
640 }
641
642 /// Installs the given type to the next available function index.
643 void InstallFunctionType(FunctionType *Ty, uint64_t BitAddress) {
644 assert(FunctionIdType.size() == NumFunctions);
645 ++NumFunctions;
646 FunctionIdType.push_back(Ty);
647 FunctionIdAddress.push_back(BitAddress);
648 // Let Valuesymtab change this to true if appropriate.
649 FunctionIdIsIntrinsic.push_back(false);
650 }
651
652 /// Returns the bit address where the function record appeared in
653 /// the bitcode file. Returns 0 if unknown.
654 uint64_t GetFunctionIdAddress(uint32_t Index) {
655 if (Index >= FunctionIdAddress.size()) return 0;
656 return FunctionIdAddress[Index];
657 }
658
659 /// Sets the record bit address to the function ID address (if known).
660 void SetRecordAddressToFunctionIdAddress(uint32_t Index) {
661 uint64_t Address = GetFunctionIdAddress(Index);
662 if (Address)
663 ObjDump.SetRecordBitAddress(Address);
664 }
665
666 //// Returns the type associated with the given function index.
667 FunctionType *GetFunctionType(uint32_t Index) {
668 if (Index >= FunctionIdType.size()) {
669 BitcodeId Id('f', Index);
670 Errors() << "Can't find definition for " << Id << "\n";
671 Fatal();
672 }
673 return FunctionIdType[Index];
674 }
675
676 /// Marks the function associated with the given Index as intrinsic.
677 void MarkFunctionAsIntrinsic(uint32_t Index) {
678 if (Index >= FunctionIdIsIntrinsic.size()) {
679 BitcodeId Id('f', Index);
680 Errors() << "Can't define " << Id << " as intrinsic, no definition";
681 }
682 FunctionIdIsIntrinsic[Index] = true;
683 }
684
685 /// Returns true if the given Index is for a function intrinsic.
686 bool IsFunctionIntrinsic(uint32_t Index) {
687 if (Index >= FunctionIdIsIntrinsic.size()) return false;
688 return FunctionIdIsIntrinsic[Index];
689 }
690
691 /// Returns true if the function is an intrinsic function.
692 bool IsIntrinsicAllowed(const std::string &FuncName,
693 const FunctionType *FuncType) {
694 return AllowedIntrinsics.isAllowed(FuncName, FuncType);
695 }
696
697 /// Returns the type of the Name'd intrinsic, if defined as an
698 /// allowed intrinsic name. Otherwise returns 0.
699 FunctionType *GetIntrinsicType(const std::string &Name) {
700 return AllowedIntrinsics.getIntrinsicType(Name);
701 }
702
703 /// Returns the number of functions (currently) defined/declared in
704 /// the bitcode file.
705 uint32_t GetNumFunctions() const {
706 return NumFunctions;
707 }
708
709 /// Installs that the given function index as having a function body
710 /// (i.e. the function address uses the "define" keyword instead of
711 /// the "declare" keyword).
712 void InstallDefinedFunction(uint32_t Index) {
713 DefinedFunctions.push_back(Index);
714 }
715
716 /// Returns true if there is an Index defined function block.
717 bool HasDefinedFunctionIndex(uint32_t Index) const {
718 return Index < DefinedFunctions.size();
719 }
720
721 /// Returns the function index associated with the Index defined
722 /// function block.
723 uint32_t GetDefinedFunctionIndex(uint32_t Index) const {
724 assert(Index < DefinedFunctions.size());
725 return DefinedFunctions[NumDefinedFunctions];
726 }
727
728 /// Returns true if there is a next defined function index.
729 bool HasNextDefinedFunctionIndex() const {
730 return HasDefinedFunctionIndex(NumDefinedFunctions);
731 }
732
733 /// Returns the function index associated with the next defined function.
734 uint32_t GetNextDefinedFunctionIndex() const {
735 return GetDefinedFunctionIndex(NumDefinedFunctions);
736 }
737
738 /// Returns true if the given value ID corresponds to a declared (rather
739 /// than defined) function.
740 bool IsDeclaredFunction(uint32_t Index) {
741 if (Index >= NumFunctions) return false;
742 for (size_t i = 0, e = DefinedFunctions.size(); i < e; ++i) {
743 if (DefinedFunctions[i] == Index) return false;
744 }
745 return true;
746 }
747
748 /// Increments the number of (currently) defined functions in the
749 /// bitcode file by one.
750 void IncNumDefinedFunctions() {
751 ++NumDefinedFunctions;
752 }
753
754 void IncNumGlobals() {
755 NumGlobals++;
756 }
757
758 /// Returns the number of globals (currently) defined in the bitcode
759 /// file.
760 uint32_t GetNumGlobals() const {
761 return NumGlobals;
762 }
763
764 /// Returns the expected number of globals (as defined by the count
765 /// record of the globals block).
766 uint32_t GetExpectedNumGlobals() const {
767 return ExpectedNumGlobals;
768 }
769
770 /// Sets field ExpectedNumGlobals to the given value.
771 void SetExpectedNumGlobals(uint32_t NewValue) {
772 ExpectedNumGlobals = NewValue;
773 }
774
775 /// Installs the given type to the next available parameter index.
776 void InstallParamType(Type *Ty) {
777 while (ParamIdType.size() <= NumParams) {
778 ParamIdType.push_back(UnknownType);
779 }
780 ParamIdType[NumParams++] = Ty;
781 }
782
783 /// Returns the type associated with the given parameter index.
784 Type *GetParamType(uint32_t Index) {
785 if (Index >= ParamIdType.size()) {
786 BitcodeId Id('p', Index);
787 Errors() << "Can't find defintion for " << Id << "\n";
788 Fatal();
789 }
790 return ParamIdType[Index];
791 }
792
793 /// Returns the number of parameters (currently) defined in the
794 /// enclosing defined function.
795 uint32_t GetNumParams() const {
796 return NumParams;
797 }
798
799 /// Installs the given type to the next available constant index.
800 void InstallConstantType(Type *Ty) {
801 while (ConstantIdType.size() <= NumConstants) {
802 ConstantIdType.push_back(UnknownType);
803 }
804 ConstantIdType[NumConstants++] = Ty;
805 }
806
807 /// Returns the type associated with the given constant index.
808 Type *GetConstantType(uint32_t Index) {
809 if (Index >= ConstantIdType.size()) {
810 BitcodeId Id('c', Index);
811 Errors() << "Can't find definition for " << Id << "\n";
812 Fatal();
813 }
814 return ConstantIdType[Index];
815 }
816
817 /// Returns the number of constants (currently) defined in the
818 /// enclosing defined function.
819 uint32_t GetNumConstants() const {
820 return NumConstants;
821 }
822
823 /// Installs the given type to the given instruction index. Note:
824 /// Instruction indices are only associated with instructions that
825 /// generate values.
826 void InstallInstType(Type *Ty, uint32_t Index) {
827 while (InstIdType.size() <= Index) {
828 InstIdType.push_back(UnknownType);
829 }
830 if (InstIdType[Index] != UnknownType && Ty != InstIdType[Index]) {
831 Errors() << BitcodeId('v', Index) << " defined with multiple types: "
832 << *Ty << " and " << *InstIdType[Index] << "\n";
833 }
834 InstIdType[Index] = Ty;
835 }
836
837 /// Installs the given type to the next available instruction index.
838 void InstallInstType(Type *Ty) {
839 InstallInstType(Ty, NumValuedInsts++);
840 }
841
842 /// Returns the type associated with the given instruction index.
843 /// Note: Instruction indices are only associated with instructions
844 /// that generate values.
845 Type *GetInstType(uint32_t Index) {
846 if (Index >= InstIdType.size()) {
847 Errors() << "Can't find type for " << BitcodeId('v', Index) << "\n";
848 return UnknownType;
849 }
850 return InstIdType[Index];
851 }
852
853 /// Returns the number of instructions (in the defined function)
854 /// that (currently) generate values.
855 uint32_t GetNumValuedInstructions() const {
856 return NumValuedInsts;
857 }
858
859 /// Resets index counters local to a defined function.
860 void ResetLocalCounters() {
861 ParamIdType.clear();
862 NumParams = 0;
863 NumConstants = 0;
864 InstIdType.clear();
865 NumValuedInsts = 0;
866 }
867
868 /// Returns the bitcode id associated with the absolute value index
869 BitcodeId GetBitcodeId(uint32_t Index);
870
871 /// Returns the type associated with the given absolute value index.
872 /// If UnderlyingType is false, function indices always return a
873 /// pointer type. Otherwise, function indices returns the declared
874 /// type of the function index.
875 Type *GetValueType(uint32_t Index, bool UnderlyingType = false);
876
877 /// Returns a type to use when the type is unknown.
878 Type *GetUnknownType() const {
879 return UnknownType;
880 }
881
882 /// Returns the type used to represent a pointer.
883 Type *GetPointerType() const {
884 return PointerType;
885 }
886
887 /// Returns the type used to represent comparison results.
888 Type *GetComparisonType() const {
889 return ComparisonType;
890 }
891
892 /// Returns the void type.
893 Type *GetVoidType() const {
894 return Type::getVoidTy(getGlobalContext());
895 }
896
897 /// Returns the float (32-bit) type.
898 Type *GetFloatType() const {
899 return Type::getFloatTy(getGlobalContext());
900 }
901
902 /// Returns the double (64-bit) type.
903 Type *GetDoubleType() const {
904 return Type::getDoubleTy(getGlobalContext());
905 }
906
907 /// Returns an integer type of N bits.
908 Type *GetIntegerType(unsigned N) const {
909 return Type::getIntNTy(getGlobalContext(), N);
910 }
911
912 /// Returns the number of defined global abbreviations (currently)
913 /// for the given block id.
914 unsigned GetNumGlobalAbbreviations(unsigned BlockID) {
915 return GlobalAbbrevsCountMap[BlockID];
916 }
917
918 /// Increments the current number of defined global abbreviations.
919 void IncNumGlobalAbbreviations(unsigned BlockID) {
920 ++GlobalAbbrevsCountMap[BlockID];
921 }
922
923 /// Verifies the given integer operator has the right type. Returns
924 /// the operator.
925 const char *VerifyIntArithmeticOp(const char *Op, Type *OpTy) {
926 if (!IgnorePNaClABIChecks &&
927 !PNaClABITypeChecker::isValidIntArithmeticType(OpTy)) {
928 Errors() << Op << ": Invalid integer arithmetic type: " << *OpTy;
929 }
930 return Op;
931 }
932
933 // Checks the Alignment for loading/storing a value of type Ty. If
934 // invalid, generates an appropriate error message.
935 void VerifyMemoryAccessAlignment(const char *Op, Type *Ty,
936 unsigned Alignment) {
937 if (IgnorePNaClABIChecks) return;
938 if (!PNaClABIProps::isAllowedAlignment(&DL, Alignment, Ty)) {
939 raw_ostream &Errs = Errors();
940 std::vector<unsigned> Alignments;
941 NaClGetExpectedLoadStoreAlignment(DL, Ty, Alignments);
942 if (!Alignments.empty()) {
943 Errs << Op << ": Illegal alignment for " << *Ty << ". Expects: ";
944 bool isFirst = true;
945 for (auto Align : Alignments) {
946 if (isFirst)
947 isFirst = false;
948 else
949 Errs << " or ";
950 Errs << Align;
951 }
952 Errs << "\n";
953 } else {
954 Errs << Op << ": Not allowed for type: " << *Ty << "\n";
955 }
956 }
957 }
958
959 // ******************************************************
960 // The following return the corresponding methods/fields
961 // from the the assembly formatter/objdumper.
962 // ******************************************************
963
964 naclbitc::TokenTextDirective &Semicolon() {
965 return AssemblyFormatter.Semicolon;
966 }
967
968 naclbitc::TokenTextDirective &Colon() {
969 return AssemblyFormatter.Colon;
970 }
971
972 naclbitc::SpaceTextDirective &Space() {
973 return AssemblyFormatter.Space;
974 }
975
976 naclbitc::TokenTextDirective &Comma() {
977 return AssemblyFormatter.Comma;
978 }
979
980 naclbitc::OpenTextDirective &OpenParen() {
981 return AssemblyFormatter.OpenParen;
982 }
983
984 naclbitc::CloseTextDirective &CloseParen() {
985 return AssemblyFormatter.CloseParen;
986 }
987
988 naclbitc::OpenTextDirective &OpenAngle() {
989 return AssemblyFormatter.OpenAngle;
990 }
991
992 naclbitc::CloseTextDirective &CloseAngle() {
993 return AssemblyFormatter.CloseAngle;
994 }
995
996 naclbitc::OpenTextDirective &OpenCurly() {
997 return AssemblyFormatter.OpenCurly;
998 }
999
1000 naclbitc::CloseTextDirective &CloseCurly() {
1001 return AssemblyFormatter.CloseCurly;
1002 }
1003
1004 naclbitc::OpenTextDirective &OpenSquare() {
1005 return AssemblyFormatter.OpenSquare;
1006 }
1007
1008 naclbitc::CloseTextDirective &CloseSquare() {
1009 return AssemblyFormatter.CloseSquare;
1010 }
1011
1012 naclbitc::EndlineTextDirective &Endline() {
1013 return AssemblyFormatter.Endline;
1014 }
1015
1016 naclbitc::StartClusteringDirective &StartCluster() {
1017 return AssemblyFormatter.StartCluster;
1018 }
1019
1020 naclbitc::FinishClusteringDirective &FinishCluster() {
1021 return AssemblyFormatter.FinishCluster;
1022 }
1023
1024 raw_ostream &Tokens() {
1025 return AssemblyFormatter.Tokens();
1026 }
1027
1028 raw_ostream &Errors() {
1029 return ObjDump.Error();
1030 }
1031
1032 raw_ostream &Warnings() {
1033 if (ReportWarningsAsErrors) return Errors();
1034 return ObjDump.Warning();
1035 }
1036
1037 const std::string &GetAssemblyIndent() const {
1038 return AssemblyFormatter.GetIndent();
1039 }
1040
1041 unsigned GetAssemblyNumTabs() const {
1042 return AssemblyFormatter.GetNumTabs();
1043 }
1044
1045 void IncAssemblyIndent() {
1046 AssemblyFormatter.Inc();
1047 }
1048
1049 void DecAssemblyIndent() {
1050 AssemblyFormatter.Dec();
1051 }
1052
1053 void IncRecordIndent() {
1054 ObjDump.IncRecordIndent();
1055 }
1056
1057 void DecRecordIndent() {
1058 ObjDump.DecRecordIndent();
1059 }
1060
1061 void ObjDumpFlush() {
1062 ObjDump.Flush();
1063 }
1064
1065 void ObjDumpSetRecordBitAddress(uint64_t Bit) {
1066 ObjDump.SetRecordBitAddress(Bit);
1067 }
1068
1069 void ObjDumpWrite(uint64_t Bit,
1070 const NaClBitcodeRecordData &Record,
1071 int32_t AbbrevIndex =
1072 naclbitc::ABBREV_INDEX_NOT_SPECIFIED) {
1073 ObjDump.Write(Bit, Record, AbbrevIndex);
1074 }
1075
1076 void ObjDumpWrite(uint64_t Bit,
1077 const NaClBitcodeRecord &Record) {
1078 ObjDump.Write(Bit, Record.GetRecordData(), Record.GetAbbreviationIndex());
1079 }
1080
1081 AssemblyTextFormatter::TypeDirective &
1082 TokenizeType(Type *Typ) {
1083 return AssemblyFormatter.TokenizeType(Typ);
1084 }
1085
1086 AssemblyTextFormatter::TypeDirective &
1087 TokenizeFunctionType(FunctionType *Type, BitcodeId *FcnId) {
1088 return AssemblyFormatter.TokenizeFunctionType(Type, FcnId);
1089 }
1090
1091 AssemblyTextFormatter::TypeDirective &
1092 TokenizeFunctionSignature(FunctionType *Typ, BitcodeId *FcnId) {
1093 return AssemblyFormatter.TokenizeFunctionSignature(Typ, FcnId);
1094 }
1095
1096 AssemblyTextFormatter::AbbreviationDirective &
1097 TokenizeAbbreviation(NaClBitCodeAbbrev *Abbrev) {
1098 return AssemblyFormatter.TokenizeAbbreviation(Abbrev);
1099 }
1100
1101 AssemblyTextFormatter::AbbrevIndexDirective &
1102 TokenizeAbbrevIndex(NaClBitcodeRecord &Record,
1103 unsigned NumGlobalAbbreviations) {
1104 return AssemblyFormatter.TokenizeAbbrevIndex(Record,
1105 NumGlobalAbbreviations);
1106 }
1107
1108 private:
1109 // A placeholder module for associating context and data layout.
1110 Module Mod;
1111 // The output stream to generate disassembly into.
1112 naclbitc::ObjDumpStream &ObjDump;
1113 // Listener used to get abbreviations as they are read.
1114 NaClBitcodeParserListener AbbrevListener;
1115 // DataLayout to use.
1116 const DataLayout DL;
1117 // The set of allowed intrinsics.
1118 PNaClAllowedIntrinsics AllowedIntrinsics;
1119 // The formatter to use to format assembly code.
1120 AssemblyTextFormatter AssemblyFormatter;
1121 // The header appearing before the beginning of the input stream.
1122 NaClBitcodeHeader &Header;
1123 // Pointer to the buffer containing the header.
1124 const unsigned char *HeaderBuffer;
1125 // The list of known types (index i defines the type associated with
1126 // type index i).
1127 std::vector<Type*> TypeIdType;
1128 // The list of known function signatures (index i defines the type
1129 // signature associated with function index i).
1130 std::vector<FunctionType*> FunctionIdType;
1131 // boolean flag defining if function id is an intrinsic.
1132 std::vector<bool> FunctionIdIsIntrinsic;
1133 // The list of record bit addresses associated with corresponding
1134 // declaration of function IDs.
1135 std::vector<uint64_t> FunctionIdAddress;
1136 // The number of function indices currently defined.
1137 uint32_t NumFunctions;
1138 // The number of global indices currently defined.
1139 uint32_t NumGlobals;
1140 // The expected number of global indices (i.e. value of count record
1141 // in the globals block).
1142 uint32_t ExpectedNumGlobals;
1143 // The list of known parameter types (index i defines the type
1144 // associated with parameter index i).
1145 std::vector<Type*>ParamIdType;
1146 // The number of parameter indices currently defined.
1147 uint32_t NumParams;
1148 std::vector<Type*>ConstantIdType;
1149 // The number of constant indices currently defined.
1150 uint32_t NumConstants;
1151 // The list of known instruction types (index i defines the type
1152 // associated with valued instruction index i).
1153 std::vector<Type*> InstIdType;
1154 // The number of valued instructions currently defined.
1155 uint32_t NumValuedInsts;
1156 // Models an unknown type.
1157 Type *UnknownType;
1158 // Models the pointer type.
1159 Type *PointerType;
1160 // Models a result of a comparison.
1161 Type *ComparisonType;
1162 // Keeps list of function indicies (in the order found in the bitcode)
1163 // that correspond to defined functions.
1164 std::vector<uint32_t> DefinedFunctions;
1165 // The number of function indices currently known to be defined.
1166 uint32_t NumDefinedFunctions;
1167 // Holds the number of global abbreviations defined for each block.
1168 std::map<unsigned, unsigned> GlobalAbbrevsCountMap;
1169 };
1170
1171 BitcodeId NaClDisTopLevelParser::GetBitcodeId(uint32_t Index) {
1172 if (Index < NumFunctions) {
1173 return BitcodeId('f', Index);
1174 }
1175 Index -= NumFunctions;
1176 if (Index < ExpectedNumGlobals) {
1177 return BitcodeId('g', Index);
1178 }
1179 Index -= ExpectedNumGlobals;
1180 if (Index < NumParams) {
1181 return BitcodeId('p', Index);
1182 }
1183 Index -= NumParams;
1184 if (Index < NumConstants) {
1185 return BitcodeId('c', Index);
1186 }
1187 Index -= NumConstants;
1188 return BitcodeId('v', Index);
1189 }
1190
1191 Type *NaClDisTopLevelParser::GetValueType(uint32_t Index, bool UnderlyingType) {
1192 uint32_t Idx = Index;
1193 if (Idx < NumFunctions)
1194 return UnderlyingType ? GetFunctionType(Idx) : PointerType;
1195 Idx -= NumFunctions;
1196 if (Idx < ExpectedNumGlobals)
1197 return PointerType;
1198 Idx -= ExpectedNumGlobals;
1199 if (Idx < NumParams)
1200 return GetParamType(Idx);
1201 Idx -= NumParams;
1202 if (Idx < NumConstants)
1203 return GetConstantType(Idx);
1204 Idx -= NumConstants;
1205 return GetInstType(Idx);
1206 }
1207
1208 // Base class of all block parsers for the bitcode file. Handles
1209 // common actions needed by derived blocks.
1210 //
1211 // Note: This class also handles blocks with unknown block ID's.
1212 class NaClDisBlockParser : public NaClBitcodeParser {
1213 protected:
1214 /// Constructor for the top-level block parser.
1215 NaClDisBlockParser(unsigned BlockID, NaClDisTopLevelParser *Context)
1216 : NaClBitcodeParser(BlockID, Context),
1217 Context(Context){
1218 InitAbbreviations();
1219 }
1220
1221 /// Constructor for nested block parsers.
1222 NaClDisBlockParser(unsigned BlockID, NaClDisBlockParser *EnclosingParser)
1223 : NaClBitcodeParser(BlockID, EnclosingParser),
1224 Context(EnclosingParser->Context) {
1225 InitAbbreviations();
1226 }
1227
1228 public:
1229
1230 ~NaClDisBlockParser() override {
1231 // Be sure to flush any remaining errors reported at end of block.
1232 ObjDumpFlush();
1233 }
1234
1235 bool ParseBlock(unsigned BlockID) override;
1236
1237 protected:
1238 void EnterBlock(unsigned NumWords) override;
1239
1240 void ExitBlock() override;
1241
1242 void ProcessRecord() override;
1243
1244 void ProcessAbbreviation(unsigned BlockID, NaClBitCodeAbbrev *Abbrev,
1245 bool IsLocal) override;
1246
1247 void InitAbbreviations() {
1248 NumGlobalAbbreviations = Context->GetNumGlobalAbbreviations(GetBlockID());
1249 NumLocalAbbreviations = 0;
1250 }
1251
1252 // Prints the block header instruction for the block. Called by EnterBlock.
1253 virtual void PrintBlockHeader();
1254
1255 // Dumps the corresponding record for a block enter.
1256 void DumpEnterBlockRecord();
1257
1258 // Returns the identifier for the next local abbreviation appearing in
1259 // the block.
1260 BitcodeId NextLocalAbbreviationId() {
1261 return BitcodeId('a', NumLocalAbbreviations, false);
1262 }
1263
1264 AssemblyTextFormatter::AbbrevIndexDirective &TokenizeAbbrevIndex() {
1265 return Context->TokenizeAbbrevIndex(Record, NumGlobalAbbreviations);
1266 }
1267
1268 // *****************************************************************
1269 // The following are dispatching methods that call the corresponding
1270 // method on the Context (i.e. NaClDisTopLevelParser).
1271 // *****************************************************************
1272
1273 /// Returns a directive to tokenize the given type.
1274 AssemblyTextFormatter::TypeDirective &TokenizeType(Type *Type) {
1275 return Context->TokenizeType(Type);
1276 }
1277
1278 /// Returns a directive to tokenize the given function type,
1279 /// using the given function id.
1280 AssemblyTextFormatter::TypeDirective
1281 &TokenizeFunctionType(FunctionType *Type, BitcodeId *FcnId) {
1282 return Context->TokenizeFunctionType(Type, FcnId);
1283 }
1284
1285 /// Returns a directive to tokenize the function signature, given the
1286 /// type of the function signature, and the given function id.
1287 AssemblyTextFormatter::TypeDirective
1288 &TokenizeFunctionSignature(FunctionType *Typ, BitcodeId *FcnId) {
1289 return Context->TokenizeFunctionSignature(Typ, FcnId);
1290 }
1291
1292 AssemblyTextFormatter::AbbreviationDirective &TokenizeAbbreviation(
1293 NaClBitCodeAbbrev *Abbrev) {
1294 return Context->TokenizeAbbreviation(Abbrev);
1295 }
1296
1297 naclbitc::TokenTextDirective &Semicolon() {
1298 return Context->Semicolon();
1299 }
1300
1301 naclbitc::TokenTextDirective &Colon() {
1302 return Context->Colon();
1303 }
1304
1305 naclbitc::SpaceTextDirective &Space() {
1306 return Context->Space();
1307 }
1308
1309 naclbitc::TokenTextDirective &Comma() {
1310 return Context->Comma();
1311 }
1312
1313 naclbitc::OpenTextDirective &OpenParen() {
1314 return Context->OpenParen();
1315 }
1316
1317
1318 naclbitc::CloseTextDirective &CloseParen() {
1319 return Context->CloseParen();
1320 }
1321
1322 naclbitc::OpenTextDirective &OpenAngle() {
1323 return Context->OpenAngle();
1324 }
1325
1326 naclbitc::CloseTextDirective &CloseAngle() {
1327 return Context->CloseAngle();
1328 }
1329
1330 naclbitc::OpenTextDirective &OpenCurly() {
1331 return Context->OpenCurly();
1332 }
1333
1334 naclbitc::CloseTextDirective &CloseCurly() {
1335 return Context->CloseCurly();
1336 }
1337
1338 naclbitc::OpenTextDirective &OpenSquare() {
1339 return Context->OpenSquare();
1340 }
1341
1342 naclbitc::CloseTextDirective &CloseSquare() {
1343 return Context->CloseSquare();
1344 }
1345
1346 naclbitc::EndlineTextDirective &Endline() {
1347 return Context->Endline();
1348 }
1349
1350 naclbitc::StartClusteringDirective &StartCluster() {
1351 return Context->StartCluster();
1352 }
1353
1354 naclbitc::FinishClusteringDirective &FinishCluster() {
1355 return Context->FinishCluster();
1356 }
1357
1358 raw_ostream &Tokens() {
1359 return Context->Tokens();
1360 }
1361
1362 raw_ostream &Errors() {
1363 return Context->Errors();
1364 }
1365
1366 raw_ostream &Warnings() {
1367 return Context->Warnings();
1368 }
1369
1370 void Fatal() {
1371 return Context->Fatal();
1372 }
1373
1374 void Fatal(const std::string &Message) {
1375 return Context->Fatal(Message);
1376 }
1377
1378 const std::string &GetAssemblyIndent() const {
1379 return Context->GetAssemblyIndent();
1380 }
1381
1382 unsigned GetAssemblyNumTabs() const {
1383 return Context->GetAssemblyNumTabs();
1384 }
1385
1386 void IncAssemblyIndent() {
1387 Context->IncAssemblyIndent();
1388 }
1389
1390 void DecAssemblyIndent() {
1391 Context->DecAssemblyIndent();
1392 }
1393
1394 void IncRecordIndent() {
1395 Context->IncRecordIndent();
1396 }
1397
1398 void DecRecordIndent() {
1399 Context->DecRecordIndent();
1400 }
1401
1402 void ObjDumpFlush() {
1403 Context->ObjDumpFlush();
1404 }
1405
1406 void ObjDumpWrite(uint64_t Bit,
1407 const NaClBitcodeRecordData &Record,
1408 int32_t AbbrevIndex =
1409 naclbitc::ABBREV_INDEX_NOT_SPECIFIED) {
1410 Context->ObjDumpWrite(Bit, Record, AbbrevIndex);
1411 }
1412
1413 void ObjDumpWrite(uint64_t Bit,
1414 const NaClBitcodeRecord &Record) {
1415 Context->ObjDumpWrite(Bit, Record);
1416 }
1417
1418 void ObjDumpSetRecordBitAddress(uint64_t Bit) {
1419 Context->ObjDumpSetRecordBitAddress(Bit);
1420 }
1421
1422 void InstallType(Type *Ty) {
1423 Context->InstallType(Ty);
1424 }
1425
1426 Type *GetType(uint32_t Index) {
1427 return Context->GetType(Index);
1428 }
1429
1430 uint32_t GetNumTypes() const {
1431 return Context->GetNumTypes();
1432 }
1433
1434 bool isValidValueType(Type *Ty) const {
1435 return Context->isValidValueType(Ty);
1436 }
1437
1438 FunctionType *GetFunctionType(uint32_t Index) {
1439 return Context->GetFunctionType(Index);
1440 }
1441
1442 uint32_t GetNumFunctions() const {
1443 return Context->GetNumFunctions();
1444 }
1445
1446 void IncNumGlobals() {
1447 Context->IncNumGlobals();
1448 }
1449
1450 uint32_t GetNumGlobals() const {
1451 return Context->GetNumGlobals();
1452 }
1453
1454 void InstallFunctionType(FunctionType *Ty) {
1455 return Context->InstallFunctionType(Ty, Record.GetStartBit());
1456 }
1457
1458 void InstallDefinedFunction(uint32_t Index) {
1459 Context->InstallDefinedFunction(Index);
1460 }
1461
1462 BitcodeId GetBitcodeId(uint32_t Id) {
1463 return Context->GetBitcodeId(Id);
1464 }
1465
1466 void InstallParamType(Type *Ty) {
1467 Context->InstallParamType(Ty);
1468 }
1469
1470 uint32_t GetNumParams() const {
1471 return Context->GetNumParams();
1472 }
1473 void InstallConstantType(Type *ConstantType) {
1474 Context->InstallConstantType(ConstantType);
1475 }
1476
1477 Type *GetConstantType(uint32_t Index) {
1478 return Context->GetConstantType(Index);
1479 }
1480
1481 uint32_t GetNumConstants() const {
1482 return Context->GetNumConstants();
1483 }
1484
1485 void InstallInstType(Type *Ty, uint32_t Index) {
1486 Context->InstallInstType(Ty, Index);
1487 }
1488
1489 void InstallInstType(Type *Ty) {
1490 Context->InstallInstType(Ty);
1491 }
1492
1493 uint32_t GetNumValuedInstructions() const {
1494 return Context->GetNumValuedInstructions();
1495 }
1496
1497 Type *GetValueType(uint32_t Id, bool UnderlyingType = false) {
1498 return Context->GetValueType(Id, UnderlyingType);
1499 }
1500
1501 Type *GetFunctionValueType(uint32_t Id) {
1502 return GetValueType(Id, /* UnderlyingType = */ true);
1503 }
1504
1505 Type *GetUnknownType() const {
1506 return Context->GetUnknownType();
1507 }
1508
1509 Type *GetPointerType() const {
1510 return Context->GetPointerType();
1511 }
1512
1513 Type *GetComparisonType() const {
1514 return Context->GetComparisonType();
1515 }
1516
1517 Type *GetVoidType() const {
1518 return Context->GetVoidType();
1519 }
1520
1521 Type *GetFloatType() const {
1522 return Context->GetFloatType();
1523 }
1524
1525 Type *GetDoubleType() const {
1526 return Context->GetDoubleType();
1527 }
1528
1529 Type *GetIntegerType(unsigned Size) const {
1530 return Context->GetIntegerType(Size);
1531 }
1532
1533 const char *VerifyIntArithmeticOp(const char *Op, Type *OpTy) {
1534 return Context->VerifyIntArithmeticOp(Op, OpTy);
1535 }
1536
1537 protected:
1538 // The context parser that contains decoding state.
1539 NaClDisTopLevelParser *Context;
1540 // The number of global abbreviations defined for this block.
1541 unsigned NumGlobalAbbreviations;
1542 // The current number of local abbreviations defined for this block.
1543 unsigned NumLocalAbbreviations;
1544 };
1545
1546 bool NaClDisBlockParser::ParseBlock(unsigned BlockId) {
1547 // Only called if we don't know the details about the block.
1548 ObjDumpSetRecordBitAddress(GetBlock().GetStartBit());
1549 Errors() << "Don't know how to parse block " << BlockId
1550 << ", when in block " << GetBlockID() << "\n";
1551 NaClDisBlockParser Parser(BlockId, this);
1552 return Parser.ParseThisBlock();
1553 }
1554
1555 void NaClDisBlockParser::PrintBlockHeader() {
1556 Errors() << "Unknown block id found: " << GetBlockID() << "\n";
1557 Tokens() << "unknown" << Space() << OpenCurly()
1558 << Space() << Space() << "// BlockID = "
1559 << GetBlockID() << Endline();
1560 }
1561
1562 void NaClDisBlockParser::EnterBlock(unsigned NumWords) {
1563 PrintBlockHeader();
1564 DumpEnterBlockRecord();
1565 IncRecordIndent();
1566 IncAssemblyIndent();
1567 }
1568
1569 void NaClDisBlockParser::ExitBlock() {
1570 DecAssemblyIndent();
1571 DecRecordIndent();
1572 Tokens() << CloseCurly() << Endline();
1573 NaClBitcodeRecordData Exit;
1574 Exit.Code = naclbitc::BLK_CODE_EXIT;
1575 ObjDumpWrite(Record.GetStartBit(), Exit, naclbitc::END_BLOCK);
1576 }
1577
1578 void NaClDisBlockParser::DumpEnterBlockRecord() {
1579 // TODO(kschimpf): Better integrate this with the bitstream reader
1580 // (which currently doesn't build any records).
1581 NaClBitcodeRecordData Enter;
1582 Enter.Code = naclbitc::BLK_CODE_ENTER;
1583 Enter.Values.push_back(GetBlockID());
1584 Enter.Values.push_back(Record.GetCursor().getAbbrevIDWidth());
1585 ObjDumpWrite(GetBlock().GetStartBit(), Enter, naclbitc::ENTER_SUBBLOCK);
1586 }
1587
1588 void NaClDisBlockParser::ProcessAbbreviation(unsigned BlockID,
1589 NaClBitCodeAbbrev *Abbrev,
1590 bool IsLocal) {
1591 Tokens() << NextLocalAbbreviationId() << Space() << "=" << Space()
1592 << "abbrev" << Space() << TokenizeAbbreviation(Abbrev)
1593 << Semicolon() << Endline();
1594 ++NumLocalAbbreviations;
1595 ObjDumpWrite(Record.GetStartBit(), Record);
1596 }
1597
1598 void NaClDisBlockParser::ProcessRecord() {
1599 // Note: Only called if block is not understood. Hence, we
1600 // only report the records.
1601 ObjDumpWrite(Record.GetStartBit(), Record);
1602 }
1603
1604 /// Parses and disassembles the blockinfo block.
1605 class NaClDisBlockInfoParser : public NaClDisBlockParser {
1606 public:
1607 NaClDisBlockInfoParser(unsigned BlockID,
1608 NaClDisBlockParser *EnclosingParser)
1609 : NaClDisBlockParser(BlockID, EnclosingParser) {
1610 }
1611
1612 ~NaClDisBlockInfoParser() override {}
1613
1614 private:
1615 void PrintBlockHeader() override;
1616
1617 void SetBID() override;
1618
1619 void ProcessAbbreviation(unsigned BlockID, NaClBitCodeAbbrev *Abbrev,
1620 bool IsLocal) override;
1621
1622 /// Returns the abbreviation id for the next global abbreviation
1623 /// to be defined for the given block id.
1624 BitcodeId NextGlobalAbbreviationId(unsigned BlockID) {
1625 return BitcodeId('a', Context->GetNumGlobalAbbreviations(BlockID), true);
1626 }
1627 };
1628
1629 void NaClDisBlockInfoParser::PrintBlockHeader() {
1630 Tokens() << "abbreviations" << Space() << OpenCurly()
1631 << Space() << Space() << "// BlockID = "
1632 << GetBlockID() << Endline();
1633 }
1634
1635 void NaClDisBlockInfoParser::SetBID() {
1636 std::string BlockName;
1637 uint64_t BlockID = Record.GetValues()[0];
1638 switch (BlockID) {
1639 case naclbitc::MODULE_BLOCK_ID:
1640 Tokens() << "module";
1641 break;
1642 case naclbitc::CONSTANTS_BLOCK_ID:
1643 Tokens() << "constants";
1644 break;
1645 case naclbitc::FUNCTION_BLOCK_ID:
1646 Tokens() << "function";
1647 break;
1648 case naclbitc::VALUE_SYMTAB_BLOCK_ID:
1649 Tokens() << "valuesymtab";
1650 break;
1651 case naclbitc::TYPE_BLOCK_ID_NEW:
1652 Tokens() << "types";
1653 break;
1654 case naclbitc::GLOBALVAR_BLOCK_ID:
1655 Tokens() << "globals";
1656 break;
1657 default:
1658 Tokens() << "block" << OpenParen() << BlockID << CloseParen();
1659 Errors() << "Block id " << BlockID << " not understood.\n";
1660 break;
1661 }
1662 Tokens() << Colon() << Endline();
1663 ObjDumpWrite(Record.GetStartBit(), Record);
1664 }
1665
1666 void NaClDisBlockInfoParser::ProcessAbbreviation(unsigned BlockID,
1667 NaClBitCodeAbbrev *Abbrev,
1668 bool IsLocal) {
1669 IncAssemblyIndent();
1670 Tokens() << NextGlobalAbbreviationId(BlockID) << Space() << "=" << Space()
1671 << "abbrev" << Space() << TokenizeAbbreviation(Abbrev)
1672 << Semicolon() << Endline();
1673 Context->IncNumGlobalAbbreviations(BlockID);
1674 DecAssemblyIndent();
1675 ObjDumpWrite(Record.GetStartBit(), Record);
1676 }
1677
1678 /// Parses and disassembles the types block.
1679 class NaClDisTypesParser : public NaClDisBlockParser {
1680 public:
1681 NaClDisTypesParser(unsigned BlockID,
1682 NaClDisBlockParser *EnclosingParser)
1683 : NaClDisBlockParser(BlockID, EnclosingParser),
1684 ExpectedNumTypes(0),
1685 IsFirstRecord(true)
1686 {
1687 }
1688
1689 ~NaClDisTypesParser() override;
1690
1691 private:
1692 void PrintBlockHeader() override;
1693
1694 void ProcessRecord() override;
1695
1696 /// Returns the value id for the next type to be defined.
1697 BitcodeId NextTypeId() {
1698 return BitcodeId('t', GetNumTypes());
1699 }
1700
1701 // Installs unknown type as definition of next type.
1702 void InstallUnknownTypeForNextId();
1703
1704
1705 uint32_t ExpectedNumTypes;
1706 bool IsFirstRecord;
1707 };
1708
1709 NaClDisTypesParser::~NaClDisTypesParser() {
1710 if (GetNumTypes() != ExpectedNumTypes) {
1711 Errors() << "Expected " << ExpectedNumTypes << " types but found: "
1712 << GetNumTypes() << "\n";
1713 }
1714 }
1715
1716 void NaClDisTypesParser::PrintBlockHeader() {
1717 Tokens() << "types" << Space() << OpenCurly()
1718 << Space() << Space() << "// BlockID = " << GetBlockID()
1719 << Endline();
1720 }
1721
1722 void NaClDisTypesParser::InstallUnknownTypeForNextId() {
1723 Type *UnknownType = GetUnknownType();
1724 Tokens() << NextTypeId() << Space() << "=" << Space()
1725 << TokenizeType(UnknownType) << Semicolon()
1726 << TokenizeAbbrevIndex() << Endline();
1727 InstallType(UnknownType);
1728 }
1729
1730 void NaClDisTypesParser::ProcessRecord() {
1731 ObjDumpSetRecordBitAddress(Record.GetStartBit());
1732 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1733 switch (Record.GetCode()) {
1734 case naclbitc::TYPE_CODE_NUMENTRY: {
1735 // NUMENTRY: [numentries]
1736 uint64_t Size = 0;
1737 if (Values.size() == 1) {
1738 Size = Values[0];
1739 } else {
1740 Errors() << "Count record should have 1 argument. Found: "
1741 << Values.size() << "\n";
1742 }
1743 if (!IsFirstRecord) {
1744 Errors() << "Count record not first record of types block\n";
1745 }
1746 Tokens() << "count" << Space() << Size << Semicolon()
1747 << TokenizeAbbrevIndex() << Endline();
1748 ExpectedNumTypes = Size;
1749 break;
1750 }
1751 case naclbitc::TYPE_CODE_VOID: {
1752 // VOID
1753 if (!Values.empty())
1754 Errors() << "Void record shouldn't have arguments. Found: "
1755 << Values.size() << "\n";
1756 Type *VoidType = GetVoidType();
1757 Tokens() << NextTypeId() << Space() << "=" << Space()
1758 << TokenizeType(VoidType) << Semicolon()
1759 << TokenizeAbbrevIndex() << Endline();
1760 InstallType(VoidType);
1761 break;
1762 }
1763 case naclbitc::TYPE_CODE_FLOAT: {
1764 // FLOAT
1765 if (!Values.empty())
1766 Errors() << "Float record shoudn't have arguments. Found: "
1767 << Values.size() << "\n";
1768 Type *FloatType = GetFloatType();
1769 Tokens() << NextTypeId() << Space() << "=" << Space()
1770 << TokenizeType(FloatType) << Semicolon()
1771 << TokenizeAbbrevIndex() << Endline();
1772 InstallType(FloatType);
1773 break;
1774 }
1775 case naclbitc::TYPE_CODE_DOUBLE: {
1776 // DOUBLE
1777 if (!Values.empty())
1778 Errors() << "Double record shound't have arguments. Found: "
1779 << Values.size() << "\n";
1780 Type *DoubleType = GetDoubleType();
1781 Tokens() << NextTypeId() << Space() << "=" << Space()
1782 << TokenizeType(DoubleType) << Semicolon()
1783 << TokenizeAbbrevIndex() << Endline();
1784 InstallType(DoubleType);
1785 break;
1786 }
1787 case naclbitc::TYPE_CODE_INTEGER: {
1788 // INTEGER: [width]
1789 uint64_t Size;
1790 if (Values.size() == 1) {
1791 Size = Values[0];
1792 } else {
1793 Errors() << "Integer record should have one argument. Found: "
1794 << Values.size() << "\n";
1795 Size = 32;
1796 }
1797 switch (Size) {
1798 case 1:
1799 case 8:
1800 case 16:
1801 case 32:
1802 case 64: {
1803 break;
1804 }
1805 default:
1806 if (!IgnorePNaClABIChecks) {
1807 Errors() << "Integer record contains bad integer size: "
1808 << Size << "\n";
1809 Size = 32;
1810 }
1811 break;
1812 }
1813 Type *IntType = GetIntegerType(Size);
1814 Tokens() << NextTypeId() << Space() << "=" << Space()
1815 << TokenizeType(IntType) << Semicolon()
1816 << TokenizeAbbrevIndex() << Endline();
1817 InstallType(IntType);
1818 break;
1819 }
1820 case naclbitc::TYPE_CODE_VECTOR: {
1821 // VECTOR: [numelts, eltty]
1822 if (Values.size() != 2) {
1823 Errors() << "Vector record should contain two arguments. Found: "
1824 << Values.size() << "\n";
1825 InstallUnknownTypeForNextId();
1826 break;
1827 }
1828 Type *BaseType = GetType(Values[1]);
1829 if (!(BaseType->isIntegerTy()
1830 || BaseType->isFloatTy()
1831 || BaseType->isDoubleTy())) {
1832 Type *ErrorRecoveryTy = GetIntegerType(32);
1833 Errors() << "Vectors can only be defined on primitive types. Found "
1834 << *BaseType << ". Assuming " << *ErrorRecoveryTy
1835 << " instead.\n";
1836 BaseType = ErrorRecoveryTy;
1837 }
1838 uint64_t NumElements = Values[0];
1839 Type *VecType = VectorType::get(BaseType, NumElements);
1840 if (!IgnorePNaClABIChecks &&
1841 !PNaClABITypeChecker::isValidVectorType(VecType)) {
1842 Errors() << "Vector type " << *VecType << " not allowed.\n";
1843 }
1844 Tokens() << NextTypeId() << Space() << "=" << Space()
1845 << TokenizeType(VecType) << Semicolon()
1846 << TokenizeAbbrevIndex() << Endline();
1847 InstallType(VecType);
1848 break;
1849 }
1850 case naclbitc::TYPE_CODE_FUNCTION: {
1851 // FUNCTION: [vararg, retty, paramty x N]
1852 if (Values.size() < 2) {
1853 Errors()
1854 << "Function record should contain at least 2 arguments. Found: "
1855 << Values.size() << "\n";
1856 InstallUnknownTypeForNextId();
1857 break;
1858 }
1859 if (Values[0]) {
1860 Errors() << "Functions with variable length arguments is not supported\n";
1861 }
1862 Type *ReturnType = GetType(Values[1]);
1863 if (!(isValidValueType(ReturnType) || ReturnType->isVoidTy())) {
1864 Type *ReplaceType = GetIntegerType(32);
1865 Errors() << "Invalid return type. Found: " << *ReturnType
1866 << ". Assuming: " << *ReplaceType << "\n";
1867 ReturnType = ReplaceType;
1868 }
1869 SmallVector<Type*, 8> Signature;
1870 for (size_t i = 2; i < Values.size(); ++i) {
1871 Type *Ty = GetType(Values[i]);
1872 if (!isValidValueType(Ty)) {
1873 Type *ReplaceTy = GetIntegerType(32);
1874 Errors() << "Invalid type for parameter " << (i - 1) << ". Found: "
1875 << *Ty << ". Assuming: " << *ReplaceTy << "\n";
1876 Ty = ReplaceTy;
1877 }
1878 Signature.push_back(Ty);
1879 }
1880 Type *FcnType = FunctionType::get(ReturnType, Signature, Values[0]);
1881 Tokens() << NextTypeId() << Space() << "=" << Space()
1882 << StartCluster() << TokenizeType(FcnType)
1883 << Semicolon() << FinishCluster() << TokenizeAbbrevIndex()
1884 << Endline();
1885 InstallType(FcnType);
1886 break;
1887 }
1888 default:
1889 Errors() << "Unknown record code in types block. Found: "
1890 << Record.GetCode() << "\n";
1891 break;
1892 }
1893 ObjDumpWrite(Record.GetStartBit(), Record);
1894 IsFirstRecord = false;
1895 }
1896
1897 /// Parses and disassembles the globalvars block.
1898 class NaClDisGlobalsParser : public NaClDisBlockParser {
1899 public:
1900 NaClDisGlobalsParser(unsigned BlockID,
1901 NaClDisBlockParser *EnclosingParser)
1902 : NaClDisBlockParser(BlockID, EnclosingParser),
1903 NumInitializers(0),
1904 InsideCompound(false),
1905 BaseTabs(GetAssemblyNumTabs()+1) {}
1906
1907 ~NaClDisGlobalsParser() override {}
1908
1909 private:
1910 void PrintBlockHeader() override;
1911
1912 void ProcessRecord() override;
1913
1914 void ExitBlock() override;
1915
1916 // Expected number of initializers associated with last globalvars
1917 // record
1918 uint32_t NumInitializers;
1919 // True if last globalvars record was defined by a compound record.
1920 bool InsideCompound;
1921 // Number of tabs used to indent elements in the globals block.
1922 unsigned BaseTabs;
1923
1924 // Returns the ID for the next defined global.
1925 BitcodeId NextGlobalId() {
1926 return BitcodeId('g', GetNumGlobals());
1927 }
1928
1929 // Prints out the close initializer "}" if necessary, and fixes
1930 // the indentation to match previous indentation.
1931 void InsertCloseInitializer();
1932
1933 uint32_t GetExpectedNumGlobals() const {
1934 return Context->GetExpectedNumGlobals();
1935 }
1936 };
1937
1938 void NaClDisGlobalsParser::PrintBlockHeader() {
1939 Tokens() << "globals" << Space() << OpenCurly()
1940 << Space() << Space() << "// BlockID = " << GetBlockID()
1941 << Endline();
1942 }
1943
1944 void NaClDisGlobalsParser::InsertCloseInitializer() {
1945 if (InsideCompound) {
1946 while (BaseTabs + 1 < GetAssemblyNumTabs()) DecAssemblyIndent();
1947 Tokens() << CloseCurly() << Endline();
1948 }
1949 while (BaseTabs < GetAssemblyNumTabs()) DecAssemblyIndent();
1950 ObjDumpFlush();
1951 NumInitializers = 0;
1952 InsideCompound = false;
1953 }
1954
1955 void NaClDisGlobalsParser::ExitBlock() {
1956 if (NumInitializers > 0) {
1957 BitcodeId LastGlobal('g', (GetNumGlobals()-1));
1958 Errors() << "More initializers for " << LastGlobal << " expected: "
1959 << NumInitializers << "\n";
1960 }
1961 if (GetNumGlobals() != GetExpectedNumGlobals()) {
1962 Errors() << "Expected " << GetExpectedNumGlobals()
1963 << " globals but found: " << GetNumGlobals() << "\n";
1964 }
1965 NaClDisBlockParser::ExitBlock();
1966 }
1967
1968 void NaClDisGlobalsParser::ProcessRecord() {
1969 ObjDumpSetRecordBitAddress(Record.GetStartBit());
1970 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1971 switch (Record.GetCode()) {
1972 case naclbitc::GLOBALVAR_VAR: {
1973 // VAR: [align, isconst]
1974 if (Values.size() != 2) {
1975 Errors() << "Globalvar record expects two arguments. Found: "
1976 << Values.size() << "\n";
1977 break;
1978 }
1979 if (GetNumGlobals() == GetExpectedNumGlobals()) {
1980 Errors() << "Exceeded expected number of globals: "
1981 << GetExpectedNumGlobals() << "\n";
1982 }
1983 if (NumInitializers > 0) {
1984 Errors() << "Previous initializer list too short. Expects "
1985 << NumInitializers << " more initializers\n";
1986 InsertCloseInitializer();
1987 }
1988 uint32_t Alignment = (1 << Values[0]) >> 1;
1989 Tokens() << StartCluster() << (Values[1] ? "const" : "var")
1990 << Space() << NextGlobalId()
1991 << Comma() << FinishCluster() << Space()
1992 << StartCluster() << "align" << Space() << Alignment
1993 << Comma() << FinishCluster() << TokenizeAbbrevIndex()
1994 << Endline();
1995 IncAssemblyIndent();
1996 IncNumGlobals();
1997 NumInitializers = 1;
1998 break;
1999 }
2000 case naclbitc::GLOBALVAR_COMPOUND:
2001 // COMPOUND: [size]
2002 if (Values.size() != 1) {
2003 Errors() << "Compound record expects one argument. Found: "
2004 << Values.size() << "\n";
2005 break;
2006 }
2007 if (NumInitializers == 1) {
2008 if (InsideCompound) {
2009 Errors() << "Nested initialization records not allowed\n";
2010 InsertCloseInitializer();
2011 }
2012 } else {
2013 Errors() << "Compound record must follow globalvars record\n";
2014 InsertCloseInitializer();
2015 }
2016 Tokens() << StartCluster() << "initializers" << Space()
2017 << Values[0] << FinishCluster() << Space()
2018 << OpenCurly() << TokenizeAbbrevIndex() << Endline();
2019 IncAssemblyIndent();
2020 NumInitializers = Values[0];
2021 InsideCompound = true;
2022 break;
2023 case naclbitc::GLOBALVAR_ZEROFILL:
2024 // ZEROFILL: [size]
2025 if (Values.size() != 1) {
2026 Errors() << "Zerofill record expects one argument. Found: "
2027 << Values.size() << "\n";
2028 break;
2029 }
2030 if (NumInitializers == 0) {
2031 Errors() << "Zerofill initializer not associated with globalvar record\n";
2032 }
2033 Tokens() << "zerofill" << Space() << Values[0] << Semicolon()
2034 << TokenizeAbbrevIndex() << Endline();
2035 --NumInitializers;
2036 break;
2037 case naclbitc::GLOBALVAR_DATA: {
2038 // DATA: [b0, b1, ...]
2039 if (Values.empty()) {
2040 Errors() << "Globals data record must have arguments.\n";
2041 }
2042 if (NumInitializers == 0) {
2043 Errors() << "Data initializer not associated with globalvar record\n";
2044 }
2045 Tokens() << StartCluster() << OpenCurly();
2046 for (size_t i = 0; i < Values.size(); ++i) {
2047 if (i > 0) Tokens() << Comma() << FinishCluster() << Space();
2048 uint64_t Byte = Values[i];
2049 if (Byte >= 256) {
2050 Errors() << "Invalid byte value in data record: " << Byte << "\n";
2051 Byte &= 0xFF;
2052 }
2053 if (i > 0) Tokens() << StartCluster();
2054 Tokens() << format("%3u", static_cast<unsigned>(Byte));
2055 }
2056 Tokens() << CloseCurly() << FinishCluster() << TokenizeAbbrevIndex()
2057 << Endline();
2058 --NumInitializers;
2059 break;
2060 }
2061 case naclbitc::GLOBALVAR_RELOC:
2062 // RELOC: [val, [addend]]
2063 if (Values.empty() || Values.size() > 2) {
2064 Errors() << "Invalid reloc record size: " << Values.size() << "\n";
2065 break;
2066 }
2067 if (NumInitializers == 0) {
2068 Errors() <<
2069 "Relocation initializer not associated with globalvar record\n";
2070 }
2071 Tokens() << "reloc" << Space() << StartCluster() << GetBitcodeId(Values[0]);
2072 if (Values.size() == 2) {
2073 int32_t Addend = static_cast<int32_t>(Values[1]);
2074 char Operator = '+';
2075 if (Addend < 0) {
2076 Operator = '-';
2077 Addend = -Addend;
2078 }
2079 Tokens() << Space()<< Operator << Space() << Addend;
2080 }
2081 Tokens() << Semicolon() << FinishCluster() << TokenizeAbbrevIndex()
2082 << Endline();
2083 --NumInitializers;
2084 break;
2085 case naclbitc::GLOBALVAR_COUNT: {
2086 // COUNT: [n]
2087 uint32_t Count = 0;
2088 if (Values.size() == 1) {
2089 Count = Values[0];
2090 } else {
2091 Errors() << "Globals count record expects one argument. Found: "
2092 << Values.size() << "\n";
2093 }
2094 if (GetNumGlobals() != 0)
2095 Errors() << "Count record not first record in block.\n";
2096 Tokens() << "count" << Space() << Count << Semicolon()
2097 << TokenizeAbbrevIndex() << Endline();
2098 Context->SetExpectedNumGlobals(Count);
2099 break;
2100 }
2101 default:
2102 Errors() << "Unknown record found in globals block.\n";
2103 }
2104
2105 ObjDumpWrite(Record.GetStartBit(), Record);
2106
2107 if (GetNumGlobals() > 0 && NumInitializers == 0)
2108 InsertCloseInitializer();
2109 }
2110
2111 /// Parsers and disassembles a valuesymtab block.
2112 class NaClDisValueSymtabParser : public NaClDisBlockParser {
2113 public:
2114 NaClDisValueSymtabParser(unsigned BlockID,
2115 NaClDisBlockParser *EnclosingParser)
2116 : NaClDisBlockParser(BlockID, EnclosingParser) {
2117 }
2118
2119 ~NaClDisValueSymtabParser() override {}
2120
2121 private:
2122 void PrintBlockHeader() override;
2123
2124 void ProcessRecord() override;
2125
2126 // Displays the context of the name (in Values) for the given Id.
2127 void DisplayEntry(BitcodeId &Id,
2128 const NaClBitcodeRecord::RecordVector &Values);
2129 };
2130
2131 void NaClDisValueSymtabParser::PrintBlockHeader() {
2132 Tokens() << "valuesymtab" << Space() << OpenCurly()
2133 << Space() << Space() << "// BlockID = " << GetBlockID()
2134 << Endline();
2135 }
2136
2137 void NaClDisValueSymtabParser::
2138 DisplayEntry(BitcodeId &Id,
2139 const NaClBitcodeRecord::RecordVector &Values) {
2140 if (Values.size() <= 1) {
2141 Errors() << "Valuesymtab entry record expects 2 arguments. Found: "
2142 << Values.size() << "\n";
2143 return;
2144 }
2145 Tokens() << Id << Space() << Colon() << Space();
2146 // Check if the name of the symbol is alphanumeric. If so, print
2147 // as a string. Otherwise, print a sequence of bytes.
2148 // Note: The check isChar6 is a test for aphanumeric + {'.', '_'}.
2149 bool IsChar6 = true; // Until proven otherwise.
2150 for (size_t i = 1; i < Values.size(); ++i) {
2151 uint64_t Byte = Values[i];
2152 if (Byte >= 256) {
2153 Errors() << "Argument " << i << " of symbol entry not byte: "
2154 << Byte << "\n";
2155 IsChar6 = false;
2156 break;
2157 }
2158 if (!NaClBitCodeAbbrevOp::isChar6(Byte))
2159 IsChar6 = false;
2160 }
2161 if (IsChar6) {
2162 Tokens() << StartCluster() << "\"";
2163 for (size_t i = 1; i < Values.size(); ++i) {
2164 Tokens() << static_cast<char>(Values[i]);
2165 }
2166 Tokens() << "\"" << Semicolon();
2167 } else {
2168 Tokens() << StartCluster() << OpenCurly();
2169 for (size_t i = 1; i < Values.size(); ++i) {
2170 if (i > 1) {
2171 Tokens() << Comma() << FinishCluster() << Space()
2172 << StartCluster();
2173 }
2174 char ch = Values[i];
2175 if (NaClBitCodeAbbrevOp::isChar6(ch)) {
2176 Tokens() << "'" << ch << "'";
2177 } else {
2178 Tokens() << format("%3u", static_cast<unsigned>(ch));
2179 }
2180 }
2181 Tokens() << CloseCurly();
2182 }
2183 Tokens() << FinishCluster() << TokenizeAbbrevIndex() << Endline();
2184 }
2185
2186 void NaClDisValueSymtabParser::ProcessRecord() {
2187 ObjDumpSetRecordBitAddress(Record.GetStartBit());
2188 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
2189 switch (Record.GetCode()) {
2190 case naclbitc::VST_CODE_ENTRY: {
2191 // VST_ENTRY: [valueid, namechar x N]
2192 uint32_t ValID = Values[0];
2193 BitcodeId ID(GetBitcodeId(ValID));
2194 DisplayEntry(ID, Values);
2195 if (ValID < GetNumFunctions()) {
2196 // Check if value is intrinsic name. If so, verify function signature.
2197 std::string Name;
2198 for (unsigned i = 1; i < Values.size(); ++i) {
2199 Name.push_back(static_cast<char>(Values[i]));
2200 }
2201 FunctionType *IntrinTy = Context->GetIntrinsicType(Name);
2202 if (IntrinTy == 0)
2203 // TODO(kschimpf): Check for _start? Complain about other names?
2204 break;
2205 Context->MarkFunctionAsIntrinsic(ValID);
2206 // Verify that expected intrinsic function type matches declared
2207 // type signature.
2208 FunctionType *FcnTy = GetFunctionType(ValID);
2209 if (FcnTy->getNumParams() != IntrinTy->getNumParams()) {
2210 Errors() << "Intrinsic " << Name
2211 << " expects " << IntrinTy->getNumParams()
2212 << " arguments. Found: " << FcnTy->getNumParams()
2213 << "\n";
2214 break;
2215 }
2216 if (!IgnorePNaClABIChecks && !PNaClABITypeChecker::IsPointerEquivType(
2217 IntrinTy->getReturnType(), FcnTy->getReturnType())) {
2218 Errors() << "Intrinsic " << Name
2219 << " expects return type " << *IntrinTy->getReturnType()
2220 << ". Found: " << *FcnTy->getReturnType() << "\n";
2221 break;
2222 }
2223 for (size_t i = 0; i < FcnTy->getNumParams(); ++i) {
2224 if (!IgnorePNaClABIChecks && !PNaClABITypeChecker::IsPointerEquivType(
2225 IntrinTy->getParamType(i),
2226 FcnTy->getParamType(i))) {
2227 Errors() << "Intrinsic " << Name
2228 << " expects " << *IntrinTy->getParamType(i)
2229 << " for argument " << (i+1) << ". Found: "
2230 << *FcnTy->getParamType(i) << "\n";
2231 break;
2232 }
2233 }
2234 }
2235 break;
2236 }
2237 case naclbitc::VST_CODE_BBENTRY: {
2238 // [bbid, namechar x N]
2239 BitcodeId ID('b', Values[0]);
2240 DisplayEntry(ID, Values);
2241 break;
2242 }
2243 default:
2244 Errors() << "Unknown record in valuesymtab block.\n";
2245 break;
2246 }
2247 ObjDumpWrite(Record.GetStartBit(), Record);
2248 }
2249
2250 /// Parses and disassembles a constants block.
2251 class NaClDisConstantsParser : public NaClDisBlockParser {
2252 public:
2253 NaClDisConstantsParser(unsigned BlockID,
2254 NaClDisBlockParser *EnclosingParser)
2255 : NaClDisBlockParser(BlockID, EnclosingParser),
2256 ConstantType(0),
2257 BlockTabs(GetAssemblyNumTabs()) {}
2258
2259 virtual ~NaClDisConstantsParser() {
2260 while (BlockTabs < GetAssemblyNumTabs()) DecAssemblyIndent();
2261 }
2262
2263 private:
2264 void PrintBlockHeader() override;
2265
2266 void ProcessRecord() override;
2267
2268 /// Generates the value id for the next generated constant.
2269 BitcodeId NextConstId() {
2270 return BitcodeId('c', GetNumConstants());
2271 }
2272
2273 // The type associated with the constant.
2274 Type *ConstantType;
2275 // The number of tabs used to indent the globals block.
2276 unsigned BlockTabs;
2277 };
2278
2279 void NaClDisConstantsParser::PrintBlockHeader() {
2280 Tokens() << "constants" << Space() << OpenCurly()
2281 << Space() << Space() << "// BlockID = " << GetBlockID()
2282 << Endline();
2283 }
2284
2285 void NaClDisConstantsParser::ProcessRecord() {
2286 ObjDumpSetRecordBitAddress(Record.GetStartBit());
2287 const NaClBitcodeRecord::RecordVector Values = Record.GetValues();
2288 switch (Record.GetCode()) {
2289 case naclbitc::CST_CODE_SETTYPE:
2290 // SETTYPE: [typeid]
2291 while (BlockTabs + 1 < GetAssemblyNumTabs()) DecAssemblyIndent();
2292 if (Values.size() == 1) {
2293 ConstantType = GetType(Values[0]);
2294 Tokens() << TokenizeType(ConstantType) << ":"
2295 << TokenizeAbbrevIndex() << Endline();
2296 } else {
2297 Errors() << "Settype record should have 1 argument. Found: "
2298 << Values.size() << "\n";
2299 // Make up a type, so we can continue.
2300 ConstantType = GetIntegerType(32);
2301 }
2302 IncAssemblyIndent();
2303 break;
2304 case naclbitc::CST_CODE_UNDEF:
2305 // CST_CODE_UNDEF: []
2306 if (!Values.empty()) {
2307 Errors() << "Undefined record should not have arguments: Found: "
2308 << Values.size() << "\n";
2309 }
2310 Tokens() << NextConstId() << Space() << "=" << Space()
2311 << StartCluster() << TokenizeType(ConstantType)
2312 << Space() << "undef"
2313 << Semicolon() << FinishCluster()
2314 << TokenizeAbbrevIndex() << Endline();
2315 InstallConstantType(ConstantType);
2316 break;
2317 case naclbitc::CST_CODE_INTEGER: {
2318 // INTEGER: [intval]
2319 SignRotatedInt Value;
2320 if (Values.size() == 1) {
2321 const SignRotatedInt MyValue(Values[0], ConstantType);
2322 Value = MyValue;
2323 } else {
2324 Errors() << "Integer record should have 1 argument. Found: "
2325 << Values.size() << "\n";
2326 }
2327 Tokens() << NextConstId() << Space() << "=" << Space() << StartCluster()
2328 << StartCluster() << TokenizeType(ConstantType) << Space()
2329 << Value << Semicolon() << FinishCluster() << FinishCluster()
2330 << TokenizeAbbrevIndex() << Endline();
2331 InstallConstantType(ConstantType);
2332 break;
2333 }
2334 case naclbitc::CST_CODE_FLOAT: {
2335 // FLOAT: [fpval]
2336 // Define initially with default value zero, in case of errors.
2337 const fltSemantics &FloatRep =
2338 ConstantType->isFloatTy() ? APFloat::IEEEsingle : APFloat::IEEEdouble;
2339 APFloat Value(APFloat::getZero(FloatRep));
2340 if (Values.size() == 1) {
2341 if (ConstantType->isFloatTy()) {
2342 Value = APFloat(FloatRep, APInt(32, static_cast<uint32_t>(Values[0])));
2343 }
2344 else if (ConstantType->isDoubleTy()) {
2345 Value = APFloat(FloatRep, APInt(64, Values[0]));
2346 } else {
2347 Errors() << "Bad floating point constant argument: "
2348 << Values[0] << "\n";
2349 }
2350 } else {
2351 Errors() << "Float record should have 1 argument. Found: "
2352 << Values.size() << "\n";
2353 }
2354 Tokens() << NextConstId() << Space() << "=" << Space() << StartCluster()
2355 << TokenizeType(ConstantType) << Space();
2356 if (ConstantType->isFloatTy()) {
2357 Tokens() << format("%g", Value.convertToFloat());
2358 } else {
2359 Tokens() << format("%g", Value.convertToDouble());
2360 }
2361 Tokens() << Semicolon() << FinishCluster()
2362 << TokenizeAbbrevIndex() << Endline();
2363 InstallConstantType(ConstantType);
2364 break;
2365 }
2366 default:
2367 Errors() << "Unknown record in valuesymtab block.\n";
2368 break;
2369 }
2370 ObjDumpWrite(Record.GetStartBit(), Record);
2371 }
2372
2373 /// Parses and disassembles function blocks.
2374 class NaClDisFunctionParser : public NaClDisBlockParser {
2375 public:
2376 NaClDisFunctionParser(unsigned BlockID,
2377 NaClDisBlockParser *EnclosingParser);
2378
2379 ~NaClDisFunctionParser() override {}
2380
2381 void PrintBlockHeader() override;
2382
2383 bool ParseBlock(unsigned BlockID) override;
2384
2385 void ProcessRecord() override;
2386
2387 /// Returns the absolute value index of the first instruction that
2388 /// generates a value in the defined function.
2389 uint32_t FirstValuedInstructionId() const {
2390 return GetNumFunctions() + GetNumGlobals() + GetNumParams()
2391 + GetNumConstants();
2392 }
2393
2394 /// Converts an instruction index to the corresponding absolute value
2395 /// index.
2396 uint32_t ValuedInstToAbsId(uint32_t Id) const {
2397 return FirstValuedInstructionId() + Id;
2398 }
2399
2400 /// Converts the (function) relative index to the corresponding
2401 /// absolute value index.
2402 uint32_t RelativeToAbsId(int32_t Id) {
2403 uint32_t AbsNextId = ValuedInstToAbsId(GetNumValuedInstructions());
2404 if (Id > 0 && AbsNextId < static_cast<uint32_t>(Id)) {
2405 Errors() << "Invalid relative value id: " << Id
2406 << " (Must be <= " << AbsNextId << ")\n";
2407 AbsNextId = Id;
2408 }
2409 return AbsNextId - Id;
2410 }
2411
2412 /// Converts the given absolute value index to a corresponding
2413 /// valued instruction index.
2414 uint32_t AbsToValuedInstId(uint32_t Id) const {
2415 return Id - FirstValuedInstructionId();
2416 }
2417
2418 /// Returns the text representation of the encoded binary operator,
2419 /// assuming the binary operator is operating on the given type.
2420 /// Generates appropriate error messages if the given type is not
2421 // allowed for the given Opcode.
2422 const char *GetBinop(uint32_t Opcode, Type *Type);
2423
2424 /// Returns the text representation of the encoded cast operator.
2425 /// Generates appropriate error messages if the given Opcode is
2426 /// not allowed for the given types.
2427 const char *GetCastOp(uint32_t Opcode, Type *FromType, Type *ToType);
2428
2429 /// Returns the text representation of the encoded integer compare
2430 /// predicate. Generates appropriate error message if the given
2431 /// Opcode is not defined.
2432 const char *GetIcmpPredicate(uint32_t Opcode);
2433
2434 /// Returns the text representation of the encoded floating point
2435 /// compare predicate. Generates appropriate error message if the
2436 /// given Opcode is not defined.
2437 const char *GetFcmpPredicate(uint32_t Opcode);
2438
2439 /// Returns the value id for the next instruction to be defined.
2440 BitcodeId NextInstId() const {
2441 return BitcodeId('v', GetNumValuedInstructions());
2442 }
2443
2444 private:
2445 // The function index of the function being defined.
2446 uint32_t FcnId;
2447 // The function type for the function being defined.
2448 FunctionType *FcnTy;
2449 // The current basic block being printed.
2450 int32_t CurrentBbIndex;
2451 // The expected number of basic blocks.
2452 uint64_t ExpectedNumBbs;
2453 // True if the previously printed instruction was a terminating
2454 // instruction. Used to figure out where to insert block labels.
2455 bool InstIsTerminating;
2456
2457 /// Returns scalar type of vector type Ty, if vector type. Otherwise
2458 /// returns Ty.
2459 Type *UnderlyingType(Type *Ty) {
2460 return Ty->isVectorTy() ? Ty->getVectorElementType() : Ty;
2461 }
2462
2463 bool isFloatingType(Type *Ty) {
2464 return Ty->isFloatTy() || Ty->isDoubleTy();
2465 }
2466
2467 /// Verifies that OpTy is an integer, or a vector of integers, for
2468 /// operator Op. Generates error messages if appropriate. Returns Op.
2469 const char *VerifyIntegerOrVectorOp(const char *Op, Type *OpTy) {
2470 Type *BaseTy = OpTy;
2471 if (OpTy->isVectorTy()) {
2472 if (!IgnorePNaClABIChecks &&
2473 !PNaClABITypeChecker::isValidVectorType(OpTy)) {
2474 Errors() << Op << ": invalid vector type: " << *OpTy << "\n";
2475 return Op;
2476 }
2477 BaseTy = OpTy->getVectorElementType();
2478 }
2479 if (BaseTy->isIntegerTy()) {
2480 if (IgnorePNaClABIChecks ||
2481 PNaClABITypeChecker::isValidScalarType(BaseTy)) {
2482 return Op;
2483 }
2484 Errors() << Op << ": Invalid integer type: " << *OpTy << "\n";
2485 } else {
2486 Errors() << Op << ": Expects integer type. Found: " << *OpTy << "\n";
2487 }
2488 return Op;
2489 }
2490
2491 /// Verifies that Opty is a floating point type, or a vector of a
2492 /// floating points, for operator Op. Generates error messages if
2493 /// appropriate. Returns Op.
2494 const char *VerifyFloatingOrVectorOp(const char *Op, Type *OpTy) {
2495 Type *BaseTy = OpTy;
2496 if (OpTy->isVectorTy()) {
2497 if (!IgnorePNaClABIChecks &&
2498 !PNaClABITypeChecker::isValidVectorType(OpTy)) {
2499 Errors() << Op << ": invalid vector type: " << *OpTy << "\n";
2500 return Op;
2501 }
2502 BaseTy = OpTy->getVectorElementType();
2503 }
2504 if (!isFloatingType(BaseTy)) {
2505 Errors() << Op << ": Expects floating point. Found "
2506 << OpTy << "\n";
2507 return Op;
2508 }
2509 if (!IgnorePNaClABIChecks &&
2510 !PNaClABITypeChecker::isValidScalarType(BaseTy)) {
2511 Errors() << Op << ": type not allowed: " << OpTy << "\n";
2512 }
2513 return Op;
2514 }
2515
2516 /// Op is the name of the operation that called this. Checks if
2517 /// OpTy is either a (non-void) scalar, or a vector of scalars. If
2518 /// not, generates an appropriate error message. Always returns Op.
2519 const char *VerifyScalarOrVectorOp(const char *Op, Type *OpTy) {
2520 if (IgnorePNaClABIChecks) return Op;
2521 if (PNaClABITypeChecker::isValidScalarType(OpTy)) {
2522 if (OpTy->isVoidTy())
2523 Errors() << Op << ": Type void not allowed\n";
2524 } else if (!PNaClABITypeChecker::isValidVectorType(OpTy)) {
2525 Errors() << Op << ": Expects scalar/vector type. Found: "
2526 << OpTy << "\n";
2527 }
2528 return Op;
2529 }
2530
2531 void VerifyIndexedVector(const char *Op, uint32_t VecValue,
2532 uint32_t IdxValue) {
2533 Type *VecType = GetValueType(VecValue);
2534 Type *IdxType = GetValueType(IdxValue);
2535 if (!IgnorePNaClABIChecks &&
2536 !PNaClABITypeChecker::isValidVectorType(VecType)){
2537 if (VecType->isVectorTy())
2538 Errors() << Op << ": Vector type " << *VecType << " not allowed\n";
2539 else
2540 Errors() << Op << ": Vector type expected. Found: " << *VecType << "\n";
2541 }
2542 // Note: This restriction appears to be LLVM specific.
2543 if (!IdxType->isIntegerTy(32)) {
2544 Errors() << Op << ": Index not i32. Found: " << *IdxType << "\n";
2545 }
2546 BitcodeId IdxId(GetBitcodeId(IdxValue));
2547 if (IdxId.GetKind() != 'c') {
2548 Errors() << Op << ": Vector index not constant: " << IdxId << "\n";
2549 // TODO(kschimpf): We should check that Idx is a constant with
2550 // valid access. However, we currently don't store constant
2551 // values, so it can't be tested.
2552 }
2553 }
2554
2555 /// Checks if block Value is a valid branch target for the current
2556 /// function block. If not, generates an appropriate error message.
2557 void VerifyBranchRange(uint64_t Value) {
2558 if (0 == Value || Value >= ExpectedNumBbs) {
2559 Errors() << "Branch " << BitcodeId('b', Value)
2560 << " out of range. Not in [1," << ExpectedNumBbs << "]\n";
2561 }
2562 }
2563
2564 /// Convert alignment exponent (i.e. power of two (or zero)) to the
2565 /// corresponding alignment to use. If alignment is too large, it generates
2566 /// an error message and returns 0.
2567 unsigned getAlignmentValue(uint64_t Exponent);
2568 };
2569
2570 NaClDisFunctionParser::NaClDisFunctionParser(
2571 unsigned BlockID,
2572 NaClDisBlockParser *EnclosingParser)
2573 : NaClDisBlockParser(BlockID, EnclosingParser),
2574 CurrentBbIndex(-1),
2575 ExpectedNumBbs(0),
2576 InstIsTerminating(false) {
2577 Context->ResetLocalCounters();
2578 if (Context->HasNextDefinedFunctionIndex()) {
2579 FcnId = Context->GetNextDefinedFunctionIndex();
2580 FcnTy = GetFunctionType(FcnId);
2581 } else {
2582 FcnId = 0;
2583 SmallVector<Type*, 8> Signature;
2584 FcnTy = FunctionType::get(GetVoidType(), Signature, 0);
2585 Errors() <<
2586 "No corresponding defining function address for function block.\n";
2587 return;
2588 }
2589 Context->IncNumDefinedFunctions();
2590
2591 // Now install parameters.
2592 for (size_t Index = 0; Index < FcnTy->getFunctionNumParams(); ++Index) {
2593 InstallParamType(FcnTy->getFunctionParamType(Index));
2594 }
2595 }
2596
2597 void NaClDisFunctionParser::PrintBlockHeader() {
2598 Tokens() << "function" << Space();
2599 BitcodeId FunctionId('f', FcnId);
2600 bool InvalidSignature = true; // until proven otherwise.
2601 if (Context->IsFunctionIntrinsic(FcnId))
2602 InvalidSignature = false;
2603 else if (IgnorePNaClABIChecks ||
2604 PNaClABITypeChecker::isValidFunctionType(FcnTy)) {
2605 InvalidSignature = false;
2606 }
2607 if (InvalidSignature) {
2608 Errors() << "Invalid type signature for "
2609 << BitcodeId('f', FcnId) << ": " << *FcnTy << "\n";
2610 }
2611 Tokens() << TokenizeFunctionSignature(FcnTy, &FunctionId)
2612 << Space() << OpenCurly()
2613 << Space() << Space() << "// BlockID = " << GetBlockID()
2614 << Endline();
2615 }
2616
2617 const char *NaClDisFunctionParser::GetBinop(uint32_t Opcode, Type *Ty) {
2618 Instruction::BinaryOps LLVMOpcode;
2619 if (!naclbitc::DecodeBinaryOpcode(Opcode, Ty, LLVMOpcode)) {
2620 Errors() << "Binary opcode not understood: " << Opcode << "\n";
2621 return "???";
2622 }
2623 switch (LLVMOpcode) {
2624 default:
2625 Errors() << "Binary opcode not understood: " << Opcode << "\n";
2626 return "???";
2627 case Instruction::Add:
2628 return VerifyIntArithmeticOp("add", Ty);
2629 case Instruction::FAdd:
2630 return VerifyFloatingOrVectorOp("fadd", Ty);
2631 case Instruction::Sub:
2632 return VerifyIntArithmeticOp("sub", Ty);
2633 case Instruction::FSub:
2634 return VerifyFloatingOrVectorOp("fsub", Ty);
2635 case Instruction::Mul:
2636 return VerifyIntArithmeticOp("mul", Ty);
2637 case Instruction::FMul:
2638 return VerifyFloatingOrVectorOp("fmul", Ty);
2639 case Instruction::UDiv:
2640 return VerifyIntArithmeticOp("udiv", Ty);
2641 case Instruction::SDiv:
2642 return VerifyIntArithmeticOp("sdiv", Ty);
2643 case Instruction::FDiv:
2644 return VerifyFloatingOrVectorOp("fdiv", Ty);
2645 case Instruction::URem:
2646 return VerifyIntArithmeticOp("urem", Ty);
2647 case Instruction::SRem:
2648 return VerifyIntArithmeticOp("srem", Ty);
2649 case Instruction::FRem:
2650 return VerifyFloatingOrVectorOp("frem", Ty);
2651 case Instruction::Shl:
2652 return VerifyIntArithmeticOp("shl", Ty);
2653 case Instruction::LShr:
2654 return VerifyIntArithmeticOp("lshr", Ty);
2655 case Instruction::AShr:
2656 return VerifyIntArithmeticOp("ashr", Ty);
2657 case Instruction::And:
2658 return VerifyIntegerOrVectorOp("and", Ty);
2659 case Instruction::Or:
2660 return VerifyIntegerOrVectorOp("or", Ty);
2661 case Instruction::Xor:
2662 return VerifyIntegerOrVectorOp("xor", Ty);
2663 }
2664 }
2665
2666 const char *NaClDisFunctionParser::GetCastOp(uint32_t Opcode,
2667 Type *FromType, Type *ToType) {
2668 Instruction::CastOps Cast;
2669 const char *CastName = "???";
2670 if (!naclbitc::DecodeCastOpcode(Opcode, Cast)) {
2671 Errors() << "Cast opcode not understood: " << Opcode << "\n";
2672 return CastName;
2673 }
2674 switch (Cast) {
2675 default:
2676 Errors() << "Cast opcode not understood: " << Opcode << "\n";
2677 return CastName;
2678 case Instruction::BitCast:
2679 CastName = "bitcast";
2680 break;
2681 case Instruction::Trunc:
2682 CastName = "trunc";
2683 break;
2684 case Instruction::ZExt:
2685 CastName = "zext";
2686 break;
2687 case Instruction::SExt:
2688 CastName = "sext";
2689 break;
2690 case Instruction::FPToUI:
2691 CastName = "fptoui";
2692 break;
2693 case Instruction::FPToSI:
2694 CastName = "fptosi";
2695 break;
2696 case Instruction::UIToFP:
2697 CastName = "uitofp";
2698 break;
2699 case Instruction::SIToFP:
2700 CastName = "sitofp";
2701 break;
2702 case Instruction::FPTrunc:
2703 CastName = "fptrunc";
2704 break;
2705 case Instruction::FPExt:
2706 CastName = "fpext";
2707 break;
2708 }
2709 if (!CastInst::castIsValid(Cast, FromType, ToType)) {
2710 Errors() << "Invalid cast '" << CastName << "'. Not defined on "
2711 << FromType << " to " << ToType << "\n";
2712 }
2713 return CastName;
2714 }
2715
2716 const char *NaClDisFunctionParser::GetIcmpPredicate(uint32_t Opcode) {
2717 CmpInst::Predicate Predicate;
2718 if (!naclbitc::DecodeIcmpPredicate(Opcode, Predicate)) {
2719 Errors() << "Icmp predicate not understood: " << Opcode << "\n";
2720 return "???";
2721 }
2722 switch (Predicate) {
2723 default:
2724 Errors() << "Icmp predicate not understood: " << Opcode << "\n";
2725 return "???";
2726 case CmpInst::ICMP_EQ:
2727 return "eq";
2728 case CmpInst::ICMP_NE:
2729 return "ne";
2730 case CmpInst::ICMP_UGT:
2731 return "ugt";
2732 case CmpInst::ICMP_UGE:
2733 return "uge";
2734 case CmpInst::ICMP_ULT:
2735 return "ult";
2736 case CmpInst::ICMP_ULE:
2737 return "ule";
2738 case CmpInst::ICMP_SGT:
2739 return "sgt";
2740 case CmpInst::ICMP_SGE:
2741 return "sge";
2742 case CmpInst::ICMP_SLT:
2743 return "slt";
2744 case CmpInst::ICMP_SLE:
2745 return "sle";
2746 }
2747 }
2748
2749 const char *NaClDisFunctionParser::GetFcmpPredicate(uint32_t Opcode) {
2750 CmpInst::Predicate Predicate;
2751 if (!naclbitc::DecodeFcmpPredicate(Opcode, Predicate)) {
2752 Errors() << "Fcmp predicate not understood: " << Opcode << "\n";
2753 return "???";
2754 }
2755 switch (Predicate) {
2756 default:
2757 Errors() << "Fcmp predicate not understood: " << Opcode << "\n";
2758 return "???";
2759 case CmpInst::FCMP_FALSE:
2760 return "false";
2761 case CmpInst::FCMP_OEQ:
2762 return "oeq";
2763 case CmpInst::FCMP_OGT:
2764 return "ogt";
2765 case CmpInst::FCMP_OGE:
2766 return "oge";
2767 case CmpInst::FCMP_OLT:
2768 return "olt";
2769 case CmpInst::FCMP_OLE:
2770 return "ole";
2771 case CmpInst::FCMP_ONE:
2772 return "one";
2773 case CmpInst::FCMP_ORD:
2774 return "ord";
2775 case CmpInst::FCMP_UNO:
2776 return "uno";
2777 case CmpInst::FCMP_UEQ:
2778 return "ueq";
2779 case CmpInst::FCMP_UGT:
2780 return "ugt";
2781 case CmpInst::FCMP_UGE:
2782 return "uge";
2783 case CmpInst::FCMP_ULT:
2784 return "ult";
2785 case CmpInst::FCMP_ULE:
2786 return "ule";
2787 case CmpInst::FCMP_UNE:
2788 return "une";
2789 case CmpInst::FCMP_TRUE:
2790 return "true";
2791 }
2792 }
2793
2794 namespace {
2795
2796 static const unsigned MaxAlignmentExponent = 29;
2797 static_assert(
2798 (1u << MaxAlignmentExponent) == Value::MaximumAlignment,
2799 "Inconsistency between Value.MaxAlignment and PNaCl alignment limit");
2800 }
2801
2802 unsigned NaClDisFunctionParser::getAlignmentValue(uint64_t Exponent) {
2803 if (Exponent > MaxAlignmentExponent + 1) {
2804 Errors() << "Alignment can't be greater than 2**" << MaxAlignmentExponent
2805 << ". Found: 2**" << (Exponent - 1) << "\n";
2806 return 0;
2807 }
2808 return (1 << static_cast<unsigned>(Exponent)) >> 1;
2809 }
2810
2811 bool NaClDisFunctionParser::ParseBlock(unsigned BlockID) {
2812 ObjDumpSetRecordBitAddress(GetBlock().GetStartBit());
2813 switch (BlockID) {
2814 case naclbitc::CONSTANTS_BLOCK_ID: {
2815 NaClDisConstantsParser Parser(BlockID, this);
2816 return Parser.ParseThisBlock();
2817 }
2818 case naclbitc::VALUE_SYMTAB_BLOCK_ID: {
2819 if (!PNaClAllowLocalSymbolTables) break;
2820 NaClDisValueSymtabParser Parser(BlockID, this);
2821 return Parser.ParseThisBlock();
2822 }
2823 default:
2824 break;
2825 }
2826 return NaClDisBlockParser::ParseBlock(BlockID);
2827 }
2828
2829 void NaClDisFunctionParser::ProcessRecord() {
2830 ObjDumpSetRecordBitAddress(Record.GetStartBit());
2831 const NaClBitcodeRecord::RecordVector Values = Record.GetValues();
2832 // Start by adding block label if previous instruction is terminating.
2833 if (InstIsTerminating) {
2834 InstIsTerminating = false;
2835 ++CurrentBbIndex;
2836 DecAssemblyIndent();
2837 Tokens() << BitcodeId('b', CurrentBbIndex) << ":" << Endline();
2838 ObjDumpFlush();
2839 IncAssemblyIndent();
2840 }
2841 switch (Record.GetCode()) {
2842 case naclbitc::FUNC_CODE_DECLAREBLOCKS:
2843 // DECLAREBLOCKS: [n]
2844 InstIsTerminating = true; // Force block label on first instruction.
2845 if (Values.size() != 1) {
2846 Errors() << "Function blocks record expects a size argument.\n";
2847 break;
2848 }
2849 ExpectedNumBbs = Values[0];
2850 if (ExpectedNumBbs == 0) {
2851 Errors() << "Functions must contain at least one block.\n";
2852 }
2853 Tokens() << "blocks" << Space() << ExpectedNumBbs << Semicolon();
2854 break;
2855 case naclbitc::FUNC_CODE_INST_BINOP: {
2856 // BINOP: [opval, opval, opcode]
2857 if (Values.size() != 3) {
2858 Errors() << "Binop record expects 3 arguments. Found: "
2859 << Values.size() << "\n";
2860 break;
2861 }
2862 uint32_t Op1 = RelativeToAbsId(Values[0]);
2863 uint32_t Op2 = RelativeToAbsId(Values[1]);
2864 Type *Type1 = GetValueType(Op1);
2865 Type *Type2 = GetValueType(Op2);
2866 if (Type1 != Type2) {
2867 Errors() << "Binop argument types differ: " << *Type1 << " and "
2868 << *Type2 << "\n";
2869 }
2870 const char *Binop = GetBinop(Values[2], Type1);
2871 Tokens() << NextInstId() << Space() << "=" << Space() << Binop << Space()
2872 << TokenizeType(Type1) << Space() << GetBitcodeId(Op1) << Comma()
2873 << Space() << GetBitcodeId(Op2) << Semicolon();
2874 InstallInstType(Type1);
2875 break;
2876 }
2877 case naclbitc::FUNC_CODE_INST_CAST: {
2878 // CAST: [opval, destty, castopc]
2879 if (Values.size() != 3) {
2880 Errors() << "Cast record expects 3 argments. Found: "
2881 << Values.size() << "\n";
2882 break;
2883 }
2884 uint32_t Op = RelativeToAbsId(Values[0]);
2885 Type *FromType = GetValueType(Op);
2886 Type *ToType = GetType(Values[1]);
2887 const char *CastOp = GetCastOp(Values[2], FromType, ToType);
2888 Tokens() << NextInstId() << Space() << "=" << Space() << CastOp << Space()
2889 << TokenizeType(FromType) << Space() << GetBitcodeId(Op)
2890 << Space() << "to" << Space() << TokenizeType(ToType)
2891 << Semicolon();
2892 InstallInstType(ToType);
2893 break;
2894 }
2895 case naclbitc::FUNC_CODE_INST_RET: {
2896 // RET: [opval?]
2897 InstIsTerminating = true;
2898 Tokens() << "ret" << Space();
2899 switch (Values.size()) {
2900 default:
2901 Errors() << "Function return record expects an optional return argument. "
2902 << "Found: " << Values.size() << " arguments\n";
2903 break;
2904 case 0:
2905 Tokens() << "void";
2906 break;
2907 case 1: {
2908 uint32_t Op = RelativeToAbsId(Values[0]);
2909 Tokens() << TokenizeType(GetValueType(Op)) << Space()<< GetBitcodeId(Op);
2910 break;
2911 }
2912 }
2913 Tokens() << Semicolon();
2914 break;
2915 }
2916 case naclbitc::FUNC_CODE_INST_BR: {
2917 // BR: [bb#, bb#, opval] or [bb#]
2918 InstIsTerminating = true;
2919 if (Values.size() != 1 && Values.size() != 3) {
2920 Errors() << "Function branch record expects 1 or 3 arguments. Found: "
2921 << Values.size() << "\n";
2922 break;
2923 }
2924 Tokens() << "br" << Space();
2925 if (Values.size() == 3) {
2926 uint32_t OpIndex = RelativeToAbsId(Values[2]);
2927 if (GetValueType(OpIndex) != GetComparisonType())
2928 Errors() << "Branch condition not i1\n";
2929 Tokens() << StartCluster() << "i1" << Space() << GetBitcodeId(OpIndex)
2930 << Comma() << FinishCluster() << Space();
2931 }
2932 VerifyBranchRange(Values[0]);
2933 Tokens() << StartCluster() << "label" << Space()
2934 << BitcodeId('b', Values[0]);
2935 if (Values.size() == 3) {
2936 VerifyBranchRange(Values[1]);
2937 Tokens() << Comma() << FinishCluster() << Space()
2938 << StartCluster() << "label" << Space()
2939 << BitcodeId('b', Values[1]);
2940 }
2941 Tokens() << Semicolon() << FinishCluster();
2942 break;
2943 }
2944 case naclbitc::FUNC_CODE_INST_SWITCH: {
2945 // SWITCH: [opty, op, bb#, n, (1, 1, int, bb#)*]
2946 InstIsTerminating = true;
2947 if (Values.size() < 4) {
2948 Errors()
2949 << "Function switch record expects at least 4 arguments. Found: "
2950 << Values.size() << "\n";
2951 break;
2952 }
2953 Type *OpType = GetType(Values[0]);
2954 uint32_t CondId = RelativeToAbsId(Values[1]);
2955 Type *CondType = GetValueType(CondId);
2956 if (OpType != CondType)
2957 Errors() << "Specified select type " << *OpType << " but found: "
2958 << *CondType << "\n";
2959 if (!IgnorePNaClABIChecks &&
2960 !PNaClABITypeChecker::isValidSwitchConditionType(CondType)) {
2961 Errors() << PNaClABITypeChecker::ExpectedSwitchConditionType(CondType)
2962 << "\n";
2963 }
2964 uint32_t DefaultBb = Values[2];
2965 unsigned NumCases = Values[3];
2966 VerifyBranchRange(DefaultBb);
2967 Tokens() << "switch" << Space() << StartCluster() << StartCluster()
2968 << TokenizeType(OpType) << Space() << GetBitcodeId(CondId)
2969 << FinishCluster() << Space() << "{" << FinishCluster()
2970 << Endline();
2971 IncAssemblyIndent();
2972 Tokens() << StartCluster() << "default" << ":" << Space()
2973 << FinishCluster() << StartCluster() << "br" << Space() << "label"
2974 << Space() << BitcodeId('b', DefaultBb) << Semicolon()
2975 << FinishCluster() << Endline();
2976 unsigned CurIdx = 4;
2977 for (unsigned i = 0; i < NumCases; ++i) {
2978 unsigned NumItems = Values[CurIdx++];
2979 bool IsSingleNumber = Values[CurIdx++];
2980 if (NumItems != 1 || !IsSingleNumber) {
2981 Errors() << "Case ranges are not supported in PNaCl\n";
2982 break;
2983 }
2984 SignRotatedInt CaseValue(Values[CurIdx++], OpType);
2985 // TODO(kschimpf) Check if CaseValue possible based on OpType.
2986 uint64_t Label = Values[CurIdx++];
2987 VerifyBranchRange(Label);
2988 Tokens() << StartCluster() << TokenizeType(OpType) << Space()
2989 << CaseValue << ":" << Space() << FinishCluster()
2990 << StartCluster() << "br" << Space() << "label" << Space()
2991 << BitcodeId('b', Label) << Semicolon() << FinishCluster()
2992 << Endline();
2993 }
2994 DecAssemblyIndent();
2995 Tokens() << "}";
2996 break;
2997 }
2998 case naclbitc::FUNC_CODE_INST_UNREACHABLE:
2999 // UNREACHABLE
3000 InstIsTerminating = true;
3001 if (!Values.empty()) {
3002 Errors() << "Function unreachable record expects no arguments. Found: "
3003 << Values.size() << "\n";
3004 }
3005 Tokens() << "unreachable" << Semicolon();
3006 break;
3007 case naclbitc::FUNC_CODE_INST_PHI: {
3008 // PHI: [ty, (val0, bb0)*]
3009 if (Values.size() < 3) {
3010 Errors() << "Function phi record expects at least 3 arguments. Found: "
3011 << Values.size() << "\n";
3012 break;
3013 } else if (Values.size() % 2 == 0) {
3014 Errors()
3015 << "Function phi records should have an odd number of arguments. "
3016 << "Found: " << Values.size() << "\n";
3017 }
3018 Type* OpType = GetType(Values[0]);
3019 Tokens() << NextInstId() << Space() << "=" << StartCluster() << Space()
3020 << "phi" << Space() << TokenizeType(OpType);
3021 for (size_t i = 1; i < Values.size(); i += 2) {
3022 if (i > 1) Tokens() << Comma();
3023 uint32_t Index = RelativeToAbsId(NaClDecodeSignRotatedValue(Values[i]));
3024 Tokens() << FinishCluster() << Space() << StartCluster() << OpenSquare()
3025 << GetBitcodeId(Index) << Comma() << Space()
3026 << BitcodeId('b', Values[i+1]) << CloseSquare();
3027 }
3028 Tokens() << Semicolon() << FinishCluster();
3029 InstallInstType(OpType);
3030 break;
3031 };
3032 case naclbitc::FUNC_CODE_INST_ALLOCA: {
3033 // ALLOCA: [size, align]
3034 if (Values.size() != 2) {
3035 Errors() << "Function alloca record expects 2 arguments. Found: "
3036 << Values.size() << "\n";
3037 break;
3038 }
3039 uint32_t SizeOp = RelativeToAbsId(Values[0]);
3040 Type* SizeType = GetValueType(SizeOp);
3041 BitcodeId SizeId(GetBitcodeId(SizeOp));
3042 unsigned Alignment = getAlignmentValue(Values[1]);
3043 if (!IgnorePNaClABIChecks && !PNaClABIProps::isAllocaSizeType(SizeType))
3044 Errors() << PNaClABIProps::ExpectedAllocaSizeType() << "\n";
3045 // TODO(kschimpf) Are there any constraints on alignment?
3046 Tokens() << NextInstId() << Space() << "=" << Space() << StartCluster()
3047 << "alloca" << Space() << "i8" << Comma() << FinishCluster()
3048 << Space() << StartCluster() << TokenizeType(SizeType) << Space()
3049 << SizeId << Comma() << FinishCluster() << Space()
3050 << StartCluster() <<"align" << Space() << Alignment << Semicolon()
3051 << FinishCluster();
3052 InstallInstType(GetPointerType());
3053 break;
3054 }
3055 case naclbitc::FUNC_CODE_INST_LOAD: {
3056 // LOAD: [op, align, ty]
3057 if (Values.size() != 3) {
3058 Errors() << "Function load record expects 3 arguments. Found: "
3059 << Values.size() << "\n";
3060 break;
3061 }
3062 unsigned Alignment = getAlignmentValue(Values[1]);
3063 Type *LoadType = GetType(Values[2]);
3064 VerifyScalarOrVectorOp("load", LoadType);
3065 Context->VerifyMemoryAccessAlignment("load", LoadType, Alignment);
3066 Tokens() << NextInstId() << Space() << "=" << Space() << StartCluster()
3067 << "load" << Space() << TokenizeType(LoadType) << "*" << Space()
3068 << GetBitcodeId(RelativeToAbsId(Values[0])) << Comma()
3069 << FinishCluster() << Space() << StartCluster()
3070 << "align" << Space() << Alignment << Semicolon()
3071 << FinishCluster();
3072 InstallInstType(LoadType);
3073 break;
3074 }
3075 case naclbitc::FUNC_CODE_INST_STORE: {
3076 // STORE: [ptr, val, align]
3077 if (Values.size() != 3) {
3078 Errors() << "Function store record expects 3 arguments. Found: "
3079 << Values.size() << "\n";
3080 break;
3081 }
3082 unsigned Alignment = getAlignmentValue(Values[2]);
3083 uint32_t Val = RelativeToAbsId(Values[1]);
3084 Type *ValType = GetValueType(Val);
3085 VerifyScalarOrVectorOp("store", ValType);
3086 Context->VerifyMemoryAccessAlignment("store", ValType, Alignment);
3087 Tokens() << StartCluster() << "store" << Space() << TokenizeType(ValType)
3088 << Space() << GetBitcodeId(Val) << Comma() << FinishCluster()
3089 << Space() << StartCluster() << TokenizeType(ValType) << "*"
3090 << Space() << GetBitcodeId(RelativeToAbsId(Values[0])) << Comma()
3091 << FinishCluster() << Space() << StartCluster() << "align"
3092 << Space() << Alignment << Semicolon() << FinishCluster();
3093 break;
3094 }
3095 case naclbitc::FUNC_CODE_INST_CMP2: {
3096 // CMP2: [opval, opval, pred]
3097 if (Values.size() != 3) {
3098 Errors() << "Function compare record expects 3 arguments. Found: "
3099 << Values.size() << "\n";
3100 break;
3101 }
3102 uint32_t Arg1 = RelativeToAbsId(Values[0]);
3103 uint32_t Arg2 = RelativeToAbsId(Values[1]);
3104 Type *Arg1Type = GetValueType(Arg1);
3105 Type *Arg2Type = GetValueType(Arg2);
3106 if (Arg1Type != Arg2Type) {
3107 Errors() << "Arguments not of same type: " << *Arg1Type << " and "
3108 << *Arg2Type << "\n";
3109 }
3110 const char *Pred = "???";
3111 Tokens() << NextInstId() << Space() << "=" << Space() << StartCluster();
3112 Type* BaseType = UnderlyingType(Arg1Type);
3113 if (BaseType->isIntegerTy()) {
3114 Pred = GetIcmpPredicate(Values[2]);
3115 Tokens() << "icmp" << Space() << Pred;
3116 } else if (isFloatingType(BaseType)) {
3117 Pred = GetFcmpPredicate(Values[2]);
3118 Tokens() << "fcmp" << Space() << Pred;
3119 } else {
3120 Errors() << "Compare not on integer/float type. Found: "
3121 << *Arg1Type << "\n";
3122 Tokens() << "cmp" << Space() << "???" "(" << Values[2] << ")";
3123 }
3124 Tokens() << FinishCluster() << Space() << StartCluster()
3125 << TokenizeType(Arg1Type) << Space () << GetBitcodeId(Arg1)
3126 << Comma() << FinishCluster() << Space() << StartCluster()
3127 << GetBitcodeId(Arg2) << Semicolon() << FinishCluster();
3128 Type *ResultType = GetComparisonType();
3129 if (Arg1Type->isVectorTy()) {
3130 ResultType = VectorType::get(ResultType,
3131 Arg1Type->getVectorNumElements());
3132 }
3133 InstallInstType(ResultType);
3134 break;
3135 }
3136 case naclbitc::FUNC_CODE_INST_VSELECT: {
3137 // VSELECT: [opval, opval, pred]
3138 if (Values.size() != 3) {
3139 Errors() << "Select record expects 3 arguments. Found: "
3140 << Values.size() << "\n";
3141 break;
3142 }
3143 uint32_t CondValue = RelativeToAbsId(Values[2]);
3144 uint32_t ThenValue = RelativeToAbsId(Values[0]);
3145 uint32_t ElseValue = RelativeToAbsId(Values[1]);
3146 Type *CondType = GetValueType(CondValue);
3147 Type *ThenType = GetValueType(ThenValue);
3148 Type *ElseType = GetValueType(ElseValue);
3149 if (ThenType != ElseType) {
3150 Errors() << "Selected arguments not of same type: "
3151 << *ThenType << " and " << *ElseType << "\n";
3152 }
3153 Type *BaseType = UnderlyingType(ThenType);
3154 if (!(BaseType->isIntegerTy() || isFloatingType(BaseType))) {
3155 Errors() << "Select arguments not integer/float. Found: " << *ThenType;
3156 }
3157 Tokens() << NextInstId() << Space() << "=" << Space() << StartCluster()
3158 << "select" << Space() << TokenizeType(CondType) << Space()
3159 << GetBitcodeId(CondValue) << Comma() << FinishCluster() << Space()
3160 << StartCluster() << TokenizeType(ThenType) << Space()
3161 << GetBitcodeId(ThenValue) << Comma() << FinishCluster() << Space()
3162 << StartCluster() << TokenizeType(ElseType) << Space()
3163 << GetBitcodeId(ElseValue) << Semicolon()
3164 << FinishCluster();
3165 InstallInstType(ThenType);
3166 break;
3167 }
3168 case naclbitc::FUNC_CODE_INST_EXTRACTELT: {
3169 // EXTRACTELT: [opval, opval]
3170 if (Values.size() != 2) {
3171 Errors() << "Extract element record expects 2 arguments. Found: "
3172 << Values.size() << "\n";
3173 break;
3174 }
3175 uint32_t VecValue = RelativeToAbsId(Values[0]);
3176 uint32_t IdxValue = RelativeToAbsId(Values[1]);
3177 VerifyIndexedVector("extractelement", VecValue, IdxValue);
3178 Type *VecType = GetValueType(VecValue);
3179 Type *IdxType = GetValueType(IdxValue);
3180 Tokens() << NextInstId() << Space() << " = " << Space() << StartCluster()
3181 << "extractelement" << Space() << TokenizeType(VecType) << Space()
3182 << GetBitcodeId(VecValue) << Comma() << FinishCluster() << Space()
3183 << StartCluster() << TokenizeType(IdxType) << Space()
3184 << GetBitcodeId(IdxValue) << Semicolon() << FinishCluster();
3185 InstallInstType(UnderlyingType(VecType));
3186 break;
3187 }
3188 case naclbitc::FUNC_CODE_INST_INSERTELT: {
3189 // INSERTELT: [opval, opval, opval]
3190 uint32_t VecValue = RelativeToAbsId(Values[0]);
3191 uint32_t EltValue = RelativeToAbsId(Values[1]);
3192 uint32_t IdxValue = RelativeToAbsId(Values[2]);
3193 VerifyIndexedVector("insertelement", VecValue, IdxValue);
3194 Type *VecType = GetValueType(VecValue);
3195 Type *EltType = GetValueType(EltValue);
3196 Type *IdxType = GetValueType(IdxValue);
3197 if (EltType != UnderlyingType(VecType)) {
3198 Errors() << "insertelement: Illegal element type " << *EltType
3199 << ". Expected: " << *UnderlyingType(VecType) << "\n";
3200 }
3201 Tokens() << NextInstId() << Space() << " = " << Space() << StartCluster()
3202 << "insertelement" << Space() << TokenizeType(VecType) << Space()
3203 << GetBitcodeId(VecValue) << Comma() << FinishCluster() << Space()
3204 << StartCluster() << TokenizeType(EltType) << Space()
3205 << GetBitcodeId(EltValue) << Comma() << FinishCluster() << Space()
3206 << StartCluster() << TokenizeType(IdxType) << Space()
3207 << GetBitcodeId(IdxValue) << Semicolon() << FinishCluster();
3208 InstallInstType(VecType);
3209 break;
3210 }
3211 case naclbitc::FUNC_CODE_INST_CALL:
3212 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: {
3213 // CALL: [cc, fnid, arg0, arg1...]
3214 // CALL_INDIRECT: [cc, fnid, returnty, args...]
3215 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) {
3216 if (Values.size() < 2) {
3217 Errors() << "Call record expects at least 2 arguments. Found: "
3218 << Values.size() << "\n";
3219 break;
3220 }
3221 } else if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL_INDIRECT) {
3222 if (Values.size() < 3) {
3223 Errors() << "Call indirect record expects at least 3 arguments. Found: "
3224 << Values.size() << "\n";
3225 break;
3226 }
3227 }
3228 unsigned IsTailCall = (Values[0] & 0x1);
3229 CallingConv::ID CallingConv;
3230 uint32_t FcnId = RelativeToAbsId(Values[1]);
3231 if (!naclbitc::DecodeCallingConv(Values[0]>>1, CallingConv))
3232 Errors() << "Call unknown calling convention:" << (Values[0]>>1) << "\n";
3233 if (!IgnorePNaClABIChecks &&
3234 !PNaClABIProps::isValidCallingConv(CallingConv)) {
3235 Errors() << "Call uses disallowed calling convention: "
3236 << PNaClABIProps::CallingConvName(CallingConv) << "("
3237 << CallingConv << ")\n";
3238 }
3239 FunctionType *FcnType = 0;
3240 Type *ReturnType = 0;
3241 size_t ArgIndex = 2;
3242 // Flag defining if type checking should be done on argument/return
3243 // types.
3244 bool CheckArgRetTypes = true;
3245 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) {
3246 Type *FcnTy = GetFunctionValueType(FcnId);
3247 if (FunctionType *FcnTyp = dyn_cast<FunctionType>(FcnTy)) {
3248 // TODO(kschimpf) Add back signature checking once we know how
3249 // to handle intrinsics (which can violate general signature
3250 // rules).
3251 CheckArgRetTypes = false;
3252 FcnType = FcnTyp;
3253 ReturnType = FcnType->getReturnType();
3254 } else {
3255 Errors() << "Invalid function signature: " << *FcnTy << "\n";
3256 ReturnType = GetVoidType();
3257 }
3258 } else {
3259 ReturnType = GetType(Values[2]);
3260 ArgIndex = 3;
3261 }
3262 if (!ReturnType->isVoidTy()) {
3263 Tokens() << NextInstId() << Space() << "=" << Space();
3264 }
3265 if (IsTailCall) {
3266 Tokens() << "tail" << Space();
3267 }
3268 if (CheckArgRetTypes &&
3269 !IgnorePNaClABIChecks &&
3270 !PNaClABITypeChecker::isValidParamType(ReturnType)) {
3271 Errors() << "Invalid return type: " << *ReturnType << "\n";
3272 }
3273 Tokens() << "call" << Space();
3274 if (CallingConv != CallingConv::C) {
3275 Tokens() << PNaClABIProps::CallingConvName(CallingConv) << Space();
3276 }
3277 Tokens() << TokenizeType(ReturnType) << Space()
3278 << StartCluster() << GetBitcodeId(FcnId) << OpenParen()
3279 << StartCluster();
3280 unsigned ParamIndex = 0;
3281 unsigned NumParams = Values.size() + 1 - ArgIndex;
3282 for (size_t i = ArgIndex; i < Values.size(); ++i, ++ParamIndex) {
3283 uint32_t ParamId = RelativeToAbsId(Values[i]);
3284 Type *ParamType = GetValueType(ParamId);
3285 if (CheckArgRetTypes &&
3286 !IgnorePNaClABIChecks &&
3287 !PNaClABITypeChecker::isValidParamType(ParamType)) {
3288 Errors() << "invalid type for parameter " << i << ": "
3289 << *ParamType << "\n";
3290 }
3291 if (FcnType) {
3292 if (ParamIndex < FcnType->getNumParams()) {
3293 Type *ExpectedType = FcnType->getParamType(ParamIndex);
3294 if (ParamType != ExpectedType) {
3295 Warnings() << "Parameter " << (ParamIndex + 1) << " mismatch: "
3296 << *ParamType << " and " << *ExpectedType << "\n";
3297 }
3298 }
3299 else if (ParamIndex == FcnType->getNumParams()) {
3300 Warnings() << "Call expects " << FcnType->getNumParams()
3301 << " arguments. Got: " << NumParams << "\n";
3302 }
3303 }
3304 if (i > ArgIndex) {
3305 Tokens() << Comma() << FinishCluster() << Space() << StartCluster();
3306 }
3307 Tokens() << TokenizeType(ParamType) << Space() << GetBitcodeId(ParamId);
3308 }
3309 Tokens() << CloseParen() << Semicolon() << FinishCluster()
3310 << FinishCluster();
3311 if (!ReturnType->isVoidTy()) InstallInstType(ReturnType);
3312 break;
3313 }
3314 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: {
3315 // TYPE: [opval, ty]
3316 if (Values.size() != 2) {
3317 Errors() << "Forward declare record expects 2 arguments. Found: "
3318 << Values.size() << "\n";
3319 break;
3320 }
3321 Type *OpType = GetType(Values[1]);
3322 Tokens() << "declare" << Space() << StartCluster()
3323 << TokenizeType(OpType) << Space()
3324 << GetBitcodeId(Values[0]) << Semicolon() << FinishCluster();
3325 InstallInstType(OpType, AbsToValuedInstId(Values[0]));
3326 break;
3327 }
3328 default:
3329 Errors() << "Unknown record found in module block.\n";
3330 break;
3331 }
3332 Tokens() << TokenizeAbbrevIndex() << Endline();
3333 ObjDumpWrite(Record.GetStartBit(), Record);
3334 }
3335
3336 /// Parses and disassembles the module block.
3337 class NaClDisModuleParser : public NaClDisBlockParser {
3338 public:
3339 NaClDisModuleParser(unsigned BlockID, NaClDisTopLevelParser *Context)
3340 : NaClDisBlockParser(BlockID, Context) {
3341 }
3342
3343 ~NaClDisModuleParser() override;
3344
3345 bool ParseBlock(unsigned BlockID) override;
3346
3347 void PrintBlockHeader() override;
3348
3349 void ProcessRecord() override;
3350 };
3351
3352 NaClDisModuleParser::~NaClDisModuleParser() {
3353 // Note: Since we can't check type signatures of most functions till
3354 // we know intrinsic names, and that isn't known until the (optional)
3355 // valuesymtab block is parsed, the only reasonable spot to check
3356 // function signatures is once the module block has been processed.
3357 unsigned NextFcnDefinedId = 0;
3358 for (unsigned i = 0, e = GetNumFunctions(); i < e; ++i) {
3359 // Note: If the type of a function isn't a function type, that
3360 // was checked in method ProcessRecord.
3361 // Note: If the function was defined, the type was checked in
3362 // NaClDisFunctionParser::PrintBlockHeader.
3363 if (Context->HasDefinedFunctionIndex(NextFcnDefinedId)
3364 && i == Context->GetDefinedFunctionIndex(NextFcnDefinedId)) {
3365 ++NextFcnDefinedId;
3366 continue;
3367 }
3368 if (FunctionType *FcnTy = dyn_cast<FunctionType>(GetFunctionValueType(i))) {
3369 if (!Context->IsFunctionIntrinsic(i) &&
3370 !IgnorePNaClABIChecks &&
3371 !PNaClABITypeChecker::isValidFunctionType(FcnTy)) {
3372 Context->SetRecordAddressToFunctionIdAddress(i);
3373 Errors() << "Invalid type signature for "
3374 << BitcodeId('f', i) << ": " << *FcnTy << "\n";
3375 }
3376 }
3377 }
3378 }
3379
3380 bool NaClDisModuleParser::ParseBlock(unsigned BlockID) {
3381 ObjDumpSetRecordBitAddress(GetBlock().GetStartBit());
3382 switch (BlockID) {
3383 case naclbitc::BLOCKINFO_BLOCK_ID: {
3384 NaClDisBlockInfoParser Parser(BlockID, this);
3385 return Parser.ParseThisBlock();
3386 }
3387 case naclbitc::TYPE_BLOCK_ID_NEW: {
3388 NaClDisTypesParser Parser(BlockID, this);
3389 return Parser.ParseThisBlock();
3390 }
3391 case naclbitc::GLOBALVAR_BLOCK_ID: {
3392 NaClDisGlobalsParser Parser(BlockID, this);
3393 return Parser.ParseThisBlock();
3394 }
3395 case naclbitc::VALUE_SYMTAB_BLOCK_ID: {
3396 NaClDisValueSymtabParser Parser(BlockID, this);
3397 return Parser.ParseThisBlock();
3398 }
3399 case naclbitc::FUNCTION_BLOCK_ID: {
3400 NaClDisFunctionParser Parser(BlockID, this);
3401 return Parser.ParseThisBlock();
3402 }
3403 default:
3404 return NaClDisBlockParser::ParseBlock(BlockID);
3405 }
3406 }
3407
3408 void NaClDisModuleParser::PrintBlockHeader() {
3409 Tokens() << "module" << Space() << OpenCurly()
3410 << Space() << Space() << "// BlockID = " << GetBlockID()
3411 << Endline();
3412 }
3413
3414 void NaClDisModuleParser::ProcessRecord() {
3415 ObjDumpSetRecordBitAddress(Record.GetStartBit());
3416 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
3417 switch (Record.GetCode()) {
3418 case naclbitc::MODULE_CODE_VERSION:
3419 // [version#]
3420 if (Values.size() != 1) {
3421 Errors() << "Version record should have one argument. Found: "
3422 << Values.size() << "\n";
3423 break;
3424 }
3425 Tokens() << "version" << Space() << Values[0] << Semicolon()
3426 << TokenizeAbbrevIndex() << Endline();
3427 break;
3428 case naclbitc::MODULE_CODE_FUNCTION: {
3429 // [type, callingconv, isproto, linkage]
3430 if (Values.size() != 4) {
3431 Errors() << "Function record should have 4 arguments. Found: "
3432 << Values.size() << "\n";
3433 break;
3434 }
3435 bool IsProto = (Values[2] != 0);
3436 Tokens() << StartCluster() << (IsProto ? "declare" : "define");
3437 uint32_t FcnId = GetNumFunctions();
3438 BitcodeId FcnName('f', FcnId);
3439 std::string FcnStrName(FcnName.GetName());
3440 GlobalValue::LinkageTypes Linkage;
3441 if (!naclbitc::DecodeLinkage(Values[3], Linkage)) {
3442 Errors() << "Unknown linkage value: " << Values[3] << "\n";
3443 } else {
3444 if (!IgnorePNaClABIChecks &&
3445 !PNaClABIProps::isValidGlobalLinkage(Linkage)) {
3446 Errors() << "Disallowed linkage type: "
3447 << PNaClABIProps::LinkageName(Linkage) << "\n";
3448 }
3449 Tokens() << Space() << PNaClABIProps::LinkageName(Linkage);
3450 }
3451 CallingConv::ID CallingConv;
3452 if (!naclbitc::DecodeCallingConv(Values[1], CallingConv)) {
3453 Errors() << "Unknown calling convention value: " << Values[1] << "\n";
3454 } else if (PNaClABIProps::isValidCallingConv(CallingConv)) {
3455 if (CallingConv != CallingConv::C) {
3456 Tokens() << Space() << PNaClABIProps::CallingConvName(CallingConv);
3457 }
3458 } else {
3459 Errors() << "Function " << FcnStrName
3460 << " has disallowed calling convention: "
3461 << PNaClABIProps::CallingConvName(CallingConv)
3462 << " (" << CallingConv << ")\n";
3463 }
3464 Tokens() << FinishCluster() << Space() << StartCluster();
3465 Type *FcnType = GetType(Values[0]);
3466 FunctionType *FunctionTy = dyn_cast<FunctionType>(FcnType);
3467 if (FunctionTy) {
3468 Tokens() << TokenizeFunctionType(FunctionTy, &FcnName);
3469 } else {
3470 BitcodeId FcnTypeId('t', Values[0]);
3471 Errors() << "Not function type: " << FcnTypeId << " = "
3472 << *FcnType << "\n";
3473 Tokens() << "???";
3474 SmallVector<Type*, 1> Signature;
3475 FunctionTy = FunctionType::get(GetVoidType(), Signature, 0);
3476 }
3477 Tokens() << Semicolon() << FinishCluster() << TokenizeAbbrevIndex()
3478 << Endline();
3479 InstallFunctionType(FunctionTy);
3480 if (!IsProto) InstallDefinedFunction(FcnId);
3481 break;
3482 }
3483 default:
3484 Errors() << "Unknown record found in module block\n";
3485 break;
3486 }
3487 ObjDumpWrite(Record.GetStartBit(), Record);
3488 }
3489
3490 bool NaClDisTopLevelParser::ParseBlock(unsigned BlockID) {
3491 // Before parsing top-level module block. Describe header.
3492 NaClBitcodeRecordData Record;
3493 size_t HeaderSize = Header.getHeaderSize();
3494 Record.Code = naclbitc::BLK_CODE_HEADER;
3495 for (size_t i = 0; i < HeaderSize; ++i) {
3496 Record.Values.push_back(HeaderBuffer[i]);
3497 }
3498 if (ObjDump.GetDumpRecords() && ObjDump.GetDumpAssembly()) {
3499 if (HeaderSize >= 4) {
3500 const NaClRecordVector &Values = Record.Values;
3501 Tokens() << "Magic" << Space() << "Number" << Colon()
3502 << Space() << StartCluster() << StartCluster() << "'"
3503 << (char) Values[0] << (char) Values[1]
3504 << (char) Values[2] << (char) Values[3]
3505 << "'" << FinishCluster() << Space()
3506 << StartCluster() << OpenParen()
3507 << Values[0] << Comma() << Space()
3508 << Values[1] << Comma() << Space()
3509 << Values[2] << Comma() << Space()
3510 << Values[3] << CloseParen() << FinishCluster()
3511 << FinishCluster() << Endline();
3512 }
3513 // Show interpretation of header as assembly.
3514 for (size_t i = 0; i < Header.NumberFields(); ++i) {
3515 Tokens() << Header.GetField(i)->Contents() << Endline();
3516 }
3517 }
3518 ObjDump.Write(0, Record);
3519 ObjDump.SetStartOffset(HeaderSize * 8);
3520
3521 if (BlockID != naclbitc::MODULE_BLOCK_ID)
3522 return Error("Module block expected at top-level, but not found");
3523
3524 // Now parse a module block.
3525 NaClDisModuleParser Parser(BlockID, this);
3526 return Parser.ParseThisBlock();
3527 }
3528
3529 }
3530
3531 namespace llvm {
3532
3533 bool NaClObjDump(MemoryBuffer *MemBuf, raw_ostream &Output,
3534 bool NoRecords, bool NoAssembly) {
3535 // Create objects needed to run parser.
3536 naclbitc::ObjDumpStream ObjDump(Output, !NoRecords, !NoAssembly);
3537
3538 if (MemBuf->getBufferSize() % 4 != 0) {
3539 ObjDump.Error()
3540 << "Bitcode stream should be a multiple of 4 bytes in length.\n";
3541 return true;
3542 }
3543
3544 const unsigned char *BufPtr = (const unsigned char *)MemBuf->getBufferStart();
3545 const unsigned char *EndBufPtr = BufPtr+MemBuf->getBufferSize();
3546 const unsigned char *HeaderPtr = BufPtr;
3547
3548 // Read header and verify it is good.
3549 NaClBitcodeHeader Header;
3550 if (Header.Read(BufPtr, EndBufPtr) || !Header.IsSupported()) {
3551 ObjDump.Error() << "Invalid PNaCl bitcode header.\n";
3552 return true;
3553 }
3554
3555 // Create a bitstream reader to read the bitcode file.
3556 NaClBitstreamReader InputStreamFile(BufPtr, EndBufPtr);
3557 NaClBitstreamCursor InputStream(InputStreamFile);
3558
3559 // Parse the the bitcode file.
3560 ::NaClDisTopLevelParser Parser(Header, HeaderPtr, InputStream, ObjDump);
3561 int NumBlocksRead = 0;
3562 bool ErrorsFound = false;
3563 while (!InputStream.AtEndOfStream()) {
3564 ++NumBlocksRead;
3565 if (Parser.Parse()) ErrorsFound = true;
3566 }
3567
3568 if (NumBlocksRead != 1) {
3569 ObjDump.Error() << "Expected 1 top level block in bitcode: Found:"
3570 << NumBlocksRead << "\n";
3571 ErrorsFound = true;
3572 }
3573
3574 ObjDump.Flush();
3575 return ErrorsFound || Parser.GetNumErrors() > 0;
3576 }
3577
3578 }
OLDNEW
« no previous file with comments | « lib/Bitcode/NaCl/Analysis/NaClCompressCodeDist.cpp ('k') | lib/Bitcode/NaCl/Analysis/NaClObjDumpStream.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698