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

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

Issue 807643002: Don't allow instructions/globals to use alignment > 2**29. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm.git@master
Patch Set: Fix issues in patch set 4. Created 6 years 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
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
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 IgnorePNaClABIChecks(
44 "ignore-pnaclabi-checks",
45 cl::desc("Ignore checking bitcode for PNaCl ABI 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 874 matching lines...) Expand 10 before | Expand all | Expand 10 after
926 } 932 }
927 933
928 /// Increments the current number of defined global abbreviations. 934 /// Increments the current number of defined global abbreviations.
929 void IncNumGlobalAbbreviations(unsigned BlockID) { 935 void IncNumGlobalAbbreviations(unsigned BlockID) {
930 ++GlobalAbbrevsCountMap[BlockID]; 936 ++GlobalAbbrevsCountMap[BlockID];
931 } 937 }
932 938
933 /// Verifies the given integer operator has the right type. Returns 939 /// Verifies the given integer operator has the right type. Returns
934 /// the operator. 940 /// the operator.
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 (!IgnorePNaClABIChecks &&
943 !PNaClABITypeChecker::isValidIntArithmeticType(OpTy)) {
937 Errors() << Op << ": Invalid integer arithmetic type: " << *OpTy; 944 Errors() << Op << ": Invalid integer arithmetic type: " << *OpTy;
938 } 945 }
939 return Op; 946 return Op;
940 } 947 }
941 948
942 // Checks the Alignment for loading/storing a value of type Ty. If 949 // Checks the Alignment for loading/storing a value of type Ty. If
943 // invalid, generates an appropriate error message. 950 // invalid, generates an appropriate error message.
944 void VerifyMemoryAccessAlignment(const char *Op, Type *Ty, 951 void VerifyMemoryAccessAlignment(const char *Op, Type *Ty,
945 uint64_t Alignment) { 952 unsigned Alignment) {
953 if (IgnorePNaClABIChecks) return;
946 if (!PNaClABIProps::isAllowedAlignment(&DL, Alignment, Ty)) { 954 if (!PNaClABIProps::isAllowedAlignment(&DL, Alignment, Ty)) {
947 if (unsigned Expected = NaClGetExpectedLoadStoreAlignment(DL, Ty)) { 955 if (unsigned Expected = NaClGetExpectedLoadStoreAlignment(DL, Ty)) {
948 Errors() << Op << ": Illegal alignment for " << *Ty 956 Errors() << Op << ": Illegal alignment for " << *Ty
949 << ". Expects: " << Expected << "\n"; 957 << ". Expects: " << Expected << "\n";
950 } else { 958 } else {
951 Errors() << Op << ": Not allowed for type: " << *Ty << "\n"; 959 Errors() << Op << ": Not allowed for type: " << *Ty << "\n";
952 } 960 }
953 } 961 }
954 } 962 }
955 963
(...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after
1790 Errors() << "Integer record should have one argument. Found: " 1798 Errors() << "Integer record should have one argument. Found: "
1791 << Values.size() << "\n"; 1799 << Values.size() << "\n";
1792 Size = 32; 1800 Size = 32;
1793 } 1801 }
1794 switch (Size) { 1802 switch (Size) {
1795 case 1: 1803 case 1:
1796 case 8: 1804 case 8:
1797 case 16: 1805 case 16:
1798 case 32: 1806 case 32:
1799 case 64: { 1807 case 64: {
1800 break; 1808 break;
1809 }
1810 default:
1811 if (!IgnorePNaClABIChecks) {
1812 Errors() << "Integer record contains bad integer size: "
1813 << Size << "\n";
1814 Size = 32;
1801 } 1815 }
1802 default:
1803 Errors() << "Integer record contains bad integer size: "
1804 << Size << "\n";
1805 Size = 32;
1806 break; 1816 break;
1807 } 1817 }
1808 Type *IntType = GetIntegerType(Size); 1818 Type *IntType = GetIntegerType(Size);
1809 Tokens() << NextTypeId() << Space() << "=" << Space() 1819 Tokens() << NextTypeId() << Space() << "=" << Space()
1810 << TokenizeType(IntType) << Semicolon() 1820 << TokenizeType(IntType) << Semicolon()
1811 << TokenizeAbbrevIndex() << Endline(); 1821 << TokenizeAbbrevIndex() << Endline();
1812 InstallType(IntType); 1822 InstallType(IntType);
1813 break; 1823 break;
1814 } 1824 }
1815 case naclbitc::TYPE_CODE_VECTOR: { 1825 case naclbitc::TYPE_CODE_VECTOR: {
1816 // VECTOR: [numelts, eltty] 1826 // VECTOR: [numelts, eltty]
1817 if (Values.size() != 2) { 1827 if (Values.size() != 2) {
1818 Errors() << "Vector record should contain two arguments. Found: " 1828 Errors() << "Vector record should contain two arguments. Found: "
1819 << Values.size() << "\n"; 1829 << Values.size() << "\n";
1820 InstallUnknownTypeForNextId(); 1830 InstallUnknownTypeForNextId();
1821 break; 1831 break;
1822 } 1832 }
1823 Type *BaseType = GetType(Values[1]); 1833 Type *BaseType = GetType(Values[1]);
1824 if (!(BaseType->isIntegerTy() 1834 if (!(BaseType->isIntegerTy()
1825 || BaseType->isFloatTy() 1835 || BaseType->isFloatTy()
1826 || BaseType->isDoubleTy())) { 1836 || BaseType->isDoubleTy())) {
1827 Type *ErrorRecoveryTy = GetIntegerType(32); 1837 Type *ErrorRecoveryTy = GetIntegerType(32);
1828 Errors() << "Vectors can only be defined on primitive types. Found " 1838 Errors() << "Vectors can only be defined on primitive types. Found "
1829 << *BaseType << ". Assuming " << *ErrorRecoveryTy 1839 << *BaseType << ". Assuming " << *ErrorRecoveryTy
1830 << " instead.\n"; 1840 << " instead.\n";
1831 BaseType = ErrorRecoveryTy; 1841 BaseType = ErrorRecoveryTy;
1832 } 1842 }
1833 uint64_t NumElements = Values[0]; 1843 uint64_t NumElements = Values[0];
1834 Type *VecType = VectorType::get(BaseType, NumElements); 1844 Type *VecType = VectorType::get(BaseType, NumElements);
1835 if (!PNaClABITypeChecker::isValidVectorType(VecType)) { 1845 if (!IgnorePNaClABIChecks &&
1846 !PNaClABITypeChecker::isValidVectorType(VecType)) {
1836 Errors() << "Vector type " << *VecType << " not allowed.\n"; 1847 Errors() << "Vector type " << *VecType << " not allowed.\n";
1837 } 1848 }
1838 Tokens() << NextTypeId() << Space() << "=" << Space() 1849 Tokens() << NextTypeId() << Space() << "=" << Space()
1839 << TokenizeType(VecType) << Semicolon() 1850 << TokenizeType(VecType) << Semicolon()
1840 << TokenizeAbbrevIndex() << Endline(); 1851 << TokenizeAbbrevIndex() << Endline();
1841 InstallType(VecType); 1852 InstallType(VecType);
1842 break; 1853 break;
1843 } 1854 }
1844 case naclbitc::TYPE_CODE_FUNCTION: { 1855 case naclbitc::TYPE_CODE_FUNCTION: {
1845 // FUNCTION: [vararg, retty, paramty x N] 1856 // FUNCTION: [vararg, retty, paramty x N]
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
2200 // Verify that expected intrinsic function type matches declared 2211 // Verify that expected intrinsic function type matches declared
2201 // type signature. 2212 // type signature.
2202 FunctionType *FcnTy = GetFunctionType(ValID); 2213 FunctionType *FcnTy = GetFunctionType(ValID);
2203 if (FcnTy->getNumParams() != IntrinTy->getNumParams()) { 2214 if (FcnTy->getNumParams() != IntrinTy->getNumParams()) {
2204 Errors() << "Intrinsic " << Name 2215 Errors() << "Intrinsic " << Name
2205 << " expects " << IntrinTy->getNumParams() 2216 << " expects " << IntrinTy->getNumParams()
2206 << " arguments. Found: " << FcnTy->getNumParams() 2217 << " arguments. Found: " << FcnTy->getNumParams()
2207 << "\n"; 2218 << "\n";
2208 break; 2219 break;
2209 } 2220 }
2210 if (!PNaClABITypeChecker::IsPointerEquivType( 2221 if (!IgnorePNaClABIChecks && !PNaClABITypeChecker::IsPointerEquivType(
2211 IntrinTy->getReturnType(), FcnTy->getReturnType())) { 2222 IntrinTy->getReturnType(), FcnTy->getReturnType())) {
2212 Errors() << "Intrinsic " << Name 2223 Errors() << "Intrinsic " << Name
2213 << " expects return type " << *IntrinTy->getReturnType() 2224 << " expects return type " << *IntrinTy->getReturnType()
2214 << ". Found: " << *FcnTy->getReturnType() << "\n"; 2225 << ". Found: " << *FcnTy->getReturnType() << "\n";
2215 break; 2226 break;
2216 } 2227 }
2217 for (size_t i = 0; i < FcnTy->getNumParams(); ++i) { 2228 for (size_t i = 0; i < FcnTy->getNumParams(); ++i) {
2218 if (!PNaClABITypeChecker::IsPointerEquivType( 2229 if (!IgnorePNaClABIChecks && !PNaClABITypeChecker::IsPointerEquivType(
2219 IntrinTy->getParamType(i), 2230 IntrinTy->getParamType(i),
2220 FcnTy->getParamType(i))) { 2231 FcnTy->getParamType(i))) {
2221 Errors() << "Intrinsic " << Name 2232 Errors() << "Intrinsic " << Name
2222 << " expects " << *IntrinTy->getParamType(i) 2233 << " expects " << *IntrinTy->getParamType(i)
2223 << " for argument " << (i+1) << ". Found: " 2234 << " for argument " << (i+1) << ". Found: "
2224 << *FcnTy->getParamType(i) << "\n"; 2235 << *FcnTy->getParamType(i) << "\n";
2225 break; 2236 break;
2226 } 2237 }
2227 } 2238 }
2228 } 2239 }
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
2456 2467
2457 bool isFloatingType(Type *Ty) { 2468 bool isFloatingType(Type *Ty) {
2458 return Ty->isFloatTy() || Ty->isDoubleTy(); 2469 return Ty->isFloatTy() || Ty->isDoubleTy();
2459 } 2470 }
2460 2471
2461 /// Verifies that OpTy is an integer, or a vector of integers, for 2472 /// Verifies that OpTy is an integer, or a vector of integers, for
2462 /// operator Op. Generates error messages if appropriate. Returns Op. 2473 /// operator Op. Generates error messages if appropriate. Returns Op.
2463 const char *VerifyIntegerOrVectorOp(const char *Op, Type *OpTy) { 2474 const char *VerifyIntegerOrVectorOp(const char *Op, Type *OpTy) {
2464 Type *BaseTy = OpTy; 2475 Type *BaseTy = OpTy;
2465 if (OpTy->isVectorTy()) { 2476 if (OpTy->isVectorTy()) {
2466 if (!PNaClABITypeChecker::isValidVectorType(OpTy)) { 2477 if (!IgnorePNaClABIChecks &&
2478 !PNaClABITypeChecker::isValidVectorType(OpTy)) {
2467 Errors() << Op << ": invalid vector type: " << *OpTy << "\n"; 2479 Errors() << Op << ": invalid vector type: " << *OpTy << "\n";
2468 return Op; 2480 return Op;
2469 } 2481 }
2470 BaseTy = OpTy->getVectorElementType(); 2482 BaseTy = OpTy->getVectorElementType();
2471 } 2483 }
2472 if (BaseTy->isIntegerTy()) { 2484 if (BaseTy->isIntegerTy()) {
2473 if (PNaClABITypeChecker::isValidScalarType(BaseTy)) return Op; 2485 if (IgnorePNaClABIChecks ||
2486 PNaClABITypeChecker::isValidScalarType(BaseTy)) return Op;
jvoung (off chromium) 2014/12/18 19:27:57 nit: put "return Op" on a separate line, now that
Karl 2014/12/18 20:39:19 Done.
2474 Errors() << Op << ": Invalid integer type: " << *OpTy << "\n"; 2487 Errors() << Op << ": Invalid integer type: " << *OpTy << "\n";
2475 } else { 2488 } else {
2476 Errors() << Op << ": Expects integer type. Found: " << *OpTy << "\n"; 2489 Errors() << Op << ": Expects integer type. Found: " << *OpTy << "\n";
2477 } 2490 }
2478 return Op; 2491 return Op;
2479 } 2492 }
2480 2493
2481 /// Verifies that Opty is a floating point type, or a vector of a 2494 /// Verifies that Opty is a floating point type, or a vector of a
2482 /// floating points, for operator Op. Generates error messages if 2495 /// floating points, for operator Op. Generates error messages if
2483 /// appropriate. Returns Op. 2496 /// appropriate. Returns Op.
2484 const char *VerifyFloatingOrVectorOp(const char *Op, Type *OpTy) { 2497 const char *VerifyFloatingOrVectorOp(const char *Op, Type *OpTy) {
2485 Type *BaseTy = OpTy; 2498 Type *BaseTy = OpTy;
2486 if (OpTy->isVectorTy()) { 2499 if (OpTy->isVectorTy()) {
2487 if (!PNaClABITypeChecker::isValidVectorType(OpTy)) { 2500 if (!IgnorePNaClABIChecks &&
2501 !PNaClABITypeChecker::isValidVectorType(OpTy)) {
2488 Errors() << Op << ": invalid vector type: " << *OpTy << "\n"; 2502 Errors() << Op << ": invalid vector type: " << *OpTy << "\n";
2489 return Op; 2503 return Op;
2490 } 2504 }
2491 BaseTy = OpTy->getVectorElementType(); 2505 BaseTy = OpTy->getVectorElementType();
2492 } 2506 }
2493 if (!isFloatingType(BaseTy)) { 2507 if (!isFloatingType(BaseTy)) {
2494 Errors() << Op << ": Expects floating point. Found " 2508 Errors() << Op << ": Expects floating point. Found "
2495 << OpTy << "\n"; 2509 << OpTy << "\n";
2496 return Op; 2510 return Op;
2497 } 2511 }
2498 if (!PNaClABITypeChecker::isValidScalarType(BaseTy)) { 2512 if (!IgnorePNaClABIChecks &&
2513 !PNaClABITypeChecker::isValidScalarType(BaseTy)) {
2499 Errors() << Op << ": type not allowed: " << OpTy << "\n"; 2514 Errors() << Op << ": type not allowed: " << OpTy << "\n";
2500 } 2515 }
2501 return Op; 2516 return Op;
2502 } 2517 }
2503 2518
2504 /// Op is the name of the operation that called this. Checks if 2519 /// Op is the name of the operation that called this. Checks if
2505 /// OpTy is either a (non-void) scalar, or a vector of scalars. If 2520 /// OpTy is either a (non-void) scalar, or a vector of scalars. If
2506 /// not, generates an appropriate error message. Always returns Op. 2521 /// not, generates an appropriate error message. Always returns Op.
2507 const char *VerifyScalarOrVectorOp(const char *Op, Type *OpTy) { 2522 const char *VerifyScalarOrVectorOp(const char *Op, Type *OpTy) {
2523 if (IgnorePNaClABIChecks) return Op;
2508 if (PNaClABITypeChecker::isValidScalarType(OpTy)) { 2524 if (PNaClABITypeChecker::isValidScalarType(OpTy)) {
2509 if (OpTy->isVoidTy()) 2525 if (OpTy->isVoidTy())
2510 Errors() << Op << ": Type void not allowed\n"; 2526 Errors() << Op << ": Type void not allowed\n";
2511 } else if (!PNaClABITypeChecker::isValidVectorType(OpTy)) { 2527 } else if (!PNaClABITypeChecker::isValidVectorType(OpTy)) {
2512 Errors() << Op << ": Expects scalar/vector type. Found: " 2528 Errors() << Op << ": Expects scalar/vector type. Found: "
2513 << OpTy << "\n"; 2529 << OpTy << "\n";
2514 } 2530 }
2515 return Op; 2531 return Op;
2516 } 2532 }
2517 2533
2518 void VerifyIndexedVector(const char *Op, uint32_t VecValue, 2534 void VerifyIndexedVector(const char *Op, uint32_t VecValue,
2519 uint32_t IdxValue) { 2535 uint32_t IdxValue) {
2520 Type *VecType = GetValueType(VecValue); 2536 Type *VecType = GetValueType(VecValue);
2521 Type *IdxType = GetValueType(IdxValue); 2537 Type *IdxType = GetValueType(IdxValue);
2522 if (!PNaClABITypeChecker::isValidVectorType(VecType)){ 2538 if (!IgnorePNaClABIChecks &&
2539 !PNaClABITypeChecker::isValidVectorType(VecType)){
2523 if (VecType->isVectorTy()) 2540 if (VecType->isVectorTy())
2524 Errors() << Op << ": Vector type " << *VecType << " not allowed\n"; 2541 Errors() << Op << ": Vector type " << *VecType << " not allowed\n";
2525 else 2542 else
2526 Errors() << Op << ": Vector type expected. Found: " << *VecType << "\n"; 2543 Errors() << Op << ": Vector type expected. Found: " << *VecType << "\n";
2527 } 2544 }
2528 // Note: This restriction appears to be LLVM specific. 2545 // Note: This restriction appears to be LLVM specific.
2529 if (!IdxType->isIntegerTy(32)) { 2546 if (!IdxType->isIntegerTy(32)) {
2530 Errors() << Op << ": Index not i32. Found: " << *IdxType << "\n"; 2547 Errors() << Op << ": Index not i32. Found: " << *IdxType << "\n";
2531 } 2548 }
2532 BitcodeId IdxId(GetBitcodeId(IdxValue)); 2549 BitcodeId IdxId(GetBitcodeId(IdxValue));
2533 if (IdxId.GetKind() != 'c') { 2550 if (IdxId.GetKind() != 'c') {
2534 Errors() << Op << ": Vector index not constant: " << IdxId << "\n"; 2551 Errors() << Op << ": Vector index not constant: " << IdxId << "\n";
2535 // TODO(kschimpf): We should check that Idx is a constant with 2552 // TODO(kschimpf): We should check that Idx is a constant with
2536 // valid access. However, we currently don't store constant 2553 // valid access. However, we currently don't store constant
2537 // values, so it can't be tested. 2554 // values, so it can't be tested.
2538 } 2555 }
2539 } 2556 }
2540 2557
2541 /// Checks if block Value is a valid branch target for the current 2558 /// Checks if block Value is a valid branch target for the current
2542 /// function block. If not, generates an appropriate error message. 2559 /// function block. If not, generates an appropriate error message.
2543 void VerifyBranchRange(uint64_t Value) { 2560 void VerifyBranchRange(uint64_t Value) {
2544 if (0 == Value || Value >= ExpectedNumBbs) { 2561 if (0 == Value || Value >= ExpectedNumBbs) {
2545 Errors() << "Branch " << BitcodeId('b', Value) 2562 Errors() << "Branch " << BitcodeId('b', Value)
2546 << " out of range. Not in [1," << ExpectedNumBbs << "]\n"; 2563 << " out of range. Not in [1," << ExpectedNumBbs << "]\n";
2547 } 2564 }
2548 } 2565 }
2566
2567 /// Convert alignment exponent (i.e. power of two (or zero)) to the
2568 /// corresponding alignment to use. If alignment is too large, it generates
2569 /// an error message and returns 0.
2570 unsigned getAlignmentValue(uint64_t Exponent);
2549 }; 2571 };
2550 2572
2551 NaClDisFunctionParser::NaClDisFunctionParser( 2573 NaClDisFunctionParser::NaClDisFunctionParser(
2552 unsigned BlockID, 2574 unsigned BlockID,
2553 NaClDisBlockParser *EnclosingParser) 2575 NaClDisBlockParser *EnclosingParser)
2554 : NaClDisBlockParser(BlockID, EnclosingParser), 2576 : NaClDisBlockParser(BlockID, EnclosingParser),
2555 CurrentBbIndex(-1), 2577 CurrentBbIndex(-1),
2556 ExpectedNumBbs(0), 2578 ExpectedNumBbs(0),
2557 InstIsTerminating(false) { 2579 InstIsTerminating(false) {
2558 Context->ResetLocalCounters(); 2580 Context->ResetLocalCounters();
(...skipping 13 matching lines...) Expand all
2572 // Now install parameters. 2594 // Now install parameters.
2573 for (size_t Index = 0; Index < FcnTy->getFunctionNumParams(); ++Index) { 2595 for (size_t Index = 0; Index < FcnTy->getFunctionNumParams(); ++Index) {
2574 InstallParamType(FcnTy->getFunctionParamType(Index)); 2596 InstallParamType(FcnTy->getFunctionParamType(Index));
2575 } 2597 }
2576 } 2598 }
2577 2599
2578 void NaClDisFunctionParser::PrintBlockHeader() { 2600 void NaClDisFunctionParser::PrintBlockHeader() {
2579 Tokens() << "function" << Space(); 2601 Tokens() << "function" << Space();
2580 BitcodeId FunctionId('f', FcnId); 2602 BitcodeId FunctionId('f', FcnId);
2581 if (!(Context->IsFunctionIntrinsic(FcnId) 2603 if (!(Context->IsFunctionIntrinsic(FcnId)
2582 || PNaClABITypeChecker::isValidFunctionType(FcnTy))) { 2604 || (!IgnorePNaClABIChecks &&
2605 PNaClABITypeChecker::isValidFunctionType(FcnTy)))) {
jvoung (off chromium) 2014/12/18 19:27:57 yikes, this one is a bit hard to parse =) If ther
Karl 2014/12/18 20:39:19 Done.
2583 Errors() << "Invalid type signature for " 2606 Errors() << "Invalid type signature for "
2584 << BitcodeId('f', FcnId) << ": " << *FcnTy << "\n"; 2607 << BitcodeId('f', FcnId) << ": " << *FcnTy << "\n";
2585 } 2608 }
2586 Tokens() << TokenizeFunctionSignature(FcnTy, &FunctionId) 2609 Tokens() << TokenizeFunctionSignature(FcnTy, &FunctionId)
2587 << Space() << OpenCurly() 2610 << Space() << OpenCurly()
2588 << Space() << Space() << "// BlockID = " << GetBlockID() 2611 << Space() << Space() << "// BlockID = " << GetBlockID()
2589 << Endline(); 2612 << Endline();
2590 } 2613 }
2591 2614
2592 const char *NaClDisFunctionParser::GetBinop(uint32_t Opcode, Type *Ty) { 2615 const char *NaClDisFunctionParser::GetBinop(uint32_t Opcode, Type *Ty) {
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
2759 return "ult"; 2782 return "ult";
2760 case CmpInst::FCMP_ULE: 2783 case CmpInst::FCMP_ULE:
2761 return "ule"; 2784 return "ule";
2762 case CmpInst::FCMP_UNE: 2785 case CmpInst::FCMP_UNE:
2763 return "une"; 2786 return "une";
2764 case CmpInst::FCMP_TRUE: 2787 case CmpInst::FCMP_TRUE:
2765 return "true"; 2788 return "true";
2766 } 2789 }
2767 } 2790 }
2768 2791
2792 namespace {
2793
2794 static const unsigned MaxAlignmentExponent = 29;
2795 static_assert(
2796 (1u << MaxAlignmentExponent) == Value::MaximumAlignment,
2797 "Inconsistency between Value.MaxAlignment and PNaCl alignment limit");
2798 }
2799
2800 unsigned NaClDisFunctionParser::getAlignmentValue(uint64_t Exponent) {
2801 if (Exponent > MaxAlignmentExponent + 1) {
2802 Errors() << "Alignment can't be greater than 2**" << MaxAlignmentExponent
2803 << ". Found: 2**" << (Exponent - 1) << "\n";
2804 return 0;
2805 }
2806 return (1 << static_cast<unsigned>(Exponent)) >> 1;
2807 }
2808
2769 bool NaClDisFunctionParser::ParseBlock(unsigned BlockID) { 2809 bool NaClDisFunctionParser::ParseBlock(unsigned BlockID) {
2770 ObjDumpSetRecordBitAddress(GetBlock().GetStartBit()); 2810 ObjDumpSetRecordBitAddress(GetBlock().GetStartBit());
2771 switch (BlockID) { 2811 switch (BlockID) {
2772 case naclbitc::CONSTANTS_BLOCK_ID: { 2812 case naclbitc::CONSTANTS_BLOCK_ID: {
2773 NaClDisConstantsParser Parser(BlockID, this); 2813 NaClDisConstantsParser Parser(BlockID, this);
2774 return Parser.ParseThisBlock(); 2814 return Parser.ParseThisBlock();
2775 } 2815 }
2776 case naclbitc::VALUE_SYMTAB_BLOCK_ID: { 2816 case naclbitc::VALUE_SYMTAB_BLOCK_ID: {
2777 if (!PNaClAllowLocalSymbolTables) break; 2817 if (!PNaClAllowLocalSymbolTables) break;
2778 NaClDisValueSymtabParser Parser(BlockID, this); 2818 NaClDisValueSymtabParser Parser(BlockID, this);
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
2907 << "Function switch record expects at least 4 arguments. Found: " 2947 << "Function switch record expects at least 4 arguments. Found: "
2908 << Values.size() << "\n"; 2948 << Values.size() << "\n";
2909 break; 2949 break;
2910 } 2950 }
2911 Type *OpType = GetType(Values[0]); 2951 Type *OpType = GetType(Values[0]);
2912 uint32_t CondId = RelativeToAbsId(Values[1]); 2952 uint32_t CondId = RelativeToAbsId(Values[1]);
2913 Type *CondType = GetValueType(CondId); 2953 Type *CondType = GetValueType(CondId);
2914 if (OpType != CondType) 2954 if (OpType != CondType)
2915 Errors() << "Specified select type " << *OpType << " but found: " 2955 Errors() << "Specified select type " << *OpType << " but found: "
2916 << *CondType << "\n"; 2956 << *CondType << "\n";
2917 if (!PNaClABITypeChecker::isValidSwitchConditionType(CondType)) 2957 if (!IgnorePNaClABIChecks &&
2958 !PNaClABITypeChecker::isValidSwitchConditionType(CondType))
jvoung (off chromium) 2014/12/18 19:27:57 Curlies around the then-statement since it's > 1 l
Karl 2014/12/18 20:39:19 Done.
2918 Errors() << PNaClABITypeChecker::ExpectedSwitchConditionType(CondType) 2959 Errors() << PNaClABITypeChecker::ExpectedSwitchConditionType(CondType)
2919 << "\n"; 2960 << "\n";
2920 uint32_t DefaultBb = Values[2]; 2961 uint32_t DefaultBb = Values[2];
2921 unsigned NumCases = Values[3]; 2962 unsigned NumCases = Values[3];
2922 VerifyBranchRange(DefaultBb); 2963 VerifyBranchRange(DefaultBb);
2923 Tokens() << "switch" << Space() << StartCluster() << StartCluster() 2964 Tokens() << "switch" << Space() << StartCluster() << StartCluster()
2924 << TokenizeType(OpType) << Space() << GetBitcodeId(CondId) 2965 << TokenizeType(OpType) << Space() << GetBitcodeId(CondId)
2925 << FinishCluster() << Space() << "{" << FinishCluster() 2966 << FinishCluster() << Space() << "{" << FinishCluster()
2926 << Endline(); 2967 << Endline();
2927 IncAssemblyIndent(); 2968 IncAssemblyIndent();
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2988 case naclbitc::FUNC_CODE_INST_ALLOCA: { 3029 case naclbitc::FUNC_CODE_INST_ALLOCA: {
2989 // ALLOCA: [size, align] 3030 // ALLOCA: [size, align]
2990 if (Values.size() != 2) { 3031 if (Values.size() != 2) {
2991 Errors() << "Function alloca record expects 2 arguments. Found: " 3032 Errors() << "Function alloca record expects 2 arguments. Found: "
2992 << Values.size() << "\n"; 3033 << Values.size() << "\n";
2993 break; 3034 break;
2994 } 3035 }
2995 uint32_t SizeOp = RelativeToAbsId(Values[0]); 3036 uint32_t SizeOp = RelativeToAbsId(Values[0]);
2996 Type* SizeType = GetValueType(SizeOp); 3037 Type* SizeType = GetValueType(SizeOp);
2997 BitcodeId SizeId(GetBitcodeId(SizeOp)); 3038 BitcodeId SizeId(GetBitcodeId(SizeOp));
2998 uint64_t Alignment = (1 << Values[1]) >> 1; 3039 unsigned Alignment = getAlignmentValue(Values[1]);
2999 if (!PNaClABIProps::isAllocaSizeType(SizeType)) 3040 if (!IgnorePNaClABIChecks && !PNaClABIProps::isAllocaSizeType(SizeType))
3000 Errors() << PNaClABIProps::ExpectedAllocaSizeType() << "\n"; 3041 Errors() << PNaClABIProps::ExpectedAllocaSizeType() << "\n";
3001 // TODO(kschimpf) Are there any constraints on alignment? 3042 // TODO(kschimpf) Are there any constraints on alignment?
3002 Tokens() << NextInstId() << Space() << "=" << Space() << StartCluster() 3043 Tokens() << NextInstId() << Space() << "=" << Space() << StartCluster()
3003 << "alloca" << Space() << "i8" << Comma() << FinishCluster() 3044 << "alloca" << Space() << "i8" << Comma() << FinishCluster()
3004 << Space() << StartCluster() << TokenizeType(SizeType) << Space() 3045 << Space() << StartCluster() << TokenizeType(SizeType) << Space()
3005 << SizeId << Comma() << FinishCluster() << Space() 3046 << SizeId << Comma() << FinishCluster() << Space()
3006 << StartCluster() <<"align" << Space() << Alignment << Semicolon() 3047 << StartCluster() <<"align" << Space() << Alignment << Semicolon()
3007 << FinishCluster(); 3048 << FinishCluster();
3008 InstallInstType(GetPointerType()); 3049 InstallInstType(GetPointerType());
3009 break; 3050 break;
3010 } 3051 }
3011 case naclbitc::FUNC_CODE_INST_LOAD: { 3052 case naclbitc::FUNC_CODE_INST_LOAD: {
3012 // LOAD: [op, align, ty] 3053 // LOAD: [op, align, ty]
3013 if (Values.size() != 3) { 3054 if (Values.size() != 3) {
3014 Errors() << "Function load record expects 3 arguments. Found: " 3055 Errors() << "Function load record expects 3 arguments. Found: "
3015 << Values.size() << "\n"; 3056 << Values.size() << "\n";
3016 break; 3057 break;
3017 } 3058 }
3018 uint64_t Alignment = (1 << Values[1]) >> 1; 3059 unsigned Alignment = getAlignmentValue(Values[1]);
3019 Type *LoadType = GetType(Values[2]); 3060 Type *LoadType = GetType(Values[2]);
3020 VerifyScalarOrVectorOp("load", LoadType); 3061 VerifyScalarOrVectorOp("load", LoadType);
3021 Context->VerifyMemoryAccessAlignment("load", LoadType, Alignment); 3062 Context->VerifyMemoryAccessAlignment("load", LoadType, Alignment);
3022 Tokens() << NextInstId() << Space() << "=" << Space() << StartCluster() 3063 Tokens() << NextInstId() << Space() << "=" << Space() << StartCluster()
3023 << "load" << Space() << TokenizeType(LoadType) << "*" << Space() 3064 << "load" << Space() << TokenizeType(LoadType) << "*" << Space()
3024 << GetBitcodeId(RelativeToAbsId(Values[0])) << Comma() 3065 << GetBitcodeId(RelativeToAbsId(Values[0])) << Comma()
3025 << FinishCluster() << Space() << StartCluster() 3066 << FinishCluster() << Space() << StartCluster()
3026 << "align" << Space() << Alignment << Semicolon() 3067 << "align" << Space() << Alignment << Semicolon()
3027 << FinishCluster(); 3068 << FinishCluster();
3028 InstallInstType(LoadType); 3069 InstallInstType(LoadType);
3029 break; 3070 break;
3030 } 3071 }
3031 case naclbitc::FUNC_CODE_INST_STORE: { 3072 case naclbitc::FUNC_CODE_INST_STORE: {
3032 // STORE: [ptr, val, align] 3073 // STORE: [ptr, val, align]
3033 if (Values.size() != 3) { 3074 if (Values.size() != 3) {
3034 Errors() << "Function store record expects 3 arguments. Found: " 3075 Errors() << "Function store record expects 3 arguments. Found: "
3035 << Values.size() << "\n"; 3076 << Values.size() << "\n";
3036 break; 3077 break;
3037 } 3078 }
3038 uint64_t Alignment = (1 << Values[2]) >> 1; 3079 unsigned Alignment = getAlignmentValue(Values[2]);
3039 uint32_t Val = RelativeToAbsId(Values[1]); 3080 uint32_t Val = RelativeToAbsId(Values[1]);
3040 Type *ValType = GetValueType(Val); 3081 Type *ValType = GetValueType(Val);
3041 VerifyScalarOrVectorOp("store", ValType); 3082 VerifyScalarOrVectorOp("store", ValType);
3042 Context->VerifyMemoryAccessAlignment("store", ValType, Alignment); 3083 Context->VerifyMemoryAccessAlignment("store", ValType, Alignment);
3043 Tokens() << StartCluster() << "store" << Space() << TokenizeType(ValType) 3084 Tokens() << StartCluster() << "store" << Space() << TokenizeType(ValType)
3044 << Space() << GetBitcodeId(Val) << Comma() << FinishCluster() 3085 << Space() << GetBitcodeId(Val) << Comma() << FinishCluster()
3045 << Space() << StartCluster() << TokenizeType(ValType) << "*" 3086 << Space() << StartCluster() << TokenizeType(ValType) << "*"
3046 << Space() << GetBitcodeId(RelativeToAbsId(Values[0])) << Comma() 3087 << Space() << GetBitcodeId(RelativeToAbsId(Values[0])) << Comma()
3047 << FinishCluster() << Space() << StartCluster() << "align" 3088 << FinishCluster() << Space() << StartCluster() << "align"
3048 << Space() << Alignment << Semicolon() << FinishCluster(); 3089 << Space() << Alignment << Semicolon() << FinishCluster();
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
3179 Errors() << "Call indirect record expects at least 3 arguments. Found: " 3220 Errors() << "Call indirect record expects at least 3 arguments. Found: "
3180 << Values.size() << "\n"; 3221 << Values.size() << "\n";
3181 break; 3222 break;
3182 } 3223 }
3183 } 3224 }
3184 unsigned IsTailCall = (Values[0] & 0x1); 3225 unsigned IsTailCall = (Values[0] & 0x1);
3185 CallingConv::ID CallingConv; 3226 CallingConv::ID CallingConv;
3186 uint32_t FcnId = RelativeToAbsId(Values[1]); 3227 uint32_t FcnId = RelativeToAbsId(Values[1]);
3187 if (!naclbitc::DecodeCallingConv(Values[0]>>1, CallingConv)) 3228 if (!naclbitc::DecodeCallingConv(Values[0]>>1, CallingConv))
3188 Errors() << "Call unknown calling convention:" << (Values[0]>>1) << "\n"; 3229 Errors() << "Call unknown calling convention:" << (Values[0]>>1) << "\n";
3189 if (!PNaClABIProps::isValidCallingConv(CallingConv)) { 3230 if (!IgnorePNaClABIChecks &&
3231 !PNaClABIProps::isValidCallingConv(CallingConv)) {
3190 Errors() << "Call uses disallowed calling convention: " 3232 Errors() << "Call uses disallowed calling convention: "
3191 << PNaClABIProps::CallingConvName(CallingConv) << "(" 3233 << PNaClABIProps::CallingConvName(CallingConv) << "("
3192 << CallingConv << ")\n"; 3234 << CallingConv << ")\n";
3193 } 3235 }
3194 FunctionType *FcnType = 0; 3236 FunctionType *FcnType = 0;
3195 Type *ReturnType = 0; 3237 Type *ReturnType = 0;
3196 size_t ArgIndex = 2; 3238 size_t ArgIndex = 2;
3197 // Flag defining if type checking should be done on argument/return 3239 // Flag defining if type checking should be done on argument/return
3198 // types. 3240 // types.
3199 bool CheckArgRetTypes = true; 3241 bool CheckArgRetTypes = true;
(...skipping 13 matching lines...) Expand all
3213 } else { 3255 } else {
3214 ReturnType = GetType(Values[2]); 3256 ReturnType = GetType(Values[2]);
3215 ArgIndex = 3; 3257 ArgIndex = 3;
3216 } 3258 }
3217 if (!ReturnType->isVoidTy()) { 3259 if (!ReturnType->isVoidTy()) {
3218 Tokens() << NextInstId() << Space() << "=" << Space(); 3260 Tokens() << NextInstId() << Space() << "=" << Space();
3219 } 3261 }
3220 if (IsTailCall) { 3262 if (IsTailCall) {
3221 Tokens() << "tail" << Space(); 3263 Tokens() << "tail" << Space();
3222 } 3264 }
3223 if (CheckArgRetTypes && !PNaClABITypeChecker::isValidParamType(ReturnType)) 3265 if (CheckArgRetTypes &&
3266 !IgnorePNaClABIChecks &&
3267 !PNaClABITypeChecker::isValidParamType(ReturnType))
3224 Errors() << "Invalid return type: " << *ReturnType << "\n"; 3268 Errors() << "Invalid return type: " << *ReturnType << "\n";
3225 Tokens() << "call" << Space(); 3269 Tokens() << "call" << Space();
3226 if (CallingConv != CallingConv::C) { 3270 if (CallingConv != CallingConv::C) {
3227 Tokens() << PNaClABIProps::CallingConvName(CallingConv) << Space(); 3271 Tokens() << PNaClABIProps::CallingConvName(CallingConv) << Space();
3228 } 3272 }
3229 Tokens() << TokenizeType(ReturnType) << Space() 3273 Tokens() << TokenizeType(ReturnType) << Space()
3230 << StartCluster() << GetBitcodeId(FcnId) << OpenParen() 3274 << StartCluster() << GetBitcodeId(FcnId) << OpenParen()
3231 << StartCluster(); 3275 << StartCluster();
3232 unsigned ParamIndex = 0; 3276 unsigned ParamIndex = 0;
3233 unsigned NumParams = Values.size() + 1 - ArgIndex; 3277 unsigned NumParams = Values.size() + 1 - ArgIndex;
3234 for (size_t i = ArgIndex; i < Values.size(); ++i, ++ParamIndex) { 3278 for (size_t i = ArgIndex; i < Values.size(); ++i, ++ParamIndex) {
3235 uint32_t ParamId = RelativeToAbsId(Values[i]); 3279 uint32_t ParamId = RelativeToAbsId(Values[i]);
3236 Type *ParamType = GetValueType(ParamId); 3280 Type *ParamType = GetValueType(ParamId);
3237 if (CheckArgRetTypes && !PNaClABITypeChecker::isValidParamType(ParamType)) 3281 if (CheckArgRetTypes &&
3282 !IgnorePNaClABIChecks &&
3283 !PNaClABITypeChecker::isValidParamType(ParamType))
3238 Errors() << "invalid type for parameter " << i << ": " 3284 Errors() << "invalid type for parameter " << i << ": "
3239 << *ParamType << "\n"; 3285 << *ParamType << "\n";
jvoung (off chromium) 2014/12/18 19:27:57 curlies for > 1 line?
Karl 2014/12/18 20:39:19 Done.
3240 if (FcnType) { 3286 if (FcnType) {
3241 if (ParamIndex < FcnType->getNumParams()) { 3287 if (ParamIndex < FcnType->getNumParams()) {
3242 Type *ExpectedType = FcnType->getParamType(ParamIndex); 3288 Type *ExpectedType = FcnType->getParamType(ParamIndex);
3243 if (ParamType != ExpectedType) { 3289 if (ParamType != ExpectedType) {
3244 Warnings() << "Parameter " << (ParamIndex + 1) << " mismatch: " 3290 Warnings() << "Parameter " << (ParamIndex + 1) << " mismatch: "
3245 << *ParamType << " and " << *ExpectedType << "\n"; 3291 << *ParamType << " and " << *ExpectedType << "\n";
3246 } 3292 }
3247 } 3293 }
3248 else if (ParamIndex == FcnType->getNumParams()) { 3294 else if (ParamIndex == FcnType->getNumParams()) {
3249 Warnings() << "Call expects " << FcnType->getNumParams() 3295 Warnings() << "Call expects " << FcnType->getNumParams()
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
3309 // was checked in method ProcessRecord. 3355 // was checked in method ProcessRecord.
3310 // Note: If the function was defined, the type was checked in 3356 // Note: If the function was defined, the type was checked in
3311 // NaClDisFunctionParser::PrintBlockHeader. 3357 // NaClDisFunctionParser::PrintBlockHeader.
3312 if (Context->HasDefinedFunctionIndex(NextFcnDefinedId) 3358 if (Context->HasDefinedFunctionIndex(NextFcnDefinedId)
3313 && i == Context->GetDefinedFunctionIndex(NextFcnDefinedId)) { 3359 && i == Context->GetDefinedFunctionIndex(NextFcnDefinedId)) {
3314 ++NextFcnDefinedId; 3360 ++NextFcnDefinedId;
3315 continue; 3361 continue;
3316 } 3362 }
3317 if (FunctionType *FcnTy = dyn_cast<FunctionType>(GetFunctionValueType(i))) { 3363 if (FunctionType *FcnTy = dyn_cast<FunctionType>(GetFunctionValueType(i))) {
3318 if (!Context->IsFunctionIntrinsic(i) && 3364 if (!Context->IsFunctionIntrinsic(i) &&
3365 !IgnorePNaClABIChecks &&
3319 !PNaClABITypeChecker::isValidFunctionType(FcnTy)) { 3366 !PNaClABITypeChecker::isValidFunctionType(FcnTy)) {
3320 Context->SetRecordAddressToFunctionIdAddress(i); 3367 Context->SetRecordAddressToFunctionIdAddress(i);
3321 Errors() << "Invalid type signature for " 3368 Errors() << "Invalid type signature for "
3322 << BitcodeId('f', i) << ": " << *FcnTy << "\n"; 3369 << BitcodeId('f', i) << ": " << *FcnTy << "\n";
3323 } 3370 }
3324 } 3371 }
3325 } 3372 }
3326 } 3373 }
3327 3374
3328 bool NaClDisModuleParser::ParseBlock(unsigned BlockID) { 3375 bool NaClDisModuleParser::ParseBlock(unsigned BlockID) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
3382 } 3429 }
3383 bool IsProto = (Values[2] != 0); 3430 bool IsProto = (Values[2] != 0);
3384 Tokens() << StartCluster() << (IsProto ? "declare" : "define"); 3431 Tokens() << StartCluster() << (IsProto ? "declare" : "define");
3385 uint32_t FcnId = GetNumFunctions(); 3432 uint32_t FcnId = GetNumFunctions();
3386 BitcodeId FcnName('f', FcnId); 3433 BitcodeId FcnName('f', FcnId);
3387 std::string FcnStrName(FcnName.GetName()); 3434 std::string FcnStrName(FcnName.GetName());
3388 GlobalValue::LinkageTypes Linkage; 3435 GlobalValue::LinkageTypes Linkage;
3389 if (!naclbitc::DecodeLinkage(Values[3], Linkage)) { 3436 if (!naclbitc::DecodeLinkage(Values[3], Linkage)) {
3390 Errors() << "Unknown linkage value: " << Values[3] << "\n"; 3437 Errors() << "Unknown linkage value: " << Values[3] << "\n";
3391 } else { 3438 } else {
3392 if (!PNaClABIProps::isValidGlobalLinkage(Linkage)) 3439 if (!IgnorePNaClABIChecks &&
3440 !PNaClABIProps::isValidGlobalLinkage(Linkage))
3393 Errors() << "Disallowed linkage type: " 3441 Errors() << "Disallowed linkage type: "
3394 << PNaClABIProps::LinkageName(Linkage) << "\n"; 3442 << PNaClABIProps::LinkageName(Linkage) << "\n";
3395 Tokens() << Space() << PNaClABIProps::LinkageName(Linkage); 3443 Tokens() << Space() << PNaClABIProps::LinkageName(Linkage);
3396 } 3444 }
3397 CallingConv::ID CallingConv; 3445 CallingConv::ID CallingConv;
3398 if (!naclbitc::DecodeCallingConv(Values[1], CallingConv)) { 3446 if (!naclbitc::DecodeCallingConv(Values[1], CallingConv)) {
3399 Errors() << "Unknown calling convention value: " << Values[1] << "\n"; 3447 Errors() << "Unknown calling convention value: " << Values[1] << "\n";
3400 } else if (PNaClABIProps::isValidCallingConv(CallingConv)) { 3448 } else if (PNaClABIProps::isValidCallingConv(CallingConv)) {
3401 if (CallingConv != CallingConv::C) { 3449 if (CallingConv != CallingConv::C) {
3402 Tokens() << Space() << PNaClABIProps::CallingConvName(CallingConv); 3450 Tokens() << Space() << PNaClABIProps::CallingConvName(CallingConv);
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
3515 ObjDump.Error() << "Expected 1 top level block in bitcode: Found:" 3563 ObjDump.Error() << "Expected 1 top level block in bitcode: Found:"
3516 << NumBlocksRead << "\n"; 3564 << NumBlocksRead << "\n";
3517 ErrorsFound = true; 3565 ErrorsFound = true;
3518 } 3566 }
3519 3567
3520 ObjDump.Flush(); 3568 ObjDump.Flush();
3521 return ErrorsFound || Parser.GetNumErrors() > 0; 3569 return ErrorsFound || Parser.GetNumErrors() > 0;
3522 } 3570 }
3523 3571
3524 } 3572 }
OLDNEW
« no previous file with comments | « no previous file | lib/Bitcode/NaCl/Reader/NaClBitcodeReader.h » ('j') | unittests/Bitcode/NaClParseInstsTest.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698