Date: Wed, 3 Jul 2019 13:40:40 -0400
Subject: update `@unionInit` to integrate with result location semantics
---
doc/langref.html.in | 17 ++++++
src/all_types.hpp | 3 +-
src/ir.cpp | 167 ++++++++++++++++++++++++++++++----------------------
src/ir_print.cpp | 4 +-
4 files changed, 118 insertions(+), 73 deletions(-)
(limited to 'src/ir.cpp')
diff --git a/doc/langref.html.in b/doc/langref.html.in
index fda741930b..ef914375f4 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -5065,6 +5065,12 @@ test "@intToPtr for pointer to zero bit type" {
{#header_close#}
{#header_close#}
+ {#header_open|Result Location Semantics#}
+
+ TODO add documentation for this
+
+ {#header_close#}
+
{#header_open|comptime#}
Zig places importance on the concept of whether an expression is known at compile-time.
@@ -7809,6 +7815,17 @@ pub const TypeInfo = union(TypeId) {
{#header_close#}
+ {#header_open|@unionInit#}
+
{#syntax#}@unionInit(comptime Union: type, comptime active_field_name: []const u8, init_expr) Union{#endsyntax#}
+
+ This is the same thing as {#link|union#} initialization syntax, except that the field name is a
+ {#link|comptime#}-known value rather than an identifier token.
+
+
+ {#syntax#}@unionInit{#endsyntax#} forwards its {#link|result location|Result Location Semantics#} to {#syntax#}init_expr{#endsyntax#}.
+
+ {#header_close#}
+
{#header_open|@Vector#}
{#syntax#}@Vector(comptime len: u32, comptime ElemType: type) type{#endsyntax#}
diff --git a/src/all_types.hpp b/src/all_types.hpp
index 0d187a1c4e..c1e54baf8d 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -3610,7 +3610,8 @@ struct IrInstructionUnionInitNamedField {
IrInstruction *union_type;
IrInstruction *field_name;
- IrInstruction *value;
+ IrInstruction *field_result_loc;
+ IrInstruction *result_loc;
};
struct IrInstructionHasDecl {
diff --git a/src/ir.cpp b/src/ir.cpp
index 594f61982a..6b19ce2909 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -198,6 +198,9 @@ static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *
IrInstruction *base_ptr, bool initializing);
static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr,
IrInstruction *ptr, IrInstruction *uncasted_value);
+static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNode *source_node,
+ IrInstruction *union_type, IrInstruction *field_name, AstNode *expr_node,
+ LVal lval, ResultLoc *parent_result_loc);
static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {
assert(get_src_ptr_type(const_val->type) != nullptr);
@@ -1069,7 +1072,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAssertNonNull *)
return IrInstructionIdAssertNonNull;
}
-<<<<<<< HEAD
static constexpr IrInstructionId ir_instruction_id(IrInstructionHasDecl *) {
return IrInstructionIdHasDecl;
}
@@ -1357,12 +1359,13 @@ static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *s
}
static IrInstruction *ir_build_field_ptr_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node,
- IrInstruction *container_ptr, IrInstruction *field_name_expr)
+ IrInstruction *container_ptr, IrInstruction *field_name_expr, bool initializing)
{
IrInstructionFieldPtr *instruction = ir_build_instruction(irb, scope, source_node);
instruction->container_ptr = container_ptr;
instruction->field_name_buffer = nullptr;
instruction->field_name_expr = field_name_expr;
+ instruction->initializing = initializing;
ir_ref_instruction(container_ptr, irb->current_basic_block);
ir_ref_instruction(field_name_expr, irb->current_basic_block);
@@ -3329,16 +3332,19 @@ static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope,
return &instruction->base;
}
-static IrInstruction *ir_build_union_init_2(IrBuilder *irb, Scope *scope, AstNode *source_node,
- IrInstruction *union_type_value, IrInstruction *field_name_expr, IrInstruction *value) {
- IrInstructionUnionInit2 *instruction = ir_build_instruction(irb, scope, source_node);
- instruction->union_type_value = union_type_value;
- instruction->field_name_expr = field_name_expr;
- instruction->value = value;
+static IrInstruction *ir_build_union_init_named_field(IrBuilder *irb, Scope *scope, AstNode *source_node,
+ IrInstruction *union_type, IrInstruction *field_name, IrInstruction *field_result_loc, IrInstruction *result_loc)
+{
+ IrInstructionUnionInitNamedField *instruction = ir_build_instruction(irb, scope, source_node);
+ instruction->union_type = union_type;
+ instruction->field_name = field_name;
+ instruction->field_result_loc = field_result_loc;
+ instruction->result_loc = result_loc;
- ir_ref_instruction(union_type_value, irb->current_basic_block);
- ir_ref_instruction(field_name_expr, irb->current_basic_block);
- ir_ref_instruction(value, irb->current_basic_block);
+ ir_ref_instruction(union_type, irb->current_basic_block);
+ ir_ref_instruction(field_name, irb->current_basic_block);
+ ir_ref_instruction(field_result_loc, irb->current_basic_block);
+ if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block);
return &instruction->base;
}
@@ -5130,7 +5136,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
if (arg1_value == irb->codegen->invalid_instruction)
return arg1_value;
- IrInstruction *ptr_instruction = ir_build_field_ptr_instruction(irb, scope, node, arg0_value, arg1_value);
+ IrInstruction *ptr_instruction = ir_build_field_ptr_instruction(irb, scope, node,
+ arg0_value, arg1_value, false);
if (lval == LValPtr)
return ptr_instruction;
@@ -5673,26 +5680,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
}
case BuiltinFnIdUnionInit:
{
+ AstNode *union_type_node = node->data.fn_call_expr.params.at(0);
+ IrInstruction *union_type_inst = ir_gen_node(irb, union_type_node, scope);
+ if (union_type_inst == irb->codegen->invalid_instruction)
+ return union_type_inst;
- AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
- IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
- if (arg0_value == irb->codegen->invalid_instruction)
- return arg0_value;
-
- AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
- IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
- if (arg1_value == irb->codegen->invalid_instruction)
- return arg1_value;
-
- AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
- IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope);
- if (arg2_value == irb->codegen->invalid_instruction)
- return arg2_value;
+ AstNode *name_node = node->data.fn_call_expr.params.at(1);
+ IrInstruction *name_inst = ir_gen_node(irb, name_node, scope);
+ if (name_inst == irb->codegen->invalid_instruction)
+ return name_inst;
- IrInstruction *result = ir_build_union_init_2(irb, scope, node, arg0_value, arg1_value, arg2_value);
+ AstNode *init_node = node->data.fn_call_expr.params.at(2);
- // TODO: Not sure if we need ir_lval_wrap or not.
- return result;
+ return ir_gen_union_init_expr(irb, scope, node, union_type_inst, name_inst, init_node,
+ lval, result_loc);
}
}
zig_unreachable();
@@ -5972,6 +5973,31 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod
zig_unreachable();
}
+static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNode *source_node,
+ IrInstruction *union_type, IrInstruction *field_name, AstNode *expr_node,
+ LVal lval, ResultLoc *parent_result_loc)
+{
+ IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, source_node, parent_result_loc, union_type);
+ IrInstruction *field_ptr = ir_build_field_ptr_instruction(irb, scope, source_node, container_ptr,
+ field_name, true);
+
+ ResultLocInstruction *result_loc_inst = allocate(1);
+ result_loc_inst->base.id = ResultLocIdInstruction;
+ result_loc_inst->base.source_instruction = field_ptr;
+ ir_ref_instruction(field_ptr, irb->current_basic_block);
+ ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base);
+
+ IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone,
+ &result_loc_inst->base);
+ if (expr_value == irb->codegen->invalid_instruction)
+ return expr_value;
+
+ IrInstruction *init_union = ir_build_union_init_named_field(irb, scope, source_node, union_type,
+ field_name, field_ptr, container_ptr);
+
+ return ir_lval_wrap(irb, scope, init_union, lval, parent_result_loc);
+}
+
static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval,
ResultLoc *parent_result_loc)
{
@@ -19451,32 +19477,21 @@ static IrInstruction *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRe
return ir_get_ref(ira, &ref_instruction->base, value, ref_instruction->is_const, ref_instruction->is_volatile);
}
-static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrInstruction *instruction,
- ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields,
- IrInstruction *result_loc)
+static IrInstruction *ir_analyze_union_init(IrAnalyze *ira, IrInstruction *source_instruction,
+ AstNode *field_source_node, ZigType *union_type, Buf *field_name, IrInstruction *field_result_loc,
+ IrInstruction *result_loc)
{
Error err;
- assert(container_type->id == ZigTypeIdUnion);
-
- if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown)))
- return ira->codegen->invalid_instruction;
-
- if (instr_field_count != 1) {
- ir_add_error(ira, instruction,
- buf_sprintf("union initialization expects exactly one field"));
- return ira->codegen->invalid_instruction;
- }
+ assert(union_type->id == ZigTypeIdUnion);
- IrInstructionContainerInitFieldsField *field = &fields[0];
- IrInstruction *field_result_loc = field->result_loc->child;
- if (type_is_invalid(field_result_loc->value.type))
+ if ((err = type_resolve(ira->codegen, union_type, ResolveStatusSizeKnown)))
return ira->codegen->invalid_instruction;
- TypeUnionField *type_field = find_union_type_field(container_type, field->name);
+ TypeUnionField *type_field = find_union_type_field(union_type, field_name);
if (type_field == nullptr) {
- ir_add_error_node(ira, field->source_node,
+ ir_add_error_node(ira, field_source_node,
buf_sprintf("no member named '%s' in union '%s'",
- buf_ptr(field->name), buf_ptr(&container_type->name)));
+ buf_ptr(field_name), buf_ptr(&union_type->name)));
return ira->codegen->invalid_instruction;
}
@@ -19493,12 +19508,12 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI
}
}
- bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope)
- || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes;
+ bool is_comptime = ir_should_inline(ira->new_irb.exec, source_instruction->scope)
+ || type_requires_comptime(ira->codegen, union_type) == ReqCompTimeYes;
- IrInstruction *result = ir_get_deref(ira, instruction, result_loc, nullptr);
+ IrInstruction *result = ir_get_deref(ira, source_instruction, result_loc, nullptr);
if (is_comptime && !instr_is_comptime(result)) {
- ir_add_error(ira, field->result_loc,
+ ir_add_error(ira, field_result_loc,
buf_sprintf("unable to evaluate constant expression"));
return ira->codegen->invalid_instruction;
}
@@ -19511,8 +19526,18 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
{
Error err;
if (container_type->id == ZigTypeIdUnion) {
- return ir_analyze_container_init_fields_union(ira, instruction, container_type, instr_field_count,
- fields, result_loc);
+ if (instr_field_count != 1) {
+ ir_add_error(ira, instruction,
+ buf_sprintf("union initialization expects exactly one field"));
+ return ira->codegen->invalid_instruction;
+ }
+ IrInstructionContainerInitFieldsField *field = &fields[0];
+ IrInstruction *field_result_loc = field->result_loc->child;
+ if (type_is_invalid(field_result_loc->value.type))
+ return ira->codegen->invalid_instruction;
+
+ return ir_analyze_union_init(ira, instruction, field->source_node, container_type, field->name,
+ field_result_loc, result_loc);
}
if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) {
ir_add_error(ira, instruction,
@@ -25369,33 +25394,33 @@ static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInst
return instruction->result_loc_bit_cast->parent->gen_instruction;
}
-static IrInstruction *ir_analyze_instruction_union_init_2(IrAnalyze *ira, IrInstructionUnionInit2 *union_init_instruction)
+static IrInstruction *ir_analyze_instruction_union_init_named_field(IrAnalyze *ira,
+ IrInstructionUnionInitNamedField *instruction)
{
- Error err;
- IrInstruction *union_type_value = union_init_instruction->union_type_value->child;
- ZigType *union_type = ir_resolve_type(ira, union_type_value);
- if (type_is_invalid(union_type)) {
+ ZigType *union_type = ir_resolve_type(ira, instruction->union_type->child);
+ if (type_is_invalid(union_type))
return ira->codegen->invalid_instruction;
- }
- if (union_type->id != ZigTypeIdUnion)
+ if (union_type->id != ZigTypeIdUnion) {
+ ir_add_error(ira, instruction->union_type,
+ buf_sprintf("non-union type '%s' passed to @unionInit", buf_ptr(&union_type->name)));
return ira->codegen->invalid_instruction;
+ }
- if ((err = ensure_complete_type(ira->codegen, union_type)))
+ Buf *field_name = ir_resolve_str(ira, instruction->field_name->child);
+ if (field_name == nullptr)
return ira->codegen->invalid_instruction;
- IrInstruction *field_name_expr = union_init_instruction->field_name_expr->child;
- Buf *field_name = ir_resolve_str(ira, field_name_expr);
- if (!field_name)
+ IrInstruction *field_result_loc = instruction->field_result_loc->child;
+ if (type_is_invalid(field_result_loc->value.type))
return ira->codegen->invalid_instruction;
- IrInstructionContainerInitFieldsField *fields = allocate(1);
-
- fields[0].name = field_name;
- fields[0].value = union_init_instruction->value;
- fields[0].source_node = union_init_instruction->base.source_node;
+ IrInstruction *result_loc = instruction->result_loc->child;
+ if (type_is_invalid(result_loc->value.type))
+ return ira->codegen->invalid_instruction;
- return ir_analyze_container_init_fields_union(ira, &union_init_instruction->base, union_type, 1, fields);
+ return ir_analyze_union_init(ira, &instruction->base, instruction->base.source_node,
+ union_type, field_name, field_result_loc, result_loc);
}
static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction *instruction) {
diff --git a/src/ir_print.cpp b/src/ir_print.cpp
index 3ecb7fb683..588a9b2882 100644
--- a/src/ir_print.cpp
+++ b/src/ir_print.cpp
@@ -1632,7 +1632,9 @@ static void ir_print_union_init_named_field(IrPrint *irp, IrInstructionUnionInit
fprintf(irp->f, ", ");
ir_print_other_instruction(irp, instruction->field_name);
fprintf(irp->f, ", ");
- ir_print_other_instruction(irp, instruction->value);
+ ir_print_other_instruction(irp, instruction->field_result_loc);
+ fprintf(irp->f, ", ");
+ ir_print_other_instruction(irp, instruction->result_loc);
fprintf(irp->f, ")");
}
--
cgit v1.2.3
From a1b952f4b03b7becad85ad47f96a75c0be620cf8 Mon Sep 17 00:00:00 2001
From: emekoi
Date: Wed, 3 Jul 2019 13:12:14 -0500
Subject: added tests for #1107 and a note in the reference
---
doc/langref.html.in | 6 ++++--
src/ir.cpp | 4 ++--
test/compile_errors.zig | 17 +++++++++++++++++
test/stage1/behavior/switch.zig | 18 ++++++++++++++++++
4 files changed, 41 insertions(+), 4 deletions(-)
(limited to 'src/ir.cpp')
diff --git a/doc/langref.html.in b/doc/langref.html.in
index 4bd594c113..3b8e77595c 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -2973,6 +2973,7 @@ test "switch on tagged union" {
A: u32,
C: Point,
D,
+ E: u32,
};
var a = Item{ .C = Point{ .x = 1, .y = 2 } };
@@ -2980,8 +2981,9 @@ test "switch on tagged union" {
// Switching on more complex enums is allowed.
const b = switch (a) {
// A capture group is allowed on a match, and will return the enum
- // value matched.
- Item.A => |item| item,
+ // value matched. If the payloads of both cases are the same
+ // they can be put into the same switch prong.
+ Item.A, Item.E => |item| item,
// A reference to the matched value can be obtained using `*` syntax.
Item.C => |*item| blk: {
diff --git a/src/ir.cpp b/src/ir.cpp
index d4cb5f90de..83155da4c1 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -19160,8 +19160,8 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru
if (field->type_entry != payload) {
if (!invalid_payload) {
invalid_payload = ir_add_error(ira, &instruction->base,
- buf_sprintf("switch prong contains cases with differing payloads"));
- invalid_payload_list = buf_sprintf("types %s", buf_ptr(&field->type_entry->name));
+ buf_sprintf("switch prong contains cases with different payloads"));
+ invalid_payload_list = buf_sprintf("payload types are %s", buf_ptr(&field->type_entry->name));
}
if (i == instruction->prongs_len - 1)
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index 94cd152eb7..592870c678 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -6048,4 +6048,21 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
"tmp.zig:5:30: error: expression value is ignored",
"tmp.zig:9:30: error: expression value is ignored",
);
+
+ cases.add(
+ "capture group on switch prong with different payloads",
+ \\const Union = union(enum) {
+ \\ A: usize,
+ \\ B: isize,
+ \\};
+ \\comptime {
+ \\ var u = Union{ .A = 8 };
+ \\ switch (u) {
+ \\ .A, .B => |e| unreachable,
+ \\ }
+ \\}
+ ,
+ "tmp.zig:8:20: error: switch prong contains cases with different payloads",
+ "tmp.zig:8:20: note: payload types are usize and isize",
+ );
}
diff --git a/test/stage1/behavior/switch.zig b/test/stage1/behavior/switch.zig
index 12e026d0ba..2b7422fa6d 100644
--- a/test/stage1/behavior/switch.zig
+++ b/test/stage1/behavior/switch.zig
@@ -391,3 +391,21 @@ test "switch with null and T peer types and inferred result location type" {
S.doTheTest(1);
comptime S.doTheTest(1);
}
+
+test "switch prongs with cases with identical payloads" {
+ const Union = union(enum) {
+ A: usize,
+ B: isize,
+ C: usize,
+ };
+ const S = struct {
+ fn doTheTest(u: Union) void {
+ switch (u) {
+ .A, .C => |e| expect(@typeOf(e) == usize),
+ .B => |e| expect(@typeOf(e) == isize),
+ }
+ }
+ };
+ S.doTheTest(Union{ .A = 8 });
+ comptime S.doTheTest(Union{ .B = -8 });
+}
--
cgit v1.2.3
From 96fd1030730e2980fa852ae45a67a2a4008bb163 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 4 Jul 2019 00:35:28 -0400
Subject: improve the error message and test coverage
---
doc/langref.html.in | 2 +-
src/ir.cpp | 77 ++++++++++++++++++++---------------------
test/compile_errors.zig | 35 ++++++++++---------
test/stage1/behavior/switch.zig | 28 +++++++++++----
4 files changed, 79 insertions(+), 63 deletions(-)
(limited to 'src/ir.cpp')
diff --git a/doc/langref.html.in b/doc/langref.html.in
index b006544f00..28d8745a81 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -3024,7 +3024,7 @@ test "switch on tagged union" {
// Switching on more complex enums is allowed.
const b = switch (a) {
// A capture group is allowed on a match, and will return the enum
- // value matched. If the payloads of both cases are the same
+ // value matched. If the payload types of both cases are the same
// they can be put into the same switch prong.
Item.A, Item.E => |item| item,
diff --git a/src/ir.cpp b/src/ir.cpp
index 995c993ab4..23035fa66d 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -19229,53 +19229,52 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru
ZigType *enum_type = target_type->data.unionation.tag_type;
assert(enum_type != nullptr);
assert(enum_type->id == ZigTypeIdEnum);
+ assert(instruction->prongs_len > 0);
- IrInstruction *prong_value = instruction->prongs_ptr[0]->child;
- if (type_is_invalid(prong_value->value.type))
+ IrInstruction *first_prong_value = instruction->prongs_ptr[0]->child;
+ if (type_is_invalid(first_prong_value->value.type))
return ira->codegen->invalid_instruction;
- IrInstruction *casted_prong_value = ir_implicit_cast(ira, prong_value, enum_type);
- if (type_is_invalid(casted_prong_value->value.type))
+ IrInstruction *first_casted_prong_value = ir_implicit_cast(ira, first_prong_value, enum_type);
+ if (type_is_invalid(first_casted_prong_value->value.type))
return ira->codegen->invalid_instruction;
- ConstExprValue *prong_val = ir_resolve_const(ira, casted_prong_value, UndefBad);
- if (!prong_val)
+ ConstExprValue *first_prong_val = ir_resolve_const(ira, first_casted_prong_value, UndefBad);
+ if (first_prong_val == nullptr)
return ira->codegen->invalid_instruction;
- TypeUnionField *field = find_union_field_by_tag(target_type, &prong_val->data.x_enum_tag);
+ TypeUnionField *first_field = find_union_field_by_tag(target_type, &first_prong_val->data.x_enum_tag);
- if (instruction->prongs_len != 1) {
- ErrorMsg *invalid_payload = nullptr;
- Buf *invalid_payload_list = nullptr;
-
- for (size_t i = 1; i < instruction->prongs_len; i++) {
- IrInstruction *casted_prong_value = ir_implicit_cast(ira, instruction->prongs_ptr[i]->child, enum_type);
- if (type_is_invalid(casted_prong_value->value.type))
- return ira->codegen->invalid_instruction;
-
- ConstExprValue *next_prong = ir_resolve_const(ira, casted_prong_value, UndefBad);
- if (!next_prong)
- return ira->codegen->invalid_instruction;
+ ErrorMsg *invalid_payload_msg = nullptr;
+ for (size_t prong_i = 1; prong_i < instruction->prongs_len; prong_i += 1) {
+ IrInstruction *this_prong_inst = instruction->prongs_ptr[prong_i]->child;
+ if (type_is_invalid(this_prong_inst->value.type))
+ return ira->codegen->invalid_instruction;
- ZigType *payload = find_union_field_by_tag(target_type, &next_prong->data.x_enum_tag)->type_entry;
+ IrInstruction *this_casted_prong_value = ir_implicit_cast(ira, this_prong_inst, enum_type);
+ if (type_is_invalid(this_casted_prong_value->value.type))
+ return ira->codegen->invalid_instruction;
- if (field->type_entry != payload) {
- if (!invalid_payload) {
- invalid_payload = ir_add_error(ira, &instruction->base,
- buf_sprintf("switch prong contains cases with different payloads"));
- invalid_payload_list = buf_sprintf("payload types are %s", buf_ptr(&field->type_entry->name));
- }
+ ConstExprValue *this_prong = ir_resolve_const(ira, this_casted_prong_value, UndefBad);
+ if (this_prong == nullptr)
+ return ira->codegen->invalid_instruction;
- if (i == instruction->prongs_len - 1)
- buf_append_buf(invalid_payload_list, buf_sprintf(" and %s", buf_ptr(&payload->name)));
- else
- buf_append_buf(invalid_payload_list, buf_sprintf(", %s", buf_ptr(&payload->name)));
+ TypeUnionField *payload_field = find_union_field_by_tag(target_type, &this_prong->data.x_enum_tag);
+ ZigType *payload_type = payload_field->type_entry;
+ if (first_field->type_entry != payload_type) {
+ if (invalid_payload_msg == nullptr) {
+ invalid_payload_msg = ir_add_error(ira, &instruction->base,
+ buf_sprintf("capture group with incompatible types"));
+ add_error_note(ira->codegen, invalid_payload_msg, first_prong_value->source_node,
+ buf_sprintf("type '%s' here", buf_ptr(&first_field->type_entry->name)));
}
+ add_error_note(ira->codegen, invalid_payload_msg, this_prong_inst->source_node,
+ buf_sprintf("type '%s' here", buf_ptr(&payload_field->type_entry->name)));
}
+ }
- if (invalid_payload)
- add_error_note(ira->codegen, invalid_payload,
- ((IrInstruction*)instruction)->source_node, invalid_payload_list);
+ if (invalid_payload_msg != nullptr) {
+ return ira->codegen->invalid_instruction;
}
if (instr_is_comptime(target_value_ptr)) {
@@ -19288,7 +19287,7 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru
return ira->codegen->invalid_instruction;
IrInstruction *result = ir_const(ira, &instruction->base,
- get_pointer_to_type(ira->codegen, field->type_entry,
+ get_pointer_to_type(ira->codegen, first_field->type_entry,
target_val_ptr->type->data.pointer.is_const));
ConstExprValue *out_val = &result->value;
out_val->data.x_ptr.special = ConstPtrSpecialRef;
@@ -19298,8 +19297,8 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru
}
IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb,
- instruction->base.scope, instruction->base.source_node, target_value_ptr, field, false, false);
- result->value.type = get_pointer_to_type(ira->codegen, field->type_entry,
+ instruction->base.scope, instruction->base.source_node, target_value_ptr, first_field, false, false);
+ result->value.type = get_pointer_to_type(ira->codegen, first_field->type_entry,
target_value_ptr->value.type->data.pointer.is_const);
return result;
} else if (target_type->id == ZigTypeIdErrorSet) {
@@ -23007,11 +23006,11 @@ static IrInstruction *ir_analyze_instruction_mul_add(IrAnalyze *ira, IrInstructi
IrInstruction *type_value = instruction->type_value->child;
if (type_is_invalid(type_value->value.type))
return ira->codegen->invalid_instruction;
-
+
ZigType *expr_type = ir_resolve_type(ira, type_value);
if (type_is_invalid(expr_type))
return ira->codegen->invalid_instruction;
-
+
// Only allow float types, and vectors of floats.
ZigType *float_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type;
if (float_type->id != ZigTypeIdFloat) {
@@ -25112,7 +25111,7 @@ static IrInstruction *ir_analyze_instruction_float_op(IrAnalyze *ira, IrInstruct
IrInstruction *type = instruction->type->child;
if (type_is_invalid(type->value.type))
return ira->codegen->invalid_instruction;
-
+
ZigType *expr_type = ir_resolve_type(ira, type);
if (type_is_invalid(expr_type))
return ira->codegen->invalid_instruction;
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index c6852621e3..df4e38583c 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -2,6 +2,24 @@ const tests = @import("tests.zig");
const builtin = @import("builtin");
pub fn addCases(cases: *tests.CompileErrorContext) void {
+ cases.add(
+ "capture group on switch prong with incompatible payload types",
+ \\const Union = union(enum) {
+ \\ A: usize,
+ \\ B: isize,
+ \\};
+ \\comptime {
+ \\ var u = Union{ .A = 8 };
+ \\ switch (u) {
+ \\ .A, .B => |e| unreachable,
+ \\ }
+ \\}
+ ,
+ "tmp.zig:8:20: error: capture group with incompatible types",
+ "tmp.zig:8:9: note: type 'usize' here",
+ "tmp.zig:8:13: note: type 'isize' here",
+ );
+
cases.add(
"wrong type to @hasField",
\\export fn entry() bool {
@@ -6073,21 +6091,4 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
"tmp.zig:5:30: error: expression value is ignored",
"tmp.zig:9:30: error: expression value is ignored",
);
-
- cases.add(
- "capture group on switch prong with different payloads",
- \\const Union = union(enum) {
- \\ A: usize,
- \\ B: isize,
- \\};
- \\comptime {
- \\ var u = Union{ .A = 8 };
- \\ switch (u) {
- \\ .A, .B => |e| unreachable,
- \\ }
- \\}
- ,
- "tmp.zig:8:20: error: switch prong contains cases with different payloads",
- "tmp.zig:8:20: note: payload types are usize and isize",
- );
}
diff --git a/test/stage1/behavior/switch.zig b/test/stage1/behavior/switch.zig
index 2b7422fa6d..806f51b28e 100644
--- a/test/stage1/behavior/switch.zig
+++ b/test/stage1/behavior/switch.zig
@@ -392,20 +392,36 @@ test "switch with null and T peer types and inferred result location type" {
comptime S.doTheTest(1);
}
-test "switch prongs with cases with identical payloads" {
+test "switch prongs with cases with identical payload types" {
const Union = union(enum) {
A: usize,
B: isize,
C: usize,
};
const S = struct {
- fn doTheTest(u: Union) void {
+ fn doTheTest() void {
+ doTheSwitch1(Union{ .A = 8 });
+ doTheSwitch2(Union{ .B = -8 });
+ }
+ fn doTheSwitch1(u: Union) void {
switch (u) {
- .A, .C => |e| expect(@typeOf(e) == usize),
- .B => |e| expect(@typeOf(e) == isize),
+ .A, .C => |e| {
+ expect(@typeOf(e) == usize);
+ expect(e == 8);
+ },
+ .B => |e| @panic("fail"),
+ }
+ }
+ fn doTheSwitch2(u: Union) void {
+ switch (u) {
+ .A, .C => |e| @panic("fail"),
+ .B => |e| {
+ expect(@typeOf(e) == isize);
+ expect(e == -8);
+ },
}
}
};
- S.doTheTest(Union{ .A = 8 });
- comptime S.doTheTest(Union{ .B = -8 });
+ S.doTheTest();
+ comptime S.doTheTest();
}
--
cgit v1.2.3
From b118806c69e44029a7af9c9b8bdfa9cdcd280260 Mon Sep 17 00:00:00 2001
From: SamTebbs33
Date: Fri, 5 Jul 2019 00:00:12 +0100
Subject: Add implicit cast for *[N]T to [*c]T
---
src/ir.cpp | 4 ++--
test/stage1/behavior/cast.zig | 10 ++++++++++
2 files changed, 12 insertions(+), 2 deletions(-)
(limited to 'src/ir.cpp')
diff --git a/src/ir.cpp b/src/ir.cpp
index 23035fa66d..f0ac2f8eaf 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -12773,9 +12773,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
}
}
- // *[N]T to [*]T
+ // *[N]T to [*]T and [*c]T
if (wanted_type->id == ZigTypeIdPointer &&
- wanted_type->data.pointer.ptr_len == PtrLenUnknown &&
+ (wanted_type->data.pointer.ptr_len == PtrLenUnknown || wanted_type->data.pointer.ptr_len == PtrLenC) &&
actual_type->id == ZigTypeIdPointer &&
actual_type->data.pointer.ptr_len == PtrLenSingle &&
actual_type->data.pointer.child_type->id == ZigTypeIdArray)
diff --git a/test/stage1/behavior/cast.zig b/test/stage1/behavior/cast.zig
index edb0f4ff17..c243f18088 100644
--- a/test/stage1/behavior/cast.zig
+++ b/test/stage1/behavior/cast.zig
@@ -404,6 +404,16 @@ test "implicit cast from *[N]T to ?[*]T" {
expect(std.mem.eql(u16, x.?[0..4], y[0..4]));
}
+test "implicit cast from *[N]T to [*c]T" {
+ var x: [4]u16 = [4]u16{ 0, 1, 2, 3 };
+ var y: [*c]u16 = &x;
+
+ expect(std.mem.eql(u16, x[0..4], y[0..4]));
+ x[0] = 8;
+ y[3] = 6;
+ expect(std.mem.eql(u16, x[0..4], y[0..4]));
+}
+
test "implicit cast from *T to ?*c_void" {
var a: u8 = 1;
incrementVoidPtrValue(&a);
--
cgit v1.2.3
From fc9e28ea37e0110836d6958c39ffe78ea6cad0f3 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Mon, 8 Jul 2019 14:26:40 -0400
Subject: std.os.getrandom does a libc version check
closes #397
---
src/ir.cpp | 2 +-
std/c.zig | 27 +++++++++++++++++++++++++++
std/os.zig | 10 +++++++---
3 files changed, 35 insertions(+), 4 deletions(-)
(limited to 'src/ir.cpp')
diff --git a/src/ir.cpp b/src/ir.cpp
index f0ac2f8eaf..94307627a1 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -11191,7 +11191,7 @@ static IrBasicBlock *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlock *old_bb,
}
static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *const_predecessor_bb) {
- assert(!old_bb->suspended);
+ ir_assert(!old_bb->suspended, old_bb->instruction_list.at(0));
ira->instruction_index = 0;
ira->old_irb.current_basic_block = old_bb;
ira->const_predecessor_bb = const_predecessor_bb;
diff --git a/std/c.zig b/std/c.zig
index 029b92e549..693f26008d 100644
--- a/std/c.zig
+++ b/std/c.zig
@@ -21,6 +21,33 @@ pub fn getErrno(rc: var) u16 {
}
}
+/// The return type is `type` to force comptime function call execution.
+/// TODO: https://github.com/ziglang/zig/issues/425
+/// If not linking libc, returns struct{pub const ok = false;}
+/// If linking musl libc, returns struct{pub const ok = true;}
+/// If linking gnu libc (glibc), the `ok` value will be true if the target
+/// version is greater than or equal to `glibc_version`.
+/// If linking a libc other than these, returns `false`.
+pub fn versionCheck(glibc_version: builtin.Version) type {
+ return struct {
+ pub const ok = blk: {
+ if (!builtin.link_libc) break :blk false;
+ switch (builtin.abi) {
+ .musl, .musleabi, .musleabihf => break :blk true,
+ .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => {
+ const ver = builtin.glibc_version orelse break :blk false;
+ if (ver.major < glibc_version.major) break :blk false;
+ if (ver.major > glibc_version.major) break :blk true;
+ if (ver.minor < glibc_version.minor) break :blk false;
+ if (ver.minor > glibc_version.minor) break :blk true;
+ break :blk ver.patch >= glibc_version.patch;
+ },
+ else => break :blk false,
+ }
+ };
+ };
+}
+
// TODO https://github.com/ziglang/zig/issues/265 on this whole file
pub extern "c" fn fopen(filename: [*]const u8, modes: [*]const u8) ?*FILE;
diff --git a/std/os.zig b/std/os.zig
index e9e9c89b4c..1971b51df4 100644
--- a/std/os.zig
+++ b/std/os.zig
@@ -105,14 +105,18 @@ pub fn getrandom(buf: []u8) GetRandomError!void {
}
if (linux.is_the_target) {
while (true) {
- // Bypass libc because it's missing on even relatively new versions.
- switch (linux.getErrno(linux.getrandom(buf.ptr, buf.len, 0))) {
+ const err = if (std.c.versionCheck(builtin.Version{ .major = 2, .minor = 25, .patch = 0 }).ok) blk: {
+ break :blk errno(std.c.getrandom(buf.ptr, buf.len, 0));
+ } else blk: {
+ break :blk linux.getErrno(linux.getrandom(buf.ptr, buf.len, 0));
+ };
+ switch (err) {
0 => return,
EINVAL => unreachable,
EFAULT => unreachable,
EINTR => continue,
ENOSYS => return getRandomBytesDevURandom(buf),
- else => |err| return unexpectedErrno(err),
+ else => return unexpectedErrno(err),
}
}
}
--
cgit v1.2.3
From 67f3bc9101957a414550ea192918da6174a2fcd2 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Wed, 10 Jul 2019 16:17:09 -0400
Subject: mingw: building and linking msvcrt-os.lib
---
CMakeLists.txt | 61 +-
libc/mingw/include/msvcrt.h | 10 +
libc/mingw/lib-common/kernel32.def.in | 1623 +++++++++++++++++++++++++++
libc/mingw/misc/__p___argv.c | 15 +
libc/mingw/misc/__p__acmdln.c | 18 +
libc/mingw/misc/__p__fmode.c | 17 +
libc/mingw/misc/__p__wcmdln.c | 18 +
libc/mingw/misc/_configthreadlocale.c | 16 +
libc/mingw/misc/_get_current_locale.c | 26 +
libc/mingw/misc/invalid_parameter_handler.c | 23 +
libc/mingw/misc/lc_locale_func.c | 50 +
libc/mingw/misc/onexit_table.c | 77 ++
libc/mingw/misc/output_format.c | 62 +
libc/mingw/misc/purecall.c | 18 +
libc/mingw/misc/register_tls_atexit.c | 29 +
libc/mingw/secapi/_access_s.c | 46 +
libc/mingw/secapi/_cgets_s.c | 56 +
libc/mingw/secapi/_cgetws_s.c | 56 +
libc/mingw/secapi/_chsize_s.c | 46 +
libc/mingw/secapi/_controlfp_s.c | 56 +
libc/mingw/secapi/_cprintf_s.c | 21 +
libc/mingw/secapi/_cprintf_s_l.c | 21 +
libc/mingw/secapi/_ctime32_s.c | 56 +
libc/mingw/secapi/_ctime64_s.c | 56 +
libc/mingw/secapi/_cwprintf_s.c | 21 +
libc/mingw/secapi/_cwprintf_s_l.c | 21 +
libc/mingw/secapi/_gmtime32_s.c | 51 +
libc/mingw/secapi/_gmtime64_s.c | 51 +
libc/mingw/secapi/_localtime32_s.c | 51 +
libc/mingw/secapi/_localtime64_s.c | 51 +
libc/mingw/secapi/_mktemp_s.c | 54 +
libc/mingw/secapi/_sopen_s.c | 42 +
libc/mingw/secapi/_strdate_s.c | 68 ++
libc/mingw/secapi/_strtime_s.c | 72 ++
libc/mingw/secapi/_umask_s.c | 45 +
libc/mingw/secapi/_vcprintf_s.c | 40 +
libc/mingw/secapi/_vcprintf_s_l.c | 40 +
libc/mingw/secapi/_vcwprintf_s.c | 40 +
libc/mingw/secapi/_vcwprintf_s_l.c | 40 +
libc/mingw/secapi/_vscprintf_p.c | 9 +
libc/mingw/secapi/_vscwprintf_p.c | 9 +
libc/mingw/secapi/_vswprintf_p.c | 9 +
libc/mingw/secapi/_waccess_s.c | 47 +
libc/mingw/secapi/_wasctime_s.c | 52 +
libc/mingw/secapi/_wctime32_s.c | 56 +
libc/mingw/secapi/_wctime64_s.c | 56 +
libc/mingw/secapi/_wmktemp_s.c | 55 +
libc/mingw/secapi/_wstrdate_s.c | 68 ++
libc/mingw/secapi/_wstrtime_s.c | 71 ++
libc/mingw/secapi/asctime_s.c | 52 +
libc/mingw/secapi/memcpy_s.c | 59 +
libc/mingw/secapi/memmove_s.c | 60 +
libc/mingw/secapi/rand_s.c | 30 +
libc/mingw/secapi/sprintf_s.c | 20 +
libc/mingw/secapi/strerror_s.c | 53 +
libc/mingw/secapi/vsprintf_s.c | 41 +
libc/mingw/secapi/wmemcpy_s.c | 61 +
libc/mingw/secapi/wmemmove_s.c | 61 +
libc/mingw/stdio/acrt_iob_func.c | 15 +
libc/mingw/stdio/mingw_lock.c | 102 ++
src/ir.cpp | 3 +-
src/link.cpp | 111 ++
std/special/compiler_rt.zig | 21 +
63 files changed, 4282 insertions(+), 3 deletions(-)
create mode 100644 libc/mingw/include/msvcrt.h
create mode 100644 libc/mingw/lib-common/kernel32.def.in
create mode 100644 libc/mingw/misc/__p___argv.c
create mode 100644 libc/mingw/misc/__p__acmdln.c
create mode 100644 libc/mingw/misc/__p__fmode.c
create mode 100644 libc/mingw/misc/__p__wcmdln.c
create mode 100644 libc/mingw/misc/_configthreadlocale.c
create mode 100644 libc/mingw/misc/_get_current_locale.c
create mode 100644 libc/mingw/misc/invalid_parameter_handler.c
create mode 100644 libc/mingw/misc/lc_locale_func.c
create mode 100644 libc/mingw/misc/onexit_table.c
create mode 100644 libc/mingw/misc/output_format.c
create mode 100644 libc/mingw/misc/purecall.c
create mode 100644 libc/mingw/misc/register_tls_atexit.c
create mode 100644 libc/mingw/secapi/_access_s.c
create mode 100644 libc/mingw/secapi/_cgets_s.c
create mode 100644 libc/mingw/secapi/_cgetws_s.c
create mode 100644 libc/mingw/secapi/_chsize_s.c
create mode 100644 libc/mingw/secapi/_controlfp_s.c
create mode 100644 libc/mingw/secapi/_cprintf_s.c
create mode 100644 libc/mingw/secapi/_cprintf_s_l.c
create mode 100644 libc/mingw/secapi/_ctime32_s.c
create mode 100644 libc/mingw/secapi/_ctime64_s.c
create mode 100644 libc/mingw/secapi/_cwprintf_s.c
create mode 100644 libc/mingw/secapi/_cwprintf_s_l.c
create mode 100644 libc/mingw/secapi/_gmtime32_s.c
create mode 100644 libc/mingw/secapi/_gmtime64_s.c
create mode 100644 libc/mingw/secapi/_localtime32_s.c
create mode 100644 libc/mingw/secapi/_localtime64_s.c
create mode 100644 libc/mingw/secapi/_mktemp_s.c
create mode 100644 libc/mingw/secapi/_sopen_s.c
create mode 100644 libc/mingw/secapi/_strdate_s.c
create mode 100644 libc/mingw/secapi/_strtime_s.c
create mode 100644 libc/mingw/secapi/_umask_s.c
create mode 100644 libc/mingw/secapi/_vcprintf_s.c
create mode 100644 libc/mingw/secapi/_vcprintf_s_l.c
create mode 100644 libc/mingw/secapi/_vcwprintf_s.c
create mode 100644 libc/mingw/secapi/_vcwprintf_s_l.c
create mode 100644 libc/mingw/secapi/_vscprintf_p.c
create mode 100644 libc/mingw/secapi/_vscwprintf_p.c
create mode 100644 libc/mingw/secapi/_vswprintf_p.c
create mode 100644 libc/mingw/secapi/_waccess_s.c
create mode 100644 libc/mingw/secapi/_wasctime_s.c
create mode 100644 libc/mingw/secapi/_wctime32_s.c
create mode 100644 libc/mingw/secapi/_wctime64_s.c
create mode 100644 libc/mingw/secapi/_wmktemp_s.c
create mode 100644 libc/mingw/secapi/_wstrdate_s.c
create mode 100644 libc/mingw/secapi/_wstrtime_s.c
create mode 100644 libc/mingw/secapi/asctime_s.c
create mode 100644 libc/mingw/secapi/memcpy_s.c
create mode 100644 libc/mingw/secapi/memmove_s.c
create mode 100644 libc/mingw/secapi/rand_s.c
create mode 100644 libc/mingw/secapi/sprintf_s.c
create mode 100644 libc/mingw/secapi/strerror_s.c
create mode 100644 libc/mingw/secapi/vsprintf_s.c
create mode 100644 libc/mingw/secapi/wmemcpy_s.c
create mode 100644 libc/mingw/secapi/wmemmove_s.c
create mode 100644 libc/mingw/stdio/acrt_iob_func.c
create mode 100644 libc/mingw/stdio/mingw_lock.c
(limited to 'src/ir.cpp')
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3897c74912..f2bfb61b5c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7613,15 +7613,72 @@ set(ZIG_LIBC_FILES
"mingw/crt/xncommod.c"
"mingw/crt/xthdloc.c"
"mingw/crt/xtxtmode.c"
- "mingw/def-include/.func.def.in.swp"
- "mingw/def-include/.msvcrt-common.def.in.swp"
"mingw/def-include/func.def.in"
"mingw/def-include/msvcrt-common.def.in"
"mingw/include/config.h"
"mingw/include/internal.h"
+ "mingw/include/msvcrt.h"
"mingw/include/oscalls.h"
"mingw/include/sect_attribs.h"
+ "mingw/lib-common/kernel32.def.in"
"mingw/lib-common/msvcrt.def.in"
+ "mingw/misc/__p___argv.c"
+ "mingw/misc/__p__acmdln.c"
+ "mingw/misc/__p__fmode.c"
+ "mingw/misc/__p__wcmdln.c"
+ "mingw/misc/_configthreadlocale.c"
+ "mingw/misc/_get_current_locale.c"
+ "mingw/misc/invalid_parameter_handler.c"
+ "mingw/misc/lc_locale_func.c"
+ "mingw/misc/onexit_table.c"
+ "mingw/misc/output_format.c"
+ "mingw/misc/purecall.c"
+ "mingw/misc/register_tls_atexit.c"
+ "mingw/secapi/_access_s.c"
+ "mingw/secapi/_cgets_s.c"
+ "mingw/secapi/_cgetws_s.c"
+ "mingw/secapi/_chsize_s.c"
+ "mingw/secapi/_controlfp_s.c"
+ "mingw/secapi/_cprintf_s.c"
+ "mingw/secapi/_cprintf_s_l.c"
+ "mingw/secapi/_ctime32_s.c"
+ "mingw/secapi/_ctime64_s.c"
+ "mingw/secapi/_cwprintf_s.c"
+ "mingw/secapi/_cwprintf_s_l.c"
+ "mingw/secapi/_gmtime32_s.c"
+ "mingw/secapi/_gmtime64_s.c"
+ "mingw/secapi/_localtime32_s.c"
+ "mingw/secapi/_localtime64_s.c"
+ "mingw/secapi/_mktemp_s.c"
+ "mingw/secapi/_sopen_s.c"
+ "mingw/secapi/_strdate_s.c"
+ "mingw/secapi/_strtime_s.c"
+ "mingw/secapi/_umask_s.c"
+ "mingw/secapi/_vcprintf_s.c"
+ "mingw/secapi/_vcprintf_s_l.c"
+ "mingw/secapi/_vcwprintf_s.c"
+ "mingw/secapi/_vcwprintf_s_l.c"
+ "mingw/secapi/_vscprintf_p.c"
+ "mingw/secapi/_vscwprintf_p.c"
+ "mingw/secapi/_vswprintf_p.c"
+ "mingw/secapi/_waccess_s.c"
+ "mingw/secapi/_wasctime_s.c"
+ "mingw/secapi/_wctime32_s.c"
+ "mingw/secapi/_wctime64_s.c"
+ "mingw/secapi/_wmktemp_s.c"
+ "mingw/secapi/_wstrdate_s.c"
+ "mingw/secapi/_wstrtime_s.c"
+ "mingw/secapi/asctime_s.c"
+ "mingw/secapi/memcpy_s.c"
+ "mingw/secapi/memmove_s.c"
+ "mingw/secapi/rand_s.c"
+ "mingw/secapi/sprintf_s.c"
+ "mingw/secapi/strerror_s.c"
+ "mingw/secapi/vsprintf_s.c"
+ "mingw/secapi/wmemcpy_s.c"
+ "mingw/secapi/wmemmove_s.c"
+ "mingw/stdio/acrt_iob_func.c"
+ "mingw/stdio/mingw_lock.c"
"musl/arch/aarch64/atomic_arch.h"
"musl/arch/aarch64/bits/alltypes.h.in"
"musl/arch/aarch64/bits/endian.h"
diff --git a/libc/mingw/include/msvcrt.h b/libc/mingw/include/msvcrt.h
new file mode 100644
index 0000000000..d5346254f0
--- /dev/null
+++ b/libc/mingw/include/msvcrt.h
@@ -0,0 +1,10 @@
+#include
+
+#ifndef __LIBMSVCRT__
+#error "This file should only be used in libmsvcrt.a"
+#endif
+
+static inline HANDLE __mingw_get_msvcrt_handle(void)
+{
+ return GetModuleHandleW(L"msvcrt.dll");
+}
diff --git a/libc/mingw/lib-common/kernel32.def.in b/libc/mingw/lib-common/kernel32.def.in
new file mode 100644
index 0000000000..3a556294c6
--- /dev/null
+++ b/libc/mingw/lib-common/kernel32.def.in
@@ -0,0 +1,1623 @@
+#include "func.def.in"
+
+LIBRARY "KERNEL32.dll"
+EXPORTS
+AcquireSRWLockExclusive
+AcquireSRWLockShared
+ActivateActCtx
+ActivateActCtxWorker
+AddAtomA
+AddAtomW
+AddConsoleAliasA
+AddConsoleAliasW
+AddDllDirectory
+AddIntegrityLabelToBoundaryDescriptor
+AddLocalAlternateComputerNameA
+AddLocalAlternateComputerNameW
+AddRefActCtx
+AddRefActCtxWorker
+AddResourceAttributeAce
+AddSIDToBoundaryDescriptor
+AddScopedPolicyIDAce
+AddSecureMemoryCacheCallback
+AddVectoredContinueHandler
+AddVectoredExceptionHandler
+AdjustCalendarDate
+AllocConsole
+AllocateUserPhysicalPages
+AllocateUserPhysicalPagesNuma
+AppXGetOSMaxVersionTested
+ApplicationRecoveryFinished
+ApplicationRecoveryInProgress
+AreFileApisANSI
+AssignProcessToJobObject
+AttachConsole
+BackupRead
+BackupSeek
+BackupWrite
+BaseCheckAppcompatCache
+BaseCheckAppcompatCacheEx
+BaseCheckAppcompatCacheExWorker
+BaseCheckAppcompatCacheWorker
+BaseCheckElevation
+BaseCheckRunApp
+BaseCleanupAppcompatCacheSupport
+BaseCleanupAppcompatCacheSupportWorker
+BaseDestroyVDMEnvironment
+BaseDllReadWriteIniFile
+BaseDumpAppcompatCache
+BaseDumpAppcompatCacheWorker
+BaseElevationPostProcessing
+BaseFlushAppcompatCache
+BaseFlushAppcompatCacheWorker
+BaseFormatObjectAttributes
+BaseFormatTimeOut
+BaseFreeAppCompatDataForProcessWorker
+BaseGenerateAppCompatData
+BaseGetNamedObjectDirectory
+BaseInitAppcompatCacheSupport
+BaseInitAppcompatCacheSupportWorker
+BaseIsAppcompatInfrastructureDisabled
+BaseIsAppcompatInfrastructureDisabledWorker
+BaseIsDosApplication
+BaseProcessInitPostImport
+BaseProcessStart
+BaseQueryModuleData
+BaseReadAppCompatDataForProcessWorker
+BaseThreadStart
+BaseSetLastNTError
+BaseThreadInitThunk
+BaseUpdateAppcompatCache
+BaseUpdateAppcompatCacheWorker
+BaseUpdateVDMEntry
+BaseVerifyUnicodeString
+BaseWriteErrorElevationRequiredEvent
+Basep8BitStringToDynamicUnicodeString
+BasepAllocateActivationContextActivationBlock
+BasepAnsiStringToDynamicUnicodeString
+BasepAppContainerEnvironmentExtension
+BasepAppXExtension
+BasepCheckAppCompat
+BasepCheckBadapp
+BasepCheckWebBladeHashes
+BasepCheckWinSaferRestrictions
+BasepConstructSxsCreateProcessMessage
+BasepCopyEncryption
+BasepFreeActivationContextActivationBlock
+BasepFreeAppCompatData
+BasepGetAppCompatData
+BasepGetComputerNameFromNtPath
+BasepGetExeArchType
+BasepIsProcessAllowed
+BasepMapModuleHandle
+BasepNotifyLoadStringResource
+BasepPostSuccessAppXExtension
+BasepProcessInvalidImage
+BasepQueryAppCompat
+BasepReleaseAppXContext
+BasepReleaseSxsCreateProcessUtilityStruct
+BasepReportFault
+BasepSetFileEncryptionCompression
+Beep
+BeginUpdateResourceA
+BeginUpdateResourceW
+BindIoCompletionCallback
+BuildCommDCBA
+BuildCommDCBAndTimeoutsA
+BuildCommDCBAndTimeoutsW
+BuildCommDCBW
+CallNamedPipeA
+CallNamedPipeW
+CallbackMayRunLong
+CalloutOnFiberStack
+CancelDeviceWakeupRequest
+CancelIo
+CancelIoEx
+CancelSynchronousIo
+CancelThreadpoolIo
+CancelTimerQueueTimer
+CancelWaitableTimer
+CeipIsOptedIn
+ChangeTimerQueueTimer
+CheckAllowDecryptedRemoteDestinationPolicy
+CheckElevation
+CheckElevationEnabled
+CheckForReadOnlyResource
+CheckForReadOnlyResourceFilter
+CheckNameLegalDOS8Dot3A
+CheckNameLegalDOS8Dot3W
+CheckRemoteDebuggerPresent
+CheckTokenCapability
+CheckTokenMembershipEx
+ClearCommBreak
+ClearCommError
+CloseConsoleHandle
+CloseHandle
+ClosePackageInfo
+ClosePrivateNamespace
+CloseProfileUserMapping
+CloseState
+CloseThreadpool
+CloseThreadpoolCleanupGroup
+CloseThreadpoolCleanupGroupMembers
+CloseThreadpoolIo
+CloseThreadpoolTimer
+CloseThreadpoolWait
+CloseThreadpoolWork
+CmdBatNotification
+CommConfigDialogA
+CommConfigDialogW
+CompareCalendarDates
+CompareFileTime
+CompareStringA
+CompareStringEx
+CompareStringOrdinal
+CompareStringW
+ConnectNamedPipe
+ConsoleIMERoutine
+ConsoleMenuControl
+ContinueDebugEvent
+ConvertCalDateTimeToSystemTime
+ConvertDefaultLocale
+ConvertFiberToThread
+ConvertNLSDayOfWeekToWin32DayOfWeek
+ConvertSystemTimeToCalDateTime
+ConvertThreadToFiber
+ConvertThreadToFiberEx
+CopyContext
+CopyExtendedContext
+CopyFile2
+CopyFileA
+CopyFileExA
+CopyFileExW
+CopyFileTransactedA
+CopyFileTransactedW
+CopyFileW
+CopyLZFile
+CreateActCtxA
+CreateActCtxW
+CreateActCtxWWorker
+CreateBoundaryDescriptorA
+CreateBoundaryDescriptorW
+CreateConsoleScreenBuffer
+CreateDirectoryA
+CreateDirectoryExA
+CreateDirectoryExW
+CreateDirectoryTransactedA
+CreateDirectoryTransactedW
+CreateDirectoryW
+CreateEventA
+CreateEventExA
+CreateEventExW
+CreateEventW
+CreateFiber
+CreateFiberEx
+CreateFile2
+CreateFileA
+CreateFileMappingA
+CreateFileMappingFromApp
+CreateFileMappingNumaA
+CreateFileMappingNumaW
+CreateFileMappingW
+CreateFileTransactedA
+CreateFileTransactedW
+CreateFileW
+CreateHardLinkA
+CreateHardLinkTransactedA
+CreateHardLinkTransactedW
+CreateHardLinkW
+CreateIoCompletionPort
+CreateJobObjectA
+CreateJobObjectW
+CreateJobSet
+CreateMailslotA
+CreateMailslotW
+CreateMemoryResourceNotification
+CreateMutexA
+CreateMutexExA
+CreateMutexExW
+CreateMutexW
+CreateNamedPipeA
+CreateNamedPipeW
+CreateNlsSecurityDescriptor
+CreatePipe
+CreatePrivateNamespaceA
+CreatePrivateNamespaceW
+CreateProcessA
+CreateProcessAsUserW
+CreateProcessInternalA
+CreateProcessInternalW
+CreateProcessW
+CreateRemoteThread
+CreateRemoteThreadEx
+CreateSemaphoreA
+CreateSemaphoreExA
+CreateSemaphoreExW
+CreateSemaphoreW
+CreateSymbolicLinkA
+CreateSymbolicLinkTransactedA
+CreateSymbolicLinkTransactedW
+CreateSymbolicLinkW
+CreateTapePartition
+CreateThread
+CreateThreadpool
+CreateThreadpoolCleanupGroup
+CreateThreadpoolIo
+CreateThreadpoolTimer
+CreateThreadpoolWait
+CreateThreadpoolWork
+CreateTimerQueue
+CreateTimerQueueTimer
+CreateToolhelp32Snapshot
+F_X64(CreateUmsCompletionList)
+F_X64(CreateUmsThreadContext)
+CreateWaitableTimerA
+CreateWaitableTimerExA
+CreateWaitableTimerExW
+CreateWaitableTimerW
+CtrlRoutine
+DeactivateActCtx
+DeactivateActCtxWorker
+DebugActiveProcess
+DebugActiveProcessStop
+DebugBreak
+DebugBreakProcess
+DebugSetProcessKillOnExit
+DecodePointer
+DecodeSystemPointer
+DefineDosDeviceA
+DefineDosDeviceW
+DelayLoadFailureHook
+DeleteAtom
+DeleteBoundaryDescriptor
+DeleteCriticalSection
+DeleteFiber
+DeleteFileA
+DeleteFileTransactedA
+DeleteFileTransactedW
+DeleteFileW
+DeleteProcThreadAttributeList
+DeleteSynchronizationBarrier
+DeleteTimerQueue
+DeleteTimerQueueEx
+DeleteTimerQueueTimer
+F_X64(DeleteUmsCompletionList)
+F_X64(DeleteUmsThreadContext)
+DeleteVolumeMountPointA
+DeleteVolumeMountPointW
+F_X64(DequeueUmsCompletionListItems)
+DeviceIoControl
+DisableThreadLibraryCalls
+DisableThreadProfiling
+DisassociateCurrentThreadFromCallback
+DiscardVirtualMemory
+DisconnectNamedPipe
+DnsHostnameToComputerNameA
+DnsHostnameToComputerNameExW
+DnsHostnameToComputerNameW
+DosDateTimeToFileTime
+DosPathToSessionPathA
+DosPathToSessionPathW
+DuplicateConsoleHandle
+DuplicateEncryptionInfoFileExt
+DuplicateHandle
+EnableThreadProfiling
+EncodePointer
+EncodeSystemPointer
+EndUpdateResourceA
+EndUpdateResourceW
+EnterCriticalSection
+F_X64(EnterUmsSchedulingMode)
+EnterSynchronizationBarrier
+EnumCalendarInfoA
+EnumCalendarInfoExA
+EnumCalendarInfoExEx
+EnumCalendarInfoExW
+EnumCalendarInfoW
+EnumDateFormatsA
+EnumDateFormatsExA
+EnumDateFormatsExEx
+EnumDateFormatsExW
+EnumDateFormatsW
+EnumLanguageGroupLocalesA
+EnumLanguageGroupLocalesW
+EnumResourceLanguagesA
+EnumResourceLanguagesExA
+EnumResourceLanguagesExW
+EnumResourceLanguagesW
+EnumResourceNamesA
+EnumResourceNamesExA
+EnumResourceNamesExW
+EnumResourceNamesW
+EnumResourceTypesA
+EnumResourceTypesExA
+EnumResourceTypesExW
+EnumResourceTypesW
+EnumSystemCodePagesA
+EnumSystemCodePagesW
+EnumSystemFirmwareTables
+EnumSystemGeoID
+EnumSystemLanguageGroupsA
+EnumSystemLanguageGroupsW
+EnumSystemLocalesA
+EnumSystemLocalesEx
+EnumSystemLocalesW
+EnumTimeFormatsA
+EnumTimeFormatsEx
+EnumTimeFormatsW
+EnumUILanguagesA
+EnumUILanguagesW
+EnumerateLocalComputerNamesA
+EnumerateLocalComputerNamesW
+EraseTape
+EscapeCommFunction
+F_X64(ExecuteUmsThread)
+ExitProcess
+ExitThread
+ExitVDM
+ExpandEnvironmentStringsA
+ExpandEnvironmentStringsW
+ExpungeConsoleCommandHistoryA
+ExpungeConsoleCommandHistoryW
+FatalAppExitA
+FatalAppExitW
+FatalExit
+FileTimeToDosDateTime
+FileTimeToLocalFileTime
+FileTimeToSystemTime
+FillConsoleOutputAttribute
+FillConsoleOutputCharacterA
+FillConsoleOutputCharacterW
+FindActCtxSectionGuid
+FindActCtxSectionGuidWorker
+FindActCtxSectionStringA
+FindActCtxSectionStringW
+FindActCtxSectionStringWWorker
+FindAtomA
+FindAtomW
+FindClose
+FindCloseChangeNotification
+FindFirstChangeNotificationA
+FindFirstChangeNotificationW
+FindFirstFileA
+FindFirstFileExA
+FindFirstFileExW
+FindFirstFileNameTransactedW
+FindFirstFileNameW
+FindFirstFileTransactedA
+FindFirstFileTransactedW
+FindFirstFileW
+FindFirstStreamTransactedW
+FindFirstStreamW
+FindFirstVolumeA
+FindFirstVolumeMountPointA
+FindFirstVolumeMountPointW
+FindFirstVolumeW
+FindNLSString
+FindNLSStringEx
+FindNextChangeNotification
+FindNextFileA
+FindNextFileNameW
+FindNextFileW
+FindNextStreamW
+FindNextVolumeA
+FindNextVolumeMountPointA
+FindNextVolumeMountPointW
+FindNextVolumeW
+FindPackagesByPackageFamily
+FindResourceA
+FindResourceExA
+FindResourceExW
+FindResourceW
+FindStringOrdinal
+FindVolumeClose
+FindVolumeMountPointClose
+FlsAlloc
+FlsFree
+FlsGetValue
+FlsSetValue
+FlushConsoleInputBuffer
+FlushFileBuffers
+FlushInstructionCache
+FlushProcessWriteBuffers
+FlushViewOfFile
+FoldStringA
+FoldStringW
+FormatApplicationUserModelId
+FormatMessageA
+FormatMessageW
+FreeConsole
+FreeEnvironmentStringsA
+FreeEnvironmentStringsW
+FreeLibrary
+FreeLibraryAndExitThread
+FreeLibraryWhenCallbackReturns
+FreeResource
+FreeUserPhysicalPages
+GenerateConsoleCtrlEvent
+GetACP
+GetActiveProcessorCount
+GetActiveProcessorGroupCount
+GetAppContainerAce
+GetAppContainerNamedObjectPath
+GetApplicationRecoveryCallback
+GetApplicationRecoveryCallbackWorker
+GetApplicationRestartSettings
+GetApplicationRestartSettingsWorker
+GetApplicationUserModelId
+GetAtomNameA
+GetAtomNameW
+GetBinaryType
+GetBinaryTypeA
+GetBinaryTypeW
+GetCPFileNameFromRegistry
+GetCPInfo
+GetCPInfoExA
+GetCPInfoExW
+GetCachedSigningLevel
+GetCalendarDateFormat
+GetCalendarDateFormatEx
+GetCalendarDaysInMonth
+GetCalendarDifferenceInDays
+GetCalendarInfoA
+GetCalendarInfoEx
+GetCalendarInfoW
+GetCalendarMonthsInYear
+GetCalendarSupportedDateRange
+GetCalendarWeekNumber
+GetComPlusPackageInstallStatus
+GetCommConfig
+GetCommMask
+GetCommModemStatus
+GetCommProperties
+GetCommState
+GetCommTimeouts
+GetCommandLineA
+GetCommandLineW
+GetCompressedFileSizeA
+GetCompressedFileSizeTransactedA
+GetCompressedFileSizeTransactedW
+GetCompressedFileSizeW
+GetComputerNameA
+GetComputerNameExA
+GetComputerNameExW
+GetComputerNameW
+GetConsoleAliasA
+GetConsoleAliasExesA
+GetConsoleAliasExesLengthA
+GetConsoleAliasExesLengthW
+GetConsoleAliasExesW
+GetConsoleAliasW
+GetConsoleAliasesA
+GetConsoleAliasesLengthA
+GetConsoleAliasesLengthW
+GetConsoleAliasesW
+GetConsoleCP
+GetConsoleCharType
+GetConsoleCommandHistoryA
+GetConsoleCommandHistoryLengthA
+GetConsoleCommandHistoryLengthW
+GetConsoleCommandHistoryW
+GetConsoleCursorInfo
+GetConsoleCursorMode
+GetConsoleDisplayMode
+GetConsoleFontInfo
+GetConsoleFontSize
+GetConsoleHardwareState
+GetConsoleHistoryInfo
+GetConsoleInputExeNameA
+GetConsoleInputExeNameW
+GetConsoleInputWaitHandle
+GetConsoleKeyboardLayoutNameA
+GetConsoleKeyboardLayoutNameW
+GetConsoleMode
+GetConsoleNlsMode
+GetConsoleOriginalTitleA
+GetConsoleOriginalTitleW
+GetConsoleOutputCP
+GetConsoleProcessList
+GetConsoleScreenBufferInfo
+GetConsoleScreenBufferInfoEx
+GetConsoleSelectionInfo
+GetConsoleTitleA
+GetConsoleTitleW
+GetConsoleWindow
+GetCurrencyFormatA
+GetCurrencyFormatEx
+GetCurrencyFormatW
+GetCurrentActCtx
+GetCurrentActCtxWorker
+GetCurrentApplicationUserModelId
+GetCurrentConsoleFont
+GetCurrentConsoleFontEx
+GetCurrentDirectoryA
+GetCurrentDirectoryW
+GetCurrentPackageFamilyName
+GetCurrentPackageFullName
+GetCurrentPackageId
+GetCurrentPackageInfo
+GetCurrentPackagePath
+GetCurrentProcess
+GetCurrentProcessId
+GetCurrentProcessorNumber
+GetCurrentProcessorNumberEx
+GetCurrentThread
+GetCurrentThreadId
+GetCurrentThreadStackLimits
+F_X64(GetCurrentUmsThread)
+GetDateFormatA
+GetDateFormatAWorker
+GetDateFormatEx
+GetDateFormatW
+GetDateFormatWWorker
+GetDefaultCommConfigA
+GetDefaultCommConfigW
+GetDefaultSortkeySize
+GetDevicePowerState
+GetDiskFreeSpaceA
+GetDiskFreeSpaceExA
+GetDiskFreeSpaceExW
+GetDiskFreeSpaceW
+GetDllDirectoryA
+GetDllDirectoryW
+GetDriveTypeA
+GetDriveTypeW
+GetDurationFormat
+GetDurationFormatEx
+GetDynamicTimeZoneInformation
+GetEnabledExtendedFeatures
+GetEncryptedFileVersionExt
+GetEnvironmentStrings
+GetEnvironmentStringsA
+GetEnvironmentStringsW
+GetEnvironmentVariableA
+GetEnvironmentVariableW
+GetEraNameCountedString
+GetErrorMode
+GetExitCodeProcess
+GetExitCodeThread
+GetExpandedNameA
+GetExpandedNameW
+GetExtendedContextLength
+GetExtendedFeaturesMask
+GetFileAttributesA
+GetFileAttributesExA
+GetFileAttributesExW
+GetFileAttributesTransactedA
+GetFileAttributesTransactedW
+GetFileAttributesW
+GetFileBandwidthReservation
+GetFileInformationByHandle
+GetFileInformationByHandleEx
+GetFileMUIInfo
+GetFileMUIPath
+GetFileSize
+GetFileSizeEx
+GetFileTime
+GetFileType
+GetFinalPathNameByHandleA
+GetFinalPathNameByHandleW
+GetFirmwareEnvironmentVariableA
+GetFirmwareEnvironmentVariableExA
+GetFirmwareEnvironmentVariableExW
+GetFirmwareEnvironmentVariableW
+GetFirmwareType
+GetFullPathNameA
+GetFullPathNameTransactedA
+GetFullPathNameTransactedW
+GetFullPathNameW
+GetGeoInfoA
+GetGeoInfoW
+GetHandleInformation
+GetLargePageMinimum
+GetLargestConsoleWindowSize
+GetLastError
+GetLinguistLangSize
+GetLocalTime
+GetLocaleInfoA
+GetLocaleInfoEx
+GetLocaleInfoW
+GetLogicalDriveStringsA
+GetLogicalDriveStringsW
+GetLogicalDrives
+GetLogicalProcessorInformation
+GetLogicalProcessorInformationEx
+GetLongPathNameA
+GetLongPathNameTransactedA
+GetLongPathNameTransactedW
+GetLongPathNameW
+GetMailslotInfo
+GetMaximumProcessorCount
+GetMaximumProcessorGroupCount
+GetMemoryErrorHandlingCapabilities
+GetModuleFileNameA
+GetModuleFileNameW
+GetModuleHandleA
+GetModuleHandleExA
+GetModuleHandleExW
+GetModuleHandleW
+GetNLSVersion
+GetNLSVersionEx
+GetNamedPipeAttribute
+GetNamedPipeClientComputerNameA
+GetNamedPipeClientComputerNameW
+GetNamedPipeClientProcessId
+GetNamedPipeClientSessionId
+GetNamedPipeHandleStateA
+GetNamedPipeHandleStateW
+GetNamedPipeInfo
+GetNamedPipeServerProcessId
+GetNamedPipeServerSessionId
+GetNativeSystemInfo
+F_X64(GetNextUmsListItem)
+GetNextVDMCommand
+GetNlsSectionName
+GetNumaAvailableMemoryNode
+GetNumaAvailableMemoryNodeEx
+GetNumaHighestNodeNumber
+GetNumaNodeNumberFromHandle
+GetNumaNodeProcessorMask
+GetNumaNodeProcessorMaskEx
+GetNumaProcessorNode
+GetNumaProcessorNodeEx
+GetNumaProximityNode
+GetNumaProximityNodeEx
+GetNumberFormatA
+GetNumberFormatEx
+GetNumberFormatW
+GetNumberOfConsoleFonts
+GetNumberOfConsoleInputEvents
+GetNumberOfConsoleMouseButtons
+GetOEMCP
+GetOverlappedResult
+GetOverlappedResultEx
+GetPackageApplicationIds
+GetPackageFamilyName
+GetPackageFullName
+GetPackageId
+GetPackageInfo
+GetPackagePath
+GetPackagePathByFullName
+GetPackagesByPackageFamily
+GetPhysicallyInstalledSystemMemory
+GetPriorityClass
+GetPrivateProfileIntA
+GetPrivateProfileIntW
+GetPrivateProfileSectionA
+GetPrivateProfileSectionNamesA
+GetPrivateProfileSectionNamesW
+GetPrivateProfileSectionW
+GetPrivateProfileStringA
+GetPrivateProfileStringW
+GetPrivateProfileStructA
+GetPrivateProfileStructW
+GetProcAddress
+GetProcessAffinityMask
+GetProcessDEPPolicy
+GetProcessGroupAffinity
+GetProcessHandleCount
+GetProcessHeap
+GetProcessHeaps
+GetProcessId
+GetProcessIdOfThread
+GetProcessInformation
+GetProcessIoCounters
+GetProcessMitigationPolicy
+GetProcessPreferredUILanguages
+GetProcessPriorityBoost
+GetProcessShutdownParameters
+GetProcessTimes
+GetProcessVersion
+GetProcessWorkingSetSize
+GetProcessWorkingSetSizeEx
+GetProcessorSystemCycleTime
+GetProductInfo
+GetProfileIntA
+GetProfileIntW
+GetProfileSectionA
+GetProfileSectionW
+GetProfileStringA
+GetProfileStringW
+GetQueuedCompletionStatus
+GetQueuedCompletionStatusEx
+GetShortPathNameA
+GetShortPathNameW
+GetStagedPackagePathByFullName
+GetStartupInfoA
+GetStartupInfoW
+GetStateFolder
+GetStdHandle
+GetStringScripts
+GetStringTypeA
+GetStringTypeExA
+GetStringTypeExW
+GetStringTypeW
+GetSystemAppDataKey
+GetSystemDEPPolicy
+GetSystemDefaultLCID
+GetSystemDefaultLangID
+GetSystemDefaultLocaleName
+GetSystemDefaultUILanguage
+GetSystemDirectoryA
+GetSystemDirectoryW
+GetSystemFileCacheSize
+GetSystemFirmwareTable
+GetSystemInfo
+GetSystemPowerStatus
+GetSystemPreferredUILanguages
+GetSystemRegistryQuota
+GetSystemTime
+GetSystemTimeAdjustment
+GetSystemTimeAsFileTime
+GetSystemTimePreciseAsFileTime
+GetSystemTimes
+GetSystemWindowsDirectoryA
+GetSystemWindowsDirectoryW
+GetSystemWow64DirectoryA
+GetSystemWow64DirectoryW
+GetTapeParameters
+GetTapePosition
+GetTapeStatus
+GetTempFileNameA
+GetTempFileNameW
+GetTempPathA
+GetTempPathW
+GetThreadContext
+GetThreadErrorMode
+GetThreadGroupAffinity
+GetThreadIOPendingFlag
+GetThreadId
+GetThreadIdealProcessorEx
+GetThreadInformation
+GetThreadLocale
+GetThreadPreferredUILanguages
+GetThreadPriority
+GetThreadPriorityBoost
+GetThreadSelectorEntry
+GetThreadTimes
+GetThreadUILanguage
+GetTickCount
+GetTickCount64
+GetTimeFormatA
+GetTimeFormatAWorker
+GetTimeFormatEx
+GetTimeFormatW
+GetTimeFormatWWorker
+GetTimeZoneInformation
+GetTimeZoneInformationForYear
+GetUILanguageInfo
+F_X64(GetUmsCompletionListEvent)
+GetUserDefaultLCID
+GetUserDefaultLangID
+GetUserDefaultLocaleName
+GetUserDefaultUILanguage
+GetUserGeoID
+GetUserPreferredUILanguages
+GetVDMCurrentDirectories
+GetVersion
+GetVersionExA
+GetVersionExW
+GetVolumeInformationA
+GetVolumeInformationByHandleW
+GetVolumeInformationW
+GetVolumeNameForVolumeMountPointA
+GetVolumeNameForVolumeMountPointW
+GetVolumePathNameA
+GetVolumePathNameW
+GetVolumePathNamesForVolumeNameA
+GetVolumePathNamesForVolumeNameW
+GetWindowsDirectoryA
+GetWindowsDirectoryW
+GetWriteWatch
+GlobalAddAtomA
+GlobalAddAtomExA
+GlobalAddAtomExW
+GlobalAddAtomW
+GlobalAlloc
+GlobalCompact
+GlobalDeleteAtom
+GlobalFindAtomA
+GlobalFindAtomW
+GlobalFix
+GlobalFlags
+GlobalFree
+GlobalGetAtomNameA
+GlobalGetAtomNameW
+GlobalHandle
+GlobalLock
+GlobalMemoryStatus
+GlobalMemoryStatusEx
+GlobalReAlloc
+GlobalSize
+GlobalUnWire
+GlobalUnfix
+GlobalUnlock
+GlobalWire
+Heap32First
+Heap32ListFirst
+Heap32ListNext
+Heap32Next
+HeapAlloc
+HeapCompact
+HeapCreate
+HeapCreateTagsW
+HeapDestroy
+HeapExtend
+HeapFree
+HeapLock
+HeapQueryInformation
+HeapQueryTagW
+HeapReAlloc
+HeapSetInformation
+HeapSize
+HeapSummary
+HeapUnlock
+HeapUsage
+HeapValidate
+HeapWalk
+IdnToAscii
+IdnToNameprepUnicode
+IdnToUnicode
+InitAtomTable
+InitializeConditionVariable
+InitializeCriticalSection
+InitOnceBeginInitialize
+InitOnceComplete
+InitOnceExecuteOnce
+InitOnceInitialize
+InitializeConditionVariable
+InitializeContext
+InitializeCriticalSection
+InitializeCriticalSectionAndSpinCount
+InitializeCriticalSectionEx
+InitializeExtendedContext
+InitializeProcThreadAttributeList
+InitializeSListHead
+InitializeSRWLock
+InitializeSynchronizationBarrier
+InstallELAMCertificateInfo
+InterlockedFlushSList
+InterlockedPopEntrySList
+InterlockedPushEntrySList
+InterlockedPushListSList
+InterlockedPushListSListEx
+InvalidateConsoleDIBits
+IsBadCodePtr
+IsBadHugeReadPtr
+IsBadHugeWritePtr
+IsBadReadPtr
+IsBadStringPtrA
+IsBadStringPtrW
+IsBadWritePtr
+IsCalendarLeapDay
+IsCalendarLeapMonth
+IsCalendarLeapYear
+IsDBCSLeadByte
+IsDBCSLeadByteEx
+IsDebuggerPresent
+IsNLSDefinedString
+IsNativeVhdBoot
+IsNormalizedString
+IsProcessCritical
+IsProcessInJob
+IsProcessorFeaturePresent
+IsSystemResumeAutomatic
+IsThreadAFiber
+IsThreadpoolTimerSet
+IsTimeZoneRedirectionEnabled
+IsValidCalDateTime
+IsValidCodePage
+IsValidLanguageGroup
+IsValidLocale
+IsValidUILanguage
+IsValidLocaleName
+IsValidNLSVersion
+IsWow64Process
+K32EmptyWorkingSet
+K32EnumDeviceDrivers
+K32EnumPageFilesA
+K32EnumPageFilesW
+K32EnumProcessModules
+K32EnumProcessModulesEx
+K32EnumProcesses
+K32GetDeviceDriverBaseNameA
+K32GetDeviceDriverBaseNameW
+K32GetDeviceDriverFileNameA
+K32GetDeviceDriverFileNameW
+K32GetMappedFileNameA
+K32GetMappedFileNameW
+K32GetModuleBaseNameA
+K32GetModuleBaseNameW
+K32GetModuleFileNameExA
+K32GetModuleFileNameExW
+K32GetModuleInformation
+K32GetPerformanceInfo
+K32GetProcessImageFileNameA
+K32GetProcessImageFileNameW
+K32GetProcessMemoryInfo
+K32GetWsChanges
+K32GetWsChangesEx
+K32InitializeProcessForWsWatch
+K32QueryWorkingSet
+K32QueryWorkingSetEx
+LCIDToLocaleName
+LCMapStringA
+LCMapStringEx
+LCMapStringW
+LZClose
+LZCloseFile
+LZCopy
+LZCreateFileW
+LZDone
+LZInit
+LZOpenFileA
+LZOpenFileW
+LZRead
+LZSeek
+LZStart
+LeaveCriticalSection
+LeaveCriticalSectionWhenCallbackReturns
+LoadAppInitDlls
+LoadLibraryA
+LoadLibraryExA
+LoadLibraryExW
+LoadLibraryW
+LoadModule
+LoadPackagedLibrary
+LoadResource
+LoadStringBaseExW
+LoadStringBaseW
+LocalAlloc
+LocalCompact
+LocalFileTimeToFileTime
+LocalFlags
+LocalFree
+LocalHandle
+LocalLock
+LocalReAlloc
+LocalShrink
+LocalSize
+LocalUnlock
+LocaleNameToLCID
+LocateExtendedFeature
+LocateLegacyContext
+LockFile
+LockFileEx
+LockResource
+MapUserPhysicalPages
+MapUserPhysicalPagesScatter
+MapViewOfFile
+MapViewOfFileEx
+MapViewOfFileExNuma
+MapViewOfFileFromApp
+Module32First
+Module32FirstW
+Module32Next
+Module32NextW
+MoveFileA
+MoveFileExA
+MoveFileExW
+MoveFileTransactedA
+MoveFileTransactedW
+MoveFileW
+MoveFileWithProgressA
+MoveFileWithProgressW
+MulDiv
+MultiByteToWideChar
+NeedCurrentDirectoryForExePathA
+NeedCurrentDirectoryForExePathW
+NlsConvertIntegerToString
+NlsCheckPolicy
+NlsEventDataDescCreate
+NlsGetCacheUpdateCount
+NlsUpdateLocale
+NlsUpdateSystemLocale
+NlsResetProcessLocale
+NlsWriteEtwEvent
+NormalizeString
+NotifyMountMgr
+NotifyUILanguageChange
+NtVdm64CreateProcessInternalW
+OOBEComplete
+OfferVirtualMemory
+OpenConsoleW
+OpenConsoleWStub
+OpenDataFile
+OpenEventA
+OpenEventW
+OpenFile
+OpenFileById
+OpenFileMappingA
+OpenFileMappingW
+OpenJobObjectA
+OpenJobObjectW
+OpenMutexA
+OpenMutexW
+OpenPackageInfoByFullName
+OpenPrivateNamespaceA
+OpenPrivateNamespaceW
+OpenProcess
+; MSDN says OpenProcessToken is from Advapi32.dll, not Kernel32.dll
+; OpenProcessToken
+OpenProfileUserMapping
+OpenSemaphoreA
+OpenSemaphoreW
+OpenState
+OpenStateExplicit
+OpenThread
+;OpenThreadToken
+OpenWaitableTimerA
+OpenWaitableTimerW
+OutputDebugStringA
+OutputDebugStringW
+PackageFamilyNameFromFullName
+PackageFamilyNameFromId
+PackageFullNameFromId
+PackageIdFromFullName
+PackageNameAndPublisherIdFromFamilyName
+ParseApplicationUserModelId
+PeekConsoleInputA
+PeekConsoleInputW
+PeekNamedPipe
+PostQueuedCompletionStatus
+PowerClearRequest
+PowerCreateRequest
+PowerSetRequest
+PrefetchVirtualMemory
+PrepareTape
+PrivCopyFileExW
+PrivMoveFileIdentityW
+Process32First
+Process32FirstW
+Process32Next
+Process32NextW
+ProcessIdToSessionId
+PssCaptureSnapshot
+PssDuplicateSnapshot
+PssFreeSnapshot
+PssQuerySnapshot
+PssWalkMarkerCreate
+PssWalkMarkerFree
+PssWalkMarkerGetPosition
+PssWalkMarkerRewind
+PssWalkMarkerSeek
+PssWalkMarkerSeekToBeginning
+PssWalkMarkerSetPosition
+PssWalkMarkerTell
+PssWalkSnapshot
+PulseEvent
+PurgeComm
+QueryActCtxSettingsW
+QueryActCtxSettingsWWorker
+QueryActCtxW
+QueryActCtxWWorker
+QueryDepthSList
+QueryDosDeviceA
+QueryDosDeviceW
+QueryFullProcessImageNameA
+QueryFullProcessImageNameW
+QueryIdleProcessorCycleTime
+QueryIdleProcessorCycleTimeEx
+QueryInformationJobObject
+QueryMemoryResourceNotification
+QueryPerformanceCounter
+QueryPerformanceFrequency
+QueryProcessAffinityUpdateMode
+QueryProcessCycleTime
+QueryThreadCycleTime
+QueryThreadProfiling
+QueryThreadpoolStackInformation
+F_X64(QueryUmsThreadInformation)
+QueryUnbiasedInterruptTime
+QueueUserAPC
+QueueUserWorkItem
+QuirkGetData2Worker
+QuirkGetDataWorker
+QuirkIsEnabled2Worker
+QuirkIsEnabled3Worker
+QuirkIsEnabledForPackage2Worker
+QuirkIsEnabledForPackageWorker
+QuirkIsEnabledForProcessWorker
+QuirkIsEnabledWorker
+RaiseException
+RaiseFailFastException
+RaiseInvalid16BitExeError
+ReOpenFile
+ReclaimVirtualMemory
+ReadConsoleA
+ReadConsoleInputA
+ReadConsoleInputExA
+ReadConsoleInputExW
+ReadConsoleInputW
+ReadConsoleOutputA
+ReadConsoleOutputAttribute
+ReadConsoleOutputCharacterA
+ReadConsoleOutputCharacterW
+ReadConsoleOutputW
+ReadConsoleW
+ReadDirectoryChangesW
+ReadFile
+ReadFileEx
+ReadFileScatter
+ReadProcessMemory
+ReadThreadProfilingData
+;
+; MSDN says these functions are exported
+; from advapi32.dll. Commented out for
+; compatibility with older versions of
+; Windows.
+;
+; RegKrnGetGlobalState and RegKrnInitialize
+; are known exceptions.
+;
+;RegCloseKey
+;RegCopyTreeW
+;RegCreateKeyExA
+;RegCreateKeyExW
+;RegDeleteKeyExA
+;RegDeleteKeyExW
+;RegDeleteTreeA
+;RegDeleteTreeW
+;RegDeleteValueA
+;RegDeleteValueW
+;RegDisablePredefinedCacheEx
+;RegEnumKeyExA
+;RegEnumKeyExW
+;RegEnumValueA
+;RegEnumValueW
+;RegFlushKey
+;RegGetKeySecurity
+;RegGetValueA
+;RegGetValueW
+RegKrnGetGlobalState
+RegKrnInitialize
+;RegLoadKeyA
+;RegLoadKeyW
+;RegLoadMUIStringA
+;RegLoadMUIStringW
+;RegNotifyChangeKeyValue
+;RegOpenCurrentUser
+;RegOpenKeyExA
+;RegOpenKeyExW
+;RegOpenUserClassesRoot
+;RegQueryInfoKeyA
+;RegQueryInfoKeyW
+;RegQueryValueExA
+;RegQueryValueExW
+;RegRestoreKeyA
+;RegRestoreKeyW
+;RegSaveKeyExA
+;RegSaveKeyExW
+;RegSetKeySecurity
+;RegSetValueExA
+;RegSetValueExW
+;RegUnLoadKeyA
+;RegUnLoadKeyW
+RegisterApplicationRecoveryCallback
+RegisterApplicationRestart
+RegisterBadMemoryNotification
+RegisterConsoleIME
+RegisterConsoleOS2
+RegisterConsoleVDM
+RegisterWaitForInputIdle
+RegisterWaitForSingleObject
+RegisterWaitForSingleObjectEx
+RegisterWaitUntilOOBECompleted
+RegisterWowBaseHandlers
+RegisterWowExec
+ReleaseActCtx
+ReleaseActCtxWorker
+ReleaseMutex
+ReleaseMutexWhenCallbackReturns
+ReleaseSRWLockExclusive
+ReleaseSRWLockShared
+ReleaseSemaphore
+ReleaseSemaphoreWhenCallbackReturns
+RemoveDirectoryA
+RemoveDirectoryTransactedA
+RemoveDirectoryTransactedW
+RemoveDirectoryW
+RemoveDllDirectory
+RemoveLocalAlternateComputerNameA
+RemoveLocalAlternateComputerNameW
+RemoveSecureMemoryCacheCallback
+RemoveVectoredContinueHandler
+RemoveVectoredExceptionHandler
+ReplaceFile
+ReplaceFileA
+ReplaceFileW
+ReplacePartitionUnit
+RequestDeviceWakeup
+RequestWakeupLatency
+ResetEvent
+ResetWriteWatch
+ResolveDelayLoadedAPI
+ResolveDelayLoadsFromDll
+ResolveLocaleName
+RestoreLastError
+ResumeThread
+RtlAddFunctionTable
+RtlCaptureContext
+RtlCaptureStackBackTrace
+RtlCompareMemory
+RtlCopyMemory
+RtlDeleteFunctionTable
+RtlFillMemory
+RtlInstallFunctionTableCallback
+RtlLookupFunctionEntry
+RtlMoveMemory
+RtlPcToFileHeader
+RtlRaiseException
+RtlRestoreContext
+RtlUnwind
+RtlUnwindEx
+RtlVirtualUnwind
+RtlZeroMemory
+ScrollConsoleScreenBufferA
+ScrollConsoleScreenBufferW
+SearchPathA
+SearchPathW
+SetCachedSigningLevel
+SetCPGlobal
+SetCalendarInfoA
+SetCalendarInfoW
+SetComPlusPackageInstallStatus
+SetCommBreak
+SetCommConfig
+SetCommMask
+SetCommState
+SetCommTimeouts
+SetComputerNameA
+SetComputerNameEx2W
+SetComputerNameExA
+SetComputerNameExW
+SetComputerNameW
+SetConsoleActiveScreenBuffer
+SetConsoleCP
+SetConsoleCommandHistoryMode
+SetConsoleCtrlHandler
+SetConsoleCursor
+SetConsoleCursorInfo
+SetConsoleCursorMode
+SetConsoleCursorPosition
+SetConsoleDisplayMode
+SetConsoleFont
+SetConsoleHardwareState
+SetConsoleHistoryInfo
+SetConsoleIcon
+SetConsoleInputExeNameA
+SetConsoleInputExeNameW
+SetConsoleKeyShortcuts
+SetConsoleLocalEUDC
+SetConsoleMaximumWindowSize
+SetConsoleMenuClose
+SetConsoleMode
+SetConsoleNlsMode
+SetConsoleNumberOfCommandsA
+SetConsoleNumberOfCommandsW
+SetConsoleOS2OemFormat
+SetConsoleOutputCP
+SetConsolePalette
+SetConsoleScreenBufferInfoEx
+SetConsoleScreenBufferSize
+SetConsoleTextAttribute
+SetConsoleTitleA
+SetConsoleTitleW
+SetConsoleWindowInfo
+SetCriticalSectionSpinCount
+SetCurrentConsoleFontEx
+SetCurrentDirectoryA
+SetCurrentDirectoryW
+SetDefaultCommConfigA
+SetDefaultCommConfigW
+SetDefaultDllDirectories
+SetDllDirectoryA
+SetDllDirectoryW
+SetDynamicTimeZoneInformation
+SetEndOfFile
+SetEnvironmentStringsA
+SetEnvironmentStringsW
+SetEnvironmentVariableA
+SetEnvironmentVariableW
+SetErrorMode
+SetEvent
+SetEventWhenCallbackReturns
+SetExtendedFeaturesMask
+SetFileApisToANSI
+SetFileApisToOEM
+SetFileAttributesA
+SetFileAttributesTransactedA
+SetFileAttributesTransactedW
+SetFileAttributesW
+SetFileBandwidthReservation
+SetFileCompletionNotificationModes
+SetFileInformationByHandle
+SetFileIoOverlappedRange
+SetFilePointer
+SetFilePointerEx
+SetFileShortNameA
+SetFileShortNameW
+SetFileTime
+SetFileValidData
+SetFirmwareEnvironmentVariableA
+SetFirmwareEnvironmentVariableExA
+SetFirmwareEnvironmentVariableExW
+SetFirmwareEnvironmentVariableW
+SetHandleCount
+SetHandleInformation
+SetInformationJobObject
+SetLastConsoleEventActive
+SetLastError
+SetLocalPrimaryComputerNameA
+SetLocalPrimaryComputerNameW
+SetLocalTime
+SetLocaleInfoA
+SetLocaleInfoW
+SetMailslotInfo
+SetMessageWaitingIndicator
+SetNamedPipeAttribute
+SetNamedPipeHandleState
+SetPriorityClass
+SetProcessAffinityMask
+SetProcessAffinityUpdateMode
+SetProcessDEPPolicy
+SetProcessInformation
+SetProcessMitigationPolicy
+SetProcessPreferredUILanguages
+SetProcessPriorityBoost
+SetProcessShutdownParameters
+SetProcessWorkingSetSize
+SetProcessWorkingSetSizeEx
+SetSearchPathMode
+SetStdHandle
+SetStdHandleEx
+SetSystemFileCacheSize
+SetSystemPowerState
+SetSystemTime
+SetSystemTimeAdjustment
+SetTapeParameters
+SetTapePosition
+SetTermsrvAppInstallMode
+SetThreadAffinityMask
+SetThreadContext
+SetThreadErrorMode
+SetThreadExecutionState
+SetThreadGroupAffinity
+SetThreadIdealProcessor
+SetThreadIdealProcessorEx
+SetThreadInformation
+SetThreadLocale
+SetThreadPreferredUILanguages
+SetThreadPriority
+SetThreadPriorityBoost
+SetThreadStackGuarantee
+SetThreadToken
+SetThreadUILanguage
+SetThreadpoolStackInformation
+SetThreadpoolThreadMaximum
+SetThreadpoolThreadMinimum
+SetThreadpoolTimer
+SetThreadpoolTimerEx
+SetThreadpoolWait
+SetThreadpoolWaitEx
+SetTimeZoneInformation
+SetTimerQueueTimer
+F_X64(SetUmsThreadInformation)
+SetUnhandledExceptionFilter
+SetUserGeoID
+SetVDMCurrentDirectories
+SetVolumeLabelA
+SetVolumeLabelW
+SetVolumeMountPointA
+SetVolumeMountPointW
+SetVolumeMountPointWStub
+SetWaitableTimer
+SetWaitableTimerEx
+SetupComm
+ShowConsoleCursor
+SignalObjectAndWait
+SizeofResource
+Sleep
+SleepConditionVariableCS
+SleepConditionVariableSRW
+SleepEx
+SortCloseHandle
+SortGetHandle
+StartThreadpoolIo
+SubmitThreadpoolWork
+SuspendThread
+SwitchToFiber
+SwitchToThread
+SystemTimeToFileTime
+SystemTimeToTzSpecificLocalTime
+SystemTimeToTzSpecificLocalTimeEx
+TerminateJobObject
+TerminateProcess
+TerminateThread
+TermsrvAppInstallMode
+TermsrvConvertSysRootToUserDir
+TermsrvCreateRegEntry
+TermsrvDeleteKey
+TermsrvDeleteValue
+TermsrvGetPreSetValue
+TermsrvGetWindowsDirectoryA
+TermsrvGetWindowsDirectoryW
+TermsrvOpenRegEntry
+TermsrvOpenUserClasses
+TermsrvRestoreKey
+TermsrvSetKeySecurity
+TermsrvSetValueKey
+TermsrvSyncUserIniFileExt
+Thread32First
+Thread32Next
+TlsAlloc
+TlsFree
+TlsGetValue
+TlsSetValue
+Toolhelp32ReadProcessMemory
+TransactNamedPipe
+TransmitCommChar
+TryAcquireSRWLockExclusive
+TryAcquireSRWLockShared
+TryEnterCriticalSection
+TrySubmitThreadpoolCallback
+TzSpecificLocalTimeToSystemTime
+TzSpecificLocalTimeToSystemTimeEx
+UTRegister
+UTUnRegister
+F_X64(UmsThreadYield)
+UnhandledExceptionFilter
+UnlockFile
+UnlockFileEx
+UnmapViewOfFile
+UnmapViewOfFileEx
+UnregisterApplicationRecoveryCallback
+UnregisterApplicationRestart
+UnregisterBadMemoryNotification
+UnregisterConsoleIME
+UnregisterWait
+UnregisterWaitEx
+UnregisterWaitUntilOOBECompleted
+UpdateCalendarDayOfWeek
+UpdateProcThreadAttribute
+UpdateResourceA
+UpdateResourceW
+VDMConsoleOperation
+VDMOperationStarted
+ValidateLCType
+ValidateLocale
+VerLanguageNameA
+VerLanguageNameW
+VerSetConditionMask
+VerifyConsoleIoHandle
+VerifyScripts
+VerifyVersionInfoA
+VerifyVersionInfoW
+VirtualAlloc
+VirtualAllocEx
+VirtualAllocExNuma
+VirtualFree
+VirtualFreeEx
+VirtualLock
+VirtualProtect
+VirtualProtectEx
+VirtualQuery
+VirtualQueryEx
+VirtualUnlock
+WTSGetActiveConsoleSessionId
+WaitCommEvent
+WaitForDebugEvent
+WaitForMultipleObjects
+WaitForMultipleObjectsEx
+WaitForSingleObject
+WaitForSingleObjectEx
+WaitForThreadpoolIoCallbacks
+WaitForThreadpoolTimerCallbacks
+WaitForThreadpoolWaitCallbacks
+WaitForThreadpoolWorkCallbacks
+WaitNamedPipeA
+WaitNamedPipeW
+WaitOnAddress
+WakeAllConditionVariable
+WakeByAddressSingle
+WakeByAddressAll
+WakeConditionVariable
+WerGetFlags
+WerRegisterFile
+WerRegisterFileWorker
+WerRegisterMemoryBlock
+WerRegisterMemoryBlockWorker
+WerRegisterRuntimeExceptionModule
+WerRegisterRuntimeExceptionModuleWorker
+WerSetFlags
+WerUnregisterFile
+WerUnregisterFileWorker
+WerUnregisterMemoryBlock
+WerUnregisterMemoryBlockWorker
+WerUnregisterRuntimeExceptionModule
+WerUnregisterRuntimeExceptionModuleWorker
+WerpCleanupMessageMapping
+WerpGetDebugger
+WerpInitiateRemoteRecovery
+WerpLaunchAeDebug
+WerpNotifyLoadStringResource
+WerpNotifyLoadStringResourceEx
+WerpNotifyLoadStringResourceWorker
+WerpNotifyUseStringResource
+WerpNotifyUseStringResourceWorker
+WerpStringLookup
+WideCharToMultiByte
+WinExec
+Wow64DisableWow64FsRedirection
+Wow64EnableWow64FsRedirection
+Wow64GetThreadContext
+Wow64GetThreadSelectorEntry
+Wow64RevertWow64FsRedirection
+Wow64SetThreadContext
+Wow64SuspendThread
+WriteConsoleA
+WriteConsoleInputA
+WriteConsoleInputVDMA
+WriteConsoleInputVDMW
+WriteConsoleInputW
+WriteConsoleOutputA
+WriteConsoleOutputAttribute
+WriteConsoleOutputCharacterA
+WriteConsoleOutputCharacterW
+WriteConsoleOutputW
+WriteConsoleW
+WriteFile
+WriteFileEx
+WriteFileGather
+WritePrivateProfileSectionA
+WritePrivateProfileSectionW
+WritePrivateProfileStringA
+WritePrivateProfileStringW
+WritePrivateProfileStructA
+WritePrivateProfileStructW
+WriteProcessMemory
+WriteProfileSectionA
+WriteProfileSectionW
+WriteProfileStringA
+WriteProfileStringW
+WriteTapemark
+ZombifyActCtx
+ZombifyActCtxWorker
+__C_specific_handler
+F_ARM32(__chkstk)
+F_X64(__misaligned_access)
+_hread
+_hwrite
+_lclose
+_lcreat
+_llseek
+_local_unwind
+_lopen
+_lread
+_lwrite
+lstrcat
+lstrcatA
+lstrcatW
+lstrcmp
+lstrcmpA
+lstrcmpW
+lstrcmpi
+lstrcmpiA
+lstrcmpiW
+lstrcpy
+lstrcpyA
+lstrcpyW
+lstrcpyn
+lstrcpynA
+lstrcpynW
+lstrlen
+lstrlenA
+lstrlenW
+uaw_lstrcmpW
+uaw_lstrcmpiW
+uaw_lstrlenW
+uaw_wcschr
+uaw_wcscpy
+uaw_wcsicmp
+uaw_wcslen
+uaw_wcsrchr
diff --git a/libc/mingw/misc/__p___argv.c b/libc/mingw/misc/__p___argv.c
new file mode 100644
index 0000000000..8e1f8ed9ac
--- /dev/null
+++ b/libc/mingw/misc/__p___argv.c
@@ -0,0 +1,15 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#include
+
+char ***__cdecl __p___argv(void)
+{
+ return __MINGW_IMP_SYMBOL(__argv);
+}
+
+typedef char ***__cdecl (*_f__p___argv)(void);
+_f__p___argv __MINGW_IMP_SYMBOL(__p___argv) = __p___argv;
diff --git a/libc/mingw/misc/__p__acmdln.c b/libc/mingw/misc/__p__acmdln.c
new file mode 100644
index 0000000000..14e3868e5a
--- /dev/null
+++ b/libc/mingw/misc/__p__acmdln.c
@@ -0,0 +1,18 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#include <_mingw.h>
+
+extern char ** __MINGW_IMP_SYMBOL(_acmdln);
+
+char **__cdecl __p__acmdln(void);
+char **__cdecl __p__acmdln(void)
+{
+ return __MINGW_IMP_SYMBOL(_acmdln);
+}
+
+typedef char **__cdecl (*_f__p__acmdln)(void);
+_f__p__acmdln __MINGW_IMP_SYMBOL(__p__acmdln) = __p__acmdln;
diff --git a/libc/mingw/misc/__p__fmode.c b/libc/mingw/misc/__p__fmode.c
new file mode 100644
index 0000000000..f788a6fcc9
--- /dev/null
+++ b/libc/mingw/misc/__p__fmode.c
@@ -0,0 +1,17 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#include <_mingw.h>
+
+extern int * __MINGW_IMP_SYMBOL(_fmode);
+
+int *__cdecl __p__fmode(void);
+int *__cdecl __p__fmode(void)
+{
+ return __MINGW_IMP_SYMBOL(_fmode);
+}
+
+typeof(__p__fmode) *__MINGW_IMP_SYMBOL(__p__fmode) = __p__fmode;
diff --git a/libc/mingw/misc/__p__wcmdln.c b/libc/mingw/misc/__p__wcmdln.c
new file mode 100644
index 0000000000..f34390468d
--- /dev/null
+++ b/libc/mingw/misc/__p__wcmdln.c
@@ -0,0 +1,18 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#include
+
+extern wchar_t ** __MINGW_IMP_SYMBOL(_wcmdln);
+
+wchar_t **__cdecl __p__wcmdln(void);
+wchar_t **__cdecl __p__wcmdln(void)
+{
+ return __MINGW_IMP_SYMBOL(_wcmdln);
+}
+
+typedef wchar_t **__cdecl (*_f__p__wcmdln)(void);
+_f__p__wcmdln __MINGW_IMP_SYMBOL(__p__wcmdln) = __p__wcmdln;
diff --git a/libc/mingw/misc/_configthreadlocale.c b/libc/mingw/misc/_configthreadlocale.c
new file mode 100644
index 0000000000..cbc60139bf
--- /dev/null
+++ b/libc/mingw/misc/_configthreadlocale.c
@@ -0,0 +1,16 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#include
+
+int __cdecl _configthreadlocale(int flag)
+{
+ /* _ENABLE_PER_THREAD_LOCALE can't work on msvcrt.dll. */
+ return flag == _ENABLE_PER_THREAD_LOCALE ? -1 : _DISABLE_PER_THREAD_LOCALE;
+}
+
+void *__MINGW_IMP_SYMBOL(_configthreadlocale) = _configthreadlocale;
+
diff --git a/libc/mingw/misc/_get_current_locale.c b/libc/mingw/misc/_get_current_locale.c
new file mode 100644
index 0000000000..f5ccc4afc1
--- /dev/null
+++ b/libc/mingw/misc/_get_current_locale.c
@@ -0,0 +1,26 @@
+#include
+#include
+#include
+
+static _locale_t __cdecl init_func(void);
+_locale_t (__cdecl *__MINGW_IMP_SYMBOL(_get_current_locale))(void) = init_func;
+
+static _locale_t __cdecl null_func(void)
+{
+ return NULL;
+}
+
+static _locale_t __cdecl init_func(void)
+{
+ HMODULE msvcrt = __mingw_get_msvcrt_handle();
+ _locale_t (__cdecl *func)(void) = NULL;
+
+ if (msvcrt) {
+ func = (void*)GetProcAddress(msvcrt, "_get_current_locale");
+ }
+
+ if (!func)
+ func = null_func;
+
+ return (__MINGW_IMP_SYMBOL(_get_current_locale) = func)();
+}
diff --git a/libc/mingw/misc/invalid_parameter_handler.c b/libc/mingw/misc/invalid_parameter_handler.c
new file mode 100644
index 0000000000..972b8598cb
--- /dev/null
+++ b/libc/mingw/misc/invalid_parameter_handler.c
@@ -0,0 +1,23 @@
+#define _CRTIMP
+#include
+
+typedef void (__cdecl *_invalid_parameter_handler)(const wchar_t *,const wchar_t *,const wchar_t *,unsigned int,uintptr_t);
+static _invalid_parameter_handler handler;
+
+static _invalid_parameter_handler __cdecl mingw_set_invalid_parameter_handler(_invalid_parameter_handler new_handler)
+{
+ return InterlockedExchangePointer((void**)&handler, new_handler);
+}
+
+_invalid_parameter_handler (__cdecl *__MINGW_IMP_SYMBOL(_set_invalid_parameter_handler))(_invalid_parameter_handler) =
+ mingw_set_invalid_parameter_handler;
+
+static _invalid_parameter_handler __cdecl mingw_get_invalid_parameter_handler(void)
+{
+ return handler;
+}
+
+_invalid_parameter_handler (__cdecl *__MINGW_IMP_SYMBOL(_get_invalid_parameter_handler))(void) = mingw_get_invalid_parameter_handler;
+
+_invalid_parameter_handler __cdecl _get_invalid_parameter_handler(void) __attribute__ ((alias ("mingw_get_invalid_parameter_handler")));
+_invalid_parameter_handler __cdecl _set_invalid_parameter_handler(_invalid_parameter_handler new_handler) __attribute__ ((alias ("mingw_set_invalid_parameter_handler")));
diff --git a/libc/mingw/misc/lc_locale_func.c b/libc/mingw/misc/lc_locale_func.c
new file mode 100644
index 0000000000..e6847ae8b6
--- /dev/null
+++ b/libc/mingw/misc/lc_locale_func.c
@@ -0,0 +1,50 @@
+#define __lc_codepage __dummy_lc_codepage
+#define ___lc_codepage_func __dummy____lc_codepage_func
+#include
+#include
+#include
+
+#undef __lc_codepage
+#undef ___lc_codepage_func
+#include "mb_wc_common.h"
+
+static unsigned int *msvcrt__lc_codepage;
+static unsigned int __cdecl msvcrt___lc_codepage_func(void)
+{
+ return *msvcrt__lc_codepage;
+}
+
+static unsigned int __cdecl setlocale_codepage_hack(void)
+{
+ /* locale :: "lang[_country[.code_page]]" | ".code_page" */
+ const char *cp_str = strchr (setlocale(LC_CTYPE, NULL), '.');
+ return cp_str ? atoi(cp_str + 1) : 0;
+}
+
+static unsigned int __cdecl init_codepage_func(void);
+unsigned int (__cdecl *__MINGW_IMP_SYMBOL(___lc_codepage_func))(void) = init_codepage_func;
+
+unsigned int __cdecl ___lc_codepage_func (void)
+{
+ return __MINGW_IMP_SYMBOL(___lc_codepage_func) ();
+}
+
+static unsigned int __cdecl init_codepage_func(void)
+{
+ HMODULE msvcrt = __mingw_get_msvcrt_handle();
+ unsigned int (__cdecl *func)(void) = NULL;
+
+ if(msvcrt) {
+ func = (void*)GetProcAddress(msvcrt, "___lc_codepage_func");
+ if(!func) {
+ msvcrt__lc_codepage = (unsigned int*)GetProcAddress(msvcrt, "__lc_codepage");
+ if(msvcrt__lc_codepage)
+ func = msvcrt___lc_codepage_func;
+ }
+ }
+
+ if(!func)
+ func = setlocale_codepage_hack;
+
+ return (__MINGW_IMP_SYMBOL(___lc_codepage_func) = func)();
+}
diff --git a/libc/mingw/misc/onexit_table.c b/libc/mingw/misc/onexit_table.c
new file mode 100644
index 0000000000..69f2ea7166
--- /dev/null
+++ b/libc/mingw/misc/onexit_table.c
@@ -0,0 +1,77 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#include
+#include
+
+#define _EXIT_LOCK1 8
+
+void __cdecl _lock (int _File);
+void __cdecl _unlock (int _File);
+
+int __cdecl _initialize_onexit_table(_onexit_table_t *table)
+{
+ if (!table) return -1;
+ table->_first = table->_last = table->_end = NULL;
+ return 0;
+}
+
+int __cdecl _register_onexit_function(_onexit_table_t *table, _onexit_t func)
+{
+ if (!table) return -1;
+
+ _lock(_EXIT_LOCK1);
+
+ if (!table->_first) {
+ table->_first = calloc(32, sizeof(void*));
+ if (!table->_first) {
+ _unlock(_EXIT_LOCK1);
+ return -1;
+ }
+ table->_last = table->_first;
+ table->_end = table->_first + 32;
+ }
+
+ if (table->_last == table->_end) {
+ size_t len = table->_end - table->_first;
+ _PVFV *new_buf = realloc(table->_first, len * sizeof(void*) * 2);
+ if (!new_buf) {
+ _unlock(_EXIT_LOCK1);
+ return -1;
+ }
+ table->_first = new_buf;
+ table->_last = new_buf + len;
+ table->_end = new_buf + len * 2;
+ }
+
+ *table->_last++ = (_PVFV)func;
+ _unlock(_EXIT_LOCK1);
+ return 0;
+}
+
+int __cdecl _execute_onexit_table(_onexit_table_t *table)
+{
+ _PVFV *first, *last;
+
+ _lock(_EXIT_LOCK1);
+ first = table->_first;
+ last = table->_last;
+ _initialize_onexit_table(table);
+ _unlock(_EXIT_LOCK1);
+
+ if (!first) return 0;
+
+ while (--last >= first)
+ if (*last)
+ (**last)();
+
+ free(first);
+ return 0;
+}
+
+typeof(_initialize_onexit_table) *__MINGW_IMP_SYMBOL(_initialize_onexit_table) = _initialize_onexit_table;
+typeof(_register_onexit_function) *__MINGW_IMP_SYMBOL(_register_onexit_function) = _register_onexit_function;
+typeof(_execute_onexit_table) *__MINGW_IMP_SYMBOL(_execute_onexit_table) = _execute_onexit_table;
diff --git a/libc/mingw/misc/output_format.c b/libc/mingw/misc/output_format.c
new file mode 100644
index 0000000000..da037556c9
--- /dev/null
+++ b/libc/mingw/misc/output_format.c
@@ -0,0 +1,62 @@
+#define _get_output_format __dummy__get_output_format
+#define _set_output_format __dummy__set_output_format
+#include
+#include
+
+#undef _get_output_format
+#undef _set_output_format
+
+static unsigned int last_value = 0;
+typedef unsigned int (*f_get_output_format)(void);
+typedef unsigned int (*f_set_output_format)(unsigned int);
+
+static unsigned int init_set_output_format(unsigned int);
+f_set_output_format __MINGW_IMP_SYMBOL(_set_output_format) = init_set_output_format;
+
+unsigned int _set_output_format(unsigned int format);
+unsigned int _set_output_format(unsigned int format)
+{
+ return __MINGW_IMP_SYMBOL(_set_output_format)(format);
+}
+
+static unsigned int fake_set_output_format(unsigned int value)
+{
+ return InterlockedExchange((LONG*)&last_value, value);
+}
+
+static unsigned int init_set_output_format(unsigned int format)
+{
+ f_set_output_format sof;
+
+ sof = (f_set_output_format) GetProcAddress (__mingw_get_msvcrt_handle(), "_set_output_format");
+ if(!sof)
+ sof = fake_set_output_format;
+
+ return (__MINGW_IMP_SYMBOL(_set_output_format) = sof)(format);
+}
+
+
+static unsigned int init_get_output_format(void);
+f_get_output_format __MINGW_IMP_SYMBOL(_get_output_format) = init_get_output_format;
+
+unsigned int _get_output_format(void);
+unsigned int _get_output_format(void)
+{
+ return __MINGW_IMP_SYMBOL(_get_output_format)();
+}
+
+static unsigned int fake_get_output_format(void)
+{
+ return last_value;
+}
+
+static unsigned int init_get_output_format(void)
+{
+ f_get_output_format gof;
+
+ gof = (f_get_output_format) GetProcAddress (__mingw_get_msvcrt_handle(), "_get_output_format");
+ if(!gof)
+ gof = fake_get_output_format;
+
+ return (__MINGW_IMP_SYMBOL(_get_output_format) = gof)();
+}
diff --git a/libc/mingw/misc/purecall.c b/libc/mingw/misc/purecall.c
new file mode 100644
index 0000000000..8c29e67609
--- /dev/null
+++ b/libc/mingw/misc/purecall.c
@@ -0,0 +1,18 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#define _CRTIMP
+#include
+#include
+
+_purecall_handler __cdecl _set_purecall_handler(_purecall_handler handler)
+{
+ static _purecall_handler prev_handler;
+ return InterlockedExchangePointer((void**)&prev_handler, handler);
+}
+
+void *__MINGW_IMP_SYMBOL(_set_purecall_handler) = _set_purecall_handler;
+
diff --git a/libc/mingw/misc/register_tls_atexit.c b/libc/mingw/misc/register_tls_atexit.c
new file mode 100644
index 0000000000..09d9270e4d
--- /dev/null
+++ b/libc/mingw/misc/register_tls_atexit.c
@@ -0,0 +1,29 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#include
+#include
+#include
+#include
+
+static _tls_callback_type callback;
+
+static void run_callback(void)
+{
+ if (callback)
+ callback(NULL, DLL_PROCESS_DETACH, 0);
+ callback = NULL;
+}
+
+void __cdecl _register_thread_local_exe_atexit_callback(_tls_callback_type cb)
+{
+ callback = cb;
+ /* This should guarantee that the callback is called. It won't be run in the
+ * exact right spot as intended to, but it will be run. */
+ atexit(run_callback);
+}
+
+typeof(_register_thread_local_exe_atexit_callback) *__MINGW_IMP_SYMBOL(_register_thread_local_exe_atexit_callback) = _register_thread_local_exe_atexit_callback;
diff --git a/libc/mingw/secapi/_access_s.c b/libc/mingw/secapi/_access_s.c
new file mode 100644
index 0000000000..9be582e878
--- /dev/null
+++ b/libc/mingw/secapi/_access_s.c
@@ -0,0 +1,46 @@
+#include
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_access_s (const char *, int);
+static errno_t __cdecl _stub (const char *, int);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(_access_s))(const char *, int) =
+ _stub;
+
+static errno_t __cdecl
+_stub (const char *s, int m)
+{
+ errno_t __cdecl (*f)(const char *, int) = __MINGW_IMP_SYMBOL(_access_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(const char *, int))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_access_s");
+ if (!f)
+ f = _int_access_s;
+ __MINGW_IMP_SYMBOL(_access_s) = f;
+ }
+ return (*f)(s, m);
+}
+
+errno_t __cdecl
+_access_s (const char *s, int m)
+{
+ return _stub (s, m);
+}
+
+static errno_t __cdecl
+_int_access_s (const char *s, int m)
+{
+ if (!s || (m & ~6) != 0)
+ {
+ _access (NULL, m);
+ return EINVAL;
+ }
+ if (!_access (s, m))
+ return 0;
+ return errno;
+}
diff --git a/libc/mingw/secapi/_cgets_s.c b/libc/mingw/secapi/_cgets_s.c
new file mode 100644
index 0000000000..e70efe7253
--- /dev/null
+++ b/libc/mingw/secapi/_cgets_s.c
@@ -0,0 +1,56 @@
+#define MINGW_HAS_SECURE_API 1
+#include
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_cgets_s (char *, size_t, size_t *);
+static errno_t __cdecl _stub (char *, size_t, size_t *);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(_cgets_s))(char *, size_t, size_t *) =
+ _stub;
+
+static errno_t __cdecl
+_stub (char *s, size_t l, size_t *r_len)
+{
+ errno_t __cdecl (*f)(char *, size_t, size_t *) = __MINGW_IMP_SYMBOL(_cgets_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(char *, size_t, size_t *))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_cgets_s");
+ if (!f)
+ f = _int_cgets_s;
+ __MINGW_IMP_SYMBOL(_cgets_s) = f;
+ }
+ return (*f)(s, l, r_len);
+}
+
+errno_t __cdecl
+_cgets_s (char *s, size_t l, size_t *r_len)
+{
+ return _stub (s, l, r_len);
+}
+
+static errno_t __cdecl
+_int_cgets_s (char *s, size_t l, size_t *r_len)
+{
+ char *h, *p;
+
+ if (s && l)
+ s[0] = 0;
+ if (!s || !l || !r_len)
+ {
+ _cgets (NULL);
+ return EINVAL;
+ }
+ p = (char *) alloca (l + 2);
+ p[0] = l;
+ h = _cgets (s);
+ if (!h)
+ return EINVAL;
+ *r_len = (size_t) p[1];
+ memcpy (s, &p[2], *r_len);
+ return 0;
+}
diff --git a/libc/mingw/secapi/_cgetws_s.c b/libc/mingw/secapi/_cgetws_s.c
new file mode 100644
index 0000000000..dff4187096
--- /dev/null
+++ b/libc/mingw/secapi/_cgetws_s.c
@@ -0,0 +1,56 @@
+#define MINGW_HAS_SECURE_API 1
+#include
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_cgetws_s (wchar_t *, size_t, size_t *);
+static errno_t __cdecl _stub (wchar_t *, size_t, size_t *);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(_cgetws_s))(wchar_t *, size_t, size_t *) =
+ _stub;
+
+static errno_t __cdecl
+_stub (wchar_t *s, size_t l, size_t *r_len)
+{
+ errno_t __cdecl (*f)(wchar_t *, size_t, size_t *) = __MINGW_IMP_SYMBOL(_cgetws_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(wchar_t *, size_t, size_t *))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_cgetws_s");
+ if (!f)
+ f = _int_cgetws_s;
+ __MINGW_IMP_SYMBOL(_cgetws_s) = f;
+ }
+ return (*f)(s, l, r_len);
+}
+
+errno_t __cdecl
+_cgetws_s (wchar_t *s, size_t l, size_t *r_len)
+{
+ return _stub (s, l, r_len);
+}
+
+static errno_t __cdecl
+_int_cgetws_s (wchar_t *s, size_t l, size_t *r_len)
+{
+ wchar_t *h, *p;
+
+ if (s && l)
+ s[0] = 0;
+ if (!s || !l || !r_len)
+ {
+ _cgetws (NULL);
+ return EINVAL;
+ }
+ p = (wchar_t *) alloca ((l + 2) * sizeof (wchar_t));
+ p[0] = l;
+ h = _cgetws (s);
+ if (!h)
+ return EINVAL;
+ *r_len = (size_t) p[1];
+ memcpy (s, &p[2], *r_len);
+ return 0;
+}
diff --git a/libc/mingw/secapi/_chsize_s.c b/libc/mingw/secapi/_chsize_s.c
new file mode 100644
index 0000000000..cd8d066ebb
--- /dev/null
+++ b/libc/mingw/secapi/_chsize_s.c
@@ -0,0 +1,46 @@
+#include
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_chsize_s (int, long long);
+static errno_t __cdecl _stub (int, long long);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(_chsize_s))(int, long long) =
+ _stub;
+
+static errno_t __cdecl
+_stub (int fd, long long sz)
+{
+ errno_t __cdecl (*f)(int, long long) = __MINGW_IMP_SYMBOL(_chsize_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(int, long long))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_chsize_s");
+ if (!f)
+ f = _int_chsize_s;
+ __MINGW_IMP_SYMBOL(_chsize_s) = f;
+ }
+ return (*f)(fd, sz);
+}
+
+errno_t __cdecl
+_chsize_s (int fd, long long sz)
+{
+ return _stub (fd, sz);
+}
+
+static errno_t __cdecl
+_int_chsize_s (int fd, long long sz)
+{
+ if (sz > 0x7fffffffll)
+ {
+ /* We can't set file bigger as 2GB, so return EACCES. */
+ return (errno = EACCES);
+ }
+ if (!_chsize (fd, sz))
+ return 0;
+ return errno;
+}
diff --git a/libc/mingw/secapi/_controlfp_s.c b/libc/mingw/secapi/_controlfp_s.c
new file mode 100644
index 0000000000..32be17cfb8
--- /dev/null
+++ b/libc/mingw/secapi/_controlfp_s.c
@@ -0,0 +1,56 @@
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _stub(
+ unsigned int *currentControl,
+ unsigned int newControl,
+ unsigned int mask
+);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(_controlfp_s))(unsigned int *, unsigned int, unsigned int) = _stub;
+
+errno_t __cdecl _controlfp_s(
+ unsigned int *currentControl,
+ unsigned int newControl,
+ unsigned int mask
+){
+ return __MINGW_IMP_SYMBOL(_controlfp_s)(currentControl,newControl,mask);
+}
+
+static const unsigned int allflags = _MCW_DN | _MCW_EM | _MCW_IC | _MCW_RC | _MCW_PC;
+static errno_t __cdecl _int_controlfp_s(
+ unsigned int *currentControl,
+ unsigned int newControl,
+ unsigned int mask
+){
+ unsigned int cont;
+ if(!(newControl & mask & ~allflags)){
+ if (currentControl) *currentControl = _controlfp( 0, 0 );
+ return EINVAL;
+ }
+ cont = _controlfp( newControl, mask );
+ if(currentControl) *currentControl = cont;
+ return 0;
+}
+
+static errno_t __cdecl _stub (
+ unsigned int *currentControl,
+ unsigned int newControl,
+ unsigned int mask
+)
+{
+ errno_t __cdecl (*f)(unsigned int *, unsigned int, unsigned int) = __MINGW_IMP_SYMBOL(_controlfp_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(unsigned int *, unsigned int, unsigned int))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_controlfp_s");
+ if (!f)
+ f = _int_controlfp_s;
+ __MINGW_IMP_SYMBOL(_controlfp_s) = f;
+ }
+ return (*f)(currentControl, newControl, mask);
+}
+
diff --git a/libc/mingw/secapi/_cprintf_s.c b/libc/mingw/secapi/_cprintf_s.c
new file mode 100644
index 0000000000..36ea582d41
--- /dev/null
+++ b/libc/mingw/secapi/_cprintf_s.c
@@ -0,0 +1,21 @@
+#define MINGW_HAS_SECURE_API 1
+#include
+#include
+#include
+#include
+#include
+
+int __cdecl (*__MINGW_IMP_SYMBOL(_cprintf_s))(const char *,...) =
+ _cprintf_s;
+
+int __cdecl
+_cprintf_s (const char *s, ...)
+{
+ va_list argp;
+ int r;
+
+ va_start (argp, s);
+ r = _vcprintf_s (s, argp);
+ va_end (argp);
+ return r;
+}
diff --git a/libc/mingw/secapi/_cprintf_s_l.c b/libc/mingw/secapi/_cprintf_s_l.c
new file mode 100644
index 0000000000..316ca86ef3
--- /dev/null
+++ b/libc/mingw/secapi/_cprintf_s_l.c
@@ -0,0 +1,21 @@
+#define MINGW_HAS_SECURE_API 1
+#include
+#include
+#include
+#include
+#include
+
+int __cdecl (*__MINGW_IMP_SYMBOL(_cprintf_s_l))(const char *, _locale_t, ...) =
+ _cprintf_s_l;
+
+int __cdecl
+_cprintf_s_l (const char *s, _locale_t loc, ...)
+{
+ va_list argp;
+ int r;
+
+ va_start (argp, loc);
+ r = _vcprintf_s_l (s, loc, argp);
+ va_end (argp);
+ return r;
+}
diff --git a/libc/mingw/secapi/_ctime32_s.c b/libc/mingw/secapi/_ctime32_s.c
new file mode 100644
index 0000000000..c59ccfc190
--- /dev/null
+++ b/libc/mingw/secapi/_ctime32_s.c
@@ -0,0 +1,56 @@
+#include
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_ctime32_s (char *, size_t, const __time32_t *);
+static errno_t __cdecl _stub (char *, size_t, const __time32_t *);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(_ctime32_s))(char *, size_t, const __time32_t *) =
+ _stub;
+
+static errno_t __cdecl
+_stub (char *d, size_t dn, const __time32_t *pt)
+{
+ errno_t __cdecl (*f)(char *, size_t, const __time32_t *) = __MINGW_IMP_SYMBOL(_ctime32_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(char *, size_t, const __time32_t *))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_ctime32_s");
+ if (!f)
+ f = _int_ctime32_s;
+ __MINGW_IMP_SYMBOL(_ctime32_s) = f;
+ }
+ return (*f)(d, dn, pt);
+}
+
+errno_t __cdecl
+_ctime32_s (char *d, size_t dn, const __time32_t *pt)
+{
+ return _stub (d, dn, pt);
+}
+
+static errno_t __cdecl
+_int_ctime32_s (char *d, size_t dn, const __time32_t *pt)
+{
+ struct tm ltm;
+ errno_t e;
+
+ if (!d || !dn)
+ {
+ errno = EINVAL;
+ return EINVAL;
+ }
+ d[0] = 0;
+ if (!pt)
+ {
+ errno = EINVAL;
+ return EINVAL;
+ }
+
+ if ((e = _localtime32_s (<m, pt)) != 0)
+ return e;
+ return asctime_s (d, dn, <m);
+}
diff --git a/libc/mingw/secapi/_ctime64_s.c b/libc/mingw/secapi/_ctime64_s.c
new file mode 100644
index 0000000000..833d14a0aa
--- /dev/null
+++ b/libc/mingw/secapi/_ctime64_s.c
@@ -0,0 +1,56 @@
+#include
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_ctime64_s (char *, size_t, const __time64_t *);
+static errno_t __cdecl _stub (char *, size_t, const __time64_t *);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(_ctime64_s))(char *, size_t, const __time64_t *) =
+ _stub;
+
+static errno_t __cdecl
+_stub (char *d, size_t dn, const __time64_t *pt)
+{
+ errno_t __cdecl (*f)(char *, size_t, const __time64_t *) = __MINGW_IMP_SYMBOL(_ctime64_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(char *, size_t, const __time64_t *))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_ctime64_s");
+ if (!f)
+ f = _int_ctime64_s;
+ __MINGW_IMP_SYMBOL(_ctime64_s) = f;
+ }
+ return (*f)(d, dn, pt);
+}
+
+errno_t __cdecl
+_ctime64_s (char *d, size_t dn, const __time64_t *pt)
+{
+ return _stub (d, dn, pt);
+}
+
+static errno_t __cdecl
+_int_ctime64_s (char *d, size_t dn, const __time64_t *pt)
+{
+ struct tm ltm;
+ errno_t e;
+
+ if (!d || !dn)
+ {
+ errno = EINVAL;
+ return EINVAL;
+ }
+ d[0] = 0;
+ if (!pt)
+ {
+ errno = EINVAL;
+ return EINVAL;
+ }
+
+ if ((e = _localtime64_s (<m, pt)) != 0)
+ return e;
+ return asctime_s (d, dn, <m);
+}
diff --git a/libc/mingw/secapi/_cwprintf_s.c b/libc/mingw/secapi/_cwprintf_s.c
new file mode 100644
index 0000000000..b5ce0ab940
--- /dev/null
+++ b/libc/mingw/secapi/_cwprintf_s.c
@@ -0,0 +1,21 @@
+#define MINGW_HAS_SECURE_API 1
+#include
+#include
+#include
+#include
+#include
+
+int __cdecl (*__MINGW_IMP_SYMBOL(_cwprintf_s))(const wchar_t *,...) =
+ _cwprintf_s;
+
+int __cdecl
+_cwprintf_s (const wchar_t *s, ...)
+{
+ va_list argp;
+ int r;
+
+ va_start (argp, s);
+ r = _vcwprintf_s (s, argp);
+ va_end (argp);
+ return r;
+}
diff --git a/libc/mingw/secapi/_cwprintf_s_l.c b/libc/mingw/secapi/_cwprintf_s_l.c
new file mode 100644
index 0000000000..cadd55d022
--- /dev/null
+++ b/libc/mingw/secapi/_cwprintf_s_l.c
@@ -0,0 +1,21 @@
+#define MINGW_HAS_SECURE_API 1
+#include
+#include
+#include
+#include
+#include
+
+int __cdecl (*__MINGW_IMP_SYMBOL(_cwprintf_s_l))(const wchar_t *, _locale_t, ...) =
+ _cwprintf_s_l;
+
+int __cdecl
+_cwprintf_s_l (const wchar_t *s, _locale_t loc, ...)
+{
+ va_list argp;
+ int r;
+
+ va_start (argp, loc);
+ r = _vcwprintf_s_l (s, loc, argp);
+ va_end (argp);
+ return r;
+}
diff --git a/libc/mingw/secapi/_gmtime32_s.c b/libc/mingw/secapi/_gmtime32_s.c
new file mode 100644
index 0000000000..7139c24df1
--- /dev/null
+++ b/libc/mingw/secapi/_gmtime32_s.c
@@ -0,0 +1,51 @@
+#include
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_gmtime32_s (struct tm *, const __time32_t *);
+static errno_t __cdecl _stub (struct tm *, const __time32_t *);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(_gmtime32_s))(struct tm *, const __time32_t *) =
+ _stub;
+
+static errno_t __cdecl
+_stub (struct tm *ptm, const __time32_t *pt)
+{
+ errno_t __cdecl (*f)(struct tm *, const __time32_t *) = __MINGW_IMP_SYMBOL(_gmtime32_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(struct tm *, const __time32_t *))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_gmtime32_s");
+ if (!f)
+ f = _int_gmtime32_s;
+ __MINGW_IMP_SYMBOL(_gmtime32_s) = f;
+ }
+ return (*f)(ptm, pt);
+}
+
+errno_t __cdecl
+_gmtime32_s (struct tm *ptm, const __time32_t *pt)
+{
+ return _stub (ptm, pt);
+}
+
+static errno_t __cdecl
+_int_gmtime32_s (struct tm *ptm, const __time32_t *pt)
+{
+ struct tm *ltm;
+
+ if (ptm)
+ memset (ptm, 0xff, sizeof (*ptm));
+ if (!ptm || !pt)
+ {
+ errno = EINVAL;
+ return EINVAL;
+ }
+ if ((ltm = _gmtime32 (pt)) == NULL)
+ return errno;
+ *ptm = *ltm;
+ return 0;
+}
diff --git a/libc/mingw/secapi/_gmtime64_s.c b/libc/mingw/secapi/_gmtime64_s.c
new file mode 100644
index 0000000000..c4ca154684
--- /dev/null
+++ b/libc/mingw/secapi/_gmtime64_s.c
@@ -0,0 +1,51 @@
+#include
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_gmtime64_s (struct tm *, const __time64_t *);
+static errno_t __cdecl _stub (struct tm *, const __time64_t *);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(_gmtime64_s))(struct tm *, const __time64_t *) =
+ _stub;
+
+static errno_t __cdecl
+_stub (struct tm *ptm, const __time64_t *pt)
+{
+ errno_t __cdecl (*f)(struct tm *, const __time64_t *) = __MINGW_IMP_SYMBOL(_gmtime64_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(struct tm *, const __time64_t *))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_gmtime64_s");
+ if (!f)
+ f = _int_gmtime64_s;
+ __MINGW_IMP_SYMBOL(_gmtime64_s) = f;
+ }
+ return (*f)(ptm, pt);
+}
+
+errno_t __cdecl
+_gmtime64_s (struct tm *ptm, const __time64_t *pt)
+{
+ return _stub (ptm, pt);
+}
+
+static errno_t __cdecl
+_int_gmtime64_s (struct tm *ptm, const __time64_t *pt)
+{
+ struct tm *ltm;
+
+ if (ptm)
+ memset (ptm, 0xff, sizeof (*ptm));
+ if (!ptm || !pt)
+ {
+ errno = EINVAL;
+ return EINVAL;
+ }
+ if ((ltm = _gmtime64 (pt)) == NULL)
+ return errno;
+ *ptm = *ltm;
+ return 0;
+}
diff --git a/libc/mingw/secapi/_localtime32_s.c b/libc/mingw/secapi/_localtime32_s.c
new file mode 100644
index 0000000000..c8a62f6cce
--- /dev/null
+++ b/libc/mingw/secapi/_localtime32_s.c
@@ -0,0 +1,51 @@
+#include
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_localtime32_s (struct tm *, const __time32_t *);
+static errno_t __cdecl _stub (struct tm *, const __time32_t *);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(_localtime32_s))(struct tm *, const __time32_t *) =
+ _stub;
+
+static errno_t __cdecl
+_stub (struct tm *ptm, const __time32_t *pt)
+{
+ errno_t __cdecl (*f)(struct tm *, const __time32_t *) = __MINGW_IMP_SYMBOL(_localtime32_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(struct tm *, const __time32_t *))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_localtime32_s");
+ if (!f)
+ f = _int_localtime32_s;
+ __MINGW_IMP_SYMBOL(_localtime32_s) = f;
+ }
+ return (*f)(ptm, pt);
+}
+
+errno_t __cdecl
+_localtime32_s (struct tm *ptm, const __time32_t *pt)
+{
+ return _stub (ptm, pt);
+}
+
+static errno_t __cdecl
+_int_localtime32_s (struct tm *ptm, const __time32_t *pt)
+{
+ struct tm *ltm;
+
+ if (ptm)
+ memset (ptm, 0xff, sizeof (*ptm));
+ if (!ptm || !pt)
+ {
+ errno = EINVAL;
+ return EINVAL;
+ }
+ if ((ltm = _localtime32 (pt)) == NULL)
+ return errno;
+ *ptm = *ltm;
+ return 0;
+}
diff --git a/libc/mingw/secapi/_localtime64_s.c b/libc/mingw/secapi/_localtime64_s.c
new file mode 100644
index 0000000000..bff0868ba1
--- /dev/null
+++ b/libc/mingw/secapi/_localtime64_s.c
@@ -0,0 +1,51 @@
+#include
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_localtime64_s (struct tm *, const __time64_t *);
+static errno_t __cdecl _stub (struct tm *, const __time64_t *);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(_localtime64_s))(struct tm *, const __time64_t *) =
+ _stub;
+
+static errno_t __cdecl
+_stub (struct tm *ptm, const __time64_t *pt)
+{
+ errno_t __cdecl (*f)(struct tm *, const __time64_t *) = __MINGW_IMP_SYMBOL(_localtime64_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(struct tm *, const __time64_t *))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_localtime64_s");
+ if (!f)
+ f = _int_localtime64_s;
+ __MINGW_IMP_SYMBOL(_localtime64_s) = f;
+ }
+ return (*f)(ptm, pt);
+}
+
+errno_t __cdecl
+_localtime64_s (struct tm *ptm, const __time64_t *pt)
+{
+ return _stub (ptm, pt);
+}
+
+static errno_t __cdecl
+_int_localtime64_s (struct tm *ptm, const __time64_t *pt)
+{
+ struct tm *ltm;
+
+ if (ptm)
+ memset (ptm, 0xff, sizeof (*ptm));
+ if (!ptm || !pt)
+ {
+ errno = EINVAL;
+ return EINVAL;
+ }
+ if ((ltm = _localtime64 (pt)) == NULL)
+ return errno;
+ *ptm = *ltm;
+ return 0;
+}
diff --git a/libc/mingw/secapi/_mktemp_s.c b/libc/mingw/secapi/_mktemp_s.c
new file mode 100644
index 0000000000..01484d9384
--- /dev/null
+++ b/libc/mingw/secapi/_mktemp_s.c
@@ -0,0 +1,54 @@
+#include
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_mktemp_s (char *, size_t);
+static errno_t __cdecl _stub (char *, size_t);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(_mktemp_s))(char *, size_t) =
+ _stub;
+
+static errno_t __cdecl
+_stub (char *d, size_t dn)
+{
+ errno_t __cdecl (*f)(char *, size_t) = __MINGW_IMP_SYMBOL(_mktemp_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(char *, size_t))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_mktemp_s");
+ if (!f)
+ f = _int_mktemp_s;
+ __MINGW_IMP_SYMBOL(_mktemp_s) = f;
+ }
+ return (*f)(d, dn);
+}
+
+errno_t __cdecl
+_mktemp_s (char *d, size_t dn)
+{
+ return _stub (d, dn);
+}
+
+static errno_t __cdecl
+_int_mktemp_s (char *d, size_t dn)
+{
+ size_t sz;
+ if (!d || !dn)
+ {
+ _mktemp (NULL);
+ return EINVAL;
+ }
+ sz = strnlen (d, dn);
+ if (sz >= dn || sz < 6)
+ {
+ d[0] = 0;
+ _mktemp (NULL);
+ return EINVAL;
+ }
+ if (_mktemp (d) != NULL)
+ return 0;
+ return errno;
+}
diff --git a/libc/mingw/secapi/_sopen_s.c b/libc/mingw/secapi/_sopen_s.c
new file mode 100644
index 0000000000..b4f8f6af5b
--- /dev/null
+++ b/libc/mingw/secapi/_sopen_s.c
@@ -0,0 +1,42 @@
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_sopen_s(int *, const char *, int, int, int);
+static errno_t __cdecl _stub(int *, const char *, int, int, int);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(_sopen_s))(int *, const char *, int, int, int) = _stub;
+
+static errno_t __cdecl
+_stub (int* pfh, const char *filename, int oflag, int shflag, int pmode)
+{
+ errno_t __cdecl (*f)(int *, const char *, int, int, int) = __MINGW_IMP_SYMBOL(_sopen_s);
+
+ if (f == _stub) {
+ f = (errno_t __cdecl (*)(int *, const char *, int, int, int))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_sopen_s");
+ if (f == NULL)
+ f = _int_sopen_s;
+ __MINGW_IMP_SYMBOL(_sopen_s) = f;
+ }
+
+ return (*f)(pfh, filename, oflag, shflag, pmode);
+}
+
+static errno_t __cdecl _int_sopen_s(int* pfh, const char *filename, int oflag, int shflag, int pmode)
+{
+ if (pfh == NULL || filename == NULL) {
+ if (pfh != NULL) *pfh = -1;
+ errno = EINVAL;
+ return EINVAL;
+ }
+
+ *pfh = _sopen(filename, oflag, shflag, pmode);
+ return errno;
+}
+
+errno_t __cdecl _sopen_s(int* pfh, const char *filename, int oflag, int shflag, int pmode)
+{
+ return _stub (pfh, filename, oflag, shflag, pmode);
+}
diff --git a/libc/mingw/secapi/_strdate_s.c b/libc/mingw/secapi/_strdate_s.c
new file mode 100644
index 0000000000..b62dec7521
--- /dev/null
+++ b/libc/mingw/secapi/_strdate_s.c
@@ -0,0 +1,68 @@
+#include
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_strdate_s (char *, size_t);
+static errno_t __cdecl _stub (char *, size_t);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(_strdate_s))(char *, size_t) =
+ _stub;
+
+static errno_t __cdecl
+_stub (char *d, size_t dn)
+{
+ errno_t __cdecl (*f)(char *, size_t) = __MINGW_IMP_SYMBOL(_strdate_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(char *, size_t))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_strdate_s");
+ if (!f)
+ f = _int_strdate_s;
+ __MINGW_IMP_SYMBOL(_strdate_s) = f;
+ }
+ return (*f)(d, dn);
+}
+
+errno_t __cdecl
+_strdate_s (char *d, size_t dn)
+{
+ return _stub (d, dn);
+}
+
+static errno_t __cdecl
+_int_strdate_s (char *d, size_t dn)
+{
+ SYSTEMTIME dt;
+
+ if (!d || !dn)
+ {
+ errno = EINVAL;
+ return EINVAL;
+ }
+
+ d[0] = 0;
+
+ if (dn < 9)
+ {
+ errno = ERANGE;
+ return ERANGE;
+ }
+
+ GetLocalTime (&dt);
+ dt.wYear %= 100;
+
+ d[0] = (char) (dt.wMonth / 10 + '0');
+ d[1] = (char) (dt.wMonth % 10 + '0');
+ d[2] = '/';
+ d[3] = (char) (dt.wDay / 10 + '0');
+ d[4] = (char) (dt.wDay % 10 + '0');
+ d[5] = '/';
+ d[6] = (char) (dt.wYear / 10 + '0');
+ d[7] = (char) (dt.wYear % 10 + '0');
+ d[8] = 0;
+
+ return 0;
+}
diff --git a/libc/mingw/secapi/_strtime_s.c b/libc/mingw/secapi/_strtime_s.c
new file mode 100644
index 0000000000..b66e3f95a8
--- /dev/null
+++ b/libc/mingw/secapi/_strtime_s.c
@@ -0,0 +1,72 @@
+#include
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_strtime_s (char *, size_t);
+static errno_t __cdecl _stub (char *, size_t);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(_strtime_s))(char *, size_t) =
+ _stub;
+
+static errno_t __cdecl
+_stub (char *d, size_t dn)
+{
+ errno_t __cdecl (*f)(char *, size_t) = __MINGW_IMP_SYMBOL(_strtime_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(char *, size_t))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_strtime_s");
+ if (!f)
+ f = _int_strtime_s;
+ __MINGW_IMP_SYMBOL(_strtime_s) = f;
+ }
+ return (*f)(d, dn);
+}
+
+errno_t __cdecl
+_strtime_s (char *d, size_t dn)
+{
+ return _stub (d, dn);
+}
+
+static errno_t __cdecl
+_int_strtime_s (char *d, size_t dn)
+{
+ SYSTEMTIME dt;
+ int hours, minutes, seconds;
+
+ if (!d || !dn)
+ {
+ errno = EINVAL;
+ return EINVAL;
+ }
+
+ d[0] = 0;
+
+ if (dn < 9)
+ {
+ errno = ERANGE;
+ return ERANGE;
+ }
+
+ GetLocalTime (&dt);
+ dt.wYear %= 100;
+
+ hours = dt.wHour;
+ minutes = dt.wMinute;
+ seconds = dt.wSecond;
+
+ d[2] = d[5] = ':';
+ d[0] = (char) (hours / 10 + '0');
+ d[1] = (char) (hours % 10 + '0');
+ d[3] = (char) (minutes / 10 + '0');
+ d[4] = (char) (minutes % 10 + '0');
+ d[6] = (char) (seconds / 10 + '0');
+ d[7] = (char) (seconds % 10 + '0');
+ d[8] = 0;
+
+ return 0;
+}
diff --git a/libc/mingw/secapi/_umask_s.c b/libc/mingw/secapi/_umask_s.c
new file mode 100644
index 0000000000..75e8ddbb46
--- /dev/null
+++ b/libc/mingw/secapi/_umask_s.c
@@ -0,0 +1,45 @@
+#include
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_umask_s (int, int *);
+static errno_t __cdecl _stub (int, int *);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(_umask_s))(int, int *) =
+ _stub;
+
+static errno_t __cdecl
+_stub (int m, int *pold)
+{
+ errno_t __cdecl (*f)(int, int *) = __MINGW_IMP_SYMBOL(_umask_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(int, int *))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_umask_s");
+ if (!f)
+ f = _int_umask_s;
+ __MINGW_IMP_SYMBOL(_umask_s) = f;
+ }
+ return (*f)(m, pold);
+}
+
+errno_t __cdecl
+_umask_s (int m, int *pold)
+{
+ return _stub (m, pold);
+}
+
+static errno_t __cdecl
+_int_umask_s (int m, int *pold)
+{
+ if (!pold)
+ {
+ errno = EINVAL;
+ return EINVAL;
+ }
+ *pold = _umask (m);
+ return 0;
+}
diff --git a/libc/mingw/secapi/_vcprintf_s.c b/libc/mingw/secapi/_vcprintf_s.c
new file mode 100644
index 0000000000..b512bb21a9
--- /dev/null
+++ b/libc/mingw/secapi/_vcprintf_s.c
@@ -0,0 +1,40 @@
+#define MINGW_HAS_SECURE_API 1
+#include
+#include
+#include
+#include
+#include
+
+static int __cdecl _int_vcprintf_s (const char *, va_list);
+static int __cdecl _stub (const char *, va_list);
+
+int __cdecl (*__MINGW_IMP_SYMBOL(_vcprintf_s))(const char *, va_list) =
+ _stub;
+
+static int __cdecl
+_stub (const char *s, va_list argp)
+{
+ int __cdecl (*f)(const char *, va_list) = __MINGW_IMP_SYMBOL(_vcprintf_s);
+
+ if (f == _stub)
+ {
+ f = (int __cdecl (*)(const char *, va_list))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_vcprintf_s");
+ if (!f)
+ f = _int_vcprintf_s;
+ __MINGW_IMP_SYMBOL(_vcprintf_s) = f;
+ }
+ return (*f)(s, argp);
+}
+
+int __cdecl
+_vcprintf_s (const char *s, va_list argp)
+{
+ return _stub (s, argp);
+}
+
+static int __cdecl
+_int_vcprintf_s (const char *s, va_list argp)
+{
+ return _vcprintf (s, argp);
+}
diff --git a/libc/mingw/secapi/_vcprintf_s_l.c b/libc/mingw/secapi/_vcprintf_s_l.c
new file mode 100644
index 0000000000..e4c86ceb96
--- /dev/null
+++ b/libc/mingw/secapi/_vcprintf_s_l.c
@@ -0,0 +1,40 @@
+#define MINGW_HAS_SECURE_API 1
+#include
+#include
+#include
+#include
+#include
+
+static int __cdecl _int_vcprintf_s_l (const char *, _locale_t, va_list);
+static int __cdecl _stub (const char *, _locale_t, va_list);
+
+int __cdecl (*__MINGW_IMP_SYMBOL(_vcprintf_s_l))(const char *, _locale_t, va_list) =
+ _stub;
+
+static int __cdecl
+_stub (const char *s, _locale_t loc, va_list argp)
+{
+ int __cdecl (*f)(const char *, _locale_t, va_list) = __MINGW_IMP_SYMBOL(_vcprintf_s_l);
+
+ if (f == _stub)
+ {
+ f = (int __cdecl (*)(const char *, _locale_t, va_list))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_vcprintf_s_l");
+ if (!f)
+ f = _int_vcprintf_s_l;
+ __MINGW_IMP_SYMBOL(_vcprintf_s_l) = f;
+ }
+ return (*f)(s, loc, argp);
+}
+
+int __cdecl
+_vcprintf_s_l (const char *s, _locale_t loc, va_list argp)
+{
+ return _stub (s, loc, argp);
+}
+
+static int __cdecl
+_int_vcprintf_s_l (const char *s, _locale_t loc, va_list argp)
+{
+ return _vcprintf_l (s, loc, argp);
+}
diff --git a/libc/mingw/secapi/_vcwprintf_s.c b/libc/mingw/secapi/_vcwprintf_s.c
new file mode 100644
index 0000000000..e6badb1ecf
--- /dev/null
+++ b/libc/mingw/secapi/_vcwprintf_s.c
@@ -0,0 +1,40 @@
+#define MINGW_HAS_SECURE_API 1
+#include
+#include
+#include
+#include
+#include
+
+static int __cdecl _int_vcwprintf_s (const wchar_t *, va_list);
+static int __cdecl _stub (const wchar_t *, va_list);
+
+int __cdecl (*__MINGW_IMP_SYMBOL(_vcwprintf_s))(const wchar_t *, va_list) =
+ _stub;
+
+static int __cdecl
+_stub (const wchar_t *s, va_list argp)
+{
+ int __cdecl (*f)(const wchar_t *, va_list) = __MINGW_IMP_SYMBOL(_vcwprintf_s);
+
+ if (f == _stub)
+ {
+ f = (int __cdecl (*)(const wchar_t *, va_list))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_vcwprintf_s");
+ if (!f)
+ f = _int_vcwprintf_s;
+ __MINGW_IMP_SYMBOL(_vcwprintf_s) = f;
+ }
+ return (*f)(s, argp);
+}
+
+int __cdecl
+_vcwprintf_s (const wchar_t *s, va_list argp)
+{
+ return _stub (s, argp);
+}
+
+static int __cdecl
+_int_vcwprintf_s (const wchar_t *s, va_list argp)
+{
+ return _vcwprintf (s, argp);
+}
diff --git a/libc/mingw/secapi/_vcwprintf_s_l.c b/libc/mingw/secapi/_vcwprintf_s_l.c
new file mode 100644
index 0000000000..2ce1deffdf
--- /dev/null
+++ b/libc/mingw/secapi/_vcwprintf_s_l.c
@@ -0,0 +1,40 @@
+#define MINGW_HAS_SECURE_API 1
+#include
+#include
+#include
+#include
+#include
+
+static int __cdecl _int_vcwprintf_s_l (const wchar_t *, _locale_t, va_list);
+static int __cdecl _stub (const wchar_t *, _locale_t, va_list);
+
+int __cdecl (*__MINGW_IMP_SYMBOL(_vcwprintf_s_l))(const wchar_t *, _locale_t, va_list) =
+ _stub;
+
+static int __cdecl
+_stub (const wchar_t *s, _locale_t loc, va_list argp)
+{
+ int __cdecl (*f)(const wchar_t *, _locale_t, va_list) = __MINGW_IMP_SYMBOL(_vcwprintf_s_l);
+
+ if (f == _stub)
+ {
+ f = (int __cdecl (*)(const wchar_t *, _locale_t, va_list))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_vcwprintf_s_l");
+ if (!f)
+ f = _int_vcwprintf_s_l;
+ __MINGW_IMP_SYMBOL(_vcwprintf_s_l) = f;
+ }
+ return (*f)(s, loc, argp);
+}
+
+int __cdecl
+_vcwprintf_s_l (const wchar_t *s, _locale_t loc, va_list argp)
+{
+ return _stub (s, loc, argp);
+}
+
+static int __cdecl
+_int_vcwprintf_s_l (const wchar_t *s, _locale_t loc, va_list argp)
+{
+ return _vcwprintf_l (s, loc, argp);
+}
diff --git a/libc/mingw/secapi/_vscprintf_p.c b/libc/mingw/secapi/_vscprintf_p.c
new file mode 100644
index 0000000000..c7ee3cc87f
--- /dev/null
+++ b/libc/mingw/secapi/_vscprintf_p.c
@@ -0,0 +1,9 @@
+#define MINGW_HAS_SECURE_API 1
+#include
+
+int __cdecl _vscprintf_p(const char *format, va_list arglist)
+{
+ return _vscprintf_p_l(format, NULL, arglist);
+}
+
+int __cdecl (*__MINGW_IMP_SYMBOL(_vscprintf_p))(const char *, va_list) = _vscprintf_p;
diff --git a/libc/mingw/secapi/_vscwprintf_p.c b/libc/mingw/secapi/_vscwprintf_p.c
new file mode 100644
index 0000000000..498bc1cf48
--- /dev/null
+++ b/libc/mingw/secapi/_vscwprintf_p.c
@@ -0,0 +1,9 @@
+#define MINGW_HAS_SECURE_API 1
+#include
+
+int __cdecl _vscwprintf_p(const wchar_t *format, va_list arglist)
+{
+ return _vscwprintf_p_l(format, NULL, arglist);
+}
+
+int __cdecl (*__MINGW_IMP_SYMBOL(_vscwprintf_p))(const wchar_t *, va_list) = _vscwprintf_p;
diff --git a/libc/mingw/secapi/_vswprintf_p.c b/libc/mingw/secapi/_vswprintf_p.c
new file mode 100644
index 0000000000..4823c81d69
--- /dev/null
+++ b/libc/mingw/secapi/_vswprintf_p.c
@@ -0,0 +1,9 @@
+#define MINGW_HAS_SECURE_API 1
+#include
+
+int __cdecl _vswprintf_p(wchar_t *_DstBuf, size_t _MaxCount, const wchar_t *_Format, va_list _ArgList)
+{
+ return _vswprintf_p_l(_DstBuf, _MaxCount, _Format, NULL, _ArgList);
+}
+
+int __cdecl (*__MINGW_IMP_SYMBOL(_vswprintf_p))(wchar_t*,size_t,const wchar_t*,va_list) = _vswprintf_p;
diff --git a/libc/mingw/secapi/_waccess_s.c b/libc/mingw/secapi/_waccess_s.c
new file mode 100644
index 0000000000..4ca83f4dd4
--- /dev/null
+++ b/libc/mingw/secapi/_waccess_s.c
@@ -0,0 +1,47 @@
+#define MINGW_HAS_SECURE_API 1
+#include
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_waccess_s (const wchar_t *, int);
+static errno_t __cdecl _stub (const wchar_t *, int);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(_waccess_s))(const wchar_t *, int) =
+ _stub;
+
+static errno_t __cdecl
+_stub (const wchar_t *s, int m)
+{
+ errno_t __cdecl (*f)(const wchar_t *, int) = __MINGW_IMP_SYMBOL(_waccess_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(const wchar_t *, int))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_waccess_s");
+ if (!f)
+ f = _int_waccess_s;
+ __MINGW_IMP_SYMBOL(_waccess_s) = f;
+ }
+ return (*f)(s, m);
+}
+
+errno_t __cdecl
+_waccess_s (const wchar_t *s, int m)
+{
+ return _stub (s, m);
+}
+
+static errno_t __cdecl
+_int_waccess_s (const wchar_t *s, int m)
+{
+ if (!s || (m & ~6) != 0)
+ {
+ _waccess (NULL, m);
+ return EINVAL;
+ }
+ if (!_waccess (s, m))
+ return 0;
+ return errno;
+}
diff --git a/libc/mingw/secapi/_wasctime_s.c b/libc/mingw/secapi/_wasctime_s.c
new file mode 100644
index 0000000000..6b414ee9dd
--- /dev/null
+++ b/libc/mingw/secapi/_wasctime_s.c
@@ -0,0 +1,52 @@
+#include
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_wasctime_s (wchar_t *, size_t, const struct tm *);
+static errno_t __cdecl _stub (wchar_t *, size_t, const struct tm *);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(_wasctime_s))(wchar_t *, size_t, const struct tm *) =
+ _stub;
+
+static errno_t __cdecl
+_stub (wchar_t *d, size_t dn, const struct tm *pt)
+{
+ errno_t __cdecl (*f)(wchar_t *, size_t, const struct tm *) = __MINGW_IMP_SYMBOL(_wasctime_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(wchar_t *, size_t, const struct tm *))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_wasctime_s");
+ if (!f)
+ f = _int_wasctime_s;
+ __MINGW_IMP_SYMBOL(_wasctime_s) = f;
+ }
+ return (*f)(d, dn, pt);
+}
+
+errno_t __cdecl
+_wasctime_s (wchar_t *d, size_t dn, const struct tm *pt)
+{
+ return _stub (d, dn, pt);
+}
+
+static errno_t __cdecl
+_int_wasctime_s (wchar_t *d, size_t dn, const struct tm *pt)
+{
+ wchar_t *tmp;
+ size_t i;
+
+ if (d && dn)
+ d[0] = 0;
+ if (!d || dn < 26 || !pt || (tmp = _wasctime (pt)) == NULL)
+ {
+ errno = EINVAL;
+ return EINVAL;
+ }
+ for (i = 0; tmp[i] != 0; i++)
+ d[i] = tmp[i];
+ d[i] = 0;
+ return 0;
+}
diff --git a/libc/mingw/secapi/_wctime32_s.c b/libc/mingw/secapi/_wctime32_s.c
new file mode 100644
index 0000000000..27c414b161
--- /dev/null
+++ b/libc/mingw/secapi/_wctime32_s.c
@@ -0,0 +1,56 @@
+#include
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_wctime32_s (wchar_t *, size_t, const __time32_t *);
+static errno_t __cdecl _stub (wchar_t *, size_t, const __time32_t *);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(_wctime32_s))(wchar_t *, size_t, const __time32_t *) =
+ _stub;
+
+static errno_t __cdecl
+_stub (wchar_t *d, size_t dn, const __time32_t *pt)
+{
+ errno_t __cdecl (*f)(wchar_t*,size_t, const __time32_t *) = __MINGW_IMP_SYMBOL(_wctime32_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(wchar_t *, size_t, const __time32_t *))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_wctime32_s");
+ if (!f)
+ f = _int_wctime32_s;
+ __MINGW_IMP_SYMBOL(_wctime32_s) = f;
+ }
+ return (*f)(d, dn, pt);
+}
+
+errno_t __cdecl
+_wctime32_s (wchar_t *d, size_t dn, const __time32_t *pt)
+{
+ return _stub (d, dn, pt);
+}
+
+static errno_t __cdecl
+_int_wctime32_s (wchar_t *d, size_t dn, const __time32_t *pt)
+{
+ struct tm ltm;
+ errno_t e;
+
+ if (!d || !dn)
+ {
+ errno = EINVAL;
+ return EINVAL;
+ }
+ d[0] = 0;
+ if (!pt)
+ {
+ errno = EINVAL;
+ return EINVAL;
+ }
+
+ if ((e = _localtime32_s (<m, pt)) != 0)
+ return e;
+ return _wasctime_s (d, dn, <m);
+}
diff --git a/libc/mingw/secapi/_wctime64_s.c b/libc/mingw/secapi/_wctime64_s.c
new file mode 100644
index 0000000000..bce40fd227
--- /dev/null
+++ b/libc/mingw/secapi/_wctime64_s.c
@@ -0,0 +1,56 @@
+#include
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_wctime64_s (wchar_t *, size_t, const __time64_t *);
+static errno_t __cdecl _stub (wchar_t *, size_t, const __time64_t *);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(_wctime64_s))(wchar_t *, size_t, const __time64_t *) =
+ _stub;
+
+static errno_t __cdecl
+_stub (wchar_t *d, size_t dn, const __time64_t *pt)
+{
+ errno_t __cdecl (*f)(wchar_t*,size_t, const __time64_t *) = __MINGW_IMP_SYMBOL(_wctime64_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(wchar_t *, size_t, const __time64_t *))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_wctime64_s");
+ if (!f)
+ f = _int_wctime64_s;
+ __MINGW_IMP_SYMBOL(_wctime64_s) = f;
+ }
+ return (*f)(d, dn, pt);
+}
+
+errno_t __cdecl
+_wctime64_s (wchar_t *d, size_t dn, const __time64_t *pt)
+{
+ return _stub (d, dn, pt);
+}
+
+static errno_t __cdecl
+_int_wctime64_s (wchar_t *d, size_t dn, const __time64_t *pt)
+{
+ struct tm ltm;
+ errno_t e;
+
+ if (!d || !dn)
+ {
+ errno = EINVAL;
+ return EINVAL;
+ }
+ d[0] = 0;
+ if (!pt)
+ {
+ errno = EINVAL;
+ return EINVAL;
+ }
+
+ if ((e = _localtime64_s (<m, pt)) != 0)
+ return e;
+ return _wasctime_s (d, dn, <m);
+}
diff --git a/libc/mingw/secapi/_wmktemp_s.c b/libc/mingw/secapi/_wmktemp_s.c
new file mode 100644
index 0000000000..3cbf0c7809
--- /dev/null
+++ b/libc/mingw/secapi/_wmktemp_s.c
@@ -0,0 +1,55 @@
+#define MINGW_HAS_SECURE_API 1
+#include
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_wmktemp_s (wchar_t *, size_t);
+static errno_t __cdecl _stub (wchar_t *, size_t);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(_wmktemp_s))(wchar_t *, size_t) =
+ _stub;
+
+static errno_t __cdecl
+_stub (wchar_t *d, size_t dn)
+{
+ errno_t __cdecl (*f)(wchar_t *, size_t) = __MINGW_IMP_SYMBOL(_wmktemp_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(wchar_t *, size_t))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_wmktemp_s");
+ if (!f)
+ f = _int_wmktemp_s;
+ __MINGW_IMP_SYMBOL(_wmktemp_s) = f;
+ }
+ return (*f)(d, dn);
+}
+
+errno_t __cdecl
+_wmktemp_s (wchar_t *d, size_t dn)
+{
+ return _stub (d, dn);
+}
+
+static errno_t __cdecl
+_int_wmktemp_s (wchar_t *d, size_t dn)
+{
+ size_t sz;
+ if (!d || !dn)
+ {
+ _wmktemp (NULL);
+ return EINVAL;
+ }
+ sz = wcsnlen (d, dn);
+ if (sz >= dn || sz < 6)
+ {
+ d[0] = 0;
+ _wmktemp (NULL);
+ return EINVAL;
+ }
+ if (_wmktemp (d) != NULL)
+ return 0;
+ return errno;
+}
diff --git a/libc/mingw/secapi/_wstrdate_s.c b/libc/mingw/secapi/_wstrdate_s.c
new file mode 100644
index 0000000000..e8ec1d446e
--- /dev/null
+++ b/libc/mingw/secapi/_wstrdate_s.c
@@ -0,0 +1,68 @@
+#include
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_wstrdate_s (wchar_t *, size_t);
+static errno_t __cdecl _stub (wchar_t *, size_t);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(_wstrdate_s))(wchar_t *, size_t) =
+ _stub;
+
+static errno_t __cdecl
+_stub (wchar_t *d, size_t dn)
+{
+ errno_t __cdecl (*f)(wchar_t *, size_t) = __MINGW_IMP_SYMBOL(_wstrdate_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(wchar_t *, size_t))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_wstrdate_s");
+ if (!f)
+ f = _int_wstrdate_s;
+ __MINGW_IMP_SYMBOL(_wstrdate_s) = f;
+ }
+ return (*f)(d, dn);
+}
+
+errno_t __cdecl
+_wstrdate_s (wchar_t *d, size_t dn)
+{
+ return _stub (d, dn);
+}
+
+static errno_t __cdecl
+_int_wstrdate_s (wchar_t *d, size_t dn)
+{
+ SYSTEMTIME dt;
+
+ if (!d || !dn)
+ {
+ errno = EINVAL;
+ return EINVAL;
+ }
+
+ d[0] = 0;
+
+ if (dn < 9)
+ {
+ errno = ERANGE;
+ return ERANGE;
+ }
+
+ GetLocalTime (&dt);
+ dt.wYear %= 100;
+
+ d[0] = (wchar_t) (dt.wMonth / 10 + '0');
+ d[1] = (wchar_t) (dt.wMonth % 10 + '0');
+ d[2] = '/';
+ d[3] = (wchar_t) (dt.wDay / 10 + '0');
+ d[4] = (wchar_t) (dt.wDay % 10 + '0');
+ d[5] = '/';
+ d[6] = (wchar_t) (dt.wYear / 10 + '0');
+ d[7] = (wchar_t) (dt.wYear % 10 + '0');
+ d[8] = 0;
+
+ return 0;
+}
diff --git a/libc/mingw/secapi/_wstrtime_s.c b/libc/mingw/secapi/_wstrtime_s.c
new file mode 100644
index 0000000000..ffb8a3e96f
--- /dev/null
+++ b/libc/mingw/secapi/_wstrtime_s.c
@@ -0,0 +1,71 @@
+#include
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_wstrtime_s (wchar_t *, size_t);
+static errno_t __cdecl _stub (wchar_t *, size_t);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(_wstrtime_s))(wchar_t *, size_t) =
+ _stub;
+
+static errno_t __cdecl
+_stub (wchar_t *d, size_t dn)
+{
+ errno_t __cdecl (*f)(wchar_t *, size_t) = __MINGW_IMP_SYMBOL(_wstrtime_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(wchar_t *, size_t))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "_wstrtime_s");
+ if (!f)
+ f = _int_wstrtime_s;
+ __MINGW_IMP_SYMBOL(_wstrtime_s) = f;
+ }
+ return (*f)(d, dn);
+}
+
+errno_t __cdecl
+_wstrtime_s (wchar_t *d, size_t dn)
+{
+ return _stub (d, dn);
+}
+
+static errno_t __cdecl
+_int_wstrtime_s (wchar_t *d, size_t dn)
+{
+ SYSTEMTIME dt;
+ int hours, minutes, seconds;
+
+ if (!d || !dn)
+ {
+ errno = EINVAL;
+ return EINVAL;
+ }
+
+ d[0] = 0;
+
+ if (dn < 9)
+ {
+ errno = ERANGE;
+ return ERANGE;
+ }
+
+ GetLocalTime (&dt);
+
+ hours = dt.wHour;
+ minutes = dt.wMinute;
+ seconds = dt.wSecond;
+
+ d[2] = d[5] = ':';
+ d[0] = (wchar_t) (hours / 10 + '0');
+ d[1] = (wchar_t) (hours % 10 + '0');
+ d[3] = (wchar_t) (minutes / 10 + '0');
+ d[4] = (wchar_t) (minutes % 10 + '0');
+ d[6] = (wchar_t) (seconds / 10 + '0');
+ d[7] = (wchar_t) (seconds % 10 + '0');
+ d[8] = 0;
+
+ return 0;
+}
diff --git a/libc/mingw/secapi/asctime_s.c b/libc/mingw/secapi/asctime_s.c
new file mode 100644
index 0000000000..aeb16e3bcf
--- /dev/null
+++ b/libc/mingw/secapi/asctime_s.c
@@ -0,0 +1,52 @@
+#include
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_asctime_s (char *, size_t, const struct tm *);
+static errno_t __cdecl _stub (char *, size_t, const struct tm *);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(asctime_s))(char *, size_t, const struct tm *) =
+ _stub;
+
+static errno_t __cdecl
+_stub (char *d, size_t dn, const struct tm *pt)
+{
+ errno_t __cdecl (*f)(char *, size_t, const struct tm *) = __MINGW_IMP_SYMBOL(asctime_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(char *, size_t, const struct tm *))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "asctime_s");
+ if (!f)
+ f = _int_asctime_s;
+ __MINGW_IMP_SYMBOL(asctime_s) = f;
+ }
+ return (*f)(d, dn, pt);
+}
+
+errno_t __cdecl
+asctime_s (char *d, size_t dn, const struct tm *pt)
+{
+ return _stub (d, dn, pt);
+}
+
+static errno_t __cdecl
+_int_asctime_s (char *d, size_t dn, const struct tm *pt)
+{
+ char *tmp;
+ size_t i;
+
+ if (d && dn)
+ d[0] = 0;
+ if (!d || dn < 26 || !pt || (tmp = asctime (pt)) == NULL)
+ {
+ errno = EINVAL;
+ return EINVAL;
+ }
+ for (i = 0; tmp[i] != 0; i++)
+ d[i] = tmp[i];
+ d[i] = 0;
+ return 0;
+}
diff --git a/libc/mingw/secapi/memcpy_s.c b/libc/mingw/secapi/memcpy_s.c
new file mode 100644
index 0000000000..013eff05c5
--- /dev/null
+++ b/libc/mingw/secapi/memcpy_s.c
@@ -0,0 +1,59 @@
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_memcpy_s (void *, size_t, const void *, size_t);
+static errno_t __cdecl _stub (void *, size_t, const void *, size_t);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(memcpy_s))(void *, size_t, const void *, size_t) =
+ _stub;
+
+static errno_t __cdecl
+_stub (void *d, size_t dn, const void *s, size_t n)
+{
+ errno_t __cdecl (*f)(void *, size_t, const void *, size_t) = __MINGW_IMP_SYMBOL(memcpy_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(void *, size_t, const void *, size_t))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "memcpy_s");
+ if (!f)
+ f = _int_memcpy_s;
+ __MINGW_IMP_SYMBOL(memcpy_s) = f;
+ }
+ return (*f)(d, dn, s, n);
+}
+
+errno_t __cdecl
+memcpy_s (void *d, size_t dn, const void *s, size_t n)
+{
+ return _stub (d, dn, s, n);
+}
+
+static errno_t __cdecl
+_int_memcpy_s (void *d, size_t dn, const void *s, size_t n)
+{
+ if (!n)
+ return 0;
+
+ if (!d || !s)
+ {
+ if (d)
+ memset (d, 0, dn);
+ errno = EINVAL;
+ return EINVAL;
+ }
+
+ if (dn < n)
+ {
+ memset (d, 0, dn);
+
+ errno = ERANGE;
+ return ERANGE;
+ }
+
+ memcpy (d, s, n);
+
+ return 0;
+}
diff --git a/libc/mingw/secapi/memmove_s.c b/libc/mingw/secapi/memmove_s.c
new file mode 100644
index 0000000000..170bdf32ce
--- /dev/null
+++ b/libc/mingw/secapi/memmove_s.c
@@ -0,0 +1,60 @@
+#define MINGW_HAS_SECURE_API 1
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_memmove_s (void *, size_t, const void *, size_t);
+static errno_t __cdecl _stub (void *, size_t, const void *, size_t);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(memmove_s))(void *, size_t, const void *, size_t) =
+ _stub;
+
+static errno_t __cdecl
+_stub (void *d, size_t dn, const void *s, size_t n)
+{
+ errno_t __cdecl (*f)(void *, size_t, const void *, size_t) = __MINGW_IMP_SYMBOL(memmove_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(void *, size_t, const void *, size_t))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "memmove_s");
+ if (!f)
+ f = _int_memmove_s;
+ __MINGW_IMP_SYMBOL(memmove_s) = f;
+ }
+ return (*f)(d, dn, s, n);
+}
+
+errno_t __cdecl
+memmove_s (void *d, size_t dn, const void *s, size_t n)
+{
+ return _stub (d, dn, s, n);
+}
+
+static errno_t __cdecl
+_int_memmove_s (void *d, size_t dn, const void *s, size_t n)
+{
+ if (!n)
+ return 0;
+
+ if (!d || !s)
+ {
+ if (d)
+ memset (d, 0, dn);
+ errno = EINVAL;
+ return EINVAL;
+ }
+
+ if (dn < n)
+ {
+ memset (d, 0, dn);
+
+ errno = ERANGE;
+ return ERANGE;
+ }
+
+ memmove (d, s, n);
+
+ return 0;
+}
diff --git a/libc/mingw/secapi/rand_s.c b/libc/mingw/secapi/rand_s.c
new file mode 100644
index 0000000000..7773d65ece
--- /dev/null
+++ b/libc/mingw/secapi/rand_s.c
@@ -0,0 +1,30 @@
+#define _CRT_RAND_S
+#include
+#include
+#include
+#include
+#include
+
+static BOOLEAN (WINAPI *pRtlGenRandom)(void*,ULONG);
+
+static errno_t mingw_rand_s(unsigned int *pval)
+{
+ return !pval || !pRtlGenRandom || !pRtlGenRandom(pval, sizeof(*pval)) ? EINVAL : 0;
+}
+
+static errno_t __cdecl init_rand_s(unsigned int*);
+
+errno_t (__cdecl *__MINGW_IMP_SYMBOL(rand_s))(unsigned int*) = init_rand_s;
+
+static errno_t __cdecl init_rand_s(unsigned int *val)
+{
+ int (__cdecl *func)(unsigned int*);
+
+ func = (void*)GetProcAddress(__mingw_get_msvcrt_handle(), "rand_s");
+ if(!func) {
+ func = mingw_rand_s;
+ pRtlGenRandom = (void*)GetProcAddress(LoadLibraryW(L"advapi32.dll"), "SystemFunction036");
+ }
+
+ return (__MINGW_IMP_SYMBOL(rand_s) = func)(val);
+}
diff --git a/libc/mingw/secapi/sprintf_s.c b/libc/mingw/secapi/sprintf_s.c
new file mode 100644
index 0000000000..3b92d07beb
--- /dev/null
+++ b/libc/mingw/secapi/sprintf_s.c
@@ -0,0 +1,20 @@
+#define MINGW_HAS_SECURE_API 1
+#include
+#include
+#include
+#include
+#include
+
+int __cdecl (*__MINGW_IMP_SYMBOL(sprintf_s))(char *, size_t, const char *,...) = sprintf_s;
+
+int __cdecl
+sprintf_s (char *_DstBuf, size_t _Size, const char *_Format, ...)
+{
+ va_list argp;
+ int r;
+
+ va_start (argp, _Format);
+ r = vsprintf_s (_DstBuf, _Size, _Format, argp);
+ va_end (argp);
+ return r;
+}
diff --git a/libc/mingw/secapi/strerror_s.c b/libc/mingw/secapi/strerror_s.c
new file mode 100644
index 0000000000..148236d393
--- /dev/null
+++ b/libc/mingw/secapi/strerror_s.c
@@ -0,0 +1,53 @@
+#define MINGW_HAS_SECURE_API 1
+#include
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_strerror_s (char *, size_t, int);
+static errno_t __cdecl _stub (char *, size_t, int);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(strerror_s))(char *, size_t, int) = _stub;
+
+static errno_t __cdecl
+_stub (char *buffer, size_t numberOfElements, int errnum)
+{
+ errno_t __cdecl (*f)(char *, size_t, int) = __MINGW_IMP_SYMBOL(strerror_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(char *, size_t, int))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "strerror_s");
+ if (!f)
+ f = _int_strerror_s;
+ __MINGW_IMP_SYMBOL(strerror_s) = f;
+ }
+ return (*f)(buffer, numberOfElements, errnum);
+}
+
+errno_t __cdecl
+strerror_s (char *buffer, size_t numberOfElements, int errnum)
+{
+ return _stub (buffer, numberOfElements, errnum);
+}
+
+static errno_t __cdecl
+_int_strerror_s (char *buffer, size_t numberOfElements, int errnum)
+{
+ char *errmsg = strerror(errnum);
+
+ if (!errmsg || !buffer || numberOfElements == 0)
+ {
+ errno = EINVAL;
+ return EINVAL;
+ }
+
+ if (sprintf_s(buffer, numberOfElements, "%s", errmsg) == -1)
+ {
+ errno = EINVAL;
+ return EINVAL;
+ }
+
+ return 0;
+}
diff --git a/libc/mingw/secapi/vsprintf_s.c b/libc/mingw/secapi/vsprintf_s.c
new file mode 100644
index 0000000000..96a7680830
--- /dev/null
+++ b/libc/mingw/secapi/vsprintf_s.c
@@ -0,0 +1,41 @@
+#define MINGW_HAS_SECURE_API 1
+#include
+#include
+#include
+#include
+#include
+#include
+
+static int __cdecl _int_vsprintf_s (char *, size_t, const char *, va_list);
+static int __cdecl _stub (char *, size_t, const char *, va_list);
+
+int __cdecl (*__MINGW_IMP_SYMBOL(vsprintf_s))(char *, size_t, const char *, va_list) =
+ _stub;
+
+static int __cdecl
+_stub (char *_DstBuf, size_t _Size, const char *_Format, va_list _ArgList)
+{
+ int __cdecl (*f)(char *, size_t, const char *, va_list) = __MINGW_IMP_SYMBOL(vsprintf_s);
+
+ if (f == _stub)
+ {
+ f = (int __cdecl (*)(char *, size_t, const char *, va_list))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "vsprintf_s");
+ if (!f)
+ f = _int_vsprintf_s;
+ __MINGW_IMP_SYMBOL(vsprintf_s) = f;
+ }
+ return (*f)(_DstBuf, _Size, _Format, _ArgList);
+}
+
+int __cdecl
+vsprintf_s (char *_DstBuf, size_t _Size, const char *_Format, va_list _ArgList)
+{
+ return _stub (_DstBuf, _Size, _Format, _ArgList);
+}
+
+static int __cdecl
+_int_vsprintf_s (char *_DstBuf, size_t _Size, const char *_Format, va_list _ArgList)
+{
+ return __ms_vsnprintf (_DstBuf, _Size, _Format, _ArgList);
+}
diff --git a/libc/mingw/secapi/wmemcpy_s.c b/libc/mingw/secapi/wmemcpy_s.c
new file mode 100644
index 0000000000..bb59bdca80
--- /dev/null
+++ b/libc/mingw/secapi/wmemcpy_s.c
@@ -0,0 +1,61 @@
+#define MINGW_HAS_SECURE_API 1
+#include
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_wmemcpy_s (wchar_t *, size_t, const wchar_t *, size_t);
+static errno_t __cdecl _stub (wchar_t *, size_t, const wchar_t *, size_t);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(wmemcpy_s))(wchar_t *, size_t, const wchar_t *, size_t) =
+ _stub;
+
+static errno_t __cdecl
+_stub (wchar_t *d, size_t dn, const wchar_t *s, size_t n)
+{
+ errno_t __cdecl (*f)(wchar_t *, size_t, const wchar_t *, size_t) = __MINGW_IMP_SYMBOL(wmemcpy_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(wchar_t *, size_t, const wchar_t *, size_t))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "wmemcpy_s");
+ if (!f)
+ f = _int_wmemcpy_s;
+ __MINGW_IMP_SYMBOL(wmemcpy_s) = f;
+ }
+ return (*f)(d, dn, s, n);
+}
+
+errno_t __cdecl
+wmemcpy_s (wchar_t *d, size_t dn, const wchar_t *s, size_t n)
+{
+ return _stub (d, dn, s, n);
+}
+
+static errno_t __cdecl
+_int_wmemcpy_s (wchar_t *d, size_t dn, const wchar_t *s, size_t n)
+{
+ if (!n)
+ return 0;
+
+ if (!d || !s)
+ {
+ if (d)
+ memset (d, 0, dn * sizeof (wchar_t));
+ errno = EINVAL;
+ return EINVAL;
+ }
+
+ if (dn < n)
+ {
+ memset (d, 0, dn * sizeof (wchar_t));
+
+ errno = ERANGE;
+ return ERANGE;
+ }
+
+ memcpy (d, s, n * sizeof (wchar_t));
+
+ return 0;
+}
diff --git a/libc/mingw/secapi/wmemmove_s.c b/libc/mingw/secapi/wmemmove_s.c
new file mode 100644
index 0000000000..788fa7e461
--- /dev/null
+++ b/libc/mingw/secapi/wmemmove_s.c
@@ -0,0 +1,61 @@
+#define MINGW_HAS_SECURE_API 1
+#include
+#include
+#include
+#include
+#include
+
+static errno_t __cdecl _int_wmemmove_s (wchar_t *, size_t, const wchar_t*, size_t);
+static errno_t __cdecl _stub (wchar_t *, size_t, const wchar_t *, size_t);
+
+errno_t __cdecl (*__MINGW_IMP_SYMBOL(wmemmove_s))(wchar_t *, size_t, const wchar_t *, size_t) =
+ _stub;
+
+static errno_t __cdecl
+_stub (wchar_t *d, size_t dn, const wchar_t *s, size_t n)
+{
+ errno_t __cdecl (*f)(wchar_t *, size_t, const wchar_t *, size_t) = __MINGW_IMP_SYMBOL(wmemmove_s);
+
+ if (f == _stub)
+ {
+ f = (errno_t __cdecl (*)(wchar_t *, size_t, const wchar_t *, size_t))
+ GetProcAddress (__mingw_get_msvcrt_handle (), "wmemmove_s");
+ if (!f)
+ f = _int_wmemmove_s;
+ __MINGW_IMP_SYMBOL(wmemmove_s) = f;
+ }
+ return (*f)(d, dn, s, n);
+}
+
+errno_t __cdecl
+wmemmove_s (wchar_t *d, size_t dn, const wchar_t *s, size_t n)
+{
+ return _stub (d, dn, s, n);
+}
+
+static errno_t __cdecl
+_int_wmemmove_s (wchar_t *d, size_t dn, const wchar_t *s, size_t n)
+{
+ if (!n)
+ return 0;
+
+ if (!d || !s)
+ {
+ if (d)
+ memset (d, 0, dn * sizeof (wchar_t));
+ errno = EINVAL;
+ return EINVAL;
+ }
+
+ if (dn < n)
+ {
+ memset (d, 0, dn * sizeof (wchar_t));
+
+ errno = ERANGE;
+ return ERANGE;
+ }
+
+ memmove (d, s, n * sizeof (wchar_t));
+
+ return 0;
+}
diff --git a/libc/mingw/stdio/acrt_iob_func.c b/libc/mingw/stdio/acrt_iob_func.c
new file mode 100644
index 0000000000..085a5fa739
--- /dev/null
+++ b/libc/mingw/stdio/acrt_iob_func.c
@@ -0,0 +1,15 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#include
+
+FILE *__cdecl __acrt_iob_func(unsigned index)
+{
+ return &(__iob_func()[index]);
+}
+
+typedef FILE *__cdecl (*_f__acrt_iob_func)(unsigned index);
+_f__acrt_iob_func __MINGW_IMP_SYMBOL(__acrt_iob_func) = __acrt_iob_func;
diff --git a/libc/mingw/stdio/mingw_lock.c b/libc/mingw/stdio/mingw_lock.c
new file mode 100644
index 0000000000..ebc3c256fe
--- /dev/null
+++ b/libc/mingw/stdio/mingw_lock.c
@@ -0,0 +1,102 @@
+#define _CRTIMP
+#include
+#include
+#include "internal.h"
+
+/***
+ * Copy of MS functions _lock_file, _unlock_file which are missing from
+ * msvcrt.dll and msvcr80.dll. They are needed to atomic/lock stdio
+ * functions (printf, fprintf, vprintf, vfprintf). We need exactly the same
+ * lock that MS uses in msvcrt.dll because we can mix mingw-w64 code with
+ * original MS functions (puts, fputs for example).
+***/
+
+
+_CRTIMP void __cdecl _lock(int locknum);
+_CRTIMP void __cdecl _unlock(int locknum);
+#define _STREAM_LOCKS 16
+#define _IOLOCKED 0x8000
+
+
+/***
+* _lock_file - Lock a FILE
+*
+*Purpose:
+* Assert the lock for a stdio-level file
+*
+*Entry:
+* pf = __piob[] entry (pointer to a FILE or _FILEX)
+*
+*Exit:
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+void __cdecl _lock_file( FILE *pf )
+{
+ /*
+ * The way the FILE (pointed to by pf) is locked depends on whether
+ * it is part of _iob[] or not
+ */
+ if ( (pf >= __acrt_iob_func(0)) && (pf <= __acrt_iob_func(_IOB_ENTRIES-1)) )
+ {
+ /*
+ * FILE lies in _iob[] so the lock lies in _locktable[].
+ */
+ _lock( _STREAM_LOCKS + (int)(pf - __acrt_iob_func(0)) );
+ /* We set _IOLOCKED to indicate we locked the stream */
+ pf->_flag |= _IOLOCKED;
+ }
+ else
+ /*
+ * Not part of _iob[]. Therefore, *pf is a _FILEX and the
+ * lock field of the struct is an initialized critical
+ * section.
+ */
+ EnterCriticalSection( &(((_FILEX *)pf)->lock) );
+}
+
+void *__MINGW_IMP_SYMBOL(_lock_file) = _lock_file;
+
+
+/***
+* _unlock_file - Unlock a FILE
+*
+*Purpose:
+* Release the lock for a stdio-level file
+*
+*Entry:
+* pf = __piob[] entry (pointer to a FILE or _FILEX)
+*
+*Exit:
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+void __cdecl _unlock_file( FILE *pf )
+{
+ /*
+ * The way the FILE (pointed to by pf) is unlocked depends on whether
+ * it is part of _iob[] or not
+ */
+ if ( (pf >= __acrt_iob_func(0)) && (pf <= __acrt_iob_func(_IOB_ENTRIES-1)) )
+ {
+ /*
+ * FILE lies in _iob[] so the lock lies in _locktable[].
+ * We reset _IOLOCKED to indicate we unlock the stream.
+ */
+ pf->_flag &= ~_IOLOCKED;
+ _unlock( _STREAM_LOCKS + (int)(pf - __acrt_iob_func(0)) );
+ }
+ else
+ /*
+ * Not part of _iob[]. Therefore, *pf is a _FILEX and the
+ * lock field of the struct is an initialized critical
+ * section.
+ */
+ LeaveCriticalSection( &(((_FILEX *)pf)->lock) );
+}
+
+void *__MINGW_IMP_SYMBOL(_unlock_file) = _unlock_file;
diff --git a/src/ir.cpp b/src/ir.cpp
index 94307627a1..616bb23132 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -15027,9 +15027,10 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
break;
}
} break;
+ case ZigTypeIdInt:
+ break;
case ZigTypeIdVoid:
case ZigTypeIdBool:
- case ZigTypeIdInt:
case ZigTypeIdFloat:
case ZigTypeIdPointer:
case ZigTypeIdComptimeFloat:
diff --git a/src/link.cpp b/src/link.cpp
index ef5db4c4ad..526f9e07f1 100644
--- a/src/link.cpp
+++ b/src/link.cpp
@@ -570,6 +570,96 @@ static const char *build_musl(CodeGen *parent) {
return buf_ptr(&child_gen->output_file_path);
}
+static const char *msvcrt_common_src[] = {
+ "misc" OS_SEP "onexit_table.c",
+ "misc" OS_SEP "register_tls_atexit.c",
+ "stdio" OS_SEP "acrt_iob_func.c",
+ "misc" OS_SEP "_configthreadlocale.c",
+ "misc" OS_SEP "_get_current_locale.c",
+ "misc" OS_SEP "invalid_parameter_handler.c",
+ "misc" OS_SEP "output_format.c",
+ "misc" OS_SEP "purecall.c",
+ "secapi" OS_SEP "_access_s.c",
+ "secapi" OS_SEP "_cgets_s.c",
+ "secapi" OS_SEP "_cgetws_s.c",
+ "secapi" OS_SEP "_chsize_s.c",
+ "secapi" OS_SEP "_controlfp_s.c",
+ "secapi" OS_SEP "_cprintf_s.c",
+ "secapi" OS_SEP "_cprintf_s_l.c",
+ "secapi" OS_SEP "_ctime32_s.c",
+ "secapi" OS_SEP "_ctime64_s.c",
+ "secapi" OS_SEP "_cwprintf_s.c",
+ "secapi" OS_SEP "_cwprintf_s_l.c",
+ "secapi" OS_SEP "_gmtime32_s.c",
+ "secapi" OS_SEP "_gmtime64_s.c",
+ "secapi" OS_SEP "_localtime32_s.c",
+ "secapi" OS_SEP "_localtime64_s.c",
+ "secapi" OS_SEP "_mktemp_s.c",
+ "secapi" OS_SEP "_sopen_s.c",
+ "secapi" OS_SEP "_strdate_s.c",
+ "secapi" OS_SEP "_strtime_s.c",
+ "secapi" OS_SEP "_umask_s.c",
+ "secapi" OS_SEP "_vcprintf_s.c",
+ "secapi" OS_SEP "_vcprintf_s_l.c",
+ "secapi" OS_SEP "_vcwprintf_s.c",
+ "secapi" OS_SEP "_vcwprintf_s_l.c",
+ "secapi" OS_SEP "_vscprintf_p.c",
+ "secapi" OS_SEP "_vscwprintf_p.c",
+ "secapi" OS_SEP "_vswprintf_p.c",
+ "secapi" OS_SEP "_waccess_s.c",
+ "secapi" OS_SEP "_wasctime_s.c",
+ "secapi" OS_SEP "_wctime32_s.c",
+ "secapi" OS_SEP "_wctime64_s.c",
+ "secapi" OS_SEP "_wstrtime_s.c",
+ "secapi" OS_SEP "_wmktemp_s.c",
+ "secapi" OS_SEP "_wstrdate_s.c",
+ "secapi" OS_SEP "asctime_s.c",
+ "secapi" OS_SEP "memcpy_s.c",
+ "secapi" OS_SEP "memmove_s.c",
+ "secapi" OS_SEP "rand_s.c",
+ "secapi" OS_SEP "sprintf_s.c",
+ "secapi" OS_SEP "strerror_s.c",
+ "secapi" OS_SEP "vsprintf_s.c",
+ "secapi" OS_SEP "wmemcpy_s.c",
+ "secapi" OS_SEP "wmemmove_s.c",
+ "stdio" OS_SEP "mingw_lock.c",
+};
+
+static const char *msvcrt_i386_src[] = {
+ "misc" OS_SEP "lc_locale_func.c",
+
+};
+
+static const char *msvcrt_other_src[] = {
+ "misc" OS_SEP "__p___argv.c",
+ "misc" OS_SEP "__p__acmdln.c",
+ "misc" OS_SEP "__p__fmode.c",
+ "misc" OS_SEP "__p__wcmdln.c",
+};
+
+static void add_msvcrt_os_dep(CodeGen *parent, CodeGen *child_gen, const char *src_path) {
+ CFile *c_file = allocate(1);
+ c_file->source_path = buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "%s",
+ buf_ptr(parent->zig_lib_dir), src_path));
+ c_file->args.append("-DHAVE_CONFIG_H");
+ c_file->args.append("-D__LIBMSVCRT__");
+
+ c_file->args.append("-I");
+ c_file->args.append(path_from_libc(parent, "mingw" OS_SEP "include" OS_SEP));
+
+ c_file->args.append("-std=gnu99");
+ c_file->args.append("-D_CRTBLD");
+ c_file->args.append("-D_WIN32_WINNT=0x0f00");
+ c_file->args.append("-D__MSVCRT_VERSION__=0x700");
+
+ c_file->args.append("-isystem");
+ c_file->args.append(path_from_libc(parent, "include" OS_SEP "any-windows-any"));
+
+ c_file->args.append("-g");
+ c_file->args.append("-O2");
+
+ child_gen->c_source_files.append(c_file);
+}
static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
if (parent->libc == nullptr && parent->zig_target->os == OsWindows) {
@@ -651,6 +741,24 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
}
codegen_build_and_link(child_gen);
return buf_ptr(&child_gen->output_file_path);
+ } else if (strcmp(file, "msvcrt-os.lib") == 0) {
+ CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr);
+ codegen_set_out_name(child_gen, buf_create_from_str("msvcrt-os"));
+
+ for (size_t i = 0; i < array_length(msvcrt_common_src); i += 1) {
+ add_msvcrt_os_dep(parent, child_gen, msvcrt_common_src[i]);
+ }
+ if (parent->zig_target->arch == ZigLLVM_x86) {
+ for (size_t i = 0; i < array_length(msvcrt_i386_src); i += 1) {
+ add_msvcrt_os_dep(parent, child_gen, msvcrt_i386_src[i]);
+ }
+ } else {
+ for (size_t i = 0; i < array_length(msvcrt_other_src); i += 1) {
+ add_msvcrt_os_dep(parent, child_gen, msvcrt_other_src[i]);
+ }
+ }
+ codegen_build_and_link(child_gen);
+ return buf_ptr(&child_gen->output_file_path);
} else {
zig_unreachable();
}
@@ -853,6 +961,7 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path,
}
child_gen->function_sections = true;
+ child_gen->want_stack_check = WantStackCheckDisabled;
codegen_build_and_link(child_gen);
return &child_gen->output_file_path;
@@ -1446,7 +1555,9 @@ static void add_mingw_link_args(LinkJob *lj, bool is_library) {
}
lj->args.append(get_libc_crt_file(g, "mingw32.lib"));
+ lj->args.append(get_libc_crt_file(g, "msvcrt-os.lib"));
lj->args.append(get_def_lib(g, "msvcrt", "mingw" OS_SEP "lib-common" OS_SEP "msvcrt.def.in"));
+ lj->args.append(get_def_lib(g, "kernel32", "mingw" OS_SEP "lib-common" OS_SEP "kernel32.def.in"));
} else {
if (is_dll) {
lj->args.append(get_libc_file(g->libc, "dllcrt2.o"));
diff --git a/std/special/compiler_rt.zig b/std/special/compiler_rt.zig
index 914f9dcb00..5064e9db29 100644
--- a/std/special/compiler_rt.zig
+++ b/std/special/compiler_rt.zig
@@ -1,6 +1,12 @@
const builtin = @import("builtin");
const is_test = builtin.is_test;
+const is_gnu = switch (builtin.abi) {
+ .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => true,
+ else => false,
+};
+const is_mingw = builtin.os == .windows and is_gnu;
+
comptime {
const linkage = if (is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Weak;
const strong_linkage = if (is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Strong;
@@ -231,6 +237,10 @@ comptime {
@export("___chkstk", @import("compiler_rt/stack_probe.zig").___chkstk, strong_linkage);
@export("__chkstk_ms", @import("compiler_rt/stack_probe.zig").__chkstk_ms, strong_linkage);
@export("___chkstk_ms", @import("compiler_rt/stack_probe.zig").___chkstk_ms, strong_linkage);
+ } else if (is_mingw) {
+ @export("___chkstk_ms", @import("compiler_rt/stack_probe.zig").___chkstk_ms, strong_linkage);
+ @export("__stack_chk_fail", __stack_chk_fail, strong_linkage);
+ @export("__stack_chk_guard", __stack_chk_guard, strong_linkage);
}
switch (builtin.arch) {
@@ -279,6 +289,17 @@ pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn
}
}
+extern fn __stack_chk_fail() noreturn {
+ @panic("stack smashing detected");
+}
+
+extern var __stack_chk_guard: usize = blk: {
+ var buf = [1]u8{0} ** @sizeOf(usize);
+ buf[@sizeOf(usize) - 1] = 255;
+ buf[@sizeOf(usize) - 2] = '\n';
+ break :blk @bitCast(usize, buf);
+};
+
extern fn __aeabi_unwind_cpp_pr0() void {
unreachable;
}
--
cgit v1.2.3
From 9c39d5720f4d06bf3e4f14ec50d702b50c9f0cdd Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Sat, 13 Jul 2019 18:38:52 -0400
Subject: ir: add an assertion in phi analysis
---
src/ir.cpp | 1 +
1 file changed, 1 insertion(+)
(limited to 'src/ir.cpp')
diff --git a/src/ir.cpp b/src/ir.cpp
index 616bb23132..5193a63ec4 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -17129,6 +17129,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh
for (size_t i = 0; i < new_incoming_values.length; i += 1) {
IrInstruction *new_value = new_incoming_values.at(i);
IrBasicBlock *predecessor = new_incoming_blocks.at(i);
+ ir_assert(predecessor->instruction_list.length != 0, &phi_instruction->base);
IrInstruction *branch_instruction = predecessor->instruction_list.pop();
ir_set_cursor_at_end(&ira->new_irb, predecessor);
IrInstruction *casted_value = ir_implicit_cast(ira, new_value, resolved_type);
--
cgit v1.2.3