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

Add fmt impl for QualifiedNameAndType #6243

Closed
wants to merge 1 commit into from

Conversation

pr0me
Copy link

@pr0me pr0me commented Dec 10, 2024

Currently, only Type has a fmt::Debug implementation, with the effect that the printer has no knowledge of the type name.
This is undesirable for, e.g., imported types.

This PR adds a debug print for QualifiedNameAndType that prints the full type declaration as it would appear in an exported header file.

If a (cleaner) way to achieve this already exists, please let me know.

@CLAassistant
Copy link

CLAassistant commented Dec 10, 2024

CLA assistant check
All committers have signed the CLA.

@emesare emesare self-assigned this Dec 13, 2024
@emesare emesare added the Component: Rust API Issue needs changes to the Rust API label Dec 13, 2024
@emesare
Copy link
Member

emesare commented Jan 2, 2025

That impl was always a little hacky, for now we are just going to omit it in favor of the Display impl.

See my commit here: 1b6b9a3

Please let me know if this is satisfactory, specifically the following:

https://github.com/Vector35/binaryninja-api/blob/1b6b9a3e10dc4640621c29df9173bbdc0fc5a8f6/rust/src/types.rs#L907-L923j

@CouleeApps
Copy link
Member

@emesare I'd be up for the Display impl using GetTypeString but for Debug I've explicitly chosen to use GetLines so it prints the members of structures. The correct answer to that awful bv hack I wrote is a way to construct an empty type container without needing a bv, and then passing that to get_lines(). I can write such a method if need be (would have to be in the core).

@pr0me
Copy link
Author

pr0me commented Jan 6, 2025

Hey, thanks for looking into this!
The current state of the rust_cleanup_0 is not really satisfactory in terms of what I want to use fmt / Debug for QualifiedNameAndType for.

The debug output of Type produces a C-compliant (besides it missing the name) representation of the type and also for structs and their sub-types, e.g.:

enum : uint16_t
{
    PE_ROM_IMAGE = 0x107,
    PE_32BIT = 0x10b,
    PE_64BIT = 0x20b
};

Looking at your commits, I didn't find an obvious way of achieving comparable output for QualifiedNameAndType which would be nice to have.
That was also the intention of this PR.

The reason I'm trying to do this is that I want to export header files, pretty much what the 'Anlaysis > Export Header File...' is doing.
Is there an easier way of doing this with the Rust API?

@emesare
Copy link
Member

emesare commented Jan 12, 2025

I see, I am going to add an example that I think does what you want, alb-eight with the side effect of requiring you to first gather all your types and have a valid binary view. Until @CouleeApps can add the required changes to the core.

  let type_printer = CoreTypePrinter::default();
  let my_structure = Type::structure(
      &Structure::builder()
          .insert_member(
              &StructureMember::new(
                  Type::int(4, false).into(),
                  "my_field".to_string(),
                  0,
                  MemberAccess::PublicAccess,
                  MemberScope::NoScope,
              ),
              false,
          )
          .finalize(),
  );

  let printed_types = type_printer.print_all_types(
      [("my_struct", my_structure)],
      // We assume you have access to a BinaryView.
      &bv,
      4,
      TokenEscapingType::NoTokenEscapingType,
  );
  
  println!("Printed types: {:?}", printed_types);
//------------------------------------------------------------------------------
// Types for /bin/cat
//
// This header file generated by Binary Ninja Ultimate 4.3 Ultimate
//------------------------------------------------------------------------------

#ifndef BN_TYPE_PARSER
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdbool.h>
#include <wchar.h>

#define __packed
#define __noreturn
#define __convention(name)
#define __syscall(number)
#define __offset(...)
#define __padding
#define __named(name)
#define __inherited
#define __base(name, offset)
#define __ptr_offset(offset)
#define __data_var_refs
#define __vtable
#define __pure
#define __ptr_width(width)
#define __ptr8
#define __ptr16
// __ptr32 and __ptr64 are real keywords on MSVC
// #define __ptr32
// #define __ptr64
#define __based(...)
typedef uint16_t wchar16;
typedef uint32_t wchar32;
#endif

//------------------------------------------------------------------------------
// Forward Declarations of Structures
//------------------------------------------------------------------------------

struct my_struct;
//------------------------------------------------------------------------------
// Type Definitions
//------------------------------------------------------------------------------

// "my_struct"
struct my_struct
{
        uint32_t my_field;
};

I am very against having the Debug impl use the type printing facilities. But I see no reason as to why you could not just use them yourself directly (assuming that which is implemented in the rust_cleanup_0 branch is merged).

@emesare emesare mentioned this pull request Jan 13, 2025
@emesare
Copy link
Member

emesare commented Jan 25, 2025

The changes above have been added with 6a63c17

@emesare emesare closed this Jan 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: Rust API Issue needs changes to the Rust API
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants