node/lib/metasm/metasm/decompile.rb
# turns an Expression to a CExpression, create+declares needed variables in scope
turns an Expression to a CExpression, create+declares needed variables in scope
turns an Expression to a CExpression create + declares needed variables in scope
def decompile_cexpr(e, scope, itype=nil)
		case e
		when Expression
			if e.op == :'=' and e.lexpr.kind_of? ::String and e.lexpr =~ /^dummy_metasm_/
				decompile_cexpr(e.rexpr, scope, itype)
			elsif e.op == :+ and e.rexpr.kind_of? ::Integer and e.rexpr < 0
				decompile_cexpr(Expression[e.lexpr, :-, -e.rexpr], scope, itype)
			elsif e.lexpr
				a = decompile_cexpr(e.lexpr, scope, itype)
				C::CExpression[a, e.op, decompile_cexpr(e.rexpr, scope, itype)]
			elsif e.op == :+
				decompile_cexpr(e.rexpr, scope, itype)
			else
				a = decompile_cexpr(e.rexpr, scope, itype)
				C::CExpression[e.op, a]
			end
		when Indirection
			case e.len
			when 1, 2, 4, 8
				bt = C::BaseType.new("__int#{e.len*8}".to_sym)
			else
				bt = C::Struct.new
				bt.members = [C::Variable.new('data', C::Array.new(C::BaseType.new(:__int8), e.len))]
			end
			itype = C::Pointer.new(bt)
			p = decompile_cexpr(e.target, scope, itype)
			p = C::CExpression[[p], itype] if not p.type.kind_of? C::Pointer
			C::CExpression[:*, p]
		when ::Integer
			C::CExpression[e]
		when C::CExpression
			e
		else
			name = e.to_s
			if not s = scope.symbol_ancestors[name]
				s = C::Variable.new
				s.type = C::BaseType.new(:__int32)
				case e
				when ::String	
					return @c_parser.toplevel.symbol[e] || new_global_var(e, itype || C::BaseType.new(:int), scope)
				when ::Symbol; s.storage = :register ; s.add_attribute("register(#{name})")
				else s.type.qualifier = [:volatile]
					puts "decompile_cexpr unhandled #{e.inspect}, using #{e.to_s.inspect}" if $VERBOSE
				end
				s.name = name
				scope.symbol[s.name] = s
				scope.statements << C::Declaration.new(s)
			end
			s
		end
	end
def decompile_cexpr ( e , scope , itype = nil ) case e when Expression if e . op == :' = ' and e . lexpr . kind_of? :: String and e . lexpr =~ / ^dummy_metasm_ / decompile_cexpr ( e . rexpr , scope , itype ) elsif e . op == :+ and e . rexpr . kind_of? :: Integer and e . rexpr < 0 decompile_cexpr ( Expression [ e . lexpr , :- , - e . rexpr ] , scope , itype ) elsif e . lexpr a = decompile_cexpr ( e . lexpr , scope , itype ) C :: CExpression [ a , e . op , decompile_cexpr ( e . rexpr , scope , itype ) ] elsif e . op == :+ decompile_cexpr ( e . rexpr , scope , itype ) else a = decompile_cexpr ( e . rexpr , scope , itype ) C :: CExpression [ e . op , a ] end when Indirection case e . len when 1 , 2 , 4 , 8 bt = C :: BaseType . new ( "__int#{e.len*8}" . to_sym ) else bt = C :: Struct . new bt . members = [ C :: Variable . new ( 'data' , C :: Array . new ( C :: BaseType . new ( :__int8 ) , e . len ) ) ] end itype = C :: Pointer . new ( bt ) p = decompile_cexpr ( e . target , scope , itype ) p = C :: CExpression [ [ p ] , itype ] if not p . type . kind_of? C :: Pointer C :: CExpression [ :* , p ] when :: Integer C :: CExpression [ e ] when C :: CExpression e else name = e . to_s if not s = scope . symbol_ancestors [ name ] s = C :: Variable . new s . type = C :: BaseType . new ( :__int32 ) case e when :: String return @c_parser . toplevel . symbol [ e ] || new_global_var ( e , itype || C :: BaseType . new ( :int ) , scope ) when :: Symbol ; s . storage = :register ; s . add_attribute ( "register(#{name})" ) else s . type . qualifier = [ :volatile ] puts "decompile_cexpr unhandled #{e.inspect}, using #{e.to_s.inspect}" if $VERBOSE end s . name = name scope . symbol [ s . name ] = s scope . statements << C :: Declaration . new ( s ) end s end end
turns an Expression to a CExpression, create+declares needed variables in scope
turns an Expression to a CExpression create + declares needed variables in scope
# edata relocation (rel.length = size of pointer)
e
scope
itype