mirror of https://github.com/rust-lang/rust.git
Auto merge of #127360 - GuillaumeGomez:rollup-f0zs1qr, r=GuillaumeGomez
Rollup of 7 pull requests Successful merges: - #124290 (DependencyList: removed outdated comment) - #126709 (Migrate `include_bytes_deps`, `optimization-remarks-dir-pgo`, `optimization-remarks-dir`, `issue-40535` and `rmeta-preferred` `run-make` tests to rmake) - #127214 (Use the native unwind function in miri where possible) - #127320 (Update windows-bindgen to 0.58.0) - #127349 (Tweak `-1 as usize` suggestion) - #127352 (coverage: Rename `mir::coverage::BranchInfo` to `CoverageInfoHi`) - #127359 (Improve run make llvm ident code) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
11dd90f761
|
@ -6356,9 +6356,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-bindgen"
|
name = "windows-bindgen"
|
||||||
version = "0.57.0"
|
version = "0.58.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1ccb96113d6277ba543c0f77e1c5494af8094bf9daf9b85acdc3f1b620e7c7b4"
|
checksum = "91cd28d93c692351f3a6e5615567c56756e330bee1c99c6bdd57bfc5ab15f589"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"rayon",
|
"rayon",
|
||||||
|
@ -6379,9 +6379,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-metadata"
|
name = "windows-metadata"
|
||||||
version = "0.57.0"
|
version = "0.58.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8308d076825b9d9e5abc64f8113e96d02b2aeeba869b20fdd65c7e70cda13dfc"
|
checksum = "2e837f3c3012cfe9e7086302a93f441a7999439be1ad4c530d55d2f6d2921809"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
|
|
|
@ -838,8 +838,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
},
|
},
|
||||||
) = ex.kind
|
) = ex.kind
|
||||||
{
|
{
|
||||||
err.span_suggestion(
|
let span = if let hir::Node::Expr(parent) =
|
||||||
ex.span,
|
self.tcx.parent_hir_node(ex.hir_id)
|
||||||
|
&& let hir::ExprKind::Cast(..) = parent.kind
|
||||||
|
{
|
||||||
|
// `-1 as usize` -> `usize::MAX`
|
||||||
|
parent.span
|
||||||
|
} else {
|
||||||
|
ex.span
|
||||||
|
};
|
||||||
|
err.span_suggestion_verbose(
|
||||||
|
span,
|
||||||
format!(
|
format!(
|
||||||
"you may have meant the maximum value of `{actual}`",
|
"you may have meant the maximum value of `{actual}`",
|
||||||
),
|
),
|
||||||
|
|
|
@ -4,15 +4,15 @@
|
||||||
//! For all the gory details, see the provider of the `dependency_formats`
|
//! For all the gory details, see the provider of the `dependency_formats`
|
||||||
//! query.
|
//! query.
|
||||||
|
|
||||||
|
// FIXME: move this file to rustc_metadata::dependency_format, but
|
||||||
|
// this will introduce circular dependency between rustc_metadata and rustc_middle
|
||||||
|
|
||||||
use rustc_macros::{Decodable, Encodable, HashStable};
|
use rustc_macros::{Decodable, Encodable, HashStable};
|
||||||
use rustc_session::config::CrateType;
|
use rustc_session::config::CrateType;
|
||||||
|
|
||||||
/// A list of dependencies for a certain crate type.
|
/// A list of dependencies for a certain crate type.
|
||||||
///
|
///
|
||||||
/// The length of this vector is the same as the number of external crates used.
|
/// The length of this vector is the same as the number of external crates used.
|
||||||
/// The value is None if the crate does not need to be linked (it was found
|
|
||||||
/// statically in another dylib), or Some(kind) if it needs to be linked as
|
|
||||||
/// `kind` (either static or dynamic).
|
|
||||||
pub type DependencyList = Vec<Linkage>;
|
pub type DependencyList = Vec<Linkage>;
|
||||||
|
|
||||||
/// A mapping of all required dependencies for a particular flavor of output.
|
/// A mapping of all required dependencies for a particular flavor of output.
|
||||||
|
|
|
@ -103,7 +103,7 @@ pub enum CoverageKind {
|
||||||
SpanMarker,
|
SpanMarker,
|
||||||
|
|
||||||
/// Marks its enclosing basic block with an ID that can be referred to by
|
/// Marks its enclosing basic block with an ID that can be referred to by
|
||||||
/// side data in [`BranchInfo`].
|
/// side data in [`CoverageInfoHi`].
|
||||||
///
|
///
|
||||||
/// Should be erased before codegen (at some point after `InstrumentCoverage`).
|
/// Should be erased before codegen (at some point after `InstrumentCoverage`).
|
||||||
BlockMarker { id: BlockMarkerId },
|
BlockMarker { id: BlockMarkerId },
|
||||||
|
@ -274,10 +274,15 @@ pub struct FunctionCoverageInfo {
|
||||||
pub mcdc_num_condition_bitmaps: usize,
|
pub mcdc_num_condition_bitmaps: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Branch information recorded during THIR-to-MIR lowering, and stored in MIR.
|
/// Coverage information for a function, recorded during MIR building and
|
||||||
|
/// attached to the corresponding `mir::Body`. Used by the `InstrumentCoverage`
|
||||||
|
/// MIR pass.
|
||||||
|
///
|
||||||
|
/// ("Hi" indicates that this is "high-level" information collected at the
|
||||||
|
/// THIR/MIR boundary, before the MIR-based coverage instrumentation pass.)
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
|
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
|
||||||
pub struct BranchInfo {
|
pub struct CoverageInfoHi {
|
||||||
/// 1 more than the highest-numbered [`CoverageKind::BlockMarker`] that was
|
/// 1 more than the highest-numbered [`CoverageKind::BlockMarker`] that was
|
||||||
/// injected into the MIR body. This makes it possible to allocate per-ID
|
/// injected into the MIR body. This makes it possible to allocate per-ID
|
||||||
/// data structures without having to scan the entire body first.
|
/// data structures without having to scan the entire body first.
|
||||||
|
|
|
@ -430,11 +430,12 @@ pub struct Body<'tcx> {
|
||||||
|
|
||||||
pub tainted_by_errors: Option<ErrorGuaranteed>,
|
pub tainted_by_errors: Option<ErrorGuaranteed>,
|
||||||
|
|
||||||
/// Branch coverage information collected during MIR building, to be used by
|
/// Coverage information collected from THIR/MIR during MIR building,
|
||||||
/// the `InstrumentCoverage` pass.
|
/// to be used by the `InstrumentCoverage` pass.
|
||||||
///
|
///
|
||||||
/// Only present if branch coverage is enabled and this function is eligible.
|
/// Only present if coverage is enabled and this function is eligible.
|
||||||
pub coverage_branch_info: Option<Box<coverage::BranchInfo>>,
|
/// Boxed to limit space overhead in non-coverage builds.
|
||||||
|
pub coverage_info_hi: Option<Box<coverage::CoverageInfoHi>>,
|
||||||
|
|
||||||
/// Per-function coverage information added by the `InstrumentCoverage`
|
/// Per-function coverage information added by the `InstrumentCoverage`
|
||||||
/// pass, to be used in conjunction with the coverage statements injected
|
/// pass, to be used in conjunction with the coverage statements injected
|
||||||
|
@ -484,7 +485,7 @@ impl<'tcx> Body<'tcx> {
|
||||||
is_polymorphic: false,
|
is_polymorphic: false,
|
||||||
injection_phase: None,
|
injection_phase: None,
|
||||||
tainted_by_errors,
|
tainted_by_errors,
|
||||||
coverage_branch_info: None,
|
coverage_info_hi: None,
|
||||||
function_coverage_info: None,
|
function_coverage_info: None,
|
||||||
};
|
};
|
||||||
body.is_polymorphic = body.has_non_region_param();
|
body.is_polymorphic = body.has_non_region_param();
|
||||||
|
@ -515,7 +516,7 @@ impl<'tcx> Body<'tcx> {
|
||||||
is_polymorphic: false,
|
is_polymorphic: false,
|
||||||
injection_phase: None,
|
injection_phase: None,
|
||||||
tainted_by_errors: None,
|
tainted_by_errors: None,
|
||||||
coverage_branch_info: None,
|
coverage_info_hi: None,
|
||||||
function_coverage_info: None,
|
function_coverage_info: None,
|
||||||
};
|
};
|
||||||
body.is_polymorphic = body.has_non_region_param();
|
body.is_polymorphic = body.has_non_region_param();
|
||||||
|
|
|
@ -473,8 +473,8 @@ pub fn write_mir_intro<'tcx>(
|
||||||
// Add an empty line before the first block is printed.
|
// Add an empty line before the first block is printed.
|
||||||
writeln!(w)?;
|
writeln!(w)?;
|
||||||
|
|
||||||
if let Some(branch_info) = &body.coverage_branch_info {
|
if let Some(coverage_info_hi) = &body.coverage_info_hi {
|
||||||
write_coverage_branch_info(branch_info, w)?;
|
write_coverage_info_hi(coverage_info_hi, w)?;
|
||||||
}
|
}
|
||||||
if let Some(function_coverage_info) = &body.function_coverage_info {
|
if let Some(function_coverage_info) = &body.function_coverage_info {
|
||||||
write_function_coverage_info(function_coverage_info, w)?;
|
write_function_coverage_info(function_coverage_info, w)?;
|
||||||
|
@ -483,18 +483,26 @@ pub fn write_mir_intro<'tcx>(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_coverage_branch_info(
|
fn write_coverage_info_hi(
|
||||||
branch_info: &coverage::BranchInfo,
|
coverage_info_hi: &coverage::CoverageInfoHi,
|
||||||
w: &mut dyn io::Write,
|
w: &mut dyn io::Write,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
let coverage::BranchInfo { branch_spans, mcdc_branch_spans, mcdc_decision_spans, .. } =
|
let coverage::CoverageInfoHi {
|
||||||
branch_info;
|
num_block_markers: _,
|
||||||
|
branch_spans,
|
||||||
|
mcdc_branch_spans,
|
||||||
|
mcdc_decision_spans,
|
||||||
|
} = coverage_info_hi;
|
||||||
|
|
||||||
|
// Only add an extra trailing newline if we printed at least one thing.
|
||||||
|
let mut did_print = false;
|
||||||
|
|
||||||
for coverage::BranchSpan { span, true_marker, false_marker } in branch_spans {
|
for coverage::BranchSpan { span, true_marker, false_marker } in branch_spans {
|
||||||
writeln!(
|
writeln!(
|
||||||
w,
|
w,
|
||||||
"{INDENT}coverage branch {{ true: {true_marker:?}, false: {false_marker:?} }} => {span:?}",
|
"{INDENT}coverage branch {{ true: {true_marker:?}, false: {false_marker:?} }} => {span:?}",
|
||||||
)?;
|
)?;
|
||||||
|
did_print = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for coverage::MCDCBranchSpan {
|
for coverage::MCDCBranchSpan {
|
||||||
|
@ -510,6 +518,7 @@ fn write_coverage_branch_info(
|
||||||
"{INDENT}coverage mcdc branch {{ condition_id: {:?}, true: {true_marker:?}, false: {false_marker:?}, depth: {decision_depth:?} }} => {span:?}",
|
"{INDENT}coverage mcdc branch {{ condition_id: {:?}, true: {true_marker:?}, false: {false_marker:?}, depth: {decision_depth:?} }} => {span:?}",
|
||||||
condition_info.map(|info| info.condition_id)
|
condition_info.map(|info| info.condition_id)
|
||||||
)?;
|
)?;
|
||||||
|
did_print = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for coverage::MCDCDecisionSpan { span, num_conditions, end_markers, decision_depth } in
|
for coverage::MCDCDecisionSpan { span, num_conditions, end_markers, decision_depth } in
|
||||||
|
@ -519,10 +528,10 @@ fn write_coverage_branch_info(
|
||||||
w,
|
w,
|
||||||
"{INDENT}coverage mcdc decision {{ num_conditions: {num_conditions:?}, end: {end_markers:?}, depth: {decision_depth:?} }} => {span:?}"
|
"{INDENT}coverage mcdc decision {{ num_conditions: {num_conditions:?}, end: {end_markers:?}, depth: {decision_depth:?} }} => {span:?}"
|
||||||
)?;
|
)?;
|
||||||
|
did_print = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !branch_spans.is_empty() || !mcdc_branch_spans.is_empty() || !mcdc_decision_spans.is_empty()
|
if did_print {
|
||||||
{
|
|
||||||
writeln!(w)?;
|
writeln!(w)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::assert_matches::assert_matches;
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_middle::mir::coverage::{BlockMarkerId, BranchSpan, CoverageKind};
|
use rustc_middle::mir::coverage::{BlockMarkerId, BranchSpan, CoverageInfoHi, CoverageKind};
|
||||||
use rustc_middle::mir::{self, BasicBlock, SourceInfo, UnOp};
|
use rustc_middle::mir::{self, BasicBlock, SourceInfo, UnOp};
|
||||||
use rustc_middle::thir::{ExprId, ExprKind, Pat, Thir};
|
use rustc_middle::thir::{ExprId, ExprKind, Pat, Thir};
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
|
@ -13,16 +13,25 @@ use crate::build::{Builder, CFG};
|
||||||
|
|
||||||
mod mcdc;
|
mod mcdc;
|
||||||
|
|
||||||
pub(crate) struct BranchInfoBuilder {
|
/// Collects coverage-related information during MIR building, to eventually be
|
||||||
|
/// turned into a function's [`CoverageInfoHi`] when MIR building is complete.
|
||||||
|
pub(crate) struct CoverageInfoBuilder {
|
||||||
/// Maps condition expressions to their enclosing `!`, for better instrumentation.
|
/// Maps condition expressions to their enclosing `!`, for better instrumentation.
|
||||||
nots: FxHashMap<ExprId, NotInfo>,
|
nots: FxHashMap<ExprId, NotInfo>,
|
||||||
|
|
||||||
markers: BlockMarkerGen,
|
markers: BlockMarkerGen,
|
||||||
branch_spans: Vec<BranchSpan>,
|
|
||||||
|
|
||||||
|
/// Present if branch coverage is enabled.
|
||||||
|
branch_info: Option<BranchInfo>,
|
||||||
|
/// Present if MC/DC coverage is enabled.
|
||||||
mcdc_info: Option<MCDCInfoBuilder>,
|
mcdc_info: Option<MCDCInfoBuilder>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct BranchInfo {
|
||||||
|
branch_spans: Vec<BranchSpan>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
struct NotInfo {
|
struct NotInfo {
|
||||||
/// When visiting the associated expression as a branch condition, treat this
|
/// When visiting the associated expression as a branch condition, treat this
|
||||||
|
@ -62,20 +71,20 @@ impl BlockMarkerGen {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BranchInfoBuilder {
|
impl CoverageInfoBuilder {
|
||||||
/// Creates a new branch info builder, but only if branch coverage instrumentation
|
/// Creates a new coverage info builder, but only if coverage instrumentation
|
||||||
/// is enabled and `def_id` represents a function that is eligible for coverage.
|
/// is enabled and `def_id` represents a function that is eligible for coverage.
|
||||||
pub(crate) fn new_if_enabled(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<Self> {
|
pub(crate) fn new_if_enabled(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<Self> {
|
||||||
if tcx.sess.instrument_coverage_branch() && tcx.is_eligible_for_coverage(def_id) {
|
if !tcx.sess.instrument_coverage() || !tcx.is_eligible_for_coverage(def_id) {
|
||||||
Some(Self {
|
return None;
|
||||||
nots: FxHashMap::default(),
|
|
||||||
markers: BlockMarkerGen::default(),
|
|
||||||
branch_spans: vec![],
|
|
||||||
mcdc_info: tcx.sess.instrument_coverage_mcdc().then(MCDCInfoBuilder::new),
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some(Self {
|
||||||
|
nots: FxHashMap::default(),
|
||||||
|
markers: BlockMarkerGen::default(),
|
||||||
|
branch_info: tcx.sess.instrument_coverage_branch().then(BranchInfo::default),
|
||||||
|
mcdc_info: tcx.sess.instrument_coverage_mcdc().then(MCDCInfoBuilder::new),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unary `!` expressions inside an `if` condition are lowered by lowering
|
/// Unary `!` expressions inside an `if` condition are lowered by lowering
|
||||||
|
@ -88,6 +97,12 @@ impl BranchInfoBuilder {
|
||||||
pub(crate) fn visit_unary_not(&mut self, thir: &Thir<'_>, unary_not: ExprId) {
|
pub(crate) fn visit_unary_not(&mut self, thir: &Thir<'_>, unary_not: ExprId) {
|
||||||
assert_matches!(thir[unary_not].kind, ExprKind::Unary { op: UnOp::Not, .. });
|
assert_matches!(thir[unary_not].kind, ExprKind::Unary { op: UnOp::Not, .. });
|
||||||
|
|
||||||
|
// The information collected by this visitor is only needed when branch
|
||||||
|
// coverage or higher is enabled.
|
||||||
|
if self.branch_info.is_none() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
self.visit_with_not_info(
|
self.visit_with_not_info(
|
||||||
thir,
|
thir,
|
||||||
unary_not,
|
unary_not,
|
||||||
|
@ -137,40 +152,40 @@ impl BranchInfoBuilder {
|
||||||
false_block,
|
false_block,
|
||||||
inject_block_marker,
|
inject_block_marker,
|
||||||
);
|
);
|
||||||
} else {
|
return;
|
||||||
let true_marker = self.markers.inject_block_marker(cfg, source_info, true_block);
|
|
||||||
let false_marker = self.markers.inject_block_marker(cfg, source_info, false_block);
|
|
||||||
|
|
||||||
self.branch_spans.push(BranchSpan {
|
|
||||||
span: source_info.span,
|
|
||||||
true_marker,
|
|
||||||
false_marker,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bail out if branch coverage is not enabled.
|
||||||
|
let Some(branch_info) = self.branch_info.as_mut() else { return };
|
||||||
|
|
||||||
|
let true_marker = self.markers.inject_block_marker(cfg, source_info, true_block);
|
||||||
|
let false_marker = self.markers.inject_block_marker(cfg, source_info, false_block);
|
||||||
|
|
||||||
|
branch_info.branch_spans.push(BranchSpan {
|
||||||
|
span: source_info.span,
|
||||||
|
true_marker,
|
||||||
|
false_marker,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn into_done(self) -> Option<Box<mir::coverage::BranchInfo>> {
|
pub(crate) fn into_done(self) -> Box<CoverageInfoHi> {
|
||||||
let Self {
|
let Self { nots: _, markers: BlockMarkerGen { num_block_markers }, branch_info, mcdc_info } =
|
||||||
nots: _,
|
self;
|
||||||
markers: BlockMarkerGen { num_block_markers },
|
|
||||||
branch_spans,
|
|
||||||
mcdc_info,
|
|
||||||
} = self;
|
|
||||||
|
|
||||||
if num_block_markers == 0 {
|
let branch_spans =
|
||||||
assert!(branch_spans.is_empty());
|
branch_info.map(|branch_info| branch_info.branch_spans).unwrap_or_default();
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let (mcdc_decision_spans, mcdc_branch_spans) =
|
let (mcdc_decision_spans, mcdc_branch_spans) =
|
||||||
mcdc_info.map(MCDCInfoBuilder::into_done).unwrap_or_default();
|
mcdc_info.map(MCDCInfoBuilder::into_done).unwrap_or_default();
|
||||||
|
|
||||||
Some(Box::new(mir::coverage::BranchInfo {
|
// For simplicity, always return an info struct (without Option), even
|
||||||
|
// if there's nothing interesting in it.
|
||||||
|
Box::new(CoverageInfoHi {
|
||||||
num_block_markers,
|
num_block_markers,
|
||||||
branch_spans,
|
branch_spans,
|
||||||
mcdc_branch_spans,
|
mcdc_branch_spans,
|
||||||
mcdc_decision_spans,
|
mcdc_decision_spans,
|
||||||
}))
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +199,7 @@ impl<'tcx> Builder<'_, 'tcx> {
|
||||||
block: &mut BasicBlock,
|
block: &mut BasicBlock,
|
||||||
) {
|
) {
|
||||||
// Bail out if condition coverage is not enabled for this function.
|
// Bail out if condition coverage is not enabled for this function.
|
||||||
let Some(branch_info) = self.coverage_branch_info.as_mut() else { return };
|
let Some(coverage_info) = self.coverage_info.as_mut() else { return };
|
||||||
if !self.tcx.sess.instrument_coverage_condition() {
|
if !self.tcx.sess.instrument_coverage_condition() {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -224,7 +239,7 @@ impl<'tcx> Builder<'_, 'tcx> {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Separate path for handling branches when MC/DC is enabled.
|
// Separate path for handling branches when MC/DC is enabled.
|
||||||
branch_info.register_two_way_branch(
|
coverage_info.register_two_way_branch(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
&mut self.cfg,
|
&mut self.cfg,
|
||||||
source_info,
|
source_info,
|
||||||
|
@ -247,12 +262,12 @@ impl<'tcx> Builder<'_, 'tcx> {
|
||||||
mut then_block: BasicBlock,
|
mut then_block: BasicBlock,
|
||||||
mut else_block: BasicBlock,
|
mut else_block: BasicBlock,
|
||||||
) {
|
) {
|
||||||
// Bail out if branch coverage is not enabled for this function.
|
// Bail out if coverage is not enabled for this function.
|
||||||
let Some(branch_info) = self.coverage_branch_info.as_mut() else { return };
|
let Some(coverage_info) = self.coverage_info.as_mut() else { return };
|
||||||
|
|
||||||
// If this condition expression is nested within one or more `!` expressions,
|
// If this condition expression is nested within one or more `!` expressions,
|
||||||
// replace it with the enclosing `!` collected by `visit_unary_not`.
|
// replace it with the enclosing `!` collected by `visit_unary_not`.
|
||||||
if let Some(&NotInfo { enclosing_not, is_flipped }) = branch_info.nots.get(&expr_id) {
|
if let Some(&NotInfo { enclosing_not, is_flipped }) = coverage_info.nots.get(&expr_id) {
|
||||||
expr_id = enclosing_not;
|
expr_id = enclosing_not;
|
||||||
if is_flipped {
|
if is_flipped {
|
||||||
std::mem::swap(&mut then_block, &mut else_block);
|
std::mem::swap(&mut then_block, &mut else_block);
|
||||||
|
@ -261,7 +276,7 @@ impl<'tcx> Builder<'_, 'tcx> {
|
||||||
|
|
||||||
let source_info = SourceInfo { span: self.thir[expr_id].span, scope: self.source_scope };
|
let source_info = SourceInfo { span: self.thir[expr_id].span, scope: self.source_scope };
|
||||||
|
|
||||||
branch_info.register_two_way_branch(
|
coverage_info.register_two_way_branch(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
&mut self.cfg,
|
&mut self.cfg,
|
||||||
source_info,
|
source_info,
|
||||||
|
@ -280,13 +295,11 @@ impl<'tcx> Builder<'_, 'tcx> {
|
||||||
true_block: BasicBlock,
|
true_block: BasicBlock,
|
||||||
false_block: BasicBlock,
|
false_block: BasicBlock,
|
||||||
) {
|
) {
|
||||||
// Bail out if branch coverage is not enabled for this function.
|
// Bail out if coverage is not enabled for this function.
|
||||||
let Some(branch_info) = self.coverage_branch_info.as_mut() else { return };
|
let Some(coverage_info) = self.coverage_info.as_mut() else { return };
|
||||||
|
|
||||||
// FIXME(#124144) This may need special handling when MC/DC is enabled.
|
|
||||||
|
|
||||||
let source_info = SourceInfo { span: pattern.span, scope: self.source_scope };
|
let source_info = SourceInfo { span: pattern.span, scope: self.source_scope };
|
||||||
branch_info.register_two_way_branch(
|
coverage_info.register_two_way_branch(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
&mut self.cfg,
|
&mut self.cfg,
|
||||||
source_info,
|
source_info,
|
||||||
|
|
|
@ -250,24 +250,24 @@ impl MCDCInfoBuilder {
|
||||||
|
|
||||||
impl Builder<'_, '_> {
|
impl Builder<'_, '_> {
|
||||||
pub(crate) fn visit_coverage_branch_operation(&mut self, logical_op: LogicalOp, span: Span) {
|
pub(crate) fn visit_coverage_branch_operation(&mut self, logical_op: LogicalOp, span: Span) {
|
||||||
if let Some(branch_info) = self.coverage_branch_info.as_mut()
|
if let Some(coverage_info) = self.coverage_info.as_mut()
|
||||||
&& let Some(mcdc_info) = branch_info.mcdc_info.as_mut()
|
&& let Some(mcdc_info) = coverage_info.mcdc_info.as_mut()
|
||||||
{
|
{
|
||||||
mcdc_info.state.record_conditions(logical_op, span);
|
mcdc_info.state.record_conditions(logical_op, span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn mcdc_increment_depth_if_enabled(&mut self) {
|
pub(crate) fn mcdc_increment_depth_if_enabled(&mut self) {
|
||||||
if let Some(branch_info) = self.coverage_branch_info.as_mut()
|
if let Some(coverage_info) = self.coverage_info.as_mut()
|
||||||
&& let Some(mcdc_info) = branch_info.mcdc_info.as_mut()
|
&& let Some(mcdc_info) = coverage_info.mcdc_info.as_mut()
|
||||||
{
|
{
|
||||||
mcdc_info.state.decision_ctx_stack.push(MCDCDecisionCtx::default());
|
mcdc_info.state.decision_ctx_stack.push(MCDCDecisionCtx::default());
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn mcdc_decrement_depth_if_enabled(&mut self) {
|
pub(crate) fn mcdc_decrement_depth_if_enabled(&mut self) {
|
||||||
if let Some(branch_info) = self.coverage_branch_info.as_mut()
|
if let Some(coverage_info) = self.coverage_info.as_mut()
|
||||||
&& let Some(mcdc_info) = branch_info.mcdc_info.as_mut()
|
&& let Some(mcdc_info) = coverage_info.mcdc_info.as_mut()
|
||||||
{
|
{
|
||||||
if mcdc_info.state.decision_ctx_stack.pop().is_none() {
|
if mcdc_info.state.decision_ctx_stack.pop().is_none() {
|
||||||
bug!("Unexpected empty decision stack");
|
bug!("Unexpected empty decision stack");
|
||||||
|
|
|
@ -62,7 +62,7 @@ pub(super) fn build_custom_mir<'tcx>(
|
||||||
tainted_by_errors: None,
|
tainted_by_errors: None,
|
||||||
injection_phase: None,
|
injection_phase: None,
|
||||||
pass_count: 0,
|
pass_count: 0,
|
||||||
coverage_branch_info: None,
|
coverage_info_hi: None,
|
||||||
function_coverage_info: None,
|
function_coverage_info: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -160,8 +160,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
// Improve branch coverage instrumentation by noting conditions
|
// Improve branch coverage instrumentation by noting conditions
|
||||||
// nested within one or more `!` expressions.
|
// nested within one or more `!` expressions.
|
||||||
// (Skipped if branch coverage is not enabled.)
|
// (Skipped if branch coverage is not enabled.)
|
||||||
if let Some(branch_info) = this.coverage_branch_info.as_mut() {
|
if let Some(coverage_info) = this.coverage_info.as_mut() {
|
||||||
branch_info.visit_unary_not(this.thir, expr_id);
|
coverage_info.visit_unary_not(this.thir, expr_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
let local_scope = this.local_scope();
|
let local_scope = this.local_scope();
|
||||||
|
|
|
@ -218,8 +218,8 @@ struct Builder<'a, 'tcx> {
|
||||||
lint_level_roots_cache: GrowableBitSet<hir::ItemLocalId>,
|
lint_level_roots_cache: GrowableBitSet<hir::ItemLocalId>,
|
||||||
|
|
||||||
/// Collects additional coverage information during MIR building.
|
/// Collects additional coverage information during MIR building.
|
||||||
/// Only present if branch coverage is enabled and this function is eligible.
|
/// Only present if coverage is enabled and this function is eligible.
|
||||||
coverage_branch_info: Option<coverageinfo::BranchInfoBuilder>,
|
coverage_info: Option<coverageinfo::CoverageInfoBuilder>,
|
||||||
}
|
}
|
||||||
|
|
||||||
type CaptureMap<'tcx> = SortedIndexMultiMap<usize, HirId, Capture<'tcx>>;
|
type CaptureMap<'tcx> = SortedIndexMultiMap<usize, HirId, Capture<'tcx>>;
|
||||||
|
@ -773,7 +773,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
unit_temp: None,
|
unit_temp: None,
|
||||||
var_debug_info: vec![],
|
var_debug_info: vec![],
|
||||||
lint_level_roots_cache: GrowableBitSet::new_empty(),
|
lint_level_roots_cache: GrowableBitSet::new_empty(),
|
||||||
coverage_branch_info: coverageinfo::BranchInfoBuilder::new_if_enabled(tcx, def),
|
coverage_info: coverageinfo::CoverageInfoBuilder::new_if_enabled(tcx, def),
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(builder.cfg.start_new_block(), START_BLOCK);
|
assert_eq!(builder.cfg.start_new_block(), START_BLOCK);
|
||||||
|
@ -802,7 +802,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
self.coroutine,
|
self.coroutine,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
body.coverage_branch_info = self.coverage_branch_info.and_then(|b| b.into_done());
|
body.coverage_info_hi = self.coverage_info.map(|b| b.into_done());
|
||||||
body
|
body
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,9 @@ use std::collections::BTreeSet;
|
||||||
use rustc_data_structures::graph::DirectedGraph;
|
use rustc_data_structures::graph::DirectedGraph;
|
||||||
use rustc_index::bit_set::BitSet;
|
use rustc_index::bit_set::BitSet;
|
||||||
use rustc_index::IndexVec;
|
use rustc_index::IndexVec;
|
||||||
use rustc_middle::mir::coverage::{BlockMarkerId, BranchSpan, ConditionInfo, CoverageKind};
|
use rustc_middle::mir::coverage::{
|
||||||
|
BlockMarkerId, BranchSpan, ConditionInfo, CoverageInfoHi, CoverageKind,
|
||||||
|
};
|
||||||
use rustc_middle::mir::{self, BasicBlock, StatementKind};
|
use rustc_middle::mir::{self, BasicBlock, StatementKind};
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
@ -157,12 +159,12 @@ impl ExtractedMappings {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_block_markers(
|
fn resolve_block_markers(
|
||||||
branch_info: &mir::coverage::BranchInfo,
|
coverage_info_hi: &CoverageInfoHi,
|
||||||
mir_body: &mir::Body<'_>,
|
mir_body: &mir::Body<'_>,
|
||||||
) -> IndexVec<BlockMarkerId, Option<BasicBlock>> {
|
) -> IndexVec<BlockMarkerId, Option<BasicBlock>> {
|
||||||
let mut block_markers = IndexVec::<BlockMarkerId, Option<BasicBlock>>::from_elem_n(
|
let mut block_markers = IndexVec::<BlockMarkerId, Option<BasicBlock>>::from_elem_n(
|
||||||
None,
|
None,
|
||||||
branch_info.num_block_markers,
|
coverage_info_hi.num_block_markers,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Fill out the mapping from block marker IDs to their enclosing blocks.
|
// Fill out the mapping from block marker IDs to their enclosing blocks.
|
||||||
|
@ -188,11 +190,11 @@ pub(super) fn extract_branch_pairs(
|
||||||
hir_info: &ExtractedHirInfo,
|
hir_info: &ExtractedHirInfo,
|
||||||
basic_coverage_blocks: &CoverageGraph,
|
basic_coverage_blocks: &CoverageGraph,
|
||||||
) -> Vec<BranchPair> {
|
) -> Vec<BranchPair> {
|
||||||
let Some(branch_info) = mir_body.coverage_branch_info.as_deref() else { return vec![] };
|
let Some(coverage_info_hi) = mir_body.coverage_info_hi.as_deref() else { return vec![] };
|
||||||
|
|
||||||
let block_markers = resolve_block_markers(branch_info, mir_body);
|
let block_markers = resolve_block_markers(coverage_info_hi, mir_body);
|
||||||
|
|
||||||
branch_info
|
coverage_info_hi
|
||||||
.branch_spans
|
.branch_spans
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|&BranchSpan { span: raw_span, true_marker, false_marker }| {
|
.filter_map(|&BranchSpan { span: raw_span, true_marker, false_marker }| {
|
||||||
|
@ -222,9 +224,9 @@ pub(super) fn extract_mcdc_mappings(
|
||||||
mcdc_branches: &mut impl Extend<MCDCBranch>,
|
mcdc_branches: &mut impl Extend<MCDCBranch>,
|
||||||
mcdc_decisions: &mut impl Extend<MCDCDecision>,
|
mcdc_decisions: &mut impl Extend<MCDCDecision>,
|
||||||
) {
|
) {
|
||||||
let Some(branch_info) = mir_body.coverage_branch_info.as_deref() else { return };
|
let Some(coverage_info_hi) = mir_body.coverage_info_hi.as_deref() else { return };
|
||||||
|
|
||||||
let block_markers = resolve_block_markers(branch_info, mir_body);
|
let block_markers = resolve_block_markers(coverage_info_hi, mir_body);
|
||||||
|
|
||||||
let bcb_from_marker =
|
let bcb_from_marker =
|
||||||
|marker: BlockMarkerId| basic_coverage_blocks.bcb_from_bb(block_markers[marker]?);
|
|marker: BlockMarkerId| basic_coverage_blocks.bcb_from_bb(block_markers[marker]?);
|
||||||
|
@ -243,7 +245,7 @@ pub(super) fn extract_mcdc_mappings(
|
||||||
Some((span, true_bcb, false_bcb))
|
Some((span, true_bcb, false_bcb))
|
||||||
};
|
};
|
||||||
|
|
||||||
mcdc_branches.extend(branch_info.mcdc_branch_spans.iter().filter_map(
|
mcdc_branches.extend(coverage_info_hi.mcdc_branch_spans.iter().filter_map(
|
||||||
|&mir::coverage::MCDCBranchSpan {
|
|&mir::coverage::MCDCBranchSpan {
|
||||||
span: raw_span,
|
span: raw_span,
|
||||||
condition_info,
|
condition_info,
|
||||||
|
@ -257,7 +259,7 @@ pub(super) fn extract_mcdc_mappings(
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
||||||
mcdc_decisions.extend(branch_info.mcdc_decision_spans.iter().filter_map(
|
mcdc_decisions.extend(coverage_info_hi.mcdc_decision_spans.iter().filter_map(
|
||||||
|decision: &mir::coverage::MCDCDecisionSpan| {
|
|decision: &mir::coverage::MCDCDecisionSpan| {
|
||||||
let span = unexpand_into_body_span(decision.span, body_span)?;
|
let span = unexpand_into_body_span(decision.span, body_span)?;
|
||||||
|
|
||||||
|
|
|
@ -36,18 +36,14 @@ use core::panic::PanicPayload;
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(target_os = "emscripten")] {
|
if #[cfg(target_os = "emscripten")] {
|
||||||
#[path = "emcc.rs"]
|
#[path = "emcc.rs"]
|
||||||
mod real_imp;
|
mod imp;
|
||||||
} else if #[cfg(target_os = "hermit")] {
|
} else if #[cfg(target_os = "hermit")] {
|
||||||
#[path = "hermit.rs"]
|
#[path = "hermit.rs"]
|
||||||
mod real_imp;
|
mod imp;
|
||||||
} else if #[cfg(target_os = "l4re")] {
|
} else if #[cfg(target_os = "l4re")] {
|
||||||
// L4Re is unix family but does not yet support unwinding.
|
// L4Re is unix family but does not yet support unwinding.
|
||||||
#[path = "dummy.rs"]
|
#[path = "dummy.rs"]
|
||||||
mod real_imp;
|
mod imp;
|
||||||
} else if #[cfg(all(target_env = "msvc", not(target_arch = "arm")))] {
|
|
||||||
// LLVM does not support unwinding on 32 bit ARM msvc (thumbv7a-pc-windows-msvc)
|
|
||||||
#[path = "seh.rs"]
|
|
||||||
mod real_imp;
|
|
||||||
} else if #[cfg(any(
|
} else if #[cfg(any(
|
||||||
all(target_family = "windows", target_env = "gnu"),
|
all(target_family = "windows", target_env = "gnu"),
|
||||||
target_os = "psp",
|
target_os = "psp",
|
||||||
|
@ -58,7 +54,16 @@ cfg_if::cfg_if! {
|
||||||
target_family = "wasm",
|
target_family = "wasm",
|
||||||
))] {
|
))] {
|
||||||
#[path = "gcc.rs"]
|
#[path = "gcc.rs"]
|
||||||
mod real_imp;
|
mod imp;
|
||||||
|
} else if #[cfg(miri)] {
|
||||||
|
// Use the Miri runtime on Windows as miri doesn't support funclet based unwinding,
|
||||||
|
// only landingpad based unwinding. Also use the Miri runtime on unsupported platforms.
|
||||||
|
#[path = "miri.rs"]
|
||||||
|
mod imp;
|
||||||
|
} else if #[cfg(all(target_env = "msvc", not(target_arch = "arm")))] {
|
||||||
|
// LLVM does not support unwinding on 32 bit ARM msvc (thumbv7a-pc-windows-msvc)
|
||||||
|
#[path = "seh.rs"]
|
||||||
|
mod imp;
|
||||||
} else {
|
} else {
|
||||||
// Targets that don't support unwinding.
|
// Targets that don't support unwinding.
|
||||||
// - os=none ("bare metal" targets)
|
// - os=none ("bare metal" targets)
|
||||||
|
@ -67,20 +72,7 @@ cfg_if::cfg_if! {
|
||||||
// - nvptx64-nvidia-cuda
|
// - nvptx64-nvidia-cuda
|
||||||
// - arch=avr
|
// - arch=avr
|
||||||
#[path = "dummy.rs"]
|
#[path = "dummy.rs"]
|
||||||
mod real_imp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
|
||||||
if #[cfg(miri)] {
|
|
||||||
// Use the Miri runtime.
|
|
||||||
// We still need to also load the normal runtime above, as rustc expects certain lang
|
|
||||||
// items from there to be defined.
|
|
||||||
#[path = "miri.rs"]
|
|
||||||
mod imp;
|
mod imp;
|
||||||
} else {
|
|
||||||
// Use the real runtime.
|
|
||||||
use real_imp as imp;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@ use crate::os::raw::{c_char, c_long, c_longlong, c_uint, c_ulong, c_ushort, c_vo
|
||||||
use crate::os::windows::io::{AsRawHandle, BorrowedHandle};
|
use crate::os::windows::io::{AsRawHandle, BorrowedHandle};
|
||||||
use crate::ptr;
|
use crate::ptr;
|
||||||
|
|
||||||
|
mod windows_targets;
|
||||||
|
|
||||||
mod windows_sys;
|
mod windows_sys;
|
||||||
pub use windows_sys::*;
|
pub use windows_sys::*;
|
||||||
|
|
||||||
|
@ -504,11 +506,8 @@ if #[cfg(not(target_vendor = "uwp"))] {
|
||||||
#[cfg(target_arch = "arm")]
|
#[cfg(target_arch = "arm")]
|
||||||
pub enum CONTEXT {}
|
pub enum CONTEXT {}
|
||||||
}}
|
}}
|
||||||
|
// WSAStartup is only redefined here so that we can override WSADATA for Arm32
|
||||||
#[link(name = "ws2_32")]
|
windows_targets::link!("ws2_32.dll" "system" fn WSAStartup(wversionrequested: u16, lpwsadata: *mut WSADATA) -> i32);
|
||||||
extern "system" {
|
|
||||||
pub fn WSAStartup(wversionrequested: u16, lpwsadata: *mut WSADATA) -> i32;
|
|
||||||
}
|
|
||||||
#[cfg(target_arch = "arm")]
|
#[cfg(target_arch = "arm")]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct WSADATA {
|
pub struct WSADATA {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
--out windows_sys.rs
|
--out windows_sys.rs
|
||||||
--config flatten std
|
--config flatten sys
|
||||||
--filter
|
--filter
|
||||||
!Windows.Win32.Foundation.INVALID_HANDLE_VALUE
|
!Windows.Win32.Foundation.INVALID_HANDLE_VALUE
|
||||||
Windows.Wdk.Storage.FileSystem.FILE_COMPLETE_IF_OPLOCKED
|
Windows.Wdk.Storage.FileSystem.FILE_COMPLETE_IF_OPLOCKED
|
||||||
|
|
|
@ -1,843 +1,136 @@
|
||||||
// Bindings generated by `windows-bindgen` 0.57.0
|
// Bindings generated by `windows-bindgen` 0.58.0
|
||||||
|
|
||||||
#![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, clippy::all)]
|
#![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, clippy::all)]
|
||||||
#[link(name = "advapi32")]
|
windows_targets::link!("advapi32.dll" "system" fn OpenProcessToken(processhandle : HANDLE, desiredaccess : TOKEN_ACCESS_MASK, tokenhandle : *mut HANDLE) -> BOOL);
|
||||||
extern "system" {
|
windows_targets::link!("advapi32.dll" "system" "SystemFunction036" fn RtlGenRandom(randombuffer : *mut core::ffi::c_void, randombufferlength : u32) -> BOOLEAN);
|
||||||
pub fn OpenProcessToken(
|
windows_targets::link!("kernel32.dll" "system" fn AcquireSRWLockExclusive(srwlock : *mut SRWLOCK));
|
||||||
processhandle: HANDLE,
|
windows_targets::link!("kernel32.dll" "system" fn AcquireSRWLockShared(srwlock : *mut SRWLOCK));
|
||||||
desiredaccess: TOKEN_ACCESS_MASK,
|
windows_targets::link!("kernel32.dll" "system" fn CancelIo(hfile : HANDLE) -> BOOL);
|
||||||
tokenhandle: *mut HANDLE,
|
windows_targets::link!("kernel32.dll" "system" fn CloseHandle(hobject : HANDLE) -> BOOL);
|
||||||
) -> BOOL;
|
windows_targets::link!("kernel32.dll" "system" fn CompareStringOrdinal(lpstring1 : PCWSTR, cchcount1 : i32, lpstring2 : PCWSTR, cchcount2 : i32, bignorecase : BOOL) -> COMPARESTRING_RESULT);
|
||||||
}
|
windows_targets::link!("kernel32.dll" "system" fn CopyFileExW(lpexistingfilename : PCWSTR, lpnewfilename : PCWSTR, lpprogressroutine : LPPROGRESS_ROUTINE, lpdata : *const core::ffi::c_void, pbcancel : *mut BOOL, dwcopyflags : u32) -> BOOL);
|
||||||
#[link(name = "advapi32")]
|
windows_targets::link!("kernel32.dll" "system" fn CreateDirectoryW(lppathname : PCWSTR, lpsecurityattributes : *const SECURITY_ATTRIBUTES) -> BOOL);
|
||||||
extern "system" {
|
windows_targets::link!("kernel32.dll" "system" fn CreateEventW(lpeventattributes : *const SECURITY_ATTRIBUTES, bmanualreset : BOOL, binitialstate : BOOL, lpname : PCWSTR) -> HANDLE);
|
||||||
#[link_name = "SystemFunction036"]
|
windows_targets::link!("kernel32.dll" "system" fn CreateFileW(lpfilename : PCWSTR, dwdesiredaccess : u32, dwsharemode : FILE_SHARE_MODE, lpsecurityattributes : *const SECURITY_ATTRIBUTES, dwcreationdisposition : FILE_CREATION_DISPOSITION, dwflagsandattributes : FILE_FLAGS_AND_ATTRIBUTES, htemplatefile : HANDLE) -> HANDLE);
|
||||||
pub fn RtlGenRandom(randombuffer: *mut core::ffi::c_void, randombufferlength: u32) -> BOOLEAN;
|
windows_targets::link!("kernel32.dll" "system" fn CreateHardLinkW(lpfilename : PCWSTR, lpexistingfilename : PCWSTR, lpsecurityattributes : *const SECURITY_ATTRIBUTES) -> BOOL);
|
||||||
}
|
windows_targets::link!("kernel32.dll" "system" fn CreateNamedPipeW(lpname : PCWSTR, dwopenmode : FILE_FLAGS_AND_ATTRIBUTES, dwpipemode : NAMED_PIPE_MODE, nmaxinstances : u32, noutbuffersize : u32, ninbuffersize : u32, ndefaulttimeout : u32, lpsecurityattributes : *const SECURITY_ATTRIBUTES) -> HANDLE);
|
||||||
#[link(name = "kernel32")]
|
windows_targets::link!("kernel32.dll" "system" fn CreateProcessW(lpapplicationname : PCWSTR, lpcommandline : PWSTR, lpprocessattributes : *const SECURITY_ATTRIBUTES, lpthreadattributes : *const SECURITY_ATTRIBUTES, binherithandles : BOOL, dwcreationflags : PROCESS_CREATION_FLAGS, lpenvironment : *const core::ffi::c_void, lpcurrentdirectory : PCWSTR, lpstartupinfo : *const STARTUPINFOW, lpprocessinformation : *mut PROCESS_INFORMATION) -> BOOL);
|
||||||
extern "system" {
|
windows_targets::link!("kernel32.dll" "system" fn CreateSymbolicLinkW(lpsymlinkfilename : PCWSTR, lptargetfilename : PCWSTR, dwflags : SYMBOLIC_LINK_FLAGS) -> BOOLEAN);
|
||||||
pub fn AcquireSRWLockExclusive(srwlock: *mut SRWLOCK);
|
windows_targets::link!("kernel32.dll" "system" fn CreateThread(lpthreadattributes : *const SECURITY_ATTRIBUTES, dwstacksize : usize, lpstartaddress : LPTHREAD_START_ROUTINE, lpparameter : *const core::ffi::c_void, dwcreationflags : THREAD_CREATION_FLAGS, lpthreadid : *mut u32) -> HANDLE);
|
||||||
}
|
windows_targets::link!("kernel32.dll" "system" fn CreateWaitableTimerExW(lptimerattributes : *const SECURITY_ATTRIBUTES, lptimername : PCWSTR, dwflags : u32, dwdesiredaccess : u32) -> HANDLE);
|
||||||
#[link(name = "kernel32")]
|
windows_targets::link!("kernel32.dll" "system" fn DeleteFileW(lpfilename : PCWSTR) -> BOOL);
|
||||||
extern "system" {
|
windows_targets::link!("kernel32.dll" "system" fn DeleteProcThreadAttributeList(lpattributelist : LPPROC_THREAD_ATTRIBUTE_LIST));
|
||||||
pub fn AcquireSRWLockShared(srwlock: *mut SRWLOCK);
|
windows_targets::link!("kernel32.dll" "system" fn DeviceIoControl(hdevice : HANDLE, dwiocontrolcode : u32, lpinbuffer : *const core::ffi::c_void, ninbuffersize : u32, lpoutbuffer : *mut core::ffi::c_void, noutbuffersize : u32, lpbytesreturned : *mut u32, lpoverlapped : *mut OVERLAPPED) -> BOOL);
|
||||||
}
|
windows_targets::link!("kernel32.dll" "system" fn DuplicateHandle(hsourceprocesshandle : HANDLE, hsourcehandle : HANDLE, htargetprocesshandle : HANDLE, lptargethandle : *mut HANDLE, dwdesiredaccess : u32, binherithandle : BOOL, dwoptions : DUPLICATE_HANDLE_OPTIONS) -> BOOL);
|
||||||
#[link(name = "kernel32")]
|
windows_targets::link!("kernel32.dll" "system" fn ExitProcess(uexitcode : u32) -> !);
|
||||||
extern "system" {
|
windows_targets::link!("kernel32.dll" "system" fn FindClose(hfindfile : HANDLE) -> BOOL);
|
||||||
pub fn CancelIo(hfile: HANDLE) -> BOOL;
|
windows_targets::link!("kernel32.dll" "system" fn FindFirstFileW(lpfilename : PCWSTR, lpfindfiledata : *mut WIN32_FIND_DATAW) -> HANDLE);
|
||||||
}
|
windows_targets::link!("kernel32.dll" "system" fn FindNextFileW(hfindfile : HANDLE, lpfindfiledata : *mut WIN32_FIND_DATAW) -> BOOL);
|
||||||
#[link(name = "kernel32")]
|
windows_targets::link!("kernel32.dll" "system" fn FlushFileBuffers(hfile : HANDLE) -> BOOL);
|
||||||
extern "system" {
|
windows_targets::link!("kernel32.dll" "system" fn FormatMessageW(dwflags : FORMAT_MESSAGE_OPTIONS, lpsource : *const core::ffi::c_void, dwmessageid : u32, dwlanguageid : u32, lpbuffer : PWSTR, nsize : u32, arguments : *const *const i8) -> u32);
|
||||||
pub fn CloseHandle(hobject: HANDLE) -> BOOL;
|
windows_targets::link!("kernel32.dll" "system" fn FreeEnvironmentStringsW(penv : PCWSTR) -> BOOL);
|
||||||
}
|
windows_targets::link!("kernel32.dll" "system" fn GetActiveProcessorCount(groupnumber : u16) -> u32);
|
||||||
#[link(name = "kernel32")]
|
windows_targets::link!("kernel32.dll" "system" fn GetCommandLineW() -> PCWSTR);
|
||||||
extern "system" {
|
windows_targets::link!("kernel32.dll" "system" fn GetConsoleMode(hconsolehandle : HANDLE, lpmode : *mut CONSOLE_MODE) -> BOOL);
|
||||||
pub fn CompareStringOrdinal(
|
windows_targets::link!("kernel32.dll" "system" fn GetCurrentDirectoryW(nbufferlength : u32, lpbuffer : PWSTR) -> u32);
|
||||||
lpstring1: PCWSTR,
|
windows_targets::link!("kernel32.dll" "system" fn GetCurrentProcess() -> HANDLE);
|
||||||
cchcount1: i32,
|
windows_targets::link!("kernel32.dll" "system" fn GetCurrentProcessId() -> u32);
|
||||||
lpstring2: PCWSTR,
|
windows_targets::link!("kernel32.dll" "system" fn GetCurrentThread() -> HANDLE);
|
||||||
cchcount2: i32,
|
windows_targets::link!("kernel32.dll" "system" fn GetEnvironmentStringsW() -> PWSTR);
|
||||||
bignorecase: BOOL,
|
windows_targets::link!("kernel32.dll" "system" fn GetEnvironmentVariableW(lpname : PCWSTR, lpbuffer : PWSTR, nsize : u32) -> u32);
|
||||||
) -> COMPARESTRING_RESULT;
|
windows_targets::link!("kernel32.dll" "system" fn GetExitCodeProcess(hprocess : HANDLE, lpexitcode : *mut u32) -> BOOL);
|
||||||
}
|
windows_targets::link!("kernel32.dll" "system" fn GetFileAttributesW(lpfilename : PCWSTR) -> u32);
|
||||||
#[link(name = "kernel32")]
|
windows_targets::link!("kernel32.dll" "system" fn GetFileInformationByHandle(hfile : HANDLE, lpfileinformation : *mut BY_HANDLE_FILE_INFORMATION) -> BOOL);
|
||||||
extern "system" {
|
windows_targets::link!("kernel32.dll" "system" fn GetFileInformationByHandleEx(hfile : HANDLE, fileinformationclass : FILE_INFO_BY_HANDLE_CLASS, lpfileinformation : *mut core::ffi::c_void, dwbuffersize : u32) -> BOOL);
|
||||||
pub fn CopyFileExW(
|
windows_targets::link!("kernel32.dll" "system" fn GetFileType(hfile : HANDLE) -> FILE_TYPE);
|
||||||
lpexistingfilename: PCWSTR,
|
windows_targets::link!("kernel32.dll" "system" fn GetFinalPathNameByHandleW(hfile : HANDLE, lpszfilepath : PWSTR, cchfilepath : u32, dwflags : GETFINALPATHNAMEBYHANDLE_FLAGS) -> u32);
|
||||||
lpnewfilename: PCWSTR,
|
windows_targets::link!("kernel32.dll" "system" fn GetFullPathNameW(lpfilename : PCWSTR, nbufferlength : u32, lpbuffer : PWSTR, lpfilepart : *mut PWSTR) -> u32);
|
||||||
lpprogressroutine: LPPROGRESS_ROUTINE,
|
windows_targets::link!("kernel32.dll" "system" fn GetLastError() -> WIN32_ERROR);
|
||||||
lpdata: *const core::ffi::c_void,
|
windows_targets::link!("kernel32.dll" "system" fn GetModuleFileNameW(hmodule : HMODULE, lpfilename : PWSTR, nsize : u32) -> u32);
|
||||||
pbcancel: *mut BOOL,
|
windows_targets::link!("kernel32.dll" "system" fn GetModuleHandleA(lpmodulename : PCSTR) -> HMODULE);
|
||||||
dwcopyflags: u32,
|
windows_targets::link!("kernel32.dll" "system" fn GetModuleHandleW(lpmodulename : PCWSTR) -> HMODULE);
|
||||||
) -> BOOL;
|
windows_targets::link!("kernel32.dll" "system" fn GetOverlappedResult(hfile : HANDLE, lpoverlapped : *const OVERLAPPED, lpnumberofbytestransferred : *mut u32, bwait : BOOL) -> BOOL);
|
||||||
}
|
windows_targets::link!("kernel32.dll" "system" fn GetProcAddress(hmodule : HMODULE, lpprocname : PCSTR) -> FARPROC);
|
||||||
#[link(name = "kernel32")]
|
windows_targets::link!("kernel32.dll" "system" fn GetProcessId(process : HANDLE) -> u32);
|
||||||
extern "system" {
|
windows_targets::link!("kernel32.dll" "system" fn GetStdHandle(nstdhandle : STD_HANDLE) -> HANDLE);
|
||||||
pub fn CreateDirectoryW(
|
windows_targets::link!("kernel32.dll" "system" fn GetSystemDirectoryW(lpbuffer : PWSTR, usize : u32) -> u32);
|
||||||
lppathname: PCWSTR,
|
windows_targets::link!("kernel32.dll" "system" fn GetSystemInfo(lpsysteminfo : *mut SYSTEM_INFO));
|
||||||
lpsecurityattributes: *const SECURITY_ATTRIBUTES,
|
windows_targets::link!("kernel32.dll" "system" fn GetSystemTimeAsFileTime(lpsystemtimeasfiletime : *mut FILETIME));
|
||||||
) -> BOOL;
|
windows_targets::link!("kernel32.dll" "system" fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime : *mut FILETIME));
|
||||||
}
|
windows_targets::link!("kernel32.dll" "system" fn GetTempPathW(nbufferlength : u32, lpbuffer : PWSTR) -> u32);
|
||||||
#[link(name = "kernel32")]
|
windows_targets::link!("kernel32.dll" "system" fn GetWindowsDirectoryW(lpbuffer : PWSTR, usize : u32) -> u32);
|
||||||
extern "system" {
|
windows_targets::link!("kernel32.dll" "system" fn InitOnceBeginInitialize(lpinitonce : *mut INIT_ONCE, dwflags : u32, fpending : *mut BOOL, lpcontext : *mut *mut core::ffi::c_void) -> BOOL);
|
||||||
pub fn CreateEventW(
|
windows_targets::link!("kernel32.dll" "system" fn InitOnceComplete(lpinitonce : *mut INIT_ONCE, dwflags : u32, lpcontext : *const core::ffi::c_void) -> BOOL);
|
||||||
lpeventattributes: *const SECURITY_ATTRIBUTES,
|
windows_targets::link!("kernel32.dll" "system" fn InitializeProcThreadAttributeList(lpattributelist : LPPROC_THREAD_ATTRIBUTE_LIST, dwattributecount : u32, dwflags : u32, lpsize : *mut usize) -> BOOL);
|
||||||
bmanualreset: BOOL,
|
windows_targets::link!("kernel32.dll" "system" fn LocalFree(hmem : HLOCAL) -> HLOCAL);
|
||||||
binitialstate: BOOL,
|
windows_targets::link!("kernel32.dll" "system" fn MoveFileExW(lpexistingfilename : PCWSTR, lpnewfilename : PCWSTR, dwflags : MOVE_FILE_FLAGS) -> BOOL);
|
||||||
lpname: PCWSTR,
|
windows_targets::link!("kernel32.dll" "system" fn MultiByteToWideChar(codepage : u32, dwflags : MULTI_BYTE_TO_WIDE_CHAR_FLAGS, lpmultibytestr : PCSTR, cbmultibyte : i32, lpwidecharstr : PWSTR, cchwidechar : i32) -> i32);
|
||||||
) -> HANDLE;
|
windows_targets::link!("kernel32.dll" "system" fn QueryPerformanceCounter(lpperformancecount : *mut i64) -> BOOL);
|
||||||
}
|
windows_targets::link!("kernel32.dll" "system" fn QueryPerformanceFrequency(lpfrequency : *mut i64) -> BOOL);
|
||||||
#[link(name = "kernel32")]
|
windows_targets::link!("kernel32.dll" "system" fn ReadConsoleW(hconsoleinput : HANDLE, lpbuffer : *mut core::ffi::c_void, nnumberofcharstoread : u32, lpnumberofcharsread : *mut u32, pinputcontrol : *const CONSOLE_READCONSOLE_CONTROL) -> BOOL);
|
||||||
extern "system" {
|
windows_targets::link!("kernel32.dll" "system" fn ReadFile(hfile : HANDLE, lpbuffer : *mut u8, nnumberofbytestoread : u32, lpnumberofbytesread : *mut u32, lpoverlapped : *mut OVERLAPPED) -> BOOL);
|
||||||
pub fn CreateFileW(
|
windows_targets::link!("kernel32.dll" "system" fn ReadFileEx(hfile : HANDLE, lpbuffer : *mut u8, nnumberofbytestoread : u32, lpoverlapped : *mut OVERLAPPED, lpcompletionroutine : LPOVERLAPPED_COMPLETION_ROUTINE) -> BOOL);
|
||||||
lpfilename: PCWSTR,
|
windows_targets::link!("kernel32.dll" "system" fn ReleaseSRWLockExclusive(srwlock : *mut SRWLOCK));
|
||||||
dwdesiredaccess: u32,
|
windows_targets::link!("kernel32.dll" "system" fn ReleaseSRWLockShared(srwlock : *mut SRWLOCK));
|
||||||
dwsharemode: FILE_SHARE_MODE,
|
windows_targets::link!("kernel32.dll" "system" fn RemoveDirectoryW(lppathname : PCWSTR) -> BOOL);
|
||||||
lpsecurityattributes: *const SECURITY_ATTRIBUTES,
|
windows_targets::link!("kernel32.dll" "system" fn SetCurrentDirectoryW(lppathname : PCWSTR) -> BOOL);
|
||||||
dwcreationdisposition: FILE_CREATION_DISPOSITION,
|
windows_targets::link!("kernel32.dll" "system" fn SetEnvironmentVariableW(lpname : PCWSTR, lpvalue : PCWSTR) -> BOOL);
|
||||||
dwflagsandattributes: FILE_FLAGS_AND_ATTRIBUTES,
|
windows_targets::link!("kernel32.dll" "system" fn SetFileAttributesW(lpfilename : PCWSTR, dwfileattributes : FILE_FLAGS_AND_ATTRIBUTES) -> BOOL);
|
||||||
htemplatefile: HANDLE,
|
windows_targets::link!("kernel32.dll" "system" fn SetFileInformationByHandle(hfile : HANDLE, fileinformationclass : FILE_INFO_BY_HANDLE_CLASS, lpfileinformation : *const core::ffi::c_void, dwbuffersize : u32) -> BOOL);
|
||||||
) -> HANDLE;
|
windows_targets::link!("kernel32.dll" "system" fn SetFilePointerEx(hfile : HANDLE, lidistancetomove : i64, lpnewfilepointer : *mut i64, dwmovemethod : SET_FILE_POINTER_MOVE_METHOD) -> BOOL);
|
||||||
}
|
windows_targets::link!("kernel32.dll" "system" fn SetFileTime(hfile : HANDLE, lpcreationtime : *const FILETIME, lplastaccesstime : *const FILETIME, lplastwritetime : *const FILETIME) -> BOOL);
|
||||||
#[link(name = "kernel32")]
|
windows_targets::link!("kernel32.dll" "system" fn SetHandleInformation(hobject : HANDLE, dwmask : u32, dwflags : HANDLE_FLAGS) -> BOOL);
|
||||||
extern "system" {
|
windows_targets::link!("kernel32.dll" "system" fn SetLastError(dwerrcode : WIN32_ERROR));
|
||||||
pub fn CreateHardLinkW(
|
windows_targets::link!("kernel32.dll" "system" fn SetThreadStackGuarantee(stacksizeinbytes : *mut u32) -> BOOL);
|
||||||
lpfilename: PCWSTR,
|
windows_targets::link!("kernel32.dll" "system" fn SetWaitableTimer(htimer : HANDLE, lpduetime : *const i64, lperiod : i32, pfncompletionroutine : PTIMERAPCROUTINE, lpargtocompletionroutine : *const core::ffi::c_void, fresume : BOOL) -> BOOL);
|
||||||
lpexistingfilename: PCWSTR,
|
windows_targets::link!("kernel32.dll" "system" fn Sleep(dwmilliseconds : u32));
|
||||||
lpsecurityattributes: *const SECURITY_ATTRIBUTES,
|
windows_targets::link!("kernel32.dll" "system" fn SleepConditionVariableSRW(conditionvariable : *mut CONDITION_VARIABLE, srwlock : *mut SRWLOCK, dwmilliseconds : u32, flags : u32) -> BOOL);
|
||||||
) -> BOOL;
|
windows_targets::link!("kernel32.dll" "system" fn SleepEx(dwmilliseconds : u32, balertable : BOOL) -> u32);
|
||||||
}
|
windows_targets::link!("kernel32.dll" "system" fn SwitchToThread() -> BOOL);
|
||||||
#[link(name = "kernel32")]
|
windows_targets::link!("kernel32.dll" "system" fn TerminateProcess(hprocess : HANDLE, uexitcode : u32) -> BOOL);
|
||||||
extern "system" {
|
windows_targets::link!("kernel32.dll" "system" fn TlsAlloc() -> u32);
|
||||||
pub fn CreateNamedPipeW(
|
windows_targets::link!("kernel32.dll" "system" fn TlsFree(dwtlsindex : u32) -> BOOL);
|
||||||
lpname: PCWSTR,
|
windows_targets::link!("kernel32.dll" "system" fn TlsGetValue(dwtlsindex : u32) -> *mut core::ffi::c_void);
|
||||||
dwopenmode: FILE_FLAGS_AND_ATTRIBUTES,
|
windows_targets::link!("kernel32.dll" "system" fn TlsSetValue(dwtlsindex : u32, lptlsvalue : *const core::ffi::c_void) -> BOOL);
|
||||||
dwpipemode: NAMED_PIPE_MODE,
|
windows_targets::link!("kernel32.dll" "system" fn TryAcquireSRWLockExclusive(srwlock : *mut SRWLOCK) -> BOOLEAN);
|
||||||
nmaxinstances: u32,
|
windows_targets::link!("kernel32.dll" "system" fn TryAcquireSRWLockShared(srwlock : *mut SRWLOCK) -> BOOLEAN);
|
||||||
noutbuffersize: u32,
|
windows_targets::link!("kernel32.dll" "system" fn UpdateProcThreadAttribute(lpattributelist : LPPROC_THREAD_ATTRIBUTE_LIST, dwflags : u32, attribute : usize, lpvalue : *const core::ffi::c_void, cbsize : usize, lppreviousvalue : *mut core::ffi::c_void, lpreturnsize : *const usize) -> BOOL);
|
||||||
ninbuffersize: u32,
|
windows_targets::link!("kernel32.dll" "system" fn WaitForMultipleObjects(ncount : u32, lphandles : *const HANDLE, bwaitall : BOOL, dwmilliseconds : u32) -> WAIT_EVENT);
|
||||||
ndefaulttimeout: u32,
|
windows_targets::link!("kernel32.dll" "system" fn WaitForSingleObject(hhandle : HANDLE, dwmilliseconds : u32) -> WAIT_EVENT);
|
||||||
lpsecurityattributes: *const SECURITY_ATTRIBUTES,
|
windows_targets::link!("kernel32.dll" "system" fn WakeAllConditionVariable(conditionvariable : *mut CONDITION_VARIABLE));
|
||||||
) -> HANDLE;
|
windows_targets::link!("kernel32.dll" "system" fn WakeConditionVariable(conditionvariable : *mut CONDITION_VARIABLE));
|
||||||
}
|
windows_targets::link!("kernel32.dll" "system" fn WideCharToMultiByte(codepage : u32, dwflags : u32, lpwidecharstr : PCWSTR, cchwidechar : i32, lpmultibytestr : PSTR, cbmultibyte : i32, lpdefaultchar : PCSTR, lpuseddefaultchar : *mut BOOL) -> i32);
|
||||||
#[link(name = "kernel32")]
|
windows_targets::link!("kernel32.dll" "system" fn WriteConsoleW(hconsoleoutput : HANDLE, lpbuffer : PCWSTR, nnumberofcharstowrite : u32, lpnumberofcharswritten : *mut u32, lpreserved : *const core::ffi::c_void) -> BOOL);
|
||||||
extern "system" {
|
windows_targets::link!("kernel32.dll" "system" fn WriteFileEx(hfile : HANDLE, lpbuffer : *const u8, nnumberofbytestowrite : u32, lpoverlapped : *mut OVERLAPPED, lpcompletionroutine : LPOVERLAPPED_COMPLETION_ROUTINE) -> BOOL);
|
||||||
pub fn CreateProcessW(
|
windows_targets::link!("ntdll.dll" "system" fn NtCreateFile(filehandle : *mut HANDLE, desiredaccess : FILE_ACCESS_RIGHTS, objectattributes : *const OBJECT_ATTRIBUTES, iostatusblock : *mut IO_STATUS_BLOCK, allocationsize : *const i64, fileattributes : FILE_FLAGS_AND_ATTRIBUTES, shareaccess : FILE_SHARE_MODE, createdisposition : NTCREATEFILE_CREATE_DISPOSITION, createoptions : NTCREATEFILE_CREATE_OPTIONS, eabuffer : *const core::ffi::c_void, ealength : u32) -> NTSTATUS);
|
||||||
lpapplicationname: PCWSTR,
|
windows_targets::link!("ntdll.dll" "system" fn NtReadFile(filehandle : HANDLE, event : HANDLE, apcroutine : PIO_APC_ROUTINE, apccontext : *const core::ffi::c_void, iostatusblock : *mut IO_STATUS_BLOCK, buffer : *mut core::ffi::c_void, length : u32, byteoffset : *const i64, key : *const u32) -> NTSTATUS);
|
||||||
lpcommandline: PWSTR,
|
windows_targets::link!("ntdll.dll" "system" fn NtWriteFile(filehandle : HANDLE, event : HANDLE, apcroutine : PIO_APC_ROUTINE, apccontext : *const core::ffi::c_void, iostatusblock : *mut IO_STATUS_BLOCK, buffer : *const core::ffi::c_void, length : u32, byteoffset : *const i64, key : *const u32) -> NTSTATUS);
|
||||||
lpprocessattributes: *const SECURITY_ATTRIBUTES,
|
windows_targets::link!("ntdll.dll" "system" fn RtlNtStatusToDosError(status : NTSTATUS) -> u32);
|
||||||
lpthreadattributes: *const SECURITY_ATTRIBUTES,
|
windows_targets::link!("userenv.dll" "system" fn GetUserProfileDirectoryW(htoken : HANDLE, lpprofiledir : PWSTR, lpcchsize : *mut u32) -> BOOL);
|
||||||
binherithandles: BOOL,
|
windows_targets::link!("ws2_32.dll" "system" fn WSACleanup() -> i32);
|
||||||
dwcreationflags: PROCESS_CREATION_FLAGS,
|
windows_targets::link!("ws2_32.dll" "system" fn WSADuplicateSocketW(s : SOCKET, dwprocessid : u32, lpprotocolinfo : *mut WSAPROTOCOL_INFOW) -> i32);
|
||||||
lpenvironment: *const core::ffi::c_void,
|
windows_targets::link!("ws2_32.dll" "system" fn WSAGetLastError() -> WSA_ERROR);
|
||||||
lpcurrentdirectory: PCWSTR,
|
windows_targets::link!("ws2_32.dll" "system" fn WSARecv(s : SOCKET, lpbuffers : *const WSABUF, dwbuffercount : u32, lpnumberofbytesrecvd : *mut u32, lpflags : *mut u32, lpoverlapped : *mut OVERLAPPED, lpcompletionroutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) -> i32);
|
||||||
lpstartupinfo: *const STARTUPINFOW,
|
windows_targets::link!("ws2_32.dll" "system" fn WSASend(s : SOCKET, lpbuffers : *const WSABUF, dwbuffercount : u32, lpnumberofbytessent : *mut u32, dwflags : u32, lpoverlapped : *mut OVERLAPPED, lpcompletionroutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) -> i32);
|
||||||
lpprocessinformation: *mut PROCESS_INFORMATION,
|
windows_targets::link!("ws2_32.dll" "system" fn WSASocketW(af : i32, r#type : i32, protocol : i32, lpprotocolinfo : *const WSAPROTOCOL_INFOW, g : u32, dwflags : u32) -> SOCKET);
|
||||||
) -> BOOL;
|
windows_targets::link!("ws2_32.dll" "system" fn accept(s : SOCKET, addr : *mut SOCKADDR, addrlen : *mut i32) -> SOCKET);
|
||||||
}
|
windows_targets::link!("ws2_32.dll" "system" fn bind(s : SOCKET, name : *const SOCKADDR, namelen : i32) -> i32);
|
||||||
#[link(name = "kernel32")]
|
windows_targets::link!("ws2_32.dll" "system" fn closesocket(s : SOCKET) -> i32);
|
||||||
extern "system" {
|
windows_targets::link!("ws2_32.dll" "system" fn connect(s : SOCKET, name : *const SOCKADDR, namelen : i32) -> i32);
|
||||||
pub fn CreateSymbolicLinkW(
|
windows_targets::link!("ws2_32.dll" "system" fn freeaddrinfo(paddrinfo : *const ADDRINFOA));
|
||||||
lpsymlinkfilename: PCWSTR,
|
windows_targets::link!("ws2_32.dll" "system" fn getaddrinfo(pnodename : PCSTR, pservicename : PCSTR, phints : *const ADDRINFOA, ppresult : *mut *mut ADDRINFOA) -> i32);
|
||||||
lptargetfilename: PCWSTR,
|
windows_targets::link!("ws2_32.dll" "system" fn getpeername(s : SOCKET, name : *mut SOCKADDR, namelen : *mut i32) -> i32);
|
||||||
dwflags: SYMBOLIC_LINK_FLAGS,
|
windows_targets::link!("ws2_32.dll" "system" fn getsockname(s : SOCKET, name : *mut SOCKADDR, namelen : *mut i32) -> i32);
|
||||||
) -> BOOLEAN;
|
windows_targets::link!("ws2_32.dll" "system" fn getsockopt(s : SOCKET, level : i32, optname : i32, optval : PSTR, optlen : *mut i32) -> i32);
|
||||||
}
|
windows_targets::link!("ws2_32.dll" "system" fn ioctlsocket(s : SOCKET, cmd : i32, argp : *mut u32) -> i32);
|
||||||
#[link(name = "kernel32")]
|
windows_targets::link!("ws2_32.dll" "system" fn listen(s : SOCKET, backlog : i32) -> i32);
|
||||||
extern "system" {
|
windows_targets::link!("ws2_32.dll" "system" fn recv(s : SOCKET, buf : PSTR, len : i32, flags : SEND_RECV_FLAGS) -> i32);
|
||||||
pub fn CreateThread(
|
windows_targets::link!("ws2_32.dll" "system" fn recvfrom(s : SOCKET, buf : PSTR, len : i32, flags : i32, from : *mut SOCKADDR, fromlen : *mut i32) -> i32);
|
||||||
lpthreadattributes: *const SECURITY_ATTRIBUTES,
|
windows_targets::link!("ws2_32.dll" "system" fn select(nfds : i32, readfds : *mut FD_SET, writefds : *mut FD_SET, exceptfds : *mut FD_SET, timeout : *const TIMEVAL) -> i32);
|
||||||
dwstacksize: usize,
|
windows_targets::link!("ws2_32.dll" "system" fn send(s : SOCKET, buf : PCSTR, len : i32, flags : SEND_RECV_FLAGS) -> i32);
|
||||||
lpstartaddress: LPTHREAD_START_ROUTINE,
|
windows_targets::link!("ws2_32.dll" "system" fn sendto(s : SOCKET, buf : PCSTR, len : i32, flags : i32, to : *const SOCKADDR, tolen : i32) -> i32);
|
||||||
lpparameter: *const core::ffi::c_void,
|
windows_targets::link!("ws2_32.dll" "system" fn setsockopt(s : SOCKET, level : i32, optname : i32, optval : PCSTR, optlen : i32) -> i32);
|
||||||
dwcreationflags: THREAD_CREATION_FLAGS,
|
windows_targets::link!("ws2_32.dll" "system" fn shutdown(s : SOCKET, how : WINSOCK_SHUTDOWN_HOW) -> i32);
|
||||||
lpthreadid: *mut u32,
|
|
||||||
) -> HANDLE;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn CreateWaitableTimerExW(
|
|
||||||
lptimerattributes: *const SECURITY_ATTRIBUTES,
|
|
||||||
lptimername: PCWSTR,
|
|
||||||
dwflags: u32,
|
|
||||||
dwdesiredaccess: u32,
|
|
||||||
) -> HANDLE;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn DeleteFileW(lpfilename: PCWSTR) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn DeleteProcThreadAttributeList(lpattributelist: LPPROC_THREAD_ATTRIBUTE_LIST);
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn DeviceIoControl(
|
|
||||||
hdevice: HANDLE,
|
|
||||||
dwiocontrolcode: u32,
|
|
||||||
lpinbuffer: *const core::ffi::c_void,
|
|
||||||
ninbuffersize: u32,
|
|
||||||
lpoutbuffer: *mut core::ffi::c_void,
|
|
||||||
noutbuffersize: u32,
|
|
||||||
lpbytesreturned: *mut u32,
|
|
||||||
lpoverlapped: *mut OVERLAPPED,
|
|
||||||
) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn DuplicateHandle(
|
|
||||||
hsourceprocesshandle: HANDLE,
|
|
||||||
hsourcehandle: HANDLE,
|
|
||||||
htargetprocesshandle: HANDLE,
|
|
||||||
lptargethandle: *mut HANDLE,
|
|
||||||
dwdesiredaccess: u32,
|
|
||||||
binherithandle: BOOL,
|
|
||||||
dwoptions: DUPLICATE_HANDLE_OPTIONS,
|
|
||||||
) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn ExitProcess(uexitcode: u32) -> !;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn FindClose(hfindfile: HANDLE) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn FindFirstFileW(lpfilename: PCWSTR, lpfindfiledata: *mut WIN32_FIND_DATAW) -> HANDLE;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn FindNextFileW(hfindfile: HANDLE, lpfindfiledata: *mut WIN32_FIND_DATAW) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn FlushFileBuffers(hfile: HANDLE) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn FormatMessageW(
|
|
||||||
dwflags: FORMAT_MESSAGE_OPTIONS,
|
|
||||||
lpsource: *const core::ffi::c_void,
|
|
||||||
dwmessageid: u32,
|
|
||||||
dwlanguageid: u32,
|
|
||||||
lpbuffer: PWSTR,
|
|
||||||
nsize: u32,
|
|
||||||
arguments: *const *const i8,
|
|
||||||
) -> u32;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn FreeEnvironmentStringsW(penv: PCWSTR) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetActiveProcessorCount(groupnumber: u16) -> u32;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetCommandLineW() -> PCWSTR;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetConsoleMode(hconsolehandle: HANDLE, lpmode: *mut CONSOLE_MODE) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetCurrentDirectoryW(nbufferlength: u32, lpbuffer: PWSTR) -> u32;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetCurrentProcess() -> HANDLE;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetCurrentProcessId() -> u32;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetCurrentThread() -> HANDLE;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetEnvironmentStringsW() -> PWSTR;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetEnvironmentVariableW(lpname: PCWSTR, lpbuffer: PWSTR, nsize: u32) -> u32;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetExitCodeProcess(hprocess: HANDLE, lpexitcode: *mut u32) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetFileAttributesW(lpfilename: PCWSTR) -> u32;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetFileInformationByHandle(
|
|
||||||
hfile: HANDLE,
|
|
||||||
lpfileinformation: *mut BY_HANDLE_FILE_INFORMATION,
|
|
||||||
) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetFileInformationByHandleEx(
|
|
||||||
hfile: HANDLE,
|
|
||||||
fileinformationclass: FILE_INFO_BY_HANDLE_CLASS,
|
|
||||||
lpfileinformation: *mut core::ffi::c_void,
|
|
||||||
dwbuffersize: u32,
|
|
||||||
) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetFileType(hfile: HANDLE) -> FILE_TYPE;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetFinalPathNameByHandleW(
|
|
||||||
hfile: HANDLE,
|
|
||||||
lpszfilepath: PWSTR,
|
|
||||||
cchfilepath: u32,
|
|
||||||
dwflags: GETFINALPATHNAMEBYHANDLE_FLAGS,
|
|
||||||
) -> u32;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetFullPathNameW(
|
|
||||||
lpfilename: PCWSTR,
|
|
||||||
nbufferlength: u32,
|
|
||||||
lpbuffer: PWSTR,
|
|
||||||
lpfilepart: *mut PWSTR,
|
|
||||||
) -> u32;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetLastError() -> WIN32_ERROR;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetModuleFileNameW(hmodule: HMODULE, lpfilename: PWSTR, nsize: u32) -> u32;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetModuleHandleA(lpmodulename: PCSTR) -> HMODULE;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetModuleHandleW(lpmodulename: PCWSTR) -> HMODULE;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetOverlappedResult(
|
|
||||||
hfile: HANDLE,
|
|
||||||
lpoverlapped: *const OVERLAPPED,
|
|
||||||
lpnumberofbytestransferred: *mut u32,
|
|
||||||
bwait: BOOL,
|
|
||||||
) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetProcAddress(hmodule: HMODULE, lpprocname: PCSTR) -> FARPROC;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetProcessId(process: HANDLE) -> u32;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetStdHandle(nstdhandle: STD_HANDLE) -> HANDLE;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetSystemDirectoryW(lpbuffer: PWSTR, usize: u32) -> u32;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetSystemInfo(lpsysteminfo: *mut SYSTEM_INFO);
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetSystemTimeAsFileTime(lpsystemtimeasfiletime: *mut FILETIME);
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime: *mut FILETIME);
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetTempPathW(nbufferlength: u32, lpbuffer: PWSTR) -> u32;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetWindowsDirectoryW(lpbuffer: PWSTR, usize: u32) -> u32;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn InitOnceBeginInitialize(
|
|
||||||
lpinitonce: *mut INIT_ONCE,
|
|
||||||
dwflags: u32,
|
|
||||||
fpending: *mut BOOL,
|
|
||||||
lpcontext: *mut *mut core::ffi::c_void,
|
|
||||||
) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn InitOnceComplete(
|
|
||||||
lpinitonce: *mut INIT_ONCE,
|
|
||||||
dwflags: u32,
|
|
||||||
lpcontext: *const core::ffi::c_void,
|
|
||||||
) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn InitializeProcThreadAttributeList(
|
|
||||||
lpattributelist: LPPROC_THREAD_ATTRIBUTE_LIST,
|
|
||||||
dwattributecount: u32,
|
|
||||||
dwflags: u32,
|
|
||||||
lpsize: *mut usize,
|
|
||||||
) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn LocalFree(hmem: HLOCAL) -> HLOCAL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn MoveFileExW(
|
|
||||||
lpexistingfilename: PCWSTR,
|
|
||||||
lpnewfilename: PCWSTR,
|
|
||||||
dwflags: MOVE_FILE_FLAGS,
|
|
||||||
) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn MultiByteToWideChar(
|
|
||||||
codepage: u32,
|
|
||||||
dwflags: MULTI_BYTE_TO_WIDE_CHAR_FLAGS,
|
|
||||||
lpmultibytestr: PCSTR,
|
|
||||||
cbmultibyte: i32,
|
|
||||||
lpwidecharstr: PWSTR,
|
|
||||||
cchwidechar: i32,
|
|
||||||
) -> i32;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn QueryPerformanceCounter(lpperformancecount: *mut i64) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn QueryPerformanceFrequency(lpfrequency: *mut i64) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn ReadConsoleW(
|
|
||||||
hconsoleinput: HANDLE,
|
|
||||||
lpbuffer: *mut core::ffi::c_void,
|
|
||||||
nnumberofcharstoread: u32,
|
|
||||||
lpnumberofcharsread: *mut u32,
|
|
||||||
pinputcontrol: *const CONSOLE_READCONSOLE_CONTROL,
|
|
||||||
) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn ReadFile(
|
|
||||||
hfile: HANDLE,
|
|
||||||
lpbuffer: *mut u8,
|
|
||||||
nnumberofbytestoread: u32,
|
|
||||||
lpnumberofbytesread: *mut u32,
|
|
||||||
lpoverlapped: *mut OVERLAPPED,
|
|
||||||
) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn ReadFileEx(
|
|
||||||
hfile: HANDLE,
|
|
||||||
lpbuffer: *mut u8,
|
|
||||||
nnumberofbytestoread: u32,
|
|
||||||
lpoverlapped: *mut OVERLAPPED,
|
|
||||||
lpcompletionroutine: LPOVERLAPPED_COMPLETION_ROUTINE,
|
|
||||||
) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn ReleaseSRWLockExclusive(srwlock: *mut SRWLOCK);
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn ReleaseSRWLockShared(srwlock: *mut SRWLOCK);
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn RemoveDirectoryW(lppathname: PCWSTR) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn SetCurrentDirectoryW(lppathname: PCWSTR) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn SetEnvironmentVariableW(lpname: PCWSTR, lpvalue: PCWSTR) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn SetFileAttributesW(
|
|
||||||
lpfilename: PCWSTR,
|
|
||||||
dwfileattributes: FILE_FLAGS_AND_ATTRIBUTES,
|
|
||||||
) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn SetFileInformationByHandle(
|
|
||||||
hfile: HANDLE,
|
|
||||||
fileinformationclass: FILE_INFO_BY_HANDLE_CLASS,
|
|
||||||
lpfileinformation: *const core::ffi::c_void,
|
|
||||||
dwbuffersize: u32,
|
|
||||||
) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn SetFilePointerEx(
|
|
||||||
hfile: HANDLE,
|
|
||||||
lidistancetomove: i64,
|
|
||||||
lpnewfilepointer: *mut i64,
|
|
||||||
dwmovemethod: SET_FILE_POINTER_MOVE_METHOD,
|
|
||||||
) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn SetFileTime(
|
|
||||||
hfile: HANDLE,
|
|
||||||
lpcreationtime: *const FILETIME,
|
|
||||||
lplastaccesstime: *const FILETIME,
|
|
||||||
lplastwritetime: *const FILETIME,
|
|
||||||
) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn SetHandleInformation(hobject: HANDLE, dwmask: u32, dwflags: HANDLE_FLAGS) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn SetLastError(dwerrcode: WIN32_ERROR);
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn SetThreadStackGuarantee(stacksizeinbytes: *mut u32) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn SetWaitableTimer(
|
|
||||||
htimer: HANDLE,
|
|
||||||
lpduetime: *const i64,
|
|
||||||
lperiod: i32,
|
|
||||||
pfncompletionroutine: PTIMERAPCROUTINE,
|
|
||||||
lpargtocompletionroutine: *const core::ffi::c_void,
|
|
||||||
fresume: BOOL,
|
|
||||||
) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn Sleep(dwmilliseconds: u32);
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn SleepConditionVariableSRW(
|
|
||||||
conditionvariable: *mut CONDITION_VARIABLE,
|
|
||||||
srwlock: *mut SRWLOCK,
|
|
||||||
dwmilliseconds: u32,
|
|
||||||
flags: u32,
|
|
||||||
) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn SleepEx(dwmilliseconds: u32, balertable: BOOL) -> u32;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn SwitchToThread() -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn TerminateProcess(hprocess: HANDLE, uexitcode: u32) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn TlsAlloc() -> u32;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn TlsFree(dwtlsindex: u32) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn TlsGetValue(dwtlsindex: u32) -> *mut core::ffi::c_void;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn TlsSetValue(dwtlsindex: u32, lptlsvalue: *const core::ffi::c_void) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn TryAcquireSRWLockExclusive(srwlock: *mut SRWLOCK) -> BOOLEAN;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn TryAcquireSRWLockShared(srwlock: *mut SRWLOCK) -> BOOLEAN;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn UpdateProcThreadAttribute(
|
|
||||||
lpattributelist: LPPROC_THREAD_ATTRIBUTE_LIST,
|
|
||||||
dwflags: u32,
|
|
||||||
attribute: usize,
|
|
||||||
lpvalue: *const core::ffi::c_void,
|
|
||||||
cbsize: usize,
|
|
||||||
lppreviousvalue: *mut core::ffi::c_void,
|
|
||||||
lpreturnsize: *const usize,
|
|
||||||
) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn WaitForMultipleObjects(
|
|
||||||
ncount: u32,
|
|
||||||
lphandles: *const HANDLE,
|
|
||||||
bwaitall: BOOL,
|
|
||||||
dwmilliseconds: u32,
|
|
||||||
) -> WAIT_EVENT;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn WaitForSingleObject(hhandle: HANDLE, dwmilliseconds: u32) -> WAIT_EVENT;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn WakeAllConditionVariable(conditionvariable: *mut CONDITION_VARIABLE);
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn WakeConditionVariable(conditionvariable: *mut CONDITION_VARIABLE);
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn WideCharToMultiByte(
|
|
||||||
codepage: u32,
|
|
||||||
dwflags: u32,
|
|
||||||
lpwidecharstr: PCWSTR,
|
|
||||||
cchwidechar: i32,
|
|
||||||
lpmultibytestr: PSTR,
|
|
||||||
cbmultibyte: i32,
|
|
||||||
lpdefaultchar: PCSTR,
|
|
||||||
lpuseddefaultchar: *mut BOOL,
|
|
||||||
) -> i32;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn WriteConsoleW(
|
|
||||||
hconsoleoutput: HANDLE,
|
|
||||||
lpbuffer: *const core::ffi::c_void,
|
|
||||||
nnumberofcharstowrite: u32,
|
|
||||||
lpnumberofcharswritten: *mut u32,
|
|
||||||
lpreserved: *const core::ffi::c_void,
|
|
||||||
) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn WriteFileEx(
|
|
||||||
hfile: HANDLE,
|
|
||||||
lpbuffer: *const u8,
|
|
||||||
nnumberofbytestowrite: u32,
|
|
||||||
lpoverlapped: *mut OVERLAPPED,
|
|
||||||
lpcompletionroutine: LPOVERLAPPED_COMPLETION_ROUTINE,
|
|
||||||
) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "ntdll")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn NtCreateFile(
|
|
||||||
filehandle: *mut HANDLE,
|
|
||||||
desiredaccess: FILE_ACCESS_RIGHTS,
|
|
||||||
objectattributes: *const OBJECT_ATTRIBUTES,
|
|
||||||
iostatusblock: *mut IO_STATUS_BLOCK,
|
|
||||||
allocationsize: *const i64,
|
|
||||||
fileattributes: FILE_FLAGS_AND_ATTRIBUTES,
|
|
||||||
shareaccess: FILE_SHARE_MODE,
|
|
||||||
createdisposition: NTCREATEFILE_CREATE_DISPOSITION,
|
|
||||||
createoptions: NTCREATEFILE_CREATE_OPTIONS,
|
|
||||||
eabuffer: *const core::ffi::c_void,
|
|
||||||
ealength: u32,
|
|
||||||
) -> NTSTATUS;
|
|
||||||
}
|
|
||||||
#[link(name = "ntdll")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn NtReadFile(
|
|
||||||
filehandle: HANDLE,
|
|
||||||
event: HANDLE,
|
|
||||||
apcroutine: PIO_APC_ROUTINE,
|
|
||||||
apccontext: *const core::ffi::c_void,
|
|
||||||
iostatusblock: *mut IO_STATUS_BLOCK,
|
|
||||||
buffer: *mut core::ffi::c_void,
|
|
||||||
length: u32,
|
|
||||||
byteoffset: *const i64,
|
|
||||||
key: *const u32,
|
|
||||||
) -> NTSTATUS;
|
|
||||||
}
|
|
||||||
#[link(name = "ntdll")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn NtWriteFile(
|
|
||||||
filehandle: HANDLE,
|
|
||||||
event: HANDLE,
|
|
||||||
apcroutine: PIO_APC_ROUTINE,
|
|
||||||
apccontext: *const core::ffi::c_void,
|
|
||||||
iostatusblock: *mut IO_STATUS_BLOCK,
|
|
||||||
buffer: *const core::ffi::c_void,
|
|
||||||
length: u32,
|
|
||||||
byteoffset: *const i64,
|
|
||||||
key: *const u32,
|
|
||||||
) -> NTSTATUS;
|
|
||||||
}
|
|
||||||
#[link(name = "ntdll")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn RtlNtStatusToDosError(status: NTSTATUS) -> u32;
|
|
||||||
}
|
|
||||||
#[link(name = "userenv")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetUserProfileDirectoryW(
|
|
||||||
htoken: HANDLE,
|
|
||||||
lpprofiledir: PWSTR,
|
|
||||||
lpcchsize: *mut u32,
|
|
||||||
) -> BOOL;
|
|
||||||
}
|
|
||||||
#[link(name = "ws2_32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn WSACleanup() -> i32;
|
|
||||||
}
|
|
||||||
#[link(name = "ws2_32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn WSADuplicateSocketW(
|
|
||||||
s: SOCKET,
|
|
||||||
dwprocessid: u32,
|
|
||||||
lpprotocolinfo: *mut WSAPROTOCOL_INFOW,
|
|
||||||
) -> i32;
|
|
||||||
}
|
|
||||||
#[link(name = "ws2_32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn WSAGetLastError() -> WSA_ERROR;
|
|
||||||
}
|
|
||||||
#[link(name = "ws2_32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn WSARecv(
|
|
||||||
s: SOCKET,
|
|
||||||
lpbuffers: *const WSABUF,
|
|
||||||
dwbuffercount: u32,
|
|
||||||
lpnumberofbytesrecvd: *mut u32,
|
|
||||||
lpflags: *mut u32,
|
|
||||||
lpoverlapped: *mut OVERLAPPED,
|
|
||||||
lpcompletionroutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE,
|
|
||||||
) -> i32;
|
|
||||||
}
|
|
||||||
#[link(name = "ws2_32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn WSASend(
|
|
||||||
s: SOCKET,
|
|
||||||
lpbuffers: *const WSABUF,
|
|
||||||
dwbuffercount: u32,
|
|
||||||
lpnumberofbytessent: *mut u32,
|
|
||||||
dwflags: u32,
|
|
||||||
lpoverlapped: *mut OVERLAPPED,
|
|
||||||
lpcompletionroutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE,
|
|
||||||
) -> i32;
|
|
||||||
}
|
|
||||||
#[link(name = "ws2_32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn WSASocketW(
|
|
||||||
af: i32,
|
|
||||||
r#type: i32,
|
|
||||||
protocol: i32,
|
|
||||||
lpprotocolinfo: *const WSAPROTOCOL_INFOW,
|
|
||||||
g: u32,
|
|
||||||
dwflags: u32,
|
|
||||||
) -> SOCKET;
|
|
||||||
}
|
|
||||||
#[link(name = "ws2_32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn accept(s: SOCKET, addr: *mut SOCKADDR, addrlen: *mut i32) -> SOCKET;
|
|
||||||
}
|
|
||||||
#[link(name = "ws2_32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn bind(s: SOCKET, name: *const SOCKADDR, namelen: i32) -> i32;
|
|
||||||
}
|
|
||||||
#[link(name = "ws2_32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn closesocket(s: SOCKET) -> i32;
|
|
||||||
}
|
|
||||||
#[link(name = "ws2_32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn connect(s: SOCKET, name: *const SOCKADDR, namelen: i32) -> i32;
|
|
||||||
}
|
|
||||||
#[link(name = "ws2_32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn freeaddrinfo(paddrinfo: *const ADDRINFOA);
|
|
||||||
}
|
|
||||||
#[link(name = "ws2_32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn getaddrinfo(
|
|
||||||
pnodename: PCSTR,
|
|
||||||
pservicename: PCSTR,
|
|
||||||
phints: *const ADDRINFOA,
|
|
||||||
ppresult: *mut *mut ADDRINFOA,
|
|
||||||
) -> i32;
|
|
||||||
}
|
|
||||||
#[link(name = "ws2_32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn getpeername(s: SOCKET, name: *mut SOCKADDR, namelen: *mut i32) -> i32;
|
|
||||||
}
|
|
||||||
#[link(name = "ws2_32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn getsockname(s: SOCKET, name: *mut SOCKADDR, namelen: *mut i32) -> i32;
|
|
||||||
}
|
|
||||||
#[link(name = "ws2_32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn getsockopt(s: SOCKET, level: i32, optname: i32, optval: PSTR, optlen: *mut i32) -> i32;
|
|
||||||
}
|
|
||||||
#[link(name = "ws2_32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn ioctlsocket(s: SOCKET, cmd: i32, argp: *mut u32) -> i32;
|
|
||||||
}
|
|
||||||
#[link(name = "ws2_32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn listen(s: SOCKET, backlog: i32) -> i32;
|
|
||||||
}
|
|
||||||
#[link(name = "ws2_32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn recv(s: SOCKET, buf: PSTR, len: i32, flags: SEND_RECV_FLAGS) -> i32;
|
|
||||||
}
|
|
||||||
#[link(name = "ws2_32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn recvfrom(
|
|
||||||
s: SOCKET,
|
|
||||||
buf: PSTR,
|
|
||||||
len: i32,
|
|
||||||
flags: i32,
|
|
||||||
from: *mut SOCKADDR,
|
|
||||||
fromlen: *mut i32,
|
|
||||||
) -> i32;
|
|
||||||
}
|
|
||||||
#[link(name = "ws2_32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn select(
|
|
||||||
nfds: i32,
|
|
||||||
readfds: *mut FD_SET,
|
|
||||||
writefds: *mut FD_SET,
|
|
||||||
exceptfds: *mut FD_SET,
|
|
||||||
timeout: *const TIMEVAL,
|
|
||||||
) -> i32;
|
|
||||||
}
|
|
||||||
#[link(name = "ws2_32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn send(s: SOCKET, buf: PCSTR, len: i32, flags: SEND_RECV_FLAGS) -> i32;
|
|
||||||
}
|
|
||||||
#[link(name = "ws2_32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn sendto(
|
|
||||||
s: SOCKET,
|
|
||||||
buf: PCSTR,
|
|
||||||
len: i32,
|
|
||||||
flags: i32,
|
|
||||||
to: *const SOCKADDR,
|
|
||||||
tolen: i32,
|
|
||||||
) -> i32;
|
|
||||||
}
|
|
||||||
#[link(name = "ws2_32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn setsockopt(s: SOCKET, level: i32, optname: i32, optval: PCSTR, optlen: i32) -> i32;
|
|
||||||
}
|
|
||||||
#[link(name = "ws2_32")]
|
|
||||||
extern "system" {
|
|
||||||
pub fn shutdown(s: SOCKET, how: WINSOCK_SHUTDOWN_HOW) -> i32;
|
|
||||||
}
|
|
||||||
pub const ABOVE_NORMAL_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 32768u32;
|
pub const ABOVE_NORMAL_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 32768u32;
|
||||||
pub type ADDRESS_FAMILY = u16;
|
pub type ADDRESS_FAMILY = u16;
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -3991,3 +3284,4 @@ pub struct XSAVE_FORMAT {
|
||||||
pub Reserved4: [u8; 224],
|
pub Reserved4: [u8; 224],
|
||||||
}
|
}
|
||||||
// ignore-tidy-filelength
|
// ignore-tidy-filelength
|
||||||
|
use super::windows_targets;
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
//! Provides the `link!` macro used by the generated windows bindings.
|
||||||
|
//!
|
||||||
|
//! This is a simple wrapper around an `extern` block with a `#[link]` attribute.
|
||||||
|
//! It's very roughly equivalent to the windows-targets crate.
|
||||||
|
|
||||||
|
pub macro link {
|
||||||
|
($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => (
|
||||||
|
// Note: the windows-targets crate uses a pre-built Windows.lib import library which we don't
|
||||||
|
// have in this repo. So instead we always link kernel32.lib and add the rest of the import
|
||||||
|
// libraries below by using an empty extern block. This works because extern blocks are not
|
||||||
|
// connected to the library given in the #[link] attribute.
|
||||||
|
#[link(name = "kernel32")]
|
||||||
|
extern $abi {
|
||||||
|
$(#[link_name=$link_name])?
|
||||||
|
pub fn $($function)*;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[link(name = "advapi32")]
|
||||||
|
#[link(name = "ntdll")]
|
||||||
|
#[link(name = "userenv")]
|
||||||
|
#[link(name = "ws2_32")]
|
||||||
|
extern "C" {}
|
|
@ -232,13 +232,7 @@ fn write_u16s(handle: c::HANDLE, data: &[u16]) -> io::Result<usize> {
|
||||||
debug_assert!(data.len() < u32::MAX as usize);
|
debug_assert!(data.len() < u32::MAX as usize);
|
||||||
let mut written = 0;
|
let mut written = 0;
|
||||||
cvt(unsafe {
|
cvt(unsafe {
|
||||||
c::WriteConsoleW(
|
c::WriteConsoleW(handle, data.as_ptr(), data.len() as u32, &mut written, ptr::null_mut())
|
||||||
handle,
|
|
||||||
data.as_ptr() as c::LPCVOID,
|
|
||||||
data.len() as u32,
|
|
||||||
&mut written,
|
|
||||||
ptr::null_mut(),
|
|
||||||
)
|
|
||||||
})?;
|
})?;
|
||||||
Ok(written as usize)
|
Ok(written as usize)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,4 +4,4 @@ version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies.windows-bindgen]
|
[dependencies.windows-bindgen]
|
||||||
version = "0.57.0"
|
version = "0.58.0"
|
||||||
|
|
|
@ -17,6 +17,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
|
||||||
let mut f = std::fs::File::options().append(true).open("windows_sys.rs")?;
|
let mut f = std::fs::File::options().append(true).open("windows_sys.rs")?;
|
||||||
writeln!(&mut f, "// ignore-tidy-filelength")?;
|
writeln!(&mut f, "// ignore-tidy-filelength")?;
|
||||||
|
writeln!(&mut f, "use super::windows_targets;")?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -758,6 +758,22 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||||
this.write_null(dest)?;
|
this.write_null(dest)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"_Unwind_RaiseException" => {
|
||||||
|
// This is not formally part of POSIX, but it is very wide-spread on POSIX systems.
|
||||||
|
// It was originally specified as part of the Itanium C++ ABI:
|
||||||
|
// https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html#base-throw.
|
||||||
|
// MinGW implements _Unwind_RaiseException on top of SEH exceptions.
|
||||||
|
if this.tcx.sess.target.env != "gnu" {
|
||||||
|
throw_unsup_format!(
|
||||||
|
"`_Unwind_RaiseException` is not supported on non-MinGW Windows",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// This function looks and behaves excatly like miri_start_unwind.
|
||||||
|
let [payload] = this.check_shim(abi, Abi::C { unwind: true }, link_name, args)?;
|
||||||
|
this.handle_miri_start_unwind(payload)?;
|
||||||
|
return Ok(EmulateItemResult::NeedsUnwind);
|
||||||
|
}
|
||||||
|
|
||||||
_ => return Ok(EmulateItemResult::NotSupported),
|
_ => return Ok(EmulateItemResult::NotSupported),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,11 +75,12 @@ impl Command {
|
||||||
/// Generic command arguments provider. Prefer specific helper methods if possible.
|
/// Generic command arguments provider. Prefer specific helper methods if possible.
|
||||||
/// Note that for some executables, arguments might be platform specific. For C/C++
|
/// Note that for some executables, arguments might be platform specific. For C/C++
|
||||||
/// compilers, arguments might be platform *and* compiler specific.
|
/// compilers, arguments might be platform *and* compiler specific.
|
||||||
pub fn args<S>(&mut self, args: &[S]) -> &mut Self
|
pub fn args<S, V>(&mut self, args: V) -> &mut Self
|
||||||
where
|
where
|
||||||
S: AsRef<ffi::OsStr>,
|
S: AsRef<ffi::OsStr>,
|
||||||
|
V: AsRef<[S]>,
|
||||||
{
|
{
|
||||||
self.cmd.args(args);
|
self.cmd.args(args.as_ref());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -261,6 +261,40 @@ pub fn test_while_readonly<P: AsRef<Path>, F: FnOnce() + std::panic::UnwindSafe>
|
||||||
success.unwrap();
|
success.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Browse the directory `path` non-recursively and return all files which respect the parameters
|
||||||
|
/// outlined by `closure`.
|
||||||
|
#[track_caller]
|
||||||
|
pub fn shallow_find_files<P: AsRef<Path>, F: Fn(&PathBuf) -> bool>(
|
||||||
|
path: P,
|
||||||
|
closure: F,
|
||||||
|
) -> Vec<PathBuf> {
|
||||||
|
let mut matching_files = Vec::new();
|
||||||
|
for entry in fs_wrapper::read_dir(path) {
|
||||||
|
let entry = entry.expect("failed to read directory entry.");
|
||||||
|
let path = entry.path();
|
||||||
|
|
||||||
|
if path.is_file() && closure(&path) {
|
||||||
|
matching_files.push(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
matching_files
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the filename at `path` starts with `prefix`.
|
||||||
|
pub fn has_prefix<P: AsRef<Path>>(path: P, prefix: &str) -> bool {
|
||||||
|
path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().starts_with(prefix))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the filename at `path` has the extension `extension`.
|
||||||
|
pub fn has_extension<P: AsRef<Path>>(path: P, extension: &str) -> bool {
|
||||||
|
path.as_ref().extension().is_some_and(|ext| ext == extension)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the filename at `path` does not contain `expected`.
|
||||||
|
pub fn not_contains<P: AsRef<Path>>(path: P, expected: &str) -> bool {
|
||||||
|
!path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().contains(expected))
|
||||||
|
}
|
||||||
|
|
||||||
/// Use `cygpath -w` on a path to get a Windows path string back. This assumes that `cygpath` is
|
/// Use `cygpath -w` on a path to get a Windows path string back. This assumes that `cygpath` is
|
||||||
/// available on the platform!
|
/// available on the platform!
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
|
|
|
@ -46,7 +46,6 @@ run-make/fmt-write-bloat/Makefile
|
||||||
run-make/foreign-double-unwind/Makefile
|
run-make/foreign-double-unwind/Makefile
|
||||||
run-make/foreign-exceptions/Makefile
|
run-make/foreign-exceptions/Makefile
|
||||||
run-make/foreign-rust-exceptions/Makefile
|
run-make/foreign-rust-exceptions/Makefile
|
||||||
run-make/include_bytes_deps/Makefile
|
|
||||||
run-make/incr-add-rust-src-component/Makefile
|
run-make/incr-add-rust-src-component/Makefile
|
||||||
run-make/incr-foreign-head-span/Makefile
|
run-make/incr-foreign-head-span/Makefile
|
||||||
run-make/interdependent-c-libraries/Makefile
|
run-make/interdependent-c-libraries/Makefile
|
||||||
|
@ -64,7 +63,6 @@ run-make/issue-33329/Makefile
|
||||||
run-make/issue-35164/Makefile
|
run-make/issue-35164/Makefile
|
||||||
run-make/issue-36710/Makefile
|
run-make/issue-36710/Makefile
|
||||||
run-make/issue-37839/Makefile
|
run-make/issue-37839/Makefile
|
||||||
run-make/issue-40535/Makefile
|
|
||||||
run-make/issue-47551/Makefile
|
run-make/issue-47551/Makefile
|
||||||
run-make/issue-69368/Makefile
|
run-make/issue-69368/Makefile
|
||||||
run-make/issue-83045/Makefile
|
run-make/issue-83045/Makefile
|
||||||
|
@ -102,8 +100,6 @@ run-make/no-alloc-shim/Makefile
|
||||||
run-make/no-builtins-attribute/Makefile
|
run-make/no-builtins-attribute/Makefile
|
||||||
run-make/no-duplicate-libs/Makefile
|
run-make/no-duplicate-libs/Makefile
|
||||||
run-make/obey-crate-type-flag/Makefile
|
run-make/obey-crate-type-flag/Makefile
|
||||||
run-make/optimization-remarks-dir-pgo/Makefile
|
|
||||||
run-make/optimization-remarks-dir/Makefile
|
|
||||||
run-make/output-type-permutations/Makefile
|
run-make/output-type-permutations/Makefile
|
||||||
run-make/panic-abort-eh_frame/Makefile
|
run-make/panic-abort-eh_frame/Makefile
|
||||||
run-make/pass-linker-flags-flavor/Makefile
|
run-make/pass-linker-flags-flavor/Makefile
|
||||||
|
@ -136,7 +132,6 @@ run-make/return-non-c-like-enum-from-c/Makefile
|
||||||
run-make/rlib-format-packed-bundled-libs-2/Makefile
|
run-make/rlib-format-packed-bundled-libs-2/Makefile
|
||||||
run-make/rlib-format-packed-bundled-libs-3/Makefile
|
run-make/rlib-format-packed-bundled-libs-3/Makefile
|
||||||
run-make/rlib-format-packed-bundled-libs/Makefile
|
run-make/rlib-format-packed-bundled-libs/Makefile
|
||||||
run-make/rmeta-preferred/Makefile
|
|
||||||
run-make/rustc-macro-dep-files/Makefile
|
run-make/rustc-macro-dep-files/Makefile
|
||||||
run-make/sanitizer-cdylib-link/Makefile
|
run-make/sanitizer-cdylib-link/Makefile
|
||||||
run-make/sanitizer-dylib-link/Makefile
|
run-make/sanitizer-dylib-link/Makefile
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
// include_bytes! and include_str! in `main.rs`
|
||||||
|
// should register the included file as of #24423,
|
||||||
|
// and this test checks that this is still the case.
|
||||||
|
// See https://github.com/rust-lang/rust/pull/24423
|
||||||
|
|
||||||
|
use run_make_support::{invalid_utf8_contains, rustc};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
rustc().emit("dep-info").input("main.rs").run();
|
||||||
|
invalid_utf8_contains("main.d", "input.txt");
|
||||||
|
invalid_utf8_contains("main.d", "input.bin");
|
||||||
|
invalid_utf8_contains("main.d", "input.md");
|
||||||
|
}
|
|
@ -1,7 +0,0 @@
|
||||||
include ../tools.mk
|
|
||||||
|
|
||||||
# ignore-freebsd
|
|
||||||
|
|
||||||
all:
|
|
||||||
$(RUSTC) --emit dep-info main.rs
|
|
||||||
$(CGREP) "input.txt" "input.bin" "input.md" < $(TMPDIR)/main.d
|
|
|
@ -1,13 +0,0 @@
|
||||||
include ../tools.mk
|
|
||||||
|
|
||||||
# The ICE occurred in the following situation:
|
|
||||||
# * `foo` declares `extern crate bar, baz`, depends only on `bar` (forgetting `baz` in `Cargo.toml`)
|
|
||||||
# * `bar` declares and depends on `extern crate baz`
|
|
||||||
# * All crates built in metadata-only mode (`cargo check`)
|
|
||||||
all:
|
|
||||||
# cc https://github.com/rust-lang/rust/issues/40623
|
|
||||||
$(RUSTC) baz.rs --emit=metadata
|
|
||||||
$(RUSTC) bar.rs --emit=metadata --extern baz=$(TMPDIR)/libbaz.rmeta
|
|
||||||
$(RUSTC) foo.rs --emit=metadata --extern bar=$(TMPDIR)/libbar.rmeta 2>&1 | \
|
|
||||||
$(CGREP) -v "unexpectedly panicked"
|
|
||||||
# ^ Succeeds if it doesn't find the ICE message
|
|
|
@ -28,7 +28,7 @@ fn main() {
|
||||||
files.push(path.to_path_buf());
|
files.push(path.to_path_buf());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
cmd(llvm_bin_dir().join("llvm-dis")).args(&files).run();
|
cmd(llvm_bin_dir().join("llvm-dis")).args(files).run();
|
||||||
|
|
||||||
// Check LLVM IR files (including temporary outputs) have `!llvm.ident`
|
// Check LLVM IR files (including temporary outputs) have `!llvm.ident`
|
||||||
// named metadata, reusing the related codegen test.
|
// named metadata, reusing the related codegen test.
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
// In a dependency hierarchy, metadata-only crates could cause an Internal
|
||||||
|
// Compiler Error (ICE) due to a compiler bug - not correctly fetching sources for
|
||||||
|
// metadata-only crates. This test is a minimal reproduction of a program that triggered
|
||||||
|
// this bug, and checks that no ICE occurs.
|
||||||
|
// See https://github.com/rust-lang/rust/issues/40535
|
||||||
|
|
||||||
|
use run_make_support::rustc;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
rustc().input("baz.rs").emit("metadata").run();
|
||||||
|
rustc().input("bar.rs").emit("metadata").extern_("baz", "libbaz.rmeta").run();
|
||||||
|
// There should be no internal compiler error.
|
||||||
|
rustc().input("foo.rs").emit("metadata").extern_("bar", "libbaz.rmeta").run();
|
||||||
|
}
|
|
@ -1,17 +0,0 @@
|
||||||
# needs-profiler-support
|
|
||||||
# ignore-cross-compile
|
|
||||||
|
|
||||||
include ../tools.mk
|
|
||||||
|
|
||||||
PROFILE_DIR=$(TMPDIR)/profiles
|
|
||||||
|
|
||||||
check_hotness:
|
|
||||||
$(RUSTC) -Cprofile-generate="$(TMPDIR)"/profdata -O foo.rs -o$(TMPDIR)/foo
|
|
||||||
$(TMPDIR)/foo
|
|
||||||
"$(LLVM_BIN_DIR)"/llvm-profdata merge \
|
|
||||||
-o "$(TMPDIR)"/merged.profdata \
|
|
||||||
"$(TMPDIR)"/profdata/*.profraw
|
|
||||||
$(RUSTC) -Cprofile-use=$(TMPDIR)/merged.profdata -O foo.rs -Cremark=all -Zremark-dir=$(PROFILE_DIR)
|
|
||||||
|
|
||||||
# Check that PGO hotness is included in the remark files
|
|
||||||
cat $(PROFILE_DIR)/*.opt.yaml | $(CGREP) -e "Hotness"
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
// This test checks the -Zremark-dir flag, which writes LLVM
|
||||||
|
// optimization remarks to the YAML format. When using PGO (Profile
|
||||||
|
// Guided Optimization), the Hotness attribute should be included in
|
||||||
|
// the output remark files.
|
||||||
|
// See https://github.com/rust-lang/rust/pull/114439
|
||||||
|
|
||||||
|
//@ needs-profiler-support
|
||||||
|
//@ ignore-cross-compile
|
||||||
|
|
||||||
|
use run_make_support::{
|
||||||
|
has_extension, has_prefix, invalid_utf8_contains, llvm_profdata, run, rustc, shallow_find_files,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
rustc().profile_generate("profdata").opt().input("foo.rs").output("foo").run();
|
||||||
|
run("foo");
|
||||||
|
// The profdata filename is a long sequence of numbers, fetch it by prefix and extension
|
||||||
|
// to keep the test working even if the filename changes.
|
||||||
|
let profdata_files = shallow_find_files("profdata", |path| {
|
||||||
|
has_prefix(path, "default") && has_extension(path, "profraw")
|
||||||
|
});
|
||||||
|
let profdata_file = profdata_files.get(0).unwrap();
|
||||||
|
llvm_profdata().merge().output("merged.profdata").input(profdata_file).run();
|
||||||
|
rustc()
|
||||||
|
.profile_use("merged.profdata")
|
||||||
|
.opt()
|
||||||
|
.input("foo.rs")
|
||||||
|
.arg("-Cremark=all")
|
||||||
|
.arg("-Zremark-dir=profiles")
|
||||||
|
.run();
|
||||||
|
// Check that PGO hotness is included in the remark files
|
||||||
|
let remark_files = shallow_find_files("profiles", |path| {
|
||||||
|
has_prefix(path, "foo") && has_extension(path, "yaml")
|
||||||
|
});
|
||||||
|
assert!(!remark_files.is_empty());
|
||||||
|
for file in remark_files {
|
||||||
|
if !file.to_str().unwrap().contains("codegen") {
|
||||||
|
invalid_utf8_contains(file, "Hotness")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +0,0 @@
|
||||||
include ../tools.mk
|
|
||||||
|
|
||||||
PROFILE_DIR=$(TMPDIR)/profiles
|
|
||||||
|
|
||||||
all: check_inline check_filter
|
|
||||||
|
|
||||||
check_inline:
|
|
||||||
$(RUSTC) -O foo.rs --crate-type=lib -Cremark=all -Zremark-dir=$(PROFILE_DIR)
|
|
||||||
cat $(PROFILE_DIR)/*.opt.yaml | $(CGREP) -e "inline"
|
|
||||||
check_filter:
|
|
||||||
$(RUSTC) -O foo.rs --crate-type=lib -Cremark=foo -Zremark-dir=$(PROFILE_DIR)
|
|
||||||
cat $(PROFILE_DIR)/*.opt.yaml | $(CGREP) -e -v "inline"
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
// In this test, the function `bar` has #[inline(never)] and the function `foo`
|
||||||
|
// does not. This test outputs LLVM optimization remarks twice - first for all
|
||||||
|
// functions (including `bar`, and the `inline` mention), and then for only `foo`
|
||||||
|
// (should not have the `inline` mention).
|
||||||
|
// See https://github.com/rust-lang/rust/pull/113040
|
||||||
|
|
||||||
|
use run_make_support::{
|
||||||
|
has_extension, has_prefix, invalid_utf8_contains, invalid_utf8_not_contains, not_contains,
|
||||||
|
rustc, shallow_find_files,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
rustc()
|
||||||
|
.opt()
|
||||||
|
.input("foo.rs")
|
||||||
|
.crate_type("lib")
|
||||||
|
.arg("-Cremark=all")
|
||||||
|
.arg("-Zremark-dir=profiles_all")
|
||||||
|
.run();
|
||||||
|
let all_remark_files = shallow_find_files("profiles_all", |path| {
|
||||||
|
has_prefix(path, "foo") && has_extension(path, "yaml") && not_contains(path, "codegen")
|
||||||
|
});
|
||||||
|
for file in all_remark_files {
|
||||||
|
invalid_utf8_contains(file, "inline")
|
||||||
|
}
|
||||||
|
rustc()
|
||||||
|
.opt()
|
||||||
|
.input("foo.rs")
|
||||||
|
.crate_type("lib")
|
||||||
|
.arg("-Cremark=foo")
|
||||||
|
.arg("-Zremark-dir=profiles_foo")
|
||||||
|
.run();
|
||||||
|
let foo_remark_files = shallow_find_files("profiles_foo", |path| {
|
||||||
|
has_prefix(path, "foo") && has_extension(path, "yaml")
|
||||||
|
});
|
||||||
|
for file in foo_remark_files {
|
||||||
|
invalid_utf8_not_contains(file, "inline")
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,16 +0,0 @@
|
||||||
# ignore-cross-compile
|
|
||||||
include ../tools.mk
|
|
||||||
|
|
||||||
# Test that using rlibs and rmeta dep crates work together. Specifically, that
|
|
||||||
# there can be both an rmeta and an rlib file and rustc will prefer the rmeta
|
|
||||||
# file.
|
|
||||||
#
|
|
||||||
# This behavior is simply making sure this doesn't accidentally change; in this
|
|
||||||
# case we want to make sure that the rlib isn't being used as that would cause
|
|
||||||
# bugs in -Zbinary-dep-depinfo (see #68298).
|
|
||||||
|
|
||||||
all:
|
|
||||||
$(RUSTC) rmeta_aux.rs --crate-type=rlib --emit link,metadata
|
|
||||||
$(RUSTC) lib.rs --crate-type=rlib --emit dep-info -Zbinary-dep-depinfo
|
|
||||||
$(CGREP) "librmeta_aux.rmeta" < $(TMPDIR)/lib.d
|
|
||||||
$(CGREP) -v "librmeta_aux.rlib" < $(TMPDIR)/lib.d
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
// This test compiles `lib.rs`'s dependency, `rmeta_aux.rs`, as both an rlib
|
||||||
|
// and an rmeta crate. By default, rustc should give the metadata crate (rmeta)
|
||||||
|
// precedence over the rust-lib (rlib). This test inspects the contents of the binary
|
||||||
|
// and that the correct (rmeta) crate was used.
|
||||||
|
// rlibs being preferred could indicate a resurgence of the -Zbinary-dep-depinfo bug
|
||||||
|
// seen in #68298.
|
||||||
|
// See https://github.com/rust-lang/rust/pull/37681
|
||||||
|
|
||||||
|
//@ ignore-cross-compile
|
||||||
|
|
||||||
|
use run_make_support::{invalid_utf8_contains, invalid_utf8_not_contains, rustc};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
rustc().input("rmeta_aux.rs").crate_type("rlib").emit("link,metadata").run();
|
||||||
|
rustc().input("lib.rs").crate_type("rlib").emit("dep-info").arg("-Zbinary-dep-depinfo").run();
|
||||||
|
invalid_utf8_contains("lib.d", "librmeta_aux.rmeta");
|
||||||
|
invalid_utf8_not_contains("lib.d", "librmeta_aux.rlib");
|
||||||
|
}
|
|
@ -2,12 +2,13 @@ error[E0600]: cannot apply unary operator `-` to type `usize`
|
||||||
--> $DIR/feature-gate-negate-unsigned.rs:10:23
|
--> $DIR/feature-gate-negate-unsigned.rs:10:23
|
||||||
|
|
|
|
||||||
LL | let _max: usize = -1;
|
LL | let _max: usize = -1;
|
||||||
| ^^
|
| ^^ cannot apply unary operator `-`
|
||||||
| |
|
|
||||||
| cannot apply unary operator `-`
|
|
||||||
| help: you may have meant the maximum value of `usize`: `usize::MAX`
|
|
||||||
|
|
|
|
||||||
= note: unsigned values cannot be negated
|
= note: unsigned values cannot be negated
|
||||||
|
help: you may have meant the maximum value of `usize`
|
||||||
|
|
|
||||||
|
LL | let _max: usize = usize::MAX;
|
||||||
|
| ~~~~~~~~~~
|
||||||
|
|
||||||
error[E0600]: cannot apply unary operator `-` to type `u8`
|
error[E0600]: cannot apply unary operator `-` to type `u8`
|
||||||
--> $DIR/feature-gate-negate-unsigned.rs:14:14
|
--> $DIR/feature-gate-negate-unsigned.rs:14:14
|
||||||
|
|
|
@ -2,34 +2,37 @@ error[E0600]: cannot apply unary operator `-` to type `usize`
|
||||||
--> $DIR/unsigned-literal-negation.rs:2:13
|
--> $DIR/unsigned-literal-negation.rs:2:13
|
||||||
|
|
|
|
||||||
LL | let x = -1 as usize;
|
LL | let x = -1 as usize;
|
||||||
| ^^
|
| ^^ cannot apply unary operator `-`
|
||||||
| |
|
|
||||||
| cannot apply unary operator `-`
|
|
||||||
| help: you may have meant the maximum value of `usize`: `usize::MAX`
|
|
||||||
|
|
|
|
||||||
= note: unsigned values cannot be negated
|
= note: unsigned values cannot be negated
|
||||||
|
help: you may have meant the maximum value of `usize`
|
||||||
|
|
|
||||||
|
LL | let x = usize::MAX;
|
||||||
|
| ~~~~~~~~~~
|
||||||
|
|
||||||
error[E0600]: cannot apply unary operator `-` to type `usize`
|
error[E0600]: cannot apply unary operator `-` to type `usize`
|
||||||
--> $DIR/unsigned-literal-negation.rs:3:13
|
--> $DIR/unsigned-literal-negation.rs:3:13
|
||||||
|
|
|
|
||||||
LL | let x = (-1) as usize;
|
LL | let x = (-1) as usize;
|
||||||
| ^^^^
|
| ^^^^ cannot apply unary operator `-`
|
||||||
| |
|
|
||||||
| cannot apply unary operator `-`
|
|
||||||
| help: you may have meant the maximum value of `usize`: `usize::MAX`
|
|
||||||
|
|
|
|
||||||
= note: unsigned values cannot be negated
|
= note: unsigned values cannot be negated
|
||||||
|
help: you may have meant the maximum value of `usize`
|
||||||
|
|
|
||||||
|
LL | let x = usize::MAX;
|
||||||
|
| ~~~~~~~~~~
|
||||||
|
|
||||||
error[E0600]: cannot apply unary operator `-` to type `u32`
|
error[E0600]: cannot apply unary operator `-` to type `u32`
|
||||||
--> $DIR/unsigned-literal-negation.rs:4:18
|
--> $DIR/unsigned-literal-negation.rs:4:18
|
||||||
|
|
|
|
||||||
LL | let x: u32 = -1;
|
LL | let x: u32 = -1;
|
||||||
| ^^
|
| ^^ cannot apply unary operator `-`
|
||||||
| |
|
|
||||||
| cannot apply unary operator `-`
|
|
||||||
| help: you may have meant the maximum value of `u32`: `u32::MAX`
|
|
||||||
|
|
|
|
||||||
= note: unsigned values cannot be negated
|
= note: unsigned values cannot be negated
|
||||||
|
help: you may have meant the maximum value of `u32`
|
||||||
|
|
|
||||||
|
LL | let x: u32 = u32::MAX;
|
||||||
|
| ~~~~~~~~
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue