Static rooting analysis updates for browser. No bug. r=NPOTB

--HG--
extra : rebase_source : f7e8f1f3039c6ebaa3dabea2a7c181a880d1792b
This commit is contained in:
Steve Fink 2013-03-21 16:29:40 -07:00
Родитель 6f73405058
Коммит 304e360031
4 изменённых файлов: 73 добавлений и 35 удалений

Просмотреть файл

@ -16,24 +16,27 @@ if (typeof arguments[0] != 'string' || typeof arguments[1] != 'string')
var gcFunctionsFile = arguments[0];
var gcTypesFile = arguments[1];
var start = arguments[2]|0;
var end = arguments[3]|0;
var tmpfile = arguments[4];
if (!start)
start = 1;
if (!tmpfile)
tmpfile = "tmp.txt";
var batch = arguments[2]|0;
var numBatches = (arguments[3]|0) || 1;
var tmpfile = arguments[4] || "tmp.txt";
var gcFunctions = {};
var suppressedFunctions = {};
var gcFunctionsText = snarf(gcFunctionsFile).split('\n');
for (var line of gcFunctionsText) {
if (match = /GC Function: (.*)/.exec(line))
gcFunctions[match[1]] = true;
if (match = /Suppressed Function: (.*)/.exec(line))
suppressedFunctions[match[1]] = true;
assert(!system("grep 'GC Function' " + gcFunctionsFile + " > tmp.txt"));
var text = snarf("tmp.txt").split('\n');
assert(text.pop().length == 0);
for (var line of text) {
match = /GC Function: (.*)/.exec(line);
gcFunctions[match[1]] = true;
}
gcFunctionsText = null;
assert(!system("grep 'Suppressed Function' " + arguments[0] + " > tmp.txt"));
text = snarf("tmp.txt").split('\n');
assert(text.pop().length == 0);
for (var line of text) {
match = /Suppressed Function: (.*)/.exec(line);
suppressedFunctions[match[1]] = true;
}
text = null;
var match;
var gcThings = {};
@ -477,7 +480,7 @@ function processBodies()
}
}
if (start == 1)
if (batch == 1)
print("Time: " + new Date);
var xdb = xdbLibrary();
@ -486,8 +489,10 @@ xdb.open("src_body.xdb");
var minStream = xdb.min_data_stream()|0;
var maxStream = xdb.max_data_stream()|0;
start += minStream - 1;
end += minStream - 1;
var N = (maxStream - minStream) + 1;
var each = Math.floor(N/numBatches);
var start = minStream + each * (batch - 1);
var end = Math.min(minStream + each * batch - 1, maxStream);
// Find the source tree
for (let nameIndex = minStream; nameIndex <= maxStream; nameIndex++) {

Просмотреть файл

@ -11,6 +11,10 @@ function indirectCallCannotGC(caller, name)
if (/CallDestroyScriptHook/.test(caller))
return true;
// hooks called deep inside utility libraries.
if (name == "_malloc_message")
return true;
return false;
}
@ -20,7 +24,9 @@ var ignoreClasses = [
"JSStringFinalizer",
"SprintfStateStr",
"JSLocaleCallbacks",
"JSC::ExecutableAllocator"
"JSC::ExecutableAllocator",
"_MD_IOVector",
"PRIOMethods"
];
function fieldCallCannotGC(csu, field)
@ -67,8 +73,19 @@ function ignoreEdgeUse(edge, variable)
return false;
}
var ignoreFunctions = [
"ptio.c:pt_MapError",
"PR_ExplodeTime",
"PR_ErrorInstallTable"
];
function ignoreGCFunction(fun)
{
for (var i = 0; i < ignoreFunctions.length; i++) {
if (fun == ignoreFunctions[i])
return true;
}
// XXX modify refillFreeList<NoGC> to not need data flow analysis to understand it cannot GC.
if (/refillFreeList/.test(fun) && /\(js::AllowGC\)0u/.test(fun))
return true;

Просмотреть файл

@ -75,6 +75,9 @@ function memo(name)
return memoized[name];
}
var seenCallees = null;
var seenSuppressedCallees = null;
function processBody(caller, body)
{
if (!('PEdge' in body))
@ -83,29 +86,43 @@ function processBody(caller, body)
if (edge.Kind != "Call")
continue;
var callee = edge.Exp[0];
var suppressText = (edge.Index[0] in body.suppressed) ? "SUPPRESS_GC " : "";
var suppressText = "";
var seen = seenCallees;
if (edge.Index[0] in body.suppressed) {
suppressText = "SUPPRESS_GC ";
seen = seenSuppressedCallees;
}
var prologue = suppressText + memo(caller) + " ";
if (callee.Kind == "Var") {
assert(callee.Variable.Kind == "Func");
var name = callee.Variable.Name[0];
print("D " + prologue + memo(name));
if (!(name in seen)) {
print("D " + prologue + memo(name));
seen[name] = true;
}
var otherName = otherDestructorName(name);
if (otherName)
if (otherName && !(otherName in seen)) {
print("D " + prologue + memo(otherName));
seen[otherName] = true;
}
} else {
assert(callee.Kind == "Drf");
if (callee.Exp[0].Kind == "Fld") {
var field = callee.Exp[0].Field;
if ("FieldInstanceFunction" in field) {
var fieldName = field.Name[0];
var csuName = field.FieldCSU.Type.Name;
if ("FieldInstanceFunction" in field && csuName != "nsISupports") {
// virtual function call.
var functions = findVirtualFunctions(field.FieldCSU.Type.Name, field.Name[0]);
for (var name of functions)
print("D " + prologue + memo(name));
} else {
var functions = findVirtualFunctions(csuName, fieldName);
for (var name of functions) {
if (!(name in seen)) {
print("D " + prologue + memo(name));
seen[name] = true;
}
}
} else if (csuName != "nsISupports" || fieldName == "QueryInterface") {
// indirect call through a field.
print("F " + prologue +
"CLASS " + field.FieldCSU.Type.Name +
" FIELD " + field.Name[0]);
print("F " + prologue + "CLASS " + csuName + " FIELD " + fieldName);
}
} else if (callee.Exp[0].Kind == "Var") {
// indirect call through a variable.
@ -150,6 +167,10 @@ for (var nameIndex = minStream; nameIndex <= maxStream; nameIndex++) {
body.suppressed = [];
for (var body of functionBodies)
computeSuppressedPoints(body);
seenCallees = {};
seenSuppressedCallees = {};
for (var body of functionBodies)
processBody(name.readString(), body);

Просмотреть файл

@ -4,13 +4,8 @@ set -e
JOBS="$1"
N=$($SIXGILL/bin/xdbkeys src_body.xdb | wc -l)
EACH=$(( $N / $JOBS ))
START=1
for j in $(seq $JOBS); do
END=$(( $START + $EACH ))
env PATH=$PATH:$SIXGILL/bin XDB=$SIXGILL/bin/xdb.so $JS $ANALYZE gcFunctions.txt gcTypes.txt $START $END tmp.$j > rootingHazards.$j &
START=$END
env PATH=$PATH:$SIXGILL/bin XDB=$SIXGILL/bin/xdb.so $JS $ANALYZE gcFunctions.txt gcTypes.txt $j $JOBS tmp.$j > rootingHazards.$j &
done
wait