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

Unified Diff: src/PNaClTranslator.cpp

Issue 1363983002: Check that address is i32 for indirect calls. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nits. Created 5 years, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests_lit/llvm2ice_tests/Input/no-terminator-inst.tbc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/PNaClTranslator.cpp
diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp
index d7928659619a9fe6e8d6cf5f2f7395d9f9e73f57..ba9eabbd7265ad6b62e5e68ff5c813e3794b5f06 100644
--- a/src/PNaClTranslator.cpp
+++ b/src/PNaClTranslator.cpp
@@ -1598,7 +1598,7 @@ private:
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << InstructionName << " address not " << PtrType
- << ". Found: " << *Op;
+ << ". Found: " << Op->getType();
Error(StrBuf.str());
return false;
}
@@ -2048,6 +2048,24 @@ private:
return LocalOperands.front();
return Context->getGlobalConstantByID(0);
}
+
+ void verifyCallArgTypeMatches(Ice::FunctionDeclaration *Fcn,
+ Ice::SizeT Index, Ice::Type ArgType,
+ Ice::Type ParamType) {
+ if (ArgType != ParamType) {
+ std::string Buffer;
+ raw_string_ostream StrBuf(Buffer);
+ StrBuf << "Argument " << (Index + 1) << " of " << printName(Fcn)
+ << " expects " << ParamType << ". Found: " << ArgType;
+ Error(StrBuf.str());
+ }
+ }
+
+ const Ice::IceString printName(Ice::FunctionDeclaration *Fcn) {
+ if (Fcn)
+ return Fcn->getName();
+ return "function";
+ }
};
void FunctionParser::ExitBlock() {
@@ -2660,46 +2678,116 @@ void FunctionParser::ProcessRecord() {
ParamsStartIndex = 3;
}
- // Extract out the called function and its return type.
uint32_t CalleeIndex = convertRelativeToAbsIndex(Values[1], BaseIndex);
Ice::Operand *Callee = getOperand(CalleeIndex);
+
+ // Pull out signature/return type of call (if possible).
+ Ice::FunctionDeclaration *Fcn = nullptr;
const Ice::FuncSigType *Signature = nullptr;
Ice::Type ReturnType = Ice::IceType_void;
const Ice::Intrinsics::FullIntrinsicInfo *IntrinsicInfo = nullptr;
- // Name of function if a direct call/intrinsic. Null otherwise.
- Ice::FunctionDeclaration *Fcn = nullptr;
if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) {
Fcn = Context->getFunctionByID(CalleeIndex);
Signature = &Fcn->getSignature();
ReturnType = Signature->getReturnType();
+ Ice::SizeT NumParams = Values.size() - ParamsStartIndex;
+ if (NumParams != Signature->getNumArgs()) {
+ std::string Buffer;
+ raw_string_ostream StrBuf(Buffer);
+ StrBuf << "Call to " << printName(Fcn) << " has " << NumParams
+ << " parameters. Signature expects: " << Signature->getNumArgs();
+ Error(StrBuf.str());
+ if (ReturnType != Ice::IceType_void)
+ setNextLocalInstIndex(nullptr);
+ return;
+ }
// Check if this direct call is to an Intrinsic (starts with "llvm.")
bool BadIntrinsic;
- const Ice::IceString &Name = Fcn->getName();
IntrinsicInfo = getTranslator().getContext()->getIntrinsicsInfo().find(
- Name, BadIntrinsic);
+ Fcn->getName(), BadIntrinsic);
if (BadIntrinsic) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
- StrBuf << "Invalid PNaCl intrinsic call to " << Name;
+ StrBuf << "Invalid PNaCl intrinsic call to " << Fcn->getName();
+ Error(StrBuf.str());
+ IntrinsicInfo = nullptr;
+ }
+ if (IntrinsicInfo && IntrinsicInfo->getNumArgs() != NumParams) {
+ std::string Buffer;
+ raw_string_ostream StrBuf(Buffer);
+ StrBuf << "Call to " << printName(Fcn) << " has " << NumParams
+ << " parameters. Intrinsic expects: " << Signature->getNumArgs();
Error(StrBuf.str());
if (ReturnType != Ice::IceType_void)
- appendErrorInstruction(ReturnType);
+ setNextLocalInstIndex(nullptr);
return;
}
- } else {
+ } else { // Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL_INDIRECT
+ // There is no signature. Assume defined by parameter types.
ReturnType = Context->getSimpleTypeByID(Values[2]);
+ if (!isIRGenerationDisabled() && Callee != nullptr)
+ isValidPointerType(Callee, "Call indirect");
+ }
+
+ if (Callee == nullptr && !isIRGenerationDisabled())
+ return;
+
+ // Extract out the the call parameters.
+ SmallVector<Ice::Operand*, 8> Params;
+ for (Ice::SizeT Index = ParamsStartIndex; Index < Values.size(); ++Index) {
+ Ice::Operand *Op = getRelativeOperand(Values[Index], BaseIndex);
+ if (isIRGenerationDisabled())
+ continue;
+ if (Op == nullptr) {
+ std::string Buffer;
+ raw_string_ostream StrBuf(Buffer);
+ StrBuf << "Parameter " << (Index - ParamsStartIndex + 1)
+ << " of " << printName(Fcn) << " is not defined";
+ Error(StrBuf.str());
+ if (ReturnType != Ice::IceType_void)
+ setNextLocalInstIndex(nullptr);
+ return;
+ }
+ Params.push_back(Op);
}
// Check return type.
if (IntrinsicInfo == nullptr && !isCallReturnType(ReturnType)) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
- StrBuf << "Return type of called function is invalid: " << ReturnType;
+ StrBuf << "Return type of " << printName(Fcn) << " is invalid: "
+ << ReturnType;
Error(StrBuf.str());
ReturnType = Ice::IceType_i32;
}
+ if (isIRGenerationDisabled()) {
+ if (ReturnType != Ice::IceType_void)
+ setNextLocalInstIndex(nullptr);
+ return;
+ }
+
+ // Type check call parameters.
+ for (Ice::SizeT Index = 0; Index < Params.size(); ++Index) {
+ Ice::Operand *Op = Params[Index];
+ Ice::Type OpType = Op->getType();
+ if (Signature)
+ verifyCallArgTypeMatches(
+ Fcn, Index, OpType, Signature->getArgType(Index));
+ if (IntrinsicInfo) {
+ verifyCallArgTypeMatches(Fcn, Index, OpType,
+ IntrinsicInfo->getArgType(Index));
+ } else if (!isCallParameterType(OpType)) {
+ std::string Buffer;
+ raw_string_ostream StrBuf(Buffer);
+ StrBuf << "Argument " << *Op << " of " << printName(Fcn)
+ << " has invalid type: " << Op->getType();
+ Error(StrBuf.str());
+ appendErrorInstruction(ReturnType);
+ }
+ }
+
// Extract call information.
uint64_t CCInfo = Values[0];
CallingConv::ID CallingConv;
@@ -2709,127 +2797,25 @@ void FunctionParser::ProcessRecord() {
StrBuf << "Function call calling convention value " << (CCInfo >> 1)
<< " not understood.";
Error(StrBuf.str());
- if (ReturnType != Ice::IceType_void)
- appendErrorInstruction(ReturnType);
+ appendErrorInstruction(ReturnType);
return;
}
bool IsTailCall = static_cast<bool>(CCInfo & 1);
- Ice::SizeT NumParams = Values.size() - ParamsStartIndex;
- if (Signature && NumParams != Signature->getNumArgs()) {
- std::string Buffer;
- raw_string_ostream StrBuf(Buffer);
- StrBuf << "Call has " << NumParams
- << " parameters. Signature expects: " << Signature->getNumArgs();
- Error(StrBuf.str());
- // Error recover by only checking parameters in both signature and call.
- NumParams = std::min(NumParams, Signature->getNumArgs());
- }
- if (isIRGenerationDisabled()) {
- assert(Callee == nullptr);
- // Check that parameters are defined.
- for (Ice::SizeT ParamIndex = 0; ParamIndex < NumParams; ++ParamIndex) {
- assert(getRelativeOperand(Values[ParamsStartIndex + ParamIndex],
- BaseIndex) == nullptr);
- }
- // Define value slot only if value returned.
- if (ReturnType != Ice::IceType_void)
- setNextLocalInstIndex(nullptr);
- return;
- }
+
// Create the call instruction.
Ice::Variable *Dest = (ReturnType == Ice::IceType_void)
? nullptr
: getNextInstVar(ReturnType);
std::unique_ptr<Ice::InstCall> Inst;
if (IntrinsicInfo) {
- Inst.reset(Ice::InstIntrinsicCall::create(Func.get(), NumParams, Dest,
+ Inst.reset(Ice::InstIntrinsicCall::create(Func.get(), Params.size(), Dest,
Callee, IntrinsicInfo->Info));
} else {
- Inst.reset(Ice::InstCall::create(Func.get(), NumParams, Dest, Callee,
+ Inst.reset(Ice::InstCall::create(Func.get(), Params.size(), Dest, Callee,
IsTailCall));
}
-
- // Add parameters.
- for (Ice::SizeT ParamIndex = 0; ParamIndex < NumParams; ++ParamIndex) {
- Ice::Operand *Op =
- getRelativeOperand(Values[ParamsStartIndex + ParamIndex], BaseIndex);
- if (Op == nullptr) {
- std::string Buffer;
- raw_string_ostream StrBuf(Buffer);
- StrBuf << "Parameter " << ParamIndex << " of call not defined";
- Error(StrBuf.str());
- if (ReturnType != Ice::IceType_void)
- appendErrorInstruction(ReturnType);
- return;
- }
-
- // Check that parameter type is valid.
- if (Signature) {
- if (Op->getType() != Signature->getArgType(ParamIndex)) {
- std::string Buffer;
- raw_string_ostream StrBuf(Buffer);
- StrBuf << "Call argument " << *Op << " expects "
- << Signature->getArgType(ParamIndex)
- << ". Found: " << Op->getType();
- Error(StrBuf.str());
- } else if (IntrinsicInfo == nullptr &&
- !isCallParameterType(Op->getType())) {
- // TODO(kschimpf): Move this check to the function declaration, so
- // that it only needs to be checked once.
- std::string Buffer;
- raw_string_ostream StrBuf(Buffer);
- StrBuf << "Call argument " << *Op
- << " matches declaration but has invalid type: "
- << Op->getType();
- Error(StrBuf.str());
- }
- } else if (!isCallParameterType(Op->getType())) {
- std::string Buffer;
- raw_string_ostream StrBuf(Buffer);
- StrBuf << "Call argument " << *Op
- << " has invalid type: " << Op->getType();
- Error(StrBuf.str());
- }
- Inst->addArg(Op);
- }
-
- // If intrinsic call, validate call signature.
- if (IntrinsicInfo) {
- Ice::SizeT ArgIndex = 0;
- switch (IntrinsicInfo->validateCall(Inst.get(), ArgIndex)) {
- case Ice::Intrinsics::IsValidCall:
- break;
- case Ice::Intrinsics::BadReturnType: {
- std::string Buffer;
- raw_string_ostream StrBuf(Buffer);
- StrBuf << "Intrinsic " << Fcn->getName() << " expects return type"
- << IntrinsicInfo->getReturnType()
- << ". Found: " << Inst->getReturnType();
- Error(StrBuf.str());
- break;
- }
- case Ice::Intrinsics::WrongNumOfArgs: {
- std::string Buffer;
- raw_string_ostream StrBuf(Buffer);
- StrBuf << "Intrinsic " << Fcn->getName() << " expects "
- << IntrinsicInfo->getNumArgs()
- << ". Found: " << Inst->getNumArgs();
- Error(StrBuf.str());
- break;
- }
- case Ice::Intrinsics::WrongCallArgType: {
- std::string Buffer;
- raw_string_ostream StrBuf(Buffer);
- StrBuf << "Intrinsic " << Fcn->getName() << " expects "
- << IntrinsicInfo->getArgType(ArgIndex) << " for argument "
- << (ArgIndex + 1)
- << ". Found: " << Inst->getArg(ArgIndex)->getType();
- Error(StrBuf.str());
- break;
- }
- }
- }
-
+ for (Ice::Operand *Param : Params)
+ Inst->addArg(Param);
CurrentNode->appendInst(Inst.release());
return;
}
« no previous file with comments | « no previous file | tests_lit/llvm2ice_tests/Input/no-terminator-inst.tbc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698