aboutsummaryrefslogtreecommitdiff
path: root/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp
diff options
context:
space:
mode:
authorKarl Schimpf <kschimpf@google.com>2013-08-01 07:12:23 -0700
committerKarl Schimpf <kschimpf@google.com>2013-08-01 07:12:23 -0700
commitb9657234ee8b1951db5977a8ffb55a2e5df6d76c (patch)
treeda9f474ea4b35ff767b93715a13a3933f0355f39 /lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp
parent365546bcef14965546dc39ebcef35f07a897b9c5 (diff)
Remove the inttoptr dependency from load instructions.
Elides inttoptr casts used (exclusively) in load instructions when PNaClVersion=2. This is an incremental start on removing the inttoptr instruction from the PNaCl wire format (See issue 3544 for more information on the strategy of removing ptrtoint). Also modifies PNaCl bitcode reader/writer to accept PNaClVersion=1 as supported, and PNaClVersion=2 as unsupported but readable (allowing pnacl-freeze and pnacl-thaw to work on such files). Also allows command-line option --pnacl-version for setting PNaClVersion in the PNaCl bitcode writer. Also fixes some problems on PNaCl bitcode headers, using common support to determine when the read/written PNaCl bitcode file is valid. BUG= https://code.google.com/p/nativeclient/issues/detail?id=3544 R=jvoung@chromium.org Review URL: https://codereview.chromium.org/5812155903377408
Diffstat (limited to 'lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp')
-rw-r--r--lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp73
1 files changed, 62 insertions, 11 deletions
diff --git a/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp b/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp
index 9c2f45ea56..40f8842b3b 100644
--- a/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp
+++ b/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp
@@ -1301,6 +1301,46 @@ bool NaClBitcodeReader::ParseBitcodeInto(Module *M) {
}
}
+// Returns true if error occured installing I into BB.
+bool NaClBitcodeReader::InstallInstruction(
+ BasicBlock *BB, Instruction *I) {
+ // Add instruction to end of current BB. If there is no current BB, reject
+ // this file.
+ if (BB == 0) {
+ delete I;
+ return Error("Invalid instruction with no BB");
+ }
+ BB->getInstList().push_back(I);
+ return false;
+}
+
+Value *NaClBitcodeReader::ConvertOpToType(Value *Op, Type *T, BasicBlock *BB) {
+ // Note: Currently only knows how to add inttoptr type conversion, since
+ // this is the only elided instruction in the bitcode writer.
+ // TODO(kschimpf): Generalize this as we expand elided conversions.
+ Value *Conversion = 0;
+ Type *OpTy = Op->getType();
+ if (OpTy == T) return Op;
+
+ // Following while loop is only run once. It is used to break on
+ // erroneous conditions.
+ while (true) {
+ if (!OpTy->isIntegerTy()) break;
+ if (!T->isPointerTy()) break;
+ Instruction *I = CastInst::Create(Instruction::IntToPtr, Op, T);
+ if (InstallInstruction(BB, I)) break;
+ Conversion = I;
+ break;
+ }
+ if (Conversion == 0) {
+ std::string Message;
+ raw_string_ostream StrM(Message);
+ StrM << "Can't convert " << *Op << " to type " << *T << "\n";
+ Error(StrM.str());
+ }
+ return Conversion;
+}
+
/// ParseFunctionBody - Lazily parse the specified function body block.
bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
DEBUG(dbgs() << "-> ParseFunctionBody\n");
@@ -1602,13 +1642,29 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
I = new AllocaInst(Type::getInt8Ty(Context), Size, (1 << Align) >> 1);
break;
}
- case naclbitc::FUNC_CODE_INST_LOAD: { // LOAD: [op, align, vol]
+ case naclbitc::FUNC_CODE_INST_LOAD: {
+ // PNaCl version 1: LOAD: [op, align, vol]
+ // PNaCl version 2: LOAD: [op, align, vol, ty]
unsigned OpNum = 0;
Value *Op;
- if (popValue(Record, &OpNum, NextValueNo, &Op) ||
- OpNum+2 != Record.size())
+ if (popValue(Record, &OpNum, NextValueNo, &Op))
return Error("Invalid LOAD record");
-
+ switch (GetPNaClVersion()) {
+ case 1:
+ if (Record.size() != 3)
+ return Error("Invalid LOAD record");
+ break;
+ case 2: {
+ if (Record.size() != 4)
+ return Error("Invalid LOAD record");
+ // Add pointer cast to op.
+ Type *T = getTypeByID(Record[3]);
+ if (T == 0)
+ return Error("Invalid type for load instruction");
+ Op = ConvertOpToType(Op, T->getPointerTo(), CurBB);
+ if (Op == 0) return true;
+ }
+ }
I = new LoadInst(Op, "", Record[OpNum+1], (1 << Record[OpNum]) >> 1);
break;
}
@@ -1677,13 +1733,8 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
continue;
}
- // Add instruction to end of current BB. If there is no current BB, reject
- // this file.
- if (CurBB == 0) {
- delete I;
- return Error("Invalid instruction with no BB");
- }
- CurBB->getInstList().push_back(I);
+ if (InstallInstruction(CurBB, I))
+ return true;
// If this was a terminator instruction, move to the next block.
if (isa<TerminatorInst>(I)) {