John,
I have looked at the real code (instead of the obsolete one) and it
appears to be easy to find if an operand is a getelementptr
instruction.
if (ConstantExpr * CE = dyn_cast<ConstantExpr>(I.getOperand(0)))
{ Out<< "*** operand 0 is a constant Expr******";
if (CE->getOpcode() == Instruction::GetElementPtr)
{ Out<< "*** operand 0 is a gep instruction ********";
if (const ArrayType *ar =
dyn_cast<ArrayType>(CE->getPointerOperandType()->getElementType()))
hi=ar->getNumElements();
Thank you for that.
You're welcome.
I would like to use safecode programs rather than write my own code.
However, the website of safecode says that it works only with version
2.6 or 2.7 of llvm whereas I use version 2.8 of llvm.
SAFECode already does all the things you mention below. Unless you have a pressing need to use LLVM 2.8, I recommend switching to LLVM 2.7 so that you can re-use the SAFECode passes unmodified.
If you must use LLVM 2.8 or mainline LLVM, then I have the following suggestions below:
To get around the problem, I plan to do as follows :
(1) Do not install safecode with llvm 2.8 (as it may or may not work)
(2) Create a new pass named "unGep", "Breaks Constant GEPs"
The BreakConstantGEP pass is self-contained and should be trivial to update to work with LLVM 2.8. There is no need for you to go through the effort to rewrite it.
(3) The new pass derives from FunctionPass (because safecode does so,
if I had to write it, ModulePass would have been good enough.)
(4) The RunOnFunction method of the unGep pass invokes
addPoolChecks(F) passing it the function F. I will modify
addGetElementPtrChecks so that it produces array bounds in the way I
need. (I need a check that array bounds are being voilated for my
reaserch to detect overflows.)
First, passes should do just one thing. The BreakConstantGEP pass should convert ConstantExpr GEPs into GEP instructions and not do anything else. A separate pass should insert bounds checks. Calling addPoolChecks() from the BreakConstantGEP pass is a bad idea; it prevents the BreakConstantGEP pass from being reusable.
I'm currently in the process of making SAFECode follow this philosophy. For example, for LLVM 2.6, the InsertPoolChecks pass added load/store checks, array bounds checks, and indirect function call checks. I've moved the code that inserts load/store checks into a separate pass in mainline SAFECode and intend to do the same for indirect function call checks. We have also moved various array bounds check optimizations into separate passes.
Second, the code in InsertPoolChecks that inserts checks on GEP instructions is pretty straightforward. If you take the mainline version and remove the call to isGEPSafe(), it should not have any other pass dependencies, and you should be able to easily update it to LLVM 2.8.
As for the implementation of the run-time check, the interface is pretty generic: it takes a pool handle, the source of the GEP, and the result of the GEP and does the run-time check. The only extraneous parameter is the pool handle, and your run-time check can just ignore it if it doesn't need it. You only need to specialize the code for your run-time array bounds check implementation if you require parameters other than these.
I will then run opt as
opt -load../unGep.so
Yes, this is how you could run the passes. We built the SAFECode tool (sc) because SAFECode uses several different libraries; creating a separate tool was easier than trying to load all the libraries into opt.
-- John T.