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

Reduce the overhead of running the frida-gum-sys build script on our build times #223

Open
4 tasks
Tracked by #98
abhirag opened this issue Jul 28, 2022 · 4 comments
Open
4 tasks
Tracked by #98
Assignees
Labels
enhancement New feature or request

Comments

@abhirag
Copy link

abhirag commented Jul 28, 2022

frida-gum-sys
Running the frida-gum-sys build script is the third biggest overhead for us during building. This overhead is primarily because we use the the auto-download feature. The time is basically spent downloading the complete compressed frida devkit, extracting everything and then statically linking against frida-gum, details can be found here. My initial thoughts are that we really don't need to download the whole devkit, keeping frida-gum static library in our source tree and statically linking against it depending on the platform in our own cargo build script can save us a lot of time. Interestingly build scripts are always run even if we are using something like sccache so this overhead is also present in CI builds.

  • Verify the findings using cargo +nightly build --timings and viewing the generated report
  • Move frida-gum.h and libfrida-gum.a into a directory and add that to the linker search path
  • Link with the platform dependent static library in the build script
  • Make sure that builds are stable for all supported platforms

Note: The idea is to modify the build script of frida-gum-sys to our use-case so refer to that build script for reference

@abhirag abhirag added the enhancement New feature or request label Jul 28, 2022
@aviramha aviramha mentioned this issue Jul 28, 2022
4 tasks
@abhirag
Copy link
Author

abhirag commented Aug 1, 2022

Alright, so I have made some progress on this. We basically need to do three things --

  1. Defer as much of the work as possible to the existing frida-gum-sys build script
  2. Keep frida-gum libs in the source tree and use cargo:rustc-link-search to add the appropriate directory for the platform to the linker path
  3. frida-gum-sys build script generates appropriate bindings using the platform specific frida-gum.h and bindgen so make sure that bindgen can find frida-gum.h

@abhirag
Copy link
Author

abhirag commented Aug 1, 2022

The first issue we face is that the lifecycle of a cargo build script is such that it is executed just before compiling the binary, which means that the build scripts of all the dependent crates are executed before the build script of mirrord-layer (and we can't have build script on the workspace level).

This basically implies that we need a mechanism to make bindgen aware of the include path for frida-gum.h and we need to it before executing our build script. Adding the appropriate path to the linker path can still be done in our build script without any problem.

@abhirag
Copy link
Author

abhirag commented Aug 1, 2022

So I have two approaches I need to discuss:

  1. As of now frida-gum has no support for configuring the include directory, this approach tweaks the frida-gum-sys build script to support configuring the include directory using an environment variable and then uses the cargo feature to set this environment variable before building mirrord.
    In my limited testing I have found this approach to work well, just that we would have to get the required changes included in frida-rust. Also we would need to keep a single header file for frida-gum with appropriate pre-processor flags for conditional compilation. Prototype for this approach can be found here.
  2. The second approach doesn't quite work yet, laying it down here in the hope that someone else can provide a better insight. This approach uses the fact that bindgen allows arguments to be passed to clang through environment variables. So we can pass the appropriate include directory by setting this environment variable in cargo configuration. The only problem being that I have not been able to figure out how to make this work with relative paths and this approach is useless without that.
    If we can make this work with relative paths we can probably set TARGET env var and then use BINDGEN_EXTRA_CLANG_ARGS_<TARGET> to set include paths based on target. The working code for this approach can be found here, although you would have to tweak the absolute path to make it work for you.

@aviramha
Copy link
Member

aviramha commented Aug 2, 2022

What about forking the auto download crate then using replace to use the fork?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants