[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
+97 -29
View File
@@ -201,6 +201,19 @@ void pop_helper(const std::vector<RegisterAccess>& vars,
}
}
namespace {
Form* strip_pcypld_64(Form* in) {
auto m = match(Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::PCPYLD),
{Matcher::integer(0), Matcher::any(0)}),
in);
if (m.matched) {
return m.maps.forms.at(0);
} else {
return in;
}
}
} // namespace
/*!
* This should be used to generate all casts.
*/
@@ -213,6 +226,9 @@ Form* cast_form(Form* in, const TypeSpec& new_type, FormPool& pool, const Env& e
auto type_info = env.dts->ts.lookup_type(new_type);
auto bitfield_info = dynamic_cast<BitFieldType*>(type_info);
if (bitfield_info) {
if (bitfield_info->get_load_size() == 8) {
in = strip_pcypld_64(in);
}
return cast_to_bitfield(bitfield_info, new_type, pool, env, in);
}
@@ -314,13 +330,6 @@ bool is_ptr_or_child(const Env& env, int my_idx, RegisterAccess var, bool) {
return type == "pointer";
}
bool is_var(Form* form) {
auto atom = form_as_atom(form);
if (atom) {
return atom->is_var();
}
return false;
}
} // namespace
/*!
@@ -846,6 +855,36 @@ void SimpleExpressionElement::update_from_stack_force_ui_2(const Env& env,
result->push_back(new_form);
}
void SimpleExpressionElement::update_from_stack_pcypld(const Env& env,
FormPool& pool,
FormStack& stack,
std::vector<FormElement*>* result,
bool allow_side_effects) {
std::vector<Form*> args;
std::vector<RegisterAccess> ras;
for (int arg_idx = 0; arg_idx < m_expr.args(); arg_idx++) {
if (m_expr.get_arg(arg_idx).is_var()) {
ras.push_back(m_expr.get_arg(arg_idx).var());
}
}
auto popped_args = pop_to_forms(ras, env, pool, stack, allow_side_effects);
int ras_idx = 0;
for (int arg_idx = 0; arg_idx < m_expr.args(); arg_idx++) {
if (m_expr.get_arg(arg_idx).is_var()) {
args.push_back(popped_args.at(ras_idx));
ras_idx++;
} else {
args.push_back(
pool.alloc_single_element_form<SimpleAtomElement>(nullptr, m_expr.get_arg(arg_idx)));
}
}
auto new_form = pool.alloc_element<GenericElement>(
GenericOperator::make_fixed(FixedOperatorKind::PCPYLD), args.at(0), args.at(1));
result->push_back(new_form);
}
void SimpleExpressionElement::update_from_stack_copy_first_int_2(const Env& env,
FixedOperatorKind kind,
FormPool& pool,
@@ -966,9 +1005,11 @@ void SimpleExpressionElement::update_from_stack_logor_or_logand(const Env& env,
if (bitfield_info) {
// either the immediate didn't fit in the 16-bit imm or it's with a variable
bool made_new_read_elt = false;
auto read_elt = dynamic_cast<BitfieldAccessElement*>(args.at(0)->try_as_single_element());
if (!read_elt) {
read_elt = pool.alloc_element<BitfieldAccessElement>(args.at(0), arg0_type);
made_new_read_elt = true;
}
auto stripped_arg1 = strip_int_or_uint_cast(args.at(1));
@@ -987,7 +1028,7 @@ void SimpleExpressionElement::update_from_stack_logor_or_logand(const Env& env,
assert(!other); // shouldn't be complete.
result->push_back(read_elt);
return;
} else {
} else if (!made_new_read_elt) {
BitfieldManip::Kind manip_kind;
if (kind == FixedOperatorKind::LOGAND) {
manip_kind = BitfieldManip::Kind::LOGAND_WITH_FORM;
@@ -1325,6 +1366,9 @@ void SimpleExpressionElement::update_from_stack(const Env& env,
case SimpleExpression::Kind::FLOAT_TO_INT:
update_from_stack_float_to_int(env, pool, stack, result, allow_side_effects);
break;
case SimpleExpression::Kind::PCPYLD:
update_from_stack_pcypld(env, pool, stack, result, allow_side_effects);
break;
default:
throw std::runtime_error(
fmt::format("SimpleExpressionElement::update_from_stack NYI for {}", to_string(env)));
@@ -2292,14 +2336,20 @@ void ShortCircuitElement::update_from_stack(const Env& env,
already_rewritten = true;
}
namespace {
Matcher make_int_uint_cast_matcher(const Matcher& thing) {
return Matcher::match_or({Matcher::cast("uint", thing), Matcher::cast("int", thing), thing});
}
} // namespace
///////////////////
// ConditionElement
///////////////////
FormElement* ConditionElement::make_zero_check_generic(const Env&,
FormElement* ConditionElement::make_zero_check_generic(const Env& env,
FormPool& pool,
const std::vector<Form*>& source_forms,
const std::vector<TypeSpec>&) {
const std::vector<TypeSpec>& source_types) {
// (zero? (+ thing small-integer)) -> (= thing (- small-integer))
assert(source_forms.size() == 1);
auto mr = match(Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::ADDITION),
@@ -2311,9 +2361,26 @@ FormElement* ConditionElement::make_zero_check_generic(const Env&,
nullptr, SimpleAtom::make_int_constant(value));
return pool.alloc_element<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::EQ),
std::vector<Form*>{mr.maps.forms.at(0), value_form});
} else {
return pool.alloc_element<GenericElement>(GenericOperator::make_compare(m_kind), source_forms);
}
auto enum_type_info = env.dts->ts.try_enum_lookup(source_types.at(0));
if (enum_type_info && !enum_type_info->is_bitfield()) {
// (zero? (+ (the-as uint arg0) (the-as uint -2))) check enum value
mr = match(Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::ADDITION),
{make_int_uint_cast_matcher(Matcher::any(0)),
make_int_uint_cast_matcher(Matcher::any_integer(1))}),
source_forms.at(0));
if (mr.matched) {
s64 value = mr.maps.ints.at(1);
value = -value;
auto enum_constant = cast_to_int_enum(enum_type_info, pool, env, value);
return pool.alloc_element<GenericElement>(
GenericOperator::make_fixed(FixedOperatorKind::EQ),
std::vector<Form*>{mr.maps.forms.at(0), enum_constant});
}
}
return pool.alloc_element<GenericElement>(GenericOperator::make_compare(m_kind), source_forms);
}
FormElement* ConditionElement::make_nonzero_check_generic(const Env& env,
@@ -2682,6 +2749,7 @@ void ReturnElement::push_to_stack(const Env& env, FormPool& pool, FormStack& sta
}
namespace {
void push_asm_srl_to_stack(const AsmOp* op,
FormElement* form_elt,
const Env& env,
@@ -2714,6 +2782,21 @@ void push_asm_srl_to_stack(const AsmOp* op,
}
}
void push_asm_to_stack(const AsmOp* op,
FormElement* form_elt,
const Env& env,
FormPool& pool,
FormStack& stack) {
switch (op->instruction().kind) {
case InstructionKind::SRL:
push_asm_srl_to_stack(op, form_elt, env, pool, stack);
break;
default:
stack.push_form_element(form_elt, true);
break;
}
}
} // namespace
void AtomicOpElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
@@ -2737,14 +2820,7 @@ void AtomicOpElement::push_to_stack(const Env& env, FormPool& pool, FormStack& s
auto as_asm = dynamic_cast<const AsmOp*>(m_op);
if (as_asm) {
switch (as_asm->instruction().kind) {
case InstructionKind::SRL:
push_asm_srl_to_stack(as_asm, this, env, pool, stack);
break;
default:
stack.push_form_element(this, true);
break;
}
push_asm_to_stack(as_asm, this, env, pool, stack);
return;
}
@@ -2753,15 +2829,7 @@ void AtomicOpElement::push_to_stack(const Env& env, FormPool& pool, FormStack& s
void AsmOpElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
mark_popped();
switch (m_op->instruction().kind) {
case InstructionKind::SRL:
push_asm_srl_to_stack(m_op, this, env, pool, stack);
break;
default:
stack.push_form_element(this, true);
break;
}
push_asm_to_stack(m_op, this, env, pool, stack);
}
void GenericElement::update_from_stack(const Env& env,