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

Side by Side Diff: lib/Bitcode/NaCl/Reader/NaClBitcodeReader.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 nit and add test cases. 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 //===- NaClBitcodeReader.cpp ----------------------------------------------===// 1 //===- NaClBitcodeReader.cpp ----------------------------------------------===//
2 // Internal NaClBitcodeReader implementation 2 // Internal NaClBitcodeReader implementation
3 // 3 //
4 // The LLVM Compiler Infrastructure 4 // The LLVM Compiler Infrastructure
5 // 5 //
6 // This file is distributed under the University of Illinois Open Source 6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details. 7 // License. See LICENSE.TXT for details.
8 // 8 //
9 //===----------------------------------------------------------------------===// 9 //===----------------------------------------------------------------------===//
10 10
(...skipping 10 matching lines...) Expand all
21 #include "llvm/IR/DerivedTypes.h" 21 #include "llvm/IR/DerivedTypes.h"
22 #include "llvm/IR/InlineAsm.h" 22 #include "llvm/IR/InlineAsm.h"
23 #include "llvm/IR/IntrinsicInst.h" 23 #include "llvm/IR/IntrinsicInst.h"
24 #include "llvm/IR/Module.h" 24 #include "llvm/IR/Module.h"
25 #include "llvm/IR/OperandTraits.h" 25 #include "llvm/IR/OperandTraits.h"
26 #include "llvm/IR/Operator.h" 26 #include "llvm/IR/Operator.h"
27 #include "llvm/Support/DataStream.h" 27 #include "llvm/Support/DataStream.h"
28 #include "llvm/Support/Debug.h" 28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/MathExtras.h" 29 #include "llvm/Support/MathExtras.h"
30 #include "llvm/Support/MemoryBuffer.h" 30 #include "llvm/Support/MemoryBuffer.h"
31 #include "llvm/Support/raw_ostream.h"
32 using namespace llvm; 31 using namespace llvm;
33 32
34 33
35 cl::opt<bool> 34 cl::opt<bool>
36 llvm::PNaClAllowLocalSymbolTables( 35 llvm::PNaClAllowLocalSymbolTables(
37 "allow-local-symbol-tables", 36 "allow-local-symbol-tables",
38 cl::desc("Allow (function) local symbol tables in PNaCl bitcode files"), 37 cl::desc("Allow (function) local symbol tables in PNaCl bitcode files"),
39 cl::init(false)); 38 cl::init(false));
40 39
41 void NaClBitcodeReader::FreeState() { 40 void NaClBitcodeReader::FreeState() {
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 //===----------------------------------------------------------------------===// 176 //===----------------------------------------------------------------------===//
178 177
179 178
180 std::error_code NaClBitcodeReader::Error(ErrorType E, 179 std::error_code NaClBitcodeReader::Error(ErrorType E,
181 const std::string &Message) const { 180 const std::string &Message) const {
182 if (Verbose) 181 if (Verbose)
183 *Verbose << "Error: " << Message << "\n"; 182 *Verbose << "Error: " << Message << "\n";
184 return Error(E); 183 return Error(E);
185 } 184 }
186 185
186 std::error_code NaClBitcodeReader::getAlignmentValue(
187 uint64_t Exponent, unsigned &Alignment) {
188 // Note: Alignement = 2 ** (Exponent - 1).
jvoung (off chromium) 2014/12/16 23:24:39 Alignement -> Alignment
Karl 2014/12/17 20:52:38 Done.
189 if (Exponent == 0) {
jvoung (off chromium) 2014/12/16 23:24:39 Hmm, I don't think we ever said that "alloca" coul
Karl 2014/12/17 20:52:38 Good point. I forgot about the alloca default case
190 Alignment = 1; // Just in case it is accessed.
191 return Error(InvalidValue, "Alignment must be greater than 0");
192 }
193 if (Exponent > 30) { // Note: Exponent is one larger than actual.
jvoung (off chromium) 2014/12/16 23:24:39 "than actual" -> "than the limit"?
jvoung (off chromium) 2014/12/16 23:24:39 include/llvm/IR/Value.h has "MaximumAlignment", wh
Karl 2014/12/17 20:52:38 Good point. Adding reference to the constant.
Karl 2014/12/17 20:52:38 Done.
194 Alignment = 1; // Just in case it is accessed.
195 std::string Buffer;
196 raw_string_ostream StrBuf(Buffer);
197 StrBuf << "Alignment can't be greater than 2**29. Found: 2**"
198 << (Exponent - 1);
199 return Error(InvalidValue, StrBuf.str());
200 }
201 uint32_t FixedExponent = Exponent - 1;
202 Alignment = 1 << FixedExponent;
203 return std::error_code();
204 }
205
187 std::error_code NaClBitcodeReader::ParseTypeTable() { 206 std::error_code NaClBitcodeReader::ParseTypeTable() {
188 DEBUG(dbgs() << "-> ParseTypeTable\n"); 207 DEBUG(dbgs() << "-> ParseTypeTable\n");
189 if (Stream.EnterSubBlock(naclbitc::TYPE_BLOCK_ID_NEW)) 208 if (Stream.EnterSubBlock(naclbitc::TYPE_BLOCK_ID_NEW))
190 return Error(InvalidRecord, "Malformed block record"); 209 return Error(InvalidRecord, "Malformed block record");
191 210
192 std::error_code result = ParseTypeTableBody(); 211 std::error_code result = ParseTypeTableBody();
193 if (!result) 212 if (!result)
194 DEBUG(dbgs() << "<- ParseTypeTable\n"); 213 DEBUG(dbgs() << "<- ParseTypeTable\n");
195 return result; 214 return result;
196 } 215 }
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 switch (Bitcode) { 414 switch (Bitcode) {
396 default: 415 default:
397 return Reader.Error(NaClBitcodeReader::InvalidValue, 416 return Reader.Error(NaClBitcodeReader::InvalidValue,
398 "Unknown global variable entry"); 417 "Unknown global variable entry");
399 case naclbitc::GLOBALVAR_VAR: 418 case naclbitc::GLOBALVAR_VAR:
400 // Start the definition of a global variable. 419 // Start the definition of a global variable.
401 if (ProcessingGlobal || Record.size() != 2) 420 if (ProcessingGlobal || Record.size() != 2)
402 return Reader.Error(NaClBitcodeReader::InvalidRecord, 421 return Reader.Error(NaClBitcodeReader::InvalidRecord,
403 "Bad GLOBALVAR_VAR record"); 422 "Bad GLOBALVAR_VAR record");
404 ProcessingGlobal = true; 423 ProcessingGlobal = true;
405 VarAlignment = (1 << Record[0]) >> 1; 424 if (std::error_code EC =
425 Reader.getAlignmentValue(Record[0], VarAlignment))
426 return EC;
406 VarIsConstant = Record[1] != 0; 427 VarIsConstant = Record[1] != 0;
407 // Assume (by default) there is a single initializer. 428 // Assume (by default) there is a single initializer.
408 VarInitializersNeeded = 1; 429 VarInitializersNeeded = 1;
409 break; 430 break;
410 case naclbitc::GLOBALVAR_COMPOUND: 431 case naclbitc::GLOBALVAR_COMPOUND:
411 // Global variable has multiple initializers. Changes the 432 // Global variable has multiple initializers. Changes the
412 // default number of initializers to the given value in 433 // default number of initializers to the given value in
413 // Record[0]. 434 // Record[0].
414 if (!ProcessingGlobal || !VarType.empty() || 435 if (!ProcessingGlobal || !VarType.empty() ||
415 VarInitializersNeeded != 1 || Record.size() != 1) 436 VarInitializersNeeded != 1 || Record.size() != 1)
(...skipping 1057 matching lines...) Expand 10 before | Expand all | Expand 10 after
1473 break; 1494 break;
1474 } 1495 }
1475 1496
1476 case naclbitc::FUNC_CODE_INST_ALLOCA: { // ALLOCA: [op, align] 1497 case naclbitc::FUNC_CODE_INST_ALLOCA: { // ALLOCA: [op, align]
1477 if (Record.size() != 2) 1498 if (Record.size() != 2)
1478 return Error(InvalidRecord, "Invalid ALLOCA record"); 1499 return Error(InvalidRecord, "Invalid ALLOCA record");
1479 Value *Size; 1500 Value *Size;
1480 unsigned OpNum = 0; 1501 unsigned OpNum = 0;
1481 if (popValue(Record, &OpNum, NextValueNo, &Size)) 1502 if (popValue(Record, &OpNum, NextValueNo, &Size))
1482 return Error(InvalidRecord, "Invalid ALLOCA record"); 1503 return Error(InvalidRecord, "Invalid ALLOCA record");
1483 unsigned Align = Record[1]; 1504 unsigned Alignment;
1484 I = new AllocaInst(Type::getInt8Ty(Context), Size, (1 << Align) >> 1); 1505 if (std::error_code EC = getAlignmentValue(Record[1], Alignment))
1506 return EC;
1507 I = new AllocaInst(Type::getInt8Ty(Context), Size, Alignment);
1485 break; 1508 break;
1486 } 1509 }
1487 case naclbitc::FUNC_CODE_INST_LOAD: { 1510 case naclbitc::FUNC_CODE_INST_LOAD: {
1488 // LOAD: [op, align, ty] 1511 // LOAD: [op, align, ty]
1489 unsigned OpNum = 0; 1512 unsigned OpNum = 0;
1490 Value *Op; 1513 Value *Op;
1491 if (popValue(Record, &OpNum, NextValueNo, &Op) || 1514 if (popValue(Record, &OpNum, NextValueNo, &Op) ||
1492 Record.size() != 3) 1515 Record.size() != 3)
1493 return Error(InvalidRecord, "Invalid LOAD record"); 1516 return Error(InvalidRecord, "Invalid LOAD record");
1494 1517
1495 // Add pointer cast to op. 1518 // Add pointer cast to op.
1496 Type *T = getTypeByID(Record[2]); 1519 Type *T = getTypeByID(Record[2]);
1497 if (T == nullptr) 1520 if (T == nullptr)
1498 return Error(InvalidType, "Invalid type for load instruction"); 1521 return Error(InvalidType, "Invalid type for load instruction");
1499 Op = ConvertOpToType(Op, T->getPointerTo(), CurBBNo); 1522 Op = ConvertOpToType(Op, T->getPointerTo(), CurBBNo);
1500 if (Op == nullptr) 1523 if (Op == nullptr)
1501 return Error(InvalidTypeForValue, "Can't convert cast to type"); 1524 return Error(InvalidTypeForValue, "Can't convert cast to type");
1502 I = new LoadInst(Op, "", false, (1 << Record[OpNum]) >> 1); 1525 unsigned Alignment;
1526 if (std::error_code EC =
1527 getLoadStoreAlignmentValue(Record[OpNum], TheModule->getDataLayout(),
1528 T, "load", Alignment)) {
1529 return EC;
1530 }
1531 I = new LoadInst(Op, "", false, Alignment);
1503 break; 1532 break;
1504 } 1533 }
1505 case naclbitc::FUNC_CODE_INST_STORE: { 1534 case naclbitc::FUNC_CODE_INST_STORE: {
1506 // STORE: [ptr, val, align] 1535 // STORE: [ptr, val, align]
1507 unsigned OpNum = 0; 1536 unsigned OpNum = 0;
1508 Value *Val, *Ptr; 1537 Value *Val, *Ptr;
1509 if (popValue(Record, &OpNum, NextValueNo, &Ptr) || 1538 if (popValue(Record, &OpNum, NextValueNo, &Ptr) ||
1510 popValue(Record, &OpNum, NextValueNo, &Val) || 1539 popValue(Record, &OpNum, NextValueNo, &Val) ||
1511 OpNum+1 != Record.size()) 1540 OpNum+1 != Record.size())
1512 return Error(InvalidRecord, "Invalid STORE record"); 1541 return Error(InvalidRecord, "Invalid STORE record");
1513 Val = ConvertOpToScalar(Val, CurBBNo); 1542 Val = ConvertOpToScalar(Val, CurBBNo);
1514 Ptr = ConvertOpToType(Ptr, Val->getType()->getPointerTo(), CurBBNo); 1543 Type *ValType = Val->getType();
1544 Ptr = ConvertOpToType(Ptr, ValType->getPointerTo(), CurBBNo);
1515 if (Ptr == nullptr) 1545 if (Ptr == nullptr)
1516 return Error(InvalidTypeForValue, "Can't convert cast to type"); 1546 return Error(InvalidTypeForValue, "Can't convert cast to type");
1517 I = new StoreInst(Val, Ptr, false, (1 << Record[OpNum]) >> 1); 1547 unsigned Alignment;
1548 if (std::error_code EC =
1549 getLoadStoreAlignmentValue(Record[OpNum], TheModule->getDataLayout(),
jvoung (off chromium) 2014/12/16 23:24:39 A little ambivalent about the extra checks -- I do
Karl 2014/12/17 20:52:38 I decided to remove this, since the bitcode reader
1550 ValType, "store", Alignment)) {
1551 return EC;
1552 }
1553 I = new StoreInst(Val, Ptr, false, Alignment);
1518 break; 1554 break;
1519 } 1555 }
1520 case naclbitc::FUNC_CODE_INST_CALL: 1556 case naclbitc::FUNC_CODE_INST_CALL:
1521 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: { 1557 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: {
1522 // CALL: [cc, fnid, arg0, arg1...] 1558 // CALL: [cc, fnid, arg0, arg1...]
1523 // CALL_INDIRECT: [cc, fnid, returnty, args...] 1559 // CALL_INDIRECT: [cc, fnid, returnty, args...]
1524 if ((Record.size() < 2) || 1560 if ((Record.size() < 2) ||
1525 (BitCode == naclbitc::FUNC_CODE_INST_CALL_INDIRECT && 1561 (BitCode == naclbitc::FUNC_CODE_INST_CALL_INDIRECT &&
1526 Record.size() < 3)) 1562 Record.size() < 3))
1527 return Error(InvalidRecord, "Invalid CALL record"); 1563 return Error(InvalidRecord, "Invalid CALL record");
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
1897 Materializer->releaseBuffer(); 1933 Materializer->releaseBuffer();
1898 delete M; 1934 delete M;
1899 return EC; 1935 return EC;
1900 } 1936 }
1901 1937
1902 // TODO: Restore the use-lists to the in-memory state when the bitcode was 1938 // TODO: Restore the use-lists to the in-memory state when the bitcode was
1903 // written. We must defer until the Module has been fully materialized. 1939 // written. We must defer until the Module has been fully materialized.
1904 1940
1905 return M; 1941 return M;
1906 } 1942 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698