Exceptions raised when generating SSA against native functions

Apologies in advance if these issues have been discussed before. I did a brief search but wasn't able to come up with anything obvious on the forum or in the documentation. The issue I'm having centers around trying to construct SSA information against native functions. I have a feeling these issues are fairly easy to solve, but thus far I haven't come across a solution.

The tool I'm working on takes care of loading assemblies and does not execute as part of a phase. Part of the analysis it performs requires constructing SSA information to analyze data flow. Function units are raised to the SymbolicFunctionUnitState (is this correct?) and then SSA information is constructed as followed:

Code Snippet

if (funit.SsaInfo ==null)

{

funit.SsaInfo = Phx.SSA.Info.New(funit.Lifetime, funit, Phx.SSA.Attribute.Aliased);

funit.SsaInfo.Build();

}

Judging from the other examples I've seen, this seems to be the correct approach to take. However, as a result of the call to Build, an exception is generated:

Object reference not set to an instance of an object.

at Phx.Alias.Info.GetAliasType(Int32 tag)
at Phx.Alias.FactorAnalyzer.ComputeProxyClosure(FunctionUnit functionUnit)
at Phx.SSA.Info.CollectBaseFlowInfo(Attribute ssaAttribute)
at Phx.SSA.Info.Build()

This same code works perfectly fine with managed assemblies. However, it seems to fail consistently on the native module that I'm attempting to analyze (it also fails on the testapp.exe included in the RDK). I've played around with a few things, such as changing the Phx.SSA.Attribute enumeration value, but this seems to result in additional exceptions. Is there some alias state that isn't being generated before hand that I need to take care of?

Thanks in advance for any insight.

Matt

[2305 byte] By [mmiller] at [2008-2-26]
# 1
It's possible that something was skipped. Can you tell if FunctionUnit.ReaderPostProcess() is being called as part of your raising?
AndyAyers-MSFT at 2007-10-2 > top of Msdn Tech,Visual Studio,Phoenix...
# 2

It looks like ReaderPostProcess is not being called for the native targets I'm analyzing (breakpoint is never hit). I confirmed that this breakpoint is indeed hit for managed binaries:

Code Snippet

break at #1 C:\WINDOWS\assembly\GAC_32\phx\0.64.20220.0__31bf3856ad364e35\phx.dll!Phx.FunctionUnit::ReaderPostProcess:0 ReaderPostProcess+0x0(il) [active]
[0030] push 7
(cordbg) w
Thread 0x1074 Current State:Normal
0)* Phx.FunctionUnit::ReaderPostProcess +0048[native] +0000[IL] in <Unknown File Name>:<Unknown Line Number>
1) Phx.FunctionUnit::DisassembleSymbolically +0444[native] +0202[IL] in <Unknown File Name>:<Unknown Line Number>
2) Phx.PEModuleUnit::Raise +0410[native] +0276[IL] in <Unknown File Name>:<Unknown Line Number>

mmiller at 2007-10-2 > top of Msdn Tech,Visual Studio,Phoenix...
# 3

To get symbolic analysis for x86, you need to pass (or programmatically set) the 'raise' option. Not every function can be raised (there are some thunks and other artifacts that are skipped). Here's a code sample that works on the testapp if you pass in an open PEModule:

Code Snippet

void RaiseToSSA

(

Phx.PEModuleUnit module

)

{

// Enable symbolic analysis of x86 code.

Phx.Controls.Parser.ParseArgumentString(null, "-raise");

foreach (Phx.FunctionUnit functionUnit in

module.GetEnumerableContributionUnit(Phx.ContributionUnitEnumerationKind.WritableFunctionUnit))

{

// Raise

Phx.Threading.Context context = Phx.Threading.Context.GetCurrent();

context.PushUnit(functionUnit);

functionUnit.ParentPEModuleUnit.Raise(functionUnit.FunctionSymbol,

Phx.FunctionUnit.SymbolicFunctionUnitState);

// Verify we could raise before building SSA.

if (functionUnit.HasSymbolicIR)

{

// Build SSA

if (functionUnit.FlowGraph != null)

{

functionUnit.DeleteFlowGraph();

functionUnit.FlowGraph = null;

}

functionUnit.SsaInfo = Phx.SSA.Info.New(functionUnit.Lifetime, functionUnit, Phx.SSA.Attribute.Aliased);

functionUnit.SsaInfo.Build();

Console.WriteLine("Have SSA for {0}", Phx.Utility.Undecorate(functionUnit.NameString, true));

}

else

{

Console.WriteLine("Can't get symbolic IR for {0}, state is {1}", Phx.Utility.Undecorate(functionUnit.NameString,

true), functionUnit.ToString());

}

// Throw out the IR we raised up.

functionUnit.ReleaseLifetime();

}

}

AndyAyers-MSFT at 2007-10-2 > top of Msdn Tech,Visual Studio,Phoenix...
# 4
I haven't had a chance to try this code out yet verbatim, but it's pretty much equivalent to what my code is currently doing. I'll keep playing around with it and post if I can track it down further.
nohaven at 2007-10-2 > top of Msdn Tech,Visual Studio,Phoenix...
# 5

As far as I can tell I'm taking almost the exact same steps as what you outline above. The one major distinction has to do with how I'm obtaining the FunctionUnit. In the context of my code, I'm only working with a FunctionSymbol. I'm not iterating over all of the function units. Instead, I acquire a function symbol's associated function unit by doing the following:

Code Snippet
functionUnit = module.Raise(functionSymbol, FunctionUnit.SymbolicFunctionUnitState);

I then use the function unit to try to build SSA information and so on. I'm guessing that acquiring a function unit in this fashion isn't fully supported (or is just plain wrong). HasSymbolicIR is always false for native code when I run the above code against it. Is there a correct way to obtain a function unit when all you have is a function symbol (which is a restriction related to how my current code is laid out)?

I'll keep messing with it and see what I can find out in the mean time.

Tangent: When enumerating the functions contained within a module, would you recommend enumerating function symbols or function units? Currently, I'm enumerating function symbols, hence the limitation described above.

mmiller at 2007-10-2 > top of Msdn Tech,Visual Studio,Phoenix...
# 6

Can you verify that you are setting the raise control as shown below fairly early on in your processing (or pass -raise on the command line)?

Code Snippet

// Enable symbolic analysis of x86 code.

Phx.Controls.Parser.ParseArgumentString(null, "-raise");

AndyAyers-MSFT at 2007-10-2 > top of Msdn Tech,Visual Studio,Phoenix...
# 7

Good catch. Guess I should read the comment more closely next time

I added this to my phoenix initialization code and it seems to work fine now. Are there any side effects that I should be concious of as a result of setting this flag? I guess a better question would be, why doesn't phoenix have this flag enabled by default (memory consumption)?

Thanks.
mmiller at 2007-10-2 > top of Msdn Tech,Visual Studio,Phoenix...

Visual Studio

Site Classified