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 new build option to support Windows DLLs #388

Merged
merged 8 commits into from
Nov 4, 2024
14 changes: 14 additions & 0 deletions src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,20 @@
/// and the fuzzer can store an input to the corpus at each condition that it passes;
/// giving it a better chance of producing an input that reaches `res = 2;`.
pub disable_branch_folding: Option<bool>,

#[arg(long)]
/// Disable the inclusion of the `/include:main` MSVC linker argument
///
/// The purpose of `/include:main` is to force the MSVC linker to include an
/// external reference to the symbol `main`, such that fuzzing targets built
/// on Windows are able to find LibFuzzer's `main` function.
///
/// In certain corner cases, users may prefer to *not* build with this
/// argument. One such example: if a user is intending to build and fuzz a
/// Windows DLL, they would likely choose to enable this flag, to prevent
/// the DLL from having an extern `main` reference added to it. (DLLs/shared
/// libraries should not have any reference to `main`.)
pub no_include_main_msvc: bool,
}

impl stdfmt::Display for BuildOptions {
Expand Down Expand Up @@ -246,7 +260,7 @@

#[test]
fn display_build_options() {
let default_opts = BuildOptions {

Check failure on line 263 in src/options.rs

View workflow job for this annotation

GitHub Actions / build

missing field `no_include_main_msvc` in initializer of `options::BuildOptions`
dev: false,
release: false,
debug_assertions: false,
Expand Down
19 changes: 17 additions & 2 deletions src/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,23 @@ impl FuzzProject {
if !build.release || build.debug_assertions || build.careful_mode {
rustflags.push_str(" -Cdebug-assertions");
}
if build.triple.contains("-msvc") {
// The entrypoint is in the bundled libfuzzer rlib, this gets the linker to find it.
if build.triple.contains("-msvc") && !build.no_include_main_msvc {
// This forces the MSVC linker (which runs on Windows systems) to
// find the entry point (i.e. the `main` function) within the
// LibFuzzer `.rlib` file produced during the build.
//
// The `--no-include-main-msvc` argument disables the addition of
// this linker argument. In certain situations, a user may not want
// this argument included as part of the MSVC invocation.
//
// For example, if the user is attempting to build and fuzz a
// Windows DLL (shared library), adding `/include:main` will force
// the DLL to compile with an external reference to `main`.
// DLLs/shared libraries are designed to be built as a separate
// object file, intentionally left *without* knowledge of the entry
// point. So, forcing a DLL to include `main` will cause linking to
// fail. Using `--no-include-main-msvc` will allow the DLL to be
// built without issue.
rustflags.push_str(" -Clink-arg=/include:main");
}

Expand Down
Loading