-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Memory Region and VSA bug fixes #270
base: main
Are you sure you want to change the base?
Conversation
src/main/scala/util/RunUtils.scala
Outdated
modified = transforms.VSAIndirectCallResolution( | ||
ctx.program, | ||
result.vsaResult, | ||
result.mmmResults | ||
).resolveIndirectCalls() | ||
if analysisResult.size < 2 then | ||
modified = true | ||
else | ||
modified = transforms.VSAIndirectCallResolution( | ||
ctx.program, | ||
result.vsaResult, | ||
result.mmmResults | ||
).resolveIndirectCalls() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the reason for this, why do we not try to resolve indirect calls until at least two iterations have been completed?
src/main/scala/util/RunUtils.scala
Outdated
while (modified || (analysisResult.size < 2 && config.memoryRegions)) { | ||
while (modified || (analysisResult.size < 2)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't want to run the analyses multiple times unless it's necessary for the memory regions
This fixes #266 and #264, which is great, but doesn't fix #265 since the heap regions are still not showing up in the output anywhere. I'm not sure why you say this addresses #100 since that's not really related to this and was fixed a long time ago, do you mean #263? With these changes, that is still an issue for indirect_calls/functionpointer/clang:BAP and indirect_calls/functionpointer/clang_pic:BAP (it seems to vary a bit which variations are affected which is why I think it's potentially some sort of non-deterministic iteration-order issue). For instance, for indirect_calls/functionpointer/clang:BAP I get the following output:
You can see the last two accesses clearly have the same index but they are incorrectly given different stack regions. There is still an issue issue with the VSA (same as the one here which has only been partially fixed: #264 (comment)) for the following cases:
For correct/basic_lock_read/gcc_pic:BAP, the relevant parts of the .bir are below.
The address 0x10FD8 points to the address of z (0x11018), so after %00000305, R0 == 0x11018 and after %0000030c R0 is equal to the value stored at z. The issue is on the second iteration of the analyses( which uses the VSA results) at %00000312, the VSA incorrectly has that R0 == 0x11018 which is not correct. |
} else { | ||
// this is a constant but we need to check if it is a data region | ||
checkIfDefined(evalMemLoadToGlobal(assign.rhs, 1, assign), n) | ||
return checkIfDefined(tryCoerceIntoData(assign.rhs, assign, 1), n) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this use an access size of 1? This seems to produce a lot of regions with size 1 in the GRA results that are not actually real regions.
This is a Draft PR. I am working on pushing fixes for the other two issues. The #100 was tagged by mistake |
All good, it's very close to being all fixed! |
@l-kent I think the latest commits should address most of the issues. I will work on merging main into this branch |
I can handle merging it, I'll look at that now. |
This most recent set of changes has introduced a lot of regressions, so it's not suitable for merging. |
Unit tests? |
You can run MemoryRegionSystemTestsBAP and MemoryRegionSystemTestsGTIRB to see. Before yesterday's changes, only these tests were failing in MemoryRegionSystemTestsBAP, since you had fixed most of the outstanding issues by early last week:
With the most recent changes, now all of the following tests fail:
I'll have a look at why these are failing. |
} | ||
) | ||
} | ||
print("Done") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please don't include print calls like this
There seems to be a bug in the stack identification. In most of these cases the issue is that there is no region identified for the first stack access. The only exceptions are the following two cases, which are still partially bugged as described in #264:
The issue is that there is an inconsistency between the GRA results and the MMM's dataMap. This is caused by the GRA creating incorrect regions that override the correct regions in the MMM. These incorrect regions are of size 1 and created through this call:
|
For correct/initialisation/clang:BAP, the main problem happens when that line is called for the line %00000371. The relevant parts of the .bir are below:
0x10FC8 contains the value 0x11040, which is the address of the global variable a. At %00000371, R8 is equal to the contents of a, but tryCoerceIntoData evaluates it as 0x11040 instead, so the GRA incorrectly creates a new, non-existent region of size 1 with address 0x11043 (69699 in decimal) which overrides the correct region with 0x11040 as they overlap. |
tryCoerceIntoData evaluates R8 at %00000371 incorrectly because that is the result the VSA gives. |
The heap identification doesn't seem to be working in all cases yet, but it's a start at least. For malloc_with_local/clang:BAP, these are the relevant allocations and heap accesses in the .bir file:
Currently, %000003cc and %000003e0 are correctly identified as heap accesses (to separate heap locations), but %000003ee and %0000040f are incorrectly identified as stack accesses. |
Hi @l-kent I am exploring correct/initialisation/clang_pic:BAP, can you please give me some clues as to why this example does not verify even after the latest changes that do not create that non-existent region? |
There is still an inconsistency between the GRA result and the MMM dataMap - the dataMap now has no region with address 69696 (there should be one of size 4) at all, but the GRA result has a region with address 69696 and size 8. |
I haven't figured out why that region is missing from the MMM dataMap yet. The size issue in the GRA result is probably related to something being loaded from the symbol table data somewhere. The GRA result is also inconsistent as it (correctly) has a region with address 69700 with size 4, which overlaps the region at address 69696 with (incorrect) size 8. |
All the other issues seem to be solved though, which is great. |
In globals list we have which means region 69696 should be of size 8 not 4? |
a is an array containing two 32-bit values. We want our regions to be based on the accesses that actually happen in the program. |
I tried to merge this in but I can't merge this in without breaking things so I will leave it for another time. |
That is okay. This branch doesn't have the change of MemoryLoad as a statement so it is a fair bit of changes. Thanks for trying I will help merge after the demo |
# Conflicts: # src/main/scala/analysis/ANR.scala # src/main/scala/analysis/Analysis.scala # src/main/scala/analysis/GlobalRegionAnalysis.scala # src/main/scala/analysis/InterprocSteensgaardAnalysis.scala # src/main/scala/analysis/MemoryRegionAnalysis.scala # src/main/scala/analysis/RNA.scala # src/main/scala/analysis/UtilMethods.scala # src/main/scala/analysis/VSA.scala # src/main/scala/util/RunUtils.scala # src/test/scala/SystemTests.scala
I've merged main into this branch and fixed one problem that was my fault but there are still further issues. I've made it throw an exception when the RegionInjector can't find a region in the MMM that should be there. |
…in GRA results, throw exception if MMM has incorrect size
case assign: LocalAssign => | ||
// this is a constant but we need to check if it is a data region | ||
checkIfDefined(evalMemLoadToGlobal(assign.rhs, 1, assign), n) | ||
checkIfDefined(tryCoerceIntoData(assign.rhs, assign, 1, noLoad = true), n) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current issues seem to be in significant part due to this line. Creating regions with a size of 1 here creates a lot of regions with incorrect sizes that cause problems.
These are what currently fail:
The issue seems to mostly be with regions loaded from the symbol table being incorrectly deleted or overwritten. |
I don't really understand why this is only happening now, but convertMemoryRegions in MemoryModelMap seems to be causing the other problems - if a region loaded from the symbol table is not in the GRA result, it is completely removed. We want to keep non-conflicting regions from the symbol table around, and may just need to adjust the size of ones that do conflict? |
There are also some issues with stack & heap identification as seen in MemoryRegionTestsMRA but we don't need to fix those right away. |
This still fails for the following two cases:
The other bug which was causing most of the failures has been fixed though, great! |
Thanks for checking Liam. I have got it to pass everything except Command: List(boogie, /printVerifiedProceduresCount:0, /timeLimit:10, /useArrayAxioms, ./src/test/correct/initialisation/clang_O2/initialisation_bap.bpl) |
This PR addresses multiple issues
Inconsistencies between GRA and MMM #266
Region identification issues with array accesses #264
Heap Identification for Regions Analysis #265
Incorrect stack region identification #263