Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===-- NaClObjDump.cpp - Dump PNaCl bitcode contents ---------------------===// | 1 //===-- NaClObjDump.cpp - Dump PNaCl bitcode contents ---------------------===// |
| 2 // | 2 // |
| 3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 | 9 |
| 10 #include "llvm/ADT/STLExtras.h" | 10 #include "llvm/ADT/STLExtras.h" |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 32 namespace { | 32 namespace { |
| 33 | 33 |
| 34 using namespace llvm; | 34 using namespace llvm; |
| 35 | 35 |
| 36 static cl::opt<bool> | 36 static cl::opt<bool> |
| 37 ReportWarningsAsErrors( | 37 ReportWarningsAsErrors( |
| 38 "Werror", | 38 "Werror", |
| 39 cl::desc("Report warnings as errors."), | 39 cl::desc("Report warnings as errors."), |
| 40 cl::init(false)); | 40 cl::init(false)); |
| 41 | 41 |
| 42 static cl::opt<bool> | |
| 43 NoDumpFinalizeRules( | |
|
jvoung (off chromium)
2014/12/17 23:36:38
I'm a bit confused about where this is used.
Karl
2014/12/17 23:53:00
One would use this as a command-line argument on a
jvoung (off chromium)
2014/12/18 00:05:40
Hmm but does tool work with non-finalized pexes?
Karl
2014/12/18 16:56:05
You are correct that we require the overall struct
jvoung (off chromium)
2014/12/18 17:10:22
Okay, I see. Yes it's very easy to do a hand-writt
jvoung (off chromium)
2014/12/18 17:18:56
Another way to look at it is the load/store align
Karl
2014/12/18 18:56:19
Renamed to IgnorePNaClABIChecks (cl flag "-ignore-
| |
| 44 "no-pnacl-dump-finalize-rules", | |
| 45 cl::desc("Don't dump finalized-only PNaCl bitcode violations"), | |
| 46 cl::init(false)); | |
| 47 | |
| 42 /// Class to handle sign rotations in a human readable form. That is, | 48 /// Class to handle sign rotations in a human readable form. That is, |
| 43 /// the sign is in the low bit. The two special cases are: | 49 /// the sign is in the low bit. The two special cases are: |
| 44 /// 1) -1 is true for i1. | 50 /// 1) -1 is true for i1. |
| 45 /// 2) The representation allows -0 (which is different than 0). | 51 /// 2) The representation allows -0 (which is different than 0). |
| 46 class SignRotatedInt { | 52 class SignRotatedInt { |
| 47 public: | 53 public: |
| 48 SignRotatedInt(uint64_t Value, Type* ValueType) | 54 SignRotatedInt(uint64_t Value, Type* ValueType) |
| 49 : SignedValue(Value >> 1), | 55 : SignedValue(Value >> 1), |
| 50 IsNegated((Value & 0x1) | 56 IsNegated((Value & 0x1) |
| 51 && !(ValueType->isIntegerTy() | 57 && !(ValueType->isIntegerTy() |
| (...skipping 883 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 935 const char *VerifyIntArithmeticOp(const char *Op, Type *OpTy) { | 941 const char *VerifyIntArithmeticOp(const char *Op, Type *OpTy) { |
| 936 if (!PNaClABITypeChecker::isValidIntArithmeticType(OpTy)) { | 942 if (!PNaClABITypeChecker::isValidIntArithmeticType(OpTy)) { |
| 937 Errors() << Op << ": Invalid integer arithmetic type: " << *OpTy; | 943 Errors() << Op << ": Invalid integer arithmetic type: " << *OpTy; |
| 938 } | 944 } |
| 939 return Op; | 945 return Op; |
| 940 } | 946 } |
| 941 | 947 |
| 942 // Checks the Alignment for loading/storing a value of type Ty. If | 948 // Checks the Alignment for loading/storing a value of type Ty. If |
| 943 // invalid, generates an appropriate error message. | 949 // invalid, generates an appropriate error message. |
| 944 void VerifyMemoryAccessAlignment(const char *Op, Type *Ty, | 950 void VerifyMemoryAccessAlignment(const char *Op, Type *Ty, |
| 945 uint64_t Alignment) { | 951 unsigned Alignment) { |
| 952 if (NoDumpFinalizeRules) return; | |
| 946 if (!PNaClABIProps::isAllowedAlignment(&DL, Alignment, Ty)) { | 953 if (!PNaClABIProps::isAllowedAlignment(&DL, Alignment, Ty)) { |
| 947 if (unsigned Expected = NaClGetExpectedLoadStoreAlignment(DL, Ty)) { | 954 if (unsigned Expected = NaClGetExpectedLoadStoreAlignment(DL, Ty)) { |
| 948 Errors() << Op << ": Illegal alignment for " << *Ty | 955 Errors() << Op << ": Illegal alignment for " << *Ty |
| 949 << ". Expects: " << Expected << "\n"; | 956 << ". Expects: " << Expected << "\n"; |
| 950 } else { | 957 } else { |
| 951 Errors() << Op << ": Not allowed for type: " << *Ty << "\n"; | 958 Errors() << Op << ": Not allowed for type: " << *Ty << "\n"; |
| 952 } | 959 } |
| 953 } | 960 } |
| 954 } | 961 } |
| 955 | 962 |
| (...skipping 1583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2539 } | 2546 } |
| 2540 | 2547 |
| 2541 /// Checks if block Value is a valid branch target for the current | 2548 /// Checks if block Value is a valid branch target for the current |
| 2542 /// function block. If not, generates an appropriate error message. | 2549 /// function block. If not, generates an appropriate error message. |
| 2543 void VerifyBranchRange(uint64_t Value) { | 2550 void VerifyBranchRange(uint64_t Value) { |
| 2544 if (0 == Value || Value >= ExpectedNumBbs) { | 2551 if (0 == Value || Value >= ExpectedNumBbs) { |
| 2545 Errors() << "Branch " << BitcodeId('b', Value) | 2552 Errors() << "Branch " << BitcodeId('b', Value) |
| 2546 << " out of range. Not in [1," << ExpectedNumBbs << "]\n"; | 2553 << " out of range. Not in [1," << ExpectedNumBbs << "]\n"; |
| 2547 } | 2554 } |
| 2548 } | 2555 } |
| 2556 | |
| 2557 /// Convert alignment exponent (i.e. power of two (or zero)) to the | |
| 2558 /// corresponding alignment to use. If alignment is too large, it generates | |
| 2559 /// an error message and returns 0. | |
| 2560 unsigned getAlignmentValue(uint64_t Exponent); | |
| 2549 }; | 2561 }; |
| 2550 | 2562 |
| 2551 NaClDisFunctionParser::NaClDisFunctionParser( | 2563 NaClDisFunctionParser::NaClDisFunctionParser( |
| 2552 unsigned BlockID, | 2564 unsigned BlockID, |
| 2553 NaClDisBlockParser *EnclosingParser) | 2565 NaClDisBlockParser *EnclosingParser) |
| 2554 : NaClDisBlockParser(BlockID, EnclosingParser), | 2566 : NaClDisBlockParser(BlockID, EnclosingParser), |
| 2555 CurrentBbIndex(-1), | 2567 CurrentBbIndex(-1), |
| 2556 ExpectedNumBbs(0), | 2568 ExpectedNumBbs(0), |
| 2557 InstIsTerminating(false) { | 2569 InstIsTerminating(false) { |
| 2558 Context->ResetLocalCounters(); | 2570 Context->ResetLocalCounters(); |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2759 return "ult"; | 2771 return "ult"; |
| 2760 case CmpInst::FCMP_ULE: | 2772 case CmpInst::FCMP_ULE: |
| 2761 return "ule"; | 2773 return "ule"; |
| 2762 case CmpInst::FCMP_UNE: | 2774 case CmpInst::FCMP_UNE: |
| 2763 return "une"; | 2775 return "une"; |
| 2764 case CmpInst::FCMP_TRUE: | 2776 case CmpInst::FCMP_TRUE: |
| 2765 return "true"; | 2777 return "true"; |
| 2766 } | 2778 } |
| 2767 } | 2779 } |
| 2768 | 2780 |
| 2781 namespace { | |
| 2782 | |
| 2783 static const unsigned MaxAlignmentExponent = 29; | |
| 2784 static_assert( | |
| 2785 (1u << MaxAlignmentExponent) == Value::MaximumAlignment, | |
| 2786 "Inconsistency between Value.MaxAlignment and PNaCl alignment limit"); | |
| 2787 } | |
| 2788 | |
| 2789 unsigned NaClDisFunctionParser::getAlignmentValue(uint64_t Exponent) { | |
| 2790 if (Exponent > MaxAlignmentExponent + 1) { | |
| 2791 Errors() << "Alignment can't be greater than 2**" << MaxAlignmentExponent | |
| 2792 << ". Found: 2**" << (Exponent - 1) << "\n"; | |
| 2793 return 0; | |
| 2794 } | |
| 2795 return (1 << static_cast<unsigned>(Exponent)) >> 1; | |
| 2796 } | |
| 2797 | |
| 2769 bool NaClDisFunctionParser::ParseBlock(unsigned BlockID) { | 2798 bool NaClDisFunctionParser::ParseBlock(unsigned BlockID) { |
| 2770 ObjDumpSetRecordBitAddress(GetBlock().GetStartBit()); | 2799 ObjDumpSetRecordBitAddress(GetBlock().GetStartBit()); |
| 2771 switch (BlockID) { | 2800 switch (BlockID) { |
| 2772 case naclbitc::CONSTANTS_BLOCK_ID: { | 2801 case naclbitc::CONSTANTS_BLOCK_ID: { |
| 2773 NaClDisConstantsParser Parser(BlockID, this); | 2802 NaClDisConstantsParser Parser(BlockID, this); |
| 2774 return Parser.ParseThisBlock(); | 2803 return Parser.ParseThisBlock(); |
| 2775 } | 2804 } |
| 2776 case naclbitc::VALUE_SYMTAB_BLOCK_ID: { | 2805 case naclbitc::VALUE_SYMTAB_BLOCK_ID: { |
| 2777 if (!PNaClAllowLocalSymbolTables) break; | 2806 if (!PNaClAllowLocalSymbolTables) break; |
| 2778 NaClDisValueSymtabParser Parser(BlockID, this); | 2807 NaClDisValueSymtabParser Parser(BlockID, this); |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2988 case naclbitc::FUNC_CODE_INST_ALLOCA: { | 3017 case naclbitc::FUNC_CODE_INST_ALLOCA: { |
| 2989 // ALLOCA: [size, align] | 3018 // ALLOCA: [size, align] |
| 2990 if (Values.size() != 2) { | 3019 if (Values.size() != 2) { |
| 2991 Errors() << "Function alloca record expects 2 arguments. Found: " | 3020 Errors() << "Function alloca record expects 2 arguments. Found: " |
| 2992 << Values.size() << "\n"; | 3021 << Values.size() << "\n"; |
| 2993 break; | 3022 break; |
| 2994 } | 3023 } |
| 2995 uint32_t SizeOp = RelativeToAbsId(Values[0]); | 3024 uint32_t SizeOp = RelativeToAbsId(Values[0]); |
| 2996 Type* SizeType = GetValueType(SizeOp); | 3025 Type* SizeType = GetValueType(SizeOp); |
| 2997 BitcodeId SizeId(GetBitcodeId(SizeOp)); | 3026 BitcodeId SizeId(GetBitcodeId(SizeOp)); |
| 2998 uint64_t Alignment = (1 << Values[1]) >> 1; | 3027 unsigned Alignment = getAlignmentValue(Values[1]); |
| 2999 if (!PNaClABIProps::isAllocaSizeType(SizeType)) | 3028 if (!PNaClABIProps::isAllocaSizeType(SizeType)) |
| 3000 Errors() << PNaClABIProps::ExpectedAllocaSizeType() << "\n"; | 3029 Errors() << PNaClABIProps::ExpectedAllocaSizeType() << "\n"; |
| 3001 // TODO(kschimpf) Are there any constraints on alignment? | 3030 // TODO(kschimpf) Are there any constraints on alignment? |
| 3002 Tokens() << NextInstId() << Space() << "=" << Space() << StartCluster() | 3031 Tokens() << NextInstId() << Space() << "=" << Space() << StartCluster() |
| 3003 << "alloca" << Space() << "i8" << Comma() << FinishCluster() | 3032 << "alloca" << Space() << "i8" << Comma() << FinishCluster() |
| 3004 << Space() << StartCluster() << TokenizeType(SizeType) << Space() | 3033 << Space() << StartCluster() << TokenizeType(SizeType) << Space() |
| 3005 << SizeId << Comma() << FinishCluster() << Space() | 3034 << SizeId << Comma() << FinishCluster() << Space() |
| 3006 << StartCluster() <<"align" << Space() << Alignment << Semicolon() | 3035 << StartCluster() <<"align" << Space() << Alignment << Semicolon() |
| 3007 << FinishCluster(); | 3036 << FinishCluster(); |
| 3008 InstallInstType(GetPointerType()); | 3037 InstallInstType(GetPointerType()); |
| 3009 break; | 3038 break; |
| 3010 } | 3039 } |
| 3011 case naclbitc::FUNC_CODE_INST_LOAD: { | 3040 case naclbitc::FUNC_CODE_INST_LOAD: { |
| 3012 // LOAD: [op, align, ty] | 3041 // LOAD: [op, align, ty] |
| 3013 if (Values.size() != 3) { | 3042 if (Values.size() != 3) { |
| 3014 Errors() << "Function load record expects 3 arguments. Found: " | 3043 Errors() << "Function load record expects 3 arguments. Found: " |
| 3015 << Values.size() << "\n"; | 3044 << Values.size() << "\n"; |
| 3016 break; | 3045 break; |
| 3017 } | 3046 } |
| 3018 uint64_t Alignment = (1 << Values[1]) >> 1; | 3047 unsigned Alignment = getAlignmentValue(Values[1]); |
| 3019 Type *LoadType = GetType(Values[2]); | 3048 Type *LoadType = GetType(Values[2]); |
| 3020 VerifyScalarOrVectorOp("load", LoadType); | 3049 VerifyScalarOrVectorOp("load", LoadType); |
| 3021 Context->VerifyMemoryAccessAlignment("load", LoadType, Alignment); | 3050 Context->VerifyMemoryAccessAlignment("load", LoadType, Alignment); |
| 3022 Tokens() << NextInstId() << Space() << "=" << Space() << StartCluster() | 3051 Tokens() << NextInstId() << Space() << "=" << Space() << StartCluster() |
| 3023 << "load" << Space() << TokenizeType(LoadType) << "*" << Space() | 3052 << "load" << Space() << TokenizeType(LoadType) << "*" << Space() |
| 3024 << GetBitcodeId(RelativeToAbsId(Values[0])) << Comma() | 3053 << GetBitcodeId(RelativeToAbsId(Values[0])) << Comma() |
| 3025 << FinishCluster() << Space() << StartCluster() | 3054 << FinishCluster() << Space() << StartCluster() |
| 3026 << "align" << Space() << Alignment << Semicolon() | 3055 << "align" << Space() << Alignment << Semicolon() |
| 3027 << FinishCluster(); | 3056 << FinishCluster(); |
| 3028 InstallInstType(LoadType); | 3057 InstallInstType(LoadType); |
| 3029 break; | 3058 break; |
| 3030 } | 3059 } |
| 3031 case naclbitc::FUNC_CODE_INST_STORE: { | 3060 case naclbitc::FUNC_CODE_INST_STORE: { |
| 3032 // STORE: [ptr, val, align] | 3061 // STORE: [ptr, val, align] |
| 3033 if (Values.size() != 3) { | 3062 if (Values.size() != 3) { |
| 3034 Errors() << "Function store record expects 3 arguments. Found: " | 3063 Errors() << "Function store record expects 3 arguments. Found: " |
| 3035 << Values.size() << "\n"; | 3064 << Values.size() << "\n"; |
| 3036 break; | 3065 break; |
| 3037 } | 3066 } |
| 3038 uint64_t Alignment = (1 << Values[2]) >> 1; | 3067 unsigned Alignment = getAlignmentValue(Values[2]); |
| 3039 uint32_t Val = RelativeToAbsId(Values[1]); | 3068 uint32_t Val = RelativeToAbsId(Values[1]); |
| 3040 Type *ValType = GetValueType(Val); | 3069 Type *ValType = GetValueType(Val); |
| 3041 VerifyScalarOrVectorOp("store", ValType); | 3070 VerifyScalarOrVectorOp("store", ValType); |
| 3042 Context->VerifyMemoryAccessAlignment("store", ValType, Alignment); | 3071 Context->VerifyMemoryAccessAlignment("store", ValType, Alignment); |
| 3043 Tokens() << StartCluster() << "store" << Space() << TokenizeType(ValType) | 3072 Tokens() << StartCluster() << "store" << Space() << TokenizeType(ValType) |
| 3044 << Space() << GetBitcodeId(Val) << Comma() << FinishCluster() | 3073 << Space() << GetBitcodeId(Val) << Comma() << FinishCluster() |
| 3045 << Space() << StartCluster() << TokenizeType(ValType) << "*" | 3074 << Space() << StartCluster() << TokenizeType(ValType) << "*" |
| 3046 << Space() << GetBitcodeId(RelativeToAbsId(Values[0])) << Comma() | 3075 << Space() << GetBitcodeId(RelativeToAbsId(Values[0])) << Comma() |
| 3047 << FinishCluster() << Space() << StartCluster() << "align" | 3076 << FinishCluster() << Space() << StartCluster() << "align" |
| 3048 << Space() << Alignment << Semicolon() << FinishCluster(); | 3077 << Space() << Alignment << Semicolon() << FinishCluster(); |
| (...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3515 ObjDump.Error() << "Expected 1 top level block in bitcode: Found:" | 3544 ObjDump.Error() << "Expected 1 top level block in bitcode: Found:" |
| 3516 << NumBlocksRead << "\n"; | 3545 << NumBlocksRead << "\n"; |
| 3517 ErrorsFound = true; | 3546 ErrorsFound = true; |
| 3518 } | 3547 } |
| 3519 | 3548 |
| 3520 ObjDump.Flush(); | 3549 ObjDump.Flush(); |
| 3521 return ErrorsFound || Parser.GetNumErrors() > 0; | 3550 return ErrorsFound || Parser.GetNumErrors() > 0; |
| 3522 } | 3551 } |
| 3523 | 3552 |
| 3524 } | 3553 } |
| OLD | NEW |