Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

capstone: add cs_regs_access #77

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

SWW13
Copy link

@SWW13 SWW13 commented Oct 8, 2019

Adds support for cs_regs_access, fixes #63.

I'm not sure how to implement the tests yet, the instructions_* tests are a bit complicated on first sight.

@codecov
Copy link

codecov bot commented Oct 8, 2019

Codecov Report

Merging #77 into master will increase coverage by 0.35%.
The diff coverage is 71.75%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #77      +/-   ##
==========================================
+ Coverage   93.81%   94.17%   +0.35%     
==========================================
  Files          20       20              
  Lines        2701     3983    +1282     
==========================================
+ Hits         2534     3751    +1217     
- Misses        167      232      +65
Impacted Files Coverage Δ
capstone-rs/src/test.rs 97.27% <100%> (+1.26%) ⬆️
capstone-rs/src/capstone.rs 96.74% <100%> (+2.78%) ⬆️
capstone-rs/src/instruction.rs 76.22% <48.61%> (-11.85%) ⬇️
capstone-rs/src/error.rs 63.41% <0%> (-1.59%) ⬇️
capstone-rs/src/constants.rs 79.06% <0%> (-0.45%) ⬇️
capstone-rs/src/arch/tms320c64x.rs 97.67% <0%> (+0.07%) ⬆️
capstone-rs/src/arch/mod.rs 90.9% <0%> (+0.08%) ⬆️
capstone-rs/src/arch/m68k.rs 91.94% <0%> (+0.15%) ⬆️
... and 1 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update efdddcb...0475878. Read the comment docs.

Copy link
Member

@tmfink tmfink left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, this looks really great.

Once you implement these changes, also add some tests in src/tests.rs. These should basically be an example program that shows how to use the new API, but also calls assert_eq!(...) to verify that you get the expected output.

@@ -328,6 +345,64 @@ impl<'a> InsnDetail<'a> {
}
}

impl<'a> InsnRegsAccess {
fn new(cs: csh, ins: &cs_insn) -> Self {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any function that can cause undefined behavior should be marked unsafe.

However, once you move the error checking (checking return value), then this shouldn't need to be marked unsafe.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have this return a CsResult<Self> instead

/// 1. Instruction was created with detail enabled
/// 2. Skipdata is disabled
/// 3. Capstone was not compiled in diet mode
pub fn insn_regs_access<'s, 'i: 's>(&'s self, insn: &'i Insn) -> CsResult<InsnRegsAccess> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of trying to do all of the error handling here, check the returned integer and convert that to a CsResult.
You can move that logic into
That way, we don't have to manually track all possible errors that capstone should be handling anyway.

For examples, see disasm(). Also, From<capstone_sys::cs_err::Type> is implemented for Error, so you can use Error::from(capstone_sys_rc)` to do the error parsing for you.

let mut regs_write_count = 0u8;

unsafe {
cs_regs_access(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check this return value to create a CsResult

@@ -145,6 +145,14 @@ pub struct Insn<'a> {
/// `ArchDetail` enum.
pub struct InsnDetail<'a>(pub(crate) &'a cs_detail, pub(crate) Arch);

/// Contains information about registers accessed by an instruction, either explicitly or implicitly
pub struct InsnRegsAccess {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add #[derive(Debug, Clone, PartialEq, Eq)]

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug, PartialEq, Eq can't be derived because of the array with size >32, I added a comment

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you manually impl PartialEq, Eq?

capstone-rs/src/instruction.rs Show resolved Hide resolved
@@ -328,6 +345,64 @@ impl<'a> InsnDetail<'a> {
}
}

impl<'a> InsnRegsAccess {
fn new(cs: csh, ins: &cs_insn) -> Self {
let mut regs_read = [0u16; 64];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use cs_regs type directly instead of manually declaring an array.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you give an example how to initialize a variable with a type?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like cs_regs is a type alias:

pub type cs_regs = [u16; 64usize];

Just add an explicit type instead of using type inference:

let mut regs_read: cs_regs = [0u16; 64];

@tmfink tmfink self-assigned this Oct 9, 2019
@tmfink
Copy link
Member

tmfink commented Oct 9, 2019

@SWW13 Thanks for the pull-request! This is great work.

If you have any questions related to review comments or capstone, feel free to reach out.

@SWW13 SWW13 changed the title WIP: capstone: add cs_regs_access capstone: add cs_regs_access Oct 9, 2019
@@ -145,6 +145,14 @@ pub struct Insn<'a> {
/// `ArchDetail` enum.
pub struct InsnDetail<'a>(pub(crate) &'a cs_detail, pub(crate) Arch);

/// Contains information about registers accessed by an instruction, either explicitly or implicitly
pub struct InsnRegsAccess {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you manually impl PartialEq, Eq?

@@ -328,6 +345,64 @@ impl<'a> InsnDetail<'a> {
}
}

impl<'a> InsnRegsAccess {
fn new(cs: csh, ins: &cs_insn) -> Self {
let mut regs_read = [0u16; 64];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like cs_regs is a type alias:

pub type cs_regs = [u16; 64usize];

Just add an explicit type instead of using type inference:

let mut regs_read: cs_regs = [0u16; 64];

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support v4 cs_regs_access API
2 participants