[Decompile] pad and gs (#389)

* update stuff

* gs reference added

* update config
This commit is contained in:
water111
2021-04-26 21:40:08 -04:00
committed by GitHub
parent 8619e6df19
commit 3d2ca71fe3
40 changed files with 3716 additions and 1542 deletions
+45 -11
View File
@@ -216,6 +216,24 @@ std::optional<BitFieldDef> get_bitfield_initial_set(Form* form,
return def;
}
// also possible to omit the shr if it would be zero:
auto matcher_no_shr = Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::SHL),
{Matcher::any(0), Matcher::any_integer(1)});
auto mr_no_shr = match(matcher_no_shr, strip_int_or_uint_cast(form));
if (mr_no_shr.matched) {
auto value = mr_no_shr.maps.forms.at(0);
int left = mr_no_shr.maps.ints.at(1);
int right = 0;
int size = 64 - left;
int offset = left - right;
auto& f = find_field(ts, type, offset, size, {});
BitFieldDef def;
def.value = value;
def.field_name = f.name();
def.is_signed = false; // we don't know.
return def;
}
return {};
}
@@ -228,7 +246,7 @@ std::optional<BitFieldDef> get_bitfield_initial_set(Form* form,
FormElement* BitfieldAccessElement::push_step(const BitfieldManip step,
const TypeSystem& ts,
FormPool& pool,
const Env& env) {
const Env&) {
if (m_steps.empty() && step.kind == BitfieldManip::Kind::LEFT_SHIFT) {
// for left/right shift combo to get a field.
m_steps.push_back(step);
@@ -354,6 +372,12 @@ FormElement* BitfieldAccessElement::push_step(const BitfieldManip step,
std::vector<BitFieldDef>{*val});
}
lg::error("Invalid state in BitfieldReadElement. Previous steps:");
for (auto& old_step : m_steps) {
lg::error(" {}", old_step.print());
}
lg::error("Current: {}\n", step.print());
throw std::runtime_error("Unknown state in BitfieldReadElement");
}
@@ -409,8 +433,14 @@ BitFieldDef BitFieldDef::from_constant(const BitFieldConstantDef& constant, Form
BitFieldDef bfd;
bfd.field_name = constant.field_name;
bfd.is_signed = constant.is_signed;
bfd.value = pool.alloc_single_element_form<SimpleAtomElement>(
nullptr, SimpleAtom::make_int_constant(constant.value));
if (constant.enum_constant) {
bfd.value =
pool.alloc_single_element_form<ConstantTokenElement>(nullptr, *constant.enum_constant);
} else {
bfd.value = pool.alloc_single_element_form<SimpleAtomElement>(
nullptr, SimpleAtom::make_int_constant(constant.value));
}
return bfd;
}
@@ -426,7 +456,7 @@ Form* cast_to_bitfield(const BitFieldType* type_info,
in = strip_int_or_uint_cast(in);
// check if it's just a constant:
auto in_as_atom = form_as_atom(in);
if (in_as_atom) {
if (in_as_atom && in_as_atom->is_int()) {
auto fields = decompile_bitfield_from_int(typespec, env.dts->ts, in_as_atom->get_int());
return pool.alloc_single_element_form<BitfieldStaticDefElement>(nullptr, typespec, fields,
pool);
@@ -458,7 +488,8 @@ Form* cast_to_bitfield(const BitFieldType* type_info,
// now variables
for (auto& arg : args) {
auto maybe_field = get_bitfield_initial_set(arg, type_info, env.dts->ts);
auto maybe_field =
get_bitfield_initial_set(strip_int_or_uint_cast(arg), type_info, env.dts->ts);
if (!maybe_field) {
// failed, just return cast.
return pool.alloc_single_element_form<CastElement>(nullptr, typespec, in);
@@ -503,16 +534,19 @@ Form* cast_to_int_enum(const EnumType* type_info,
assert(!type_info->is_bitfield());
auto integer = get_goal_integer_constant(strip_int_or_uint_cast(in), env);
if (integer) {
auto entry =
decompile_int_enum_from_int(TypeSpec(type_info->get_name()), env.dts->ts, *integer);
auto oper = GenericOperator::make_function(
pool.alloc_single_element_form<ConstantTokenElement>(nullptr, type_info->get_name()));
return pool.alloc_single_element_form<GenericElement>(
nullptr, oper, pool.alloc_single_element_form<ConstantTokenElement>(nullptr, entry));
return cast_to_int_enum(type_info, pool, env, *integer);
} else {
// all failed, just return whatever.
return pool.alloc_single_element_form<CastElement>(nullptr, typespec, in);
}
}
Form* cast_to_int_enum(const EnumType* type_info, FormPool& pool, const Env& env, s64 in) {
auto entry = decompile_int_enum_from_int(TypeSpec(type_info->get_name()), env.dts->ts, in);
auto oper = GenericOperator::make_function(
pool.alloc_single_element_form<ConstantTokenElement>(nullptr, type_info->get_name()));
return pool.alloc_single_element_form<GenericElement>(
nullptr, oper, pool.alloc_single_element_form<ConstantTokenElement>(nullptr, entry));
}
} // namespace decompiler