Update to Zig 0.14.1 including ManagedIter#3
Conversation
SoraTenshi
left a comment
There was a problem hiding this comment.
Great job!
I wasn't using capstone much when i was creating those bindings, so it's great to get some actual user feedback. If you had some major refactorings / etc. in mind, please let me know!
Also in case there's discussion / style question, i am fine with discussing those as well.
|
|
||
| pub fn deinit(self: *Self) void { | ||
| impl.close(&self.native) catch |e| { | ||
| std.debug.print("Failed to close handle: {any}\n", .{impl.strerror(e)}); |
There was a problem hiding this comment.
don't use debug print here, instead:
std.io.getStdErr().writer().print("Failed to close handle: {any}\n", .{impl.strerror(e)});There was a problem hiding this comment.
hmm so std.io.getStdErr().writer().print("Failed to close handle: {any}\n", .{impl.strerror(e)}) catch {}; since the print returns error, I don't think a deinit function should return any error?
| insn: [*]Insn, | ||
|
|
||
| pub fn init(handle: Handle, code: []const u8, address: u64) IterManaged { | ||
| const insn: [*]Insn = @ptrCast(cs.cs_malloc(handle)); |
There was a problem hiding this comment.
Hmm, this seems a bit fishy, i believe i have forgotten to implement an abstraction for cs_malloc that returns either an error or the pointer (which must be valid).
in src/impl.zig there's a malloc function, this we should probably fix in case of OOM.
There was a problem hiding this comment.
Actually the cs_malloc doesn't return any error... https://github.com/capstone-engine/capstone/blob/280b749e84adca4177b7525504e55be4d8c74e44/cs.c#L1429 ow wait I mean it doesn't return the error directly but it does set the error to the handle, hmm ye the managed iter needs to return error too
There was a problem hiding this comment.
i was thinking about wrapping the type for it.
pub fn allocInsn(handle: Handle) ![*]Insn {
const insn: ?[*]Insn = @ptrCast(cs.cs_malloc(handle));
return if(insn) |i| i else error.OutOfMemory;
}There was a problem hiding this comment.
I think ye we should just replace the
pub fn malloc(handle: Handle) [*]insn.Insn {
return @ptrCast(cs.cs_malloc(handle));
}this malloc really doesn't make sense from the user space, since all it does is allocate space for only one insn.Insn
There was a problem hiding this comment.
i was thinking about wrapping the type for it.
pub fn allocInsn(handle: Handle) ![*]Insn { const insn: ?[*]Insn = @ptrCast(cs.cs_malloc(handle)); return if(insn) |i| i else error.OutOfMemory; }
and by the way shouldn't we return a *Insn the many pointer [*] variant doesn't make sense here, coz it will always return one Insn I will try to convert all the [*] many pointer variants to one pointer variant where it's appropiate
There was a problem hiding this comment.
I am not tooo familiar with capstone, hence i tried and kept it as close to C as possible.
But yeah, if it is always a single instance of an Insn, then i agree with you.
|
Also, i am fine with exposing all the defines that come from C, generally. |
hmm, i think we can abuse comptime to only expose the "defines"/ |
Any thoughts how we might be exposing these? capstone-bindings-zig/src/arch/arch.zig Lines 1 to 18 in b89ba9f some functions might just wanna specific arch like only |
In Userspace this shouldn't be much of an issue, considering you can just make the definition yourself. const x86 = arch.x86;
const arm = arch.arm;I mean, an earlier way of dealing with something like this would be to just use Can you give me an exact example of what you mean? |
| /// Return an Iter object | ||
| /// Does not yet consume any element. | ||
| pub fn disasmIter(handle: Handle, code: []const u8, address: u64, ins: [*]insn.Insn) Iter { | ||
| return Iter.init(handle, code, address, ins); | ||
| return Iter{ | ||
| .handle = handle, | ||
| .code = code, | ||
| .original_code = code, | ||
| .original_address = address, | ||
| .address = address, | ||
| .insn = ins, | ||
| }; | ||
| } |
There was a problem hiding this comment.
Now this whole function seems to be unnecessary.
This might be a style-question, but simply constructing structures by the initialization form seems in my opinion a bit better, considering that a init function that doesn't really do much other than fill in parameters seems a bit superfluous.
There was a problem hiding this comment.
I mean the init function had a little purpose here if you notice I have added original_code and original_address for resetting capabilities, from user land you would just want to pass the code not also initialize the original_code field which would feel extra work, since original_code is there just for some logical purpose and has nothing to do with user initializing an Iterator.
ah let's say I am trying to analyze the I was thinking we could just make them capstone-bindings-zig/src/arch/arch.zig Lines 1 to 18 in b89ba9f and then just make them accessible from the main capstone.zig kinda repitive but it would be more than good enough, then we also wouldn't need to access some defines/enum values from the C header module.
|
Co-authored-by: Sora <s0la.luladust@gmail.com>
I wonder why they aren't pub in the first place. Perhaps it would also not be a bad Idea to have some sort of utility functions directly on the I will probably checkout this pr this evening when i am out of work and try to see if i can manage to make it easier to access fields of the union, e.g. |
btw are we on the same page? just making sure kinda confused at my own text wasn't thinking it through. the main issue I was having is I couldn't define a function which accepts And!! I really think we don't need |
Oh, it sounded like there were some usability issues, that's how i interpreted your text.
the point of |
owh cool let me do a commit so you can review if we can agree :).
I mean everything is fine but the hash map :) I don't know can we follow something like this https://github.com/bernardassan/czalloc/blob/main/src/root.zig just against the hash map can agree with everything else :) |
looks good!
Ah you don't like the extra allocations the hash map is doing i guess? |
should we make all of these public too? https://github.com/Zig-Sec/capstone-bindings-zig/blob/main/src/arch/m680x/all.zig#L1 |
yeah i think it would make sense to expose everything that may be used. |
| cs.cs_free(@ptrCast(ins.ptr), ins.len); | ||
| /// Equivilent to cs_free | ||
| /// Only accepts `[]insn.Insn` or `*insn.Insn` types. | ||
| pub fn free(ins: anytype) void { |
There was a problem hiding this comment.
to keep it consistent (especially in terms of contracts) i would name it insn
SoraTenshi
left a comment
There was a problem hiding this comment.
I think with those last changes, we can merge it.
Also please undraft.
Thank you so much for the work you put in there! :)
SoraTenshi
left a comment
There was a problem hiding this comment.
Thank you a lot!
This is looking fantastic!
|
(i also took this pr to pull back up the ci, probably need to adjust all my other repos for this) |
Okay so, the things I exposed were really needed for one of my projects I was using this for past couple of days, well tbh was not a must but were really convinient to have.
I wanted to have different functions to analyze different parts, and those function were only executed after checking specific things.
say I want to have a function to analyze the
Detail.arch.x86field only, coz well the x86 architecture needs special logic so it kinda makes sense to have a function to only acceptDetail.archonly instead of the fullInsn, we could just do theInsn.detail.?.x86but it's kinda felt redundant to do always, so just exposedInsnandDetail, we could get away with just exposing theInsnbut anyways withoutDetailthere was really no point of having justInsn, just my 2cents.why exposing
capstone-c? you won't believe how many times I needed to access the C defines, the binding doesn't expose 70% of the things I needed, to split the "analyzer" into different sections, but I feel like if it's a binding it should not expose the c part? I don't know actually I have seen some Rust bindings to do that or I didn't... But we should talk about this I really needed defines/enums values likeX86_INS_*,CS_GRP_*and some others I can't remember as of writing.That's why it's in draft phase, I really liked the way it's setup, just need to use it more to figure out more things.