Skip to content

Commit

Permalink
Merge pull request #388 from cwshugg/no_include_main_msvc
Browse files Browse the repository at this point in the history
Add new build option to support Windows DLLs
  • Loading branch information
fitzgen authored Nov 4, 2024
2 parents a608970 + b404951 commit 2d7a467
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
15 changes: 15 additions & 0 deletions src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,20 @@ pub struct BuildOptions {
/// 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 @@ -265,6 +279,7 @@ mod test {
no_cfg_fuzzing: false,
no_trace_compares: false,
disable_branch_folding: None,
no_include_main_msvc: false,
};

let opts = vec![
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

0 comments on commit 2d7a467

Please sign in to comment.