Skip to content

capstone: add cs_regs_access #77

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

Closed
wants to merge 6 commits into 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

Attention: Patch coverage is 71.75573% with 37 lines in your changes missing coverage. Please review.

Project coverage is 94.17%. Comparing base (efdddcb) to head (0475878).
Report is 140 commits behind head on master.

Files with missing lines Patch % Lines
capstone-rs/src/instruction.rs 48.61% 37 Missing ⚠️
Additional details and impacted files
@@            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     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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?

@@ -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];

@tmfink
Copy link
Member

tmfink commented Apr 20, 2025

Addresses #84

@tmfink
Copy link
Member

tmfink commented Apr 20, 2025

Thanks for the PR, but I decided to go with #149 as a starting point.

@tmfink tmfink closed this Apr 20, 2025
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