Skip to content

Commit

Permalink
[move-decompiler] Model import from binary and basic decompiler setup
Browse files Browse the repository at this point in the history
This PR closes the loop on the needed components for the decompiler and sets up basic plumbing for the command line tool.

- A major addition is a way to import Move bytecode into the move-model. Until now, this wasn't directly possible. The new module `binary_module_loader` now takes care of this. The code is mostly complete, what is missing is a way to analyze metadata to synthesize attributes. (Future PRs.)
- The crate `move-decompiler` has been added, which glues the various parts which have been created in the last few PRs into a command line tool.
- Some tests have been added together with the decompiler, which is also a good way to test the new `binary_module_loader`, by replicating parts of the move-stdlib. However, the decompiler isn't functional yet, the code isn't correct in multiple instances. This has to be fixed in subsequent PRs, until the tests in `move-decompiler` allow to compile and executed decompiled code.
  • Loading branch information
wrwg committed Oct 15, 2024
1 parent 2a0e7d6 commit cdd298f
Show file tree
Hide file tree
Showing 94 changed files with 4,410 additions and 283 deletions.
21 changes: 21 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ members = [
"third_party/move/tools/move-bytecode-viewer",
"third_party/move/tools/move-cli",
"third_party/move/tools/move-coverage",
"third_party/move/tools/move-decompiler",
"third_party/move/tools/move-disassembler",
"third_party/move/tools/move-explain",
"third_party/move/tools/move-package",
Expand Down Expand Up @@ -825,6 +826,7 @@ move-coverage = { path = "third_party/move/tools/move-coverage" }
move-compiler = { path = "third_party/move/move-compiler" }
move-compiler-v2 = { path = "third_party/move/move-compiler-v2" }
move-core-types = { path = "third_party/move/move-core/types" }
move-decompiler = { path = "third_party/move/tools/move-decompiler" }
move-docgen = { path = "third_party/move/move-prover/move-docgen" }
move-disassembler = { path = "third_party/move/tools/move-disassembler" }
move-ir-types = { path = "third_party/move/move-ir/types" }
Expand Down
8 changes: 8 additions & 0 deletions third_party/move/move-binary-format/src/views.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,10 @@ impl<'a, T: ModuleAccess> StructDefinitionView<'a, T> {
self.struct_handle_view.abilities()
}

pub fn handle_idx(&self) -> StructHandleIndex {
self.struct_def.struct_handle
}

pub fn is_native(&self) -> bool {
match &self.struct_def.field_information {
StructFieldInformation::Native => true,
Expand Down Expand Up @@ -491,6 +495,10 @@ impl<'a, T: ModuleAccess> FunctionDefinitionView<'a, T> {
}
}

pub fn handle_idx(&self) -> FunctionHandleIndex {
self.function_def.function
}

pub fn visibility(&self) -> Visibility {
self.function_def.visibility
}
Expand Down
6 changes: 5 additions & 1 deletion third_party/move/move-command-line-common/src/files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ pub struct FileHash(pub [u8; 32]);

impl FileHash {
pub fn new(file_contents: &str) -> Self {
Self(sha2::Sha256::digest(file_contents.as_bytes()).into())
Self::new_from_bytes(file_contents.as_bytes())
}

pub fn new_from_bytes(bytes: &[u8]) -> Self {
Self(sha2::Sha256::digest(bytes).into())
}

pub const fn empty() -> Self {
Expand Down
13 changes: 2 additions & 11 deletions third_party/move/move-compiler-v2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ use crate::{
variable_coalescing::VariableCoalescing,
},
};
use anyhow::bail;
use codespan_reporting::{
diagnostic::Severity,
term::termcolor::{ColorChoice, StandardStream, WriteColor},
Expand Down Expand Up @@ -596,21 +595,13 @@ fn get_vm_error_loc(env: &GlobalEnv, source_map: &SourceMap, e: &VMError) -> Opt
}

/// Report any diags in the env to the writer and fail if there are errors.
pub fn check_errors<W>(
env: &GlobalEnv,
error_writer: &mut W,
msg: &'static str,
) -> anyhow::Result<()>
pub fn check_errors<W>(env: &GlobalEnv, error_writer: &mut W, msg: &str) -> anyhow::Result<()>
where
W: WriteColor + Write,
{
let options = env.get_extension::<Options>().unwrap_or_default();
env.report_diag(error_writer, options.report_severity());
if env.has_errors() {
bail!("exiting with {}", msg);
} else {
Ok(())
}
env.check_diag(error_writer, options.report_severity(), msg)
}

/// Annotate the given compiled units.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,18 @@ module 0x815::m {
}
fun update_common_field(): u64 {
let common = CommonFields::Bar{x: 30,y: 40u8,z: 50u32};
common.Foo.x = 15;
common.Foo.x
common.x = 15;
common.x
}
fun update_common_field_different_offset(): u8 {
let common = CommonFields::Bar{x: 30,y: 40u8,z: 50u32};
common.Foo.y = 15u8;
common.Foo.y
common.y = 15u8;
common.y
}
fun update_non_common_field(): u32 {
let common = CommonFields::Bar{x: 30,y: 40u8,z: 50u32};
common.Bar.z = 15u32;
common.Bar.z
common.z = 15u32;
common.z
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ module 0x815::m {
}
fun test_common_access(): u8 {
let x = Positional::A(42u8);
x.A.0 = 19u8;
x.0 = 19u8;
20u8
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ module 0x8675::M {
test1(7) + test1(2)
}
fun test1(r: u64): u64 {
let tref = &mut (if (r < 4) r else 3);
let tref = &mut (if (r < 4) r
else 3);
*tref = 10;
let y = r;
let tref2 = &mut y;
Expand All @@ -127,7 +128,8 @@ module 0x8675::M {
}
fun test1b(r: S): u64 {
let x = S{f: 3};
let tref = &mut (if (r.f < 4) r else x);
let tref = &mut (if (r.f < 4) r
else x);
(*tref).f = 10;
let y = r;
let tref2 = &mut y;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ module 0x42::freeze_mut_ref {
/*freeze*/v
}
public fun borrow_mut3<Element>(v1: &mut Element, v2: &Element): &Element {
if (true) /*freeze*/v1 else v2
if (true) /*freeze*/v1
else v2
}
public fun borrow_mut4<Element>(v: &mut Element): &Element {
/*freeze*/v
Expand Down Expand Up @@ -157,14 +158,17 @@ module 0x42::freeze_mut_ref {
}
fun t6(cond: bool, s: &mut S, other: &S) {
let x;
if (cond) x = /*freeze*/copy s else x = other;
if (cond) x = /*freeze*/copy s
else x = other;
}
fun t7(cond: bool, s: &mut S, other: &S) {
let _x;
_x = if (cond) /*freeze*/s else other;
_x = if (cond) /*freeze*/s
else other;
}
fun t8(cond: bool, s: &mut S, other: &S) {
let _x = if (cond) /*freeze*/s else other;
let _x = if (cond) /*freeze*/s
else other;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@ module 0x42::if_else {
// -- Sourcified model before bytecode pipeline
module 0x42::if_else {
fun if_else(cond: bool, x: u64): u64 {
if (cond) x + 1 else x - 1
if (cond) x + 1
else x - 1
}
fun if_else_nested(cond: bool, x: u64): u64 {
if ((if (cond) x + 1 else x - 1) > 10) x * 2 else x / 2
if ((if (cond) x + 1
else x - 1) > 10) x * 2
else x / 2
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ module 0x815::test {
fun f1() {
'l0: loop {
loop 'l1: loop if (true) loop {
if (false) continue 'l0 else break 'l1;
if (false) continue 'l0
else break 'l1;
break
} else continue 'l0;
}
else continue 'l0;
break
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -320,13 +320,13 @@ module 0xc0ffee::m {
}
}
fun select_common_fields(s: CommonFields): u64 {
s.Foo.x + (match (s) {
s.x + (match (s) {
CommonFields::Foo{x: _,y: y} => y,
CommonFields::Bar{x: _,z: z} => z,
})
}
fun select_common_fields_different_offset(s: CommonFieldsAtDifferentOffset): u64 {
s.Bar.z
s.z
}
fun test_common(s: CommonFields): bool {
s is Foo | Bar
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ module <SELF>_0 {
// -- Sourcified model before bytecode pipeline
script {
fun main() {
if (false) () else break;
if (false) ()
else break;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ module 0x42::m {
// -- Sourcified model before bytecode pipeline
module 0x42::m {
fun invalid<T: drop + key>(addr: address) {
if (exists<T>(addr)) () else abort 0;
if (exists<T>(addr)) ()
else abort 0;
let _ = borrow_global<T>(addr);
move_from<T>(addr);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,17 +122,14 @@ module 0x42::m {
}
fun f10(x: u64)
acquires *(m::make_up_address(x))

{
}
fun f11()
!reads *(0x42)
!reads *(0x43)

{
}
fun f12()

{
}
fun f2()
Expand Down Expand Up @@ -161,16 +158,18 @@ module 0x42::m {
}
fun f8()
acquires *(0x42)

{
}
fun f9(a: address)
acquires *(a)

{
}
fun f_multiple()
acquires Rreads Rwrites Twrites Sreads G<u64>
acquires R
reads R
writes T
writes S
reads G<u64>
{
}
fun make_up_address(x: u64): address {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ module 0x815::test {
fun f1() {
'l0: loop {
loop 'l1: loop if (true) loop {
if (false) continue 'l0 else break 'l1;
if (false) continue 'l0
else break 'l1;
break
} else continue 'l0;
}
else continue 'l0;
break
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,8 @@ module 0x42::test {
}
fun simple_5(x: E1): u8 {
match (x) {
E1::A(_,y) => if (y) 1u8 else 0u8,
E1::A(_,y) => if (y) 1u8
else 0u8,
E1::B(x) => x,
E1::C{x: _,y: S1(x)} => x,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ module 0x1::m {
{
let x = borrow_global_mut<R>(0x1);
x.value = false;
if (borrow_global<R>(0x1).value == false) () else abort 1;
if (borrow_global<R>(0x1).value == false) ()
else abort 1;
borrow_global_mut<R>(0x1).value = true;
if (borrow_global<R>(0x1).value == true) () else abort 2;
if (borrow_global<R>(0x1).value == true) ()
else abort 2;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ module 0xcafe::vectors {
i = i + 1
}
};
if (v == vector[2, 3, 4]) () else abort 0;
if (v == vector[2, 3, 4]) ()
else abort 0;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ module 0xcafe::vectors {
let (flips) = (&flips);
let i = 0;
while (i < 0x1::vector::length<u8>(flips)) {
if (*0x1::vector::borrow<u8>(flips, i) == 0u8) () else abort 3;
if (*0x1::vector::borrow<u8>(flips, i) == 0u8) ()
else abort 3;
i = i + 1;
};
};
Expand All @@ -226,7 +227,8 @@ module 0xcafe::vectors {
inline fun loops_without_break(flips: &vector<u8>) {
let i = 0;
while (i < 0x1::vector::length<u8>(flips)) {
if (*0x1::vector::borrow<u8>(flips, i) == 0u8) () else abort 3;
if (*0x1::vector::borrow<u8>(flips, i) == 0u8) ()
else abort 3;
i = i + 1;
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ module 0x42::test {
use 0x42::mathtest2;
use 0x42::mathtest;
fun test_nested_fun1() {
if (true) () else abort 0;
if (true) ()
else abort 0;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ module 0x42::LambdaTest {
1120
}
fun test_lambda() {
if (false) () else abort 0;
if (false) ()
else abort 0;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ module 0x42::LambdaTest {
1120
}
fun test_lambda() {
if (false) () else abort 0;
if (false) ()
else abort 0;
}
}

Expand Down
Loading

0 comments on commit cdd298f

Please sign in to comment.