Compare commits
116 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
783cb980ab | ||
|
|
cf0e453cc9 | ||
|
|
9d2e5bbcb4 | ||
|
|
a42c712934 | ||
|
|
1bbf731e7e | ||
|
|
a6de0b4136 | ||
|
|
5df9f15843 | ||
|
|
4797fdb3db | ||
|
|
74c17aa8c5 | ||
|
|
465b90c1fa | ||
|
|
00664dbdce | ||
|
|
c9bc8b9d0c | ||
|
|
fd4c98cbb7 | ||
|
|
21236c0151 | ||
|
|
ea70a983ba | ||
|
|
235d56cb82 | ||
|
|
b4c0396d3c | ||
|
|
97692cb4fe | ||
|
|
d9c808e3ff | ||
|
|
1f09584d05 | ||
|
|
cad2e8da9d | ||
|
|
b124d04e6a | ||
|
|
a7eea0813f | ||
|
|
85c1db9222 | ||
|
|
40e37d4324 | ||
|
|
1ec0261518 | ||
|
|
5c13a4e54a | ||
|
|
c2de3bdc12 | ||
|
|
ad95eecf37 | ||
|
|
83b2785a43 | ||
|
|
e2104ecc2d | ||
|
|
05fefc0d3f | ||
|
|
01ff3684dc | ||
|
|
48c8948f49 | ||
|
|
f385419259 | ||
|
|
96a703ee6d | ||
|
|
32997a2fb0 | ||
|
|
a1d0c77539 | ||
|
|
2ce5f84c2f | ||
|
|
05265160ae | ||
|
|
52de625df9 | ||
|
|
cdde9d8885 | ||
|
|
ff802cc996 | ||
|
|
0ac43154eb | ||
|
|
401d091fb4 | ||
|
|
b1f52ca7f2 | ||
|
|
02cb3841a6 | ||
|
|
7c13bec7cb | ||
|
|
7add370371 | ||
|
|
d15a0ec7b2 | ||
|
|
0858d7b0df | ||
|
|
a4c8bd8fd4 | ||
|
|
7099dff7ea | ||
|
|
6bf19e32e7 | ||
|
|
c8b8f0ea13 | ||
|
|
d2445764a9 | ||
|
|
a9b7d8fa07 | ||
|
|
57ac835a03 | ||
|
|
3c907e51d1 | ||
|
|
791e38da8c | ||
|
|
1a61a9d4bf | ||
|
|
8f346d9a4b | ||
|
|
a7c2cfe16d | ||
|
|
0a4a99ec87 | ||
|
|
be2adff087 | ||
|
|
a6222d1d4b | ||
|
|
f09f960ce4 | ||
|
|
288b8b535f | ||
|
|
36b8f5d194 | ||
|
|
41d57b051f | ||
|
|
24d4bfb666 | ||
|
|
06a75c16ff | ||
|
|
8af016c5be | ||
|
|
a05ae01b4f | ||
|
|
1344706b47 | ||
|
|
72980388ca | ||
|
|
c6c25a1c09 | ||
|
|
3f134cfe5e | ||
|
|
e814f71052 | ||
|
|
50269f2315 | ||
|
|
8af0a1987b | ||
|
|
b498d26376 | ||
|
|
d3f1a4edce | ||
|
|
1add7c616f | ||
|
|
5f9a664de9 | ||
|
|
1c8cd268be | ||
|
|
eea4cd2924 | ||
|
|
4d44a813de | ||
|
|
51ffb0548d | ||
|
|
5b42704ea7 | ||
|
|
c8b6e407ba | ||
|
|
9e1e91dafc | ||
|
|
6624f9cd5c | ||
|
|
7d0c461b77 | ||
|
|
2d280825cd | ||
|
|
10617593f8 | ||
|
|
10b1001a12 | ||
|
|
eaa1db2002 | ||
|
|
1aec406311 | ||
|
|
b6350a2b3f | ||
|
|
8c62733927 | ||
|
|
aa6fc29744 | ||
|
|
01a927a0cb | ||
|
|
7d3c5f207a | ||
|
|
0405698696 | ||
|
|
73455eaf42 | ||
|
|
85665386c6 | ||
|
|
2c0caa8533 | ||
|
|
904c513a1e | ||
|
|
0e2eb6eb65 | ||
|
|
c2c3177d82 | ||
|
|
a28c244afb | ||
|
|
97ec177953 | ||
|
|
810c03f426 | ||
|
|
0f4b893d6d | ||
|
|
61507d95d8 |
294
CMakeLists.txt
294
CMakeLists.txt
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 2.8.5)
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
# Use ccache if possible
|
||||
FIND_PROGRAM(CCACHE_PROGRAM ccache)
|
||||
@@ -26,7 +26,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
|
||||
|
||||
set(ZIG_VERSION_MAJOR 0)
|
||||
set(ZIG_VERSION_MINOR 7)
|
||||
set(ZIG_VERSION_PATCH 0)
|
||||
set(ZIG_VERSION_PATCH 1)
|
||||
set(ZIG_VERSION "" CACHE STRING "Override Zig version string. Default is to find out with git.")
|
||||
|
||||
if("${ZIG_VERSION}" STREQUAL "")
|
||||
@@ -258,6 +258,15 @@ set(SOFTFLOAT_LIBRARIES embedded_softfloat)
|
||||
|
||||
find_package(Threads)
|
||||
|
||||
set(ZIG_LIB_DIR "lib/zig")
|
||||
set(C_HEADERS_DEST "${ZIG_LIB_DIR}/include")
|
||||
set(LIBC_FILES_DEST "${ZIG_LIB_DIR}/libc")
|
||||
set(LIBUNWIND_FILES_DEST "${ZIG_LIB_DIR}/libunwind")
|
||||
set(LIBCXX_FILES_DEST "${ZIG_LIB_DIR}/libcxx")
|
||||
set(ZIG_STD_DEST "${ZIG_LIB_DIR}/std")
|
||||
set(ZIG_CONFIG_H_OUT "${CMAKE_BINARY_DIR}/config.h")
|
||||
set(ZIG_CONFIG_ZIG_OUT "${CMAKE_BINARY_DIR}/config.zig")
|
||||
|
||||
# This is our shim which will be replaced by stage1.zig.
|
||||
set(ZIG0_SOURCES
|
||||
"${CMAKE_SOURCE_DIR}/src/stage1/zig0.cpp"
|
||||
@@ -299,6 +308,258 @@ set(ZIG_CPP_SOURCES
|
||||
# https://github.com/ziglang/zig/issues/6363
|
||||
"${CMAKE_SOURCE_DIR}/src/windows_sdk.cpp"
|
||||
)
|
||||
# Needed because we use cmake, not the zig build system, to build zig1.o.
|
||||
# This list is generated by building zig and then clearing the zig-cache directory,
|
||||
# then manually running the build-obj command (see BUILD_ZIG1_ARGS), and then looking
|
||||
# in the zig-cache directory for the compiler-generated list of zig file dependencies.
|
||||
set(ZIG_STAGE2_SOURCES
|
||||
"${ZIG_CONFIG_ZIG_OUT}"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/array_hash_map.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/array_list.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/ascii.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/atomic.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/atomic/int.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/atomic/queue.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/atomic/stack.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/auto_reset_event.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/base64.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/buf_map.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/builtin.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/c.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/c/linux.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/c/tokenizer.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/child_process.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/coff.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/comptime_string_map.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/crypto.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/crypto/blake3.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/crypto/siphash.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/debug.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/debug/leb128.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/dwarf.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/dwarf_bits.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/elf.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/event.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/event/batch.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/event/loop.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/fifo.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/fmt.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/fmt/errol.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/fmt/errol/enum3.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/fmt/errol/lookup.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/fmt/parse_float.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/fs.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/fs/file.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/fs/get_app_data_dir.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/fs/path.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/hash.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/hash/auto_hash.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/hash/wyhash.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/hash_map.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/heap.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/heap/arena_allocator.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/io.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/io/auto_indenting_stream.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/io/buffered_atomic_file.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/io/buffered_writer.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/io/change_detection_stream.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/io/counting_writer.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/io/find_byte_out_stream.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/io/fixed_buffer_stream.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/io/reader.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/io/seekable_stream.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/io/writer.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/json.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/json/write_stream.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/linked_list.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/log.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/macho.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/math.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/math/big.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/math/big/int.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/math/floor.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/math/frexp.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/math/inf.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/math/isinf.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/math/isnan.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/math/ln.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/math/log.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/math/log10.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/math/log2.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/math/nan.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/math/signbit.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/math/sqrt.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/mem.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/mem/Allocator.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/meta.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/meta/trailer_flags.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/meta/trait.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/mutex.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/os.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/os/bits.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/os/bits/linux.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/os/bits/linux/errno-generic.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/os/bits/linux/netlink.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/os/bits/linux/prctl.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/os/bits/linux/securebits.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/os/bits/linux/x86_64.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/os/linux.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/os/linux/io_uring.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/os/linux/x86_64.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/os/windows.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/os/windows/bits.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/os/windows/ntstatus.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/os/windows/win32error.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/pdb.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/process.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/progress.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/rand.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/reset_event.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/sort.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/addXf3.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/atomics.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/clear_cache.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/clzsi2.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/compareXf2.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/divdf3.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/divsf3.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/divtf3.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/divti3.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/extendXfYf2.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixdfdi.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixdfsi.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixdfti.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixint.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixsfdi.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixsfsi.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixsfti.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixtfdi.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixtfsi.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixtfti.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixuint.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixunsdfdi.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixunsdfsi.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixunsdfti.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixunssfdi.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixunssfsi.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixunssfti.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixunstfdi.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixunstfsi.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixunstfti.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatXisf.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatdidf.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatditf.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatsiXf.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floattidf.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floattitf.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatundidf.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatundisf.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatunditf.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatunsidf.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatunsisf.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatunsitf.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatuntidf.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatuntisf.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatuntitf.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/int.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/modti3.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/mulXf3.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/muldi3.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/mulodi4.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/muloti4.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/multi3.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/negXf2.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/popcountdi2.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/shift.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/stack_probe.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/truncXfYf2.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/udivmod.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/udivmodti4.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/udivti3.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/umodti3.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/spinlock.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/start.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/std.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/target.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/target/aarch64.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/target/amdgpu.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/target/arm.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/target/avr.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/target/bpf.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/target/hexagon.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/target/mips.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/target/msp430.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/target/nvptx.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/target/powerpc.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/target/riscv.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/target/sparc.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/target/systemz.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/target/wasm.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/target/x86.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/thread.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/time.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/unicode.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/zig.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/zig/ast.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/zig/cross_target.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/zig/parse.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/zig/render.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/zig/string_literal.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/zig/system.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/zig/system/x86.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/zig/tokenizer.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/Cache.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/Compilation.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/DepTokenizer.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/Module.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/Package.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/RangeSet.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/TypedValue.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/astgen.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/clang.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/clang_options.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/clang_options_data.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/codegen.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/codegen/arm.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/codegen/c.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/codegen/llvm.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/codegen/riscv64.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/codegen/spu-mk2.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/codegen/wasm.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/codegen/x86_64.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/glibc.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/introspect.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/ir.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/libc_installation.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/libcxx.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/libunwind.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/link.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/link/C.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/link/Coff.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/link/Elf.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/link/MachO.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/link/MachO/Trie.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/link/Wasm.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/link/cbe.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/link/msdos-stub.bin"
|
||||
"${CMAKE_SOURCE_DIR}/src/liveness.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/llvm.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/main.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/mingw.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/musl.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/print_env.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/print_targets.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/stage1.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/target.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/tracy.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/translate_c.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/type.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/value.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/windows_sdk.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/zir.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/zir_sema.zig"
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
set(MSVC_DIA_SDK_DIR "$ENV{VSINSTALLDIR}DIA SDK")
|
||||
@@ -308,14 +569,6 @@ if(MSVC)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(ZIG_LIB_DIR "lib/zig")
|
||||
set(C_HEADERS_DEST "${ZIG_LIB_DIR}/include")
|
||||
set(LIBC_FILES_DEST "${ZIG_LIB_DIR}/libc")
|
||||
set(LIBUNWIND_FILES_DEST "${ZIG_LIB_DIR}/libunwind")
|
||||
set(LIBCXX_FILES_DEST "${ZIG_LIB_DIR}/libcxx")
|
||||
set(ZIG_STD_DEST "${ZIG_LIB_DIR}/std")
|
||||
set(ZIG_CONFIG_H_OUT "${CMAKE_BINARY_DIR}/config.h")
|
||||
set(ZIG_CONFIG_ZIG_OUT "${CMAKE_BINARY_DIR}/config.zig")
|
||||
configure_file (
|
||||
"${CMAKE_SOURCE_DIR}/src/stage1/config.h.in"
|
||||
"${ZIG_CONFIG_H_OUT}"
|
||||
@@ -348,6 +601,10 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
|
||||
if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 7.0)
|
||||
set(EXE_CFLAGS "${EXE_CFLAGS} -Werror=implicit-fallthrough")
|
||||
endif()
|
||||
# GCC 9.2 and older are unable to detect valid variable initialization in some cases
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS_EQUAL 9.2)
|
||||
set(EXE_CFLAGS "${EXE_CFLAGS} -Wno-maybe-uninitialized")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -468,10 +725,10 @@ set(BUILD_ZIG1_ARGS
|
||||
)
|
||||
|
||||
if("${ZIG_EXECUTABLE}" STREQUAL "")
|
||||
add_custom_target(zig_build_zig1 ALL
|
||||
add_custom_command(
|
||||
OUTPUT "${ZIG1_OBJECT}"
|
||||
COMMAND zig0 ${BUILD_ZIG1_ARGS}
|
||||
DEPENDS zig0
|
||||
BYPRODUCTS "${ZIG1_OBJECT}"
|
||||
DEPENDS zig0 "${ZIG_STAGE2_SOURCES}"
|
||||
COMMENT STATUS "Building self-hosted component ${ZIG1_OBJECT}"
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
)
|
||||
@@ -480,28 +737,29 @@ if("${ZIG_EXECUTABLE}" STREQUAL "")
|
||||
set(ZIG_EXECUTABLE "${ZIG_EXECUTABLE}.exe")
|
||||
endif()
|
||||
else()
|
||||
add_custom_target(zig_build_zig1 ALL
|
||||
COMMAND "${ZIG_EXECUTABLE}" "build-obj" ${BUILD_ZIG1_ARGS}
|
||||
add_custom_command(
|
||||
OUTPUT "${ZIG1_OBJECT}"
|
||||
BYPRODUCTS "${ZIG1_OBJECT}"
|
||||
COMMAND "${ZIG_EXECUTABLE}" "build-obj" ${BUILD_ZIG1_ARGS}
|
||||
DEPENDS ${ZIG_STAGE2_SOURCES}
|
||||
COMMENT STATUS "Building self-hosted component ${ZIG1_OBJECT}"
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
)
|
||||
endif()
|
||||
|
||||
# cmake won't let us configure an executable without C sources.
|
||||
add_executable(zig "${CMAKE_SOURCE_DIR}/src/stage1/empty.cpp")
|
||||
add_executable(zig "${CMAKE_SOURCE_DIR}/src/stage1/empty.cpp" "${ZIG1_OBJECT}")
|
||||
|
||||
set_target_properties(zig PROPERTIES
|
||||
COMPILE_FLAGS ${EXE_CFLAGS}
|
||||
LINK_FLAGS ${EXE_LDFLAGS}
|
||||
)
|
||||
target_link_libraries(zig "${ZIG1_OBJECT}" zigstage1)
|
||||
target_link_libraries(zig zigstage1)
|
||||
if(MSVC)
|
||||
target_link_libraries(zig ntdll.lib)
|
||||
elseif(MINGW)
|
||||
target_link_libraries(zig ntdll)
|
||||
endif()
|
||||
add_dependencies(zig zig_build_zig1)
|
||||
|
||||
install(TARGETS zig DESTINATION bin)
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ const fs = std.fs;
|
||||
const InstallDirectoryOptions = std.build.InstallDirectoryOptions;
|
||||
const assert = std.debug.assert;
|
||||
|
||||
const zig_version = std.builtin.Version{ .major = 0, .minor = 6, .patch = 0 };
|
||||
const zig_version = std.builtin.Version{ .major = 0, .minor = 7, .patch = 1 };
|
||||
|
||||
pub fn build(b: *Builder) !void {
|
||||
b.setPreferredReleaseMode(.ReleaseFast);
|
||||
@@ -128,11 +128,11 @@ pub fn build(b: *Builder) !void {
|
||||
break :s b.fmt("dirty{x}", .{@truncate(u32, dirty_hash)});
|
||||
};
|
||||
|
||||
// This will look like e.g. "0.6.0^0" for a tag commit.
|
||||
// This will look like e.g. "0.7.0^0" for a tag commit.
|
||||
if (mem.endsWith(u8, git_sha_trimmed, "^0")) {
|
||||
const git_ver_string = git_sha_trimmed[0 .. git_sha_trimmed.len - 2];
|
||||
if (!mem.eql(u8, git_ver_string, version_string)) {
|
||||
std.debug.print("Expected git tag '{}', found '{}'", .{ version_string, git_ver_string });
|
||||
std.debug.print("Expected git tag '{}', found '{}'\n", .{ version_string, git_ver_string });
|
||||
std.process.exit(1);
|
||||
}
|
||||
break :v b.fmt("{}{}", .{ version_string, dirty_suffix });
|
||||
@@ -215,7 +215,7 @@ pub fn build(b: *Builder) !void {
|
||||
test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filter, modes));
|
||||
test_step.dependOn(tests.addRuntimeSafetyTests(b, test_filter, modes));
|
||||
test_step.dependOn(tests.addTranslateCTests(b, test_filter));
|
||||
test_step.dependOn(tests.addRunTranslatedCTests(b, test_filter));
|
||||
test_step.dependOn(tests.addRunTranslatedCTests(b, test_filter, target));
|
||||
// tests for this feature are disabled until we have the self-hosted compiler available
|
||||
// test_step.dependOn(tests.addGenHTests(b, test_filter));
|
||||
if (!skip_compile_errors) {
|
||||
|
||||
@@ -8,11 +8,27 @@ BUILDDIR="$(pwd)"
|
||||
sudo sh -c 'echo "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-11 main" >> /etc/apt/sources.list'
|
||||
wget -O - http://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
|
||||
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
sudo apt-get update -q
|
||||
|
||||
sudo apt-get remove -y llvm-*
|
||||
sudo rm -rf /usr/local/*
|
||||
sudo apt-get install -y libxml2-dev libclang-11-dev llvm-11 llvm-11-dev liblld-11-dev cmake s3cmd gcc-7 g++-7 ninja-build tidy
|
||||
|
||||
# Some APT mirrors can be flaky, retry the download instead of failing right
|
||||
# away.
|
||||
APT_MAX_RETRY=3
|
||||
|
||||
for i in $(seq 1 "$APT_MAX_RETRY"); do
|
||||
sudo apt-get update -q
|
||||
sudo apt-get install -y \
|
||||
libxml2-dev libclang-11-dev llvm-11 llvm-11-dev liblld-11-dev cmake s3cmd \
|
||||
gcc-7 g++-7 ninja-build tidy \
|
||||
&& break
|
||||
if [ "$i" -eq "$APT_MAX_RETRY" ]; then
|
||||
echo 'apt-get failed, giving up...'
|
||||
exit 1
|
||||
fi
|
||||
echo 'apt-get failed, retrying...'
|
||||
sleep 5s
|
||||
done
|
||||
|
||||
QEMUBASE="qemu-linux-x86_64-5.1.0"
|
||||
wget https://ziglang.org/deps/$QEMUBASE.tar.xz
|
||||
|
||||
@@ -189,6 +189,7 @@
|
||||
<a href="https://ziglang.org/documentation/0.4.0/">0.4.0</a> |
|
||||
<a href="https://ziglang.org/documentation/0.5.0/">0.5.0</a> |
|
||||
<a href="https://ziglang.org/documentation/0.6.0/">0.6.0</a> |
|
||||
<a href="https://ziglang.org/documentation/0.7.0/">0.7.0</a> |
|
||||
master
|
||||
<h1>Contents</h1>
|
||||
{#nav#}
|
||||
@@ -1742,8 +1743,8 @@ const B = error{Two};
|
||||
{#header_open|Precedence#}
|
||||
<pre>{#syntax#}x() x[] x.y
|
||||
a!b
|
||||
!x -x -%x ~x &x ?x
|
||||
x{} x.* x.?
|
||||
!x -x -%x ~x &x ?x
|
||||
! * / % ** *% ||
|
||||
+ - ++ +% -%
|
||||
<< >>
|
||||
@@ -7454,7 +7455,7 @@ test "main" {
|
||||
<p>
|
||||
If the binary is built with error return tracing, and this function is invoked in a
|
||||
function that calls a function with an error or error union return type, returns a
|
||||
stack trace object. Otherwise returns `null`.
|
||||
stack trace object. Otherwise returns {#link|null#}.
|
||||
</p>
|
||||
{#header_close#}
|
||||
|
||||
@@ -7987,7 +7988,7 @@ test "@wasmMemoryGrow" {
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@setEvalBranchQuota#}
|
||||
<pre>{#syntax#}@setEvalBranchQuota(new_quota: usize){#endsyntax#}</pre>
|
||||
<pre>{#syntax#}@setEvalBranchQuota(new_quota: u32){#endsyntax#}</pre>
|
||||
<p>
|
||||
Changes the maximum number of backwards branches that compile-time code
|
||||
execution can use before giving up and making a compile error.
|
||||
@@ -8214,8 +8215,7 @@ test "vector @splat" {
|
||||
<pre>{#syntax#}@reduce(comptime op: builtin.ReduceOp, value: anytype) std.meta.Child(value){#endsyntax#}</pre>
|
||||
<p>
|
||||
Transforms a {#link|vector|Vectors#} into a scalar value by performing a
|
||||
sequential horizontal reduction of its elements using the specified
|
||||
specified operator {#syntax#}op{#endsyntax#}.
|
||||
sequential horizontal reduction of its elements using the specified operator {#syntax#}op{#endsyntax#}.
|
||||
</p>
|
||||
<p>
|
||||
Not every operator is available for every vector element type:
|
||||
@@ -9446,17 +9446,17 @@ test "string literal to constant slice" {
|
||||
}
|
||||
{#code_end#}
|
||||
<p>
|
||||
Just like string literals, `const` declarations, when the value is known at {#link|comptime#},
|
||||
Just like string literals, {#syntax#}const{#endsyntax#} declarations, when the value is known at {#link|comptime#},
|
||||
are stored in the global constant data section. Also {#link|Compile Time Variables#} are stored
|
||||
in the global constant data section.
|
||||
</p>
|
||||
<p>
|
||||
`var` declarations inside functions are stored in the function's stack frame. Once a function returns,
|
||||
{#syntax#}var{#endsyntax#} declarations inside functions are stored in the function's stack frame. Once a function returns,
|
||||
any {#link|Pointers#} to variables in the function's stack frame become invalid references, and
|
||||
dereferencing them becomes unchecked {#link|Undefined Behavior#}.
|
||||
</p>
|
||||
<p>
|
||||
`var` declarations at the top level or in {#link|struct#} declarations are stored in the global
|
||||
{#syntax#}var{#endsyntax#} declarations at the top level or in {#link|struct#} declarations are stored in the global
|
||||
data section.
|
||||
</p>
|
||||
<p>
|
||||
|
||||
6
lib/include/__clang_cuda_complex_builtins.h
vendored
6
lib/include/__clang_cuda_complex_builtins.h
vendored
@@ -16,7 +16,7 @@
|
||||
// to work with CUDA and OpenMP target offloading [in C and C++ mode].)
|
||||
|
||||
#pragma push_macro("__DEVICE__")
|
||||
#ifdef _OPENMP
|
||||
#ifdef __OPENMP_NVPTX__
|
||||
#pragma omp declare target
|
||||
#define __DEVICE__ __attribute__((noinline, nothrow, cold, weak))
|
||||
#else
|
||||
@@ -26,7 +26,7 @@
|
||||
// To make the algorithms available for C and C++ in CUDA and OpenMP we select
|
||||
// different but equivalent function versions. TODO: For OpenMP we currently
|
||||
// select the native builtins as the overload support for templates is lacking.
|
||||
#if !defined(_OPENMP)
|
||||
#if !defined(__OPENMP_NVPTX__)
|
||||
#define _ISNANd std::isnan
|
||||
#define _ISNANf std::isnan
|
||||
#define _ISINFd std::isinf
|
||||
@@ -250,7 +250,7 @@ __DEVICE__ float _Complex __divsc3(float __a, float __b, float __c, float __d) {
|
||||
#undef _LOGBd
|
||||
#undef _LOGBf
|
||||
|
||||
#ifdef _OPENMP
|
||||
#ifdef __OPENMP_NVPTX__
|
||||
#pragma omp end declare target
|
||||
#endif
|
||||
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
#include <cmath>
|
||||
|
||||
#define __CUDA__
|
||||
#define __OPENMP_NVPTX__
|
||||
#include <__clang_cuda_complex_builtins.h>
|
||||
#undef __OPENMP_NVPTX__
|
||||
#endif
|
||||
|
||||
// Grab the host header too.
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
#include <math.h>
|
||||
|
||||
#define __CUDA__
|
||||
#define __OPENMP_NVPTX__
|
||||
#include <__clang_cuda_complex_builtins.h>
|
||||
#undef __OPENMP_NVPTX__
|
||||
#endif
|
||||
|
||||
// Grab the host header too.
|
||||
|
||||
385
lib/libc/include/wasm-freestanding-musl/bits/alltypes.h
Normal file
385
lib/libc/include/wasm-freestanding-musl/bits/alltypes.h
Normal file
@@ -0,0 +1,385 @@
|
||||
#define _Addr long
|
||||
#define _Int64 long long
|
||||
#define _Reg long
|
||||
|
||||
#if defined(__NEED_va_list) && !defined(__DEFINED_va_list)
|
||||
typedef __builtin_va_list va_list;
|
||||
#define __DEFINED_va_list
|
||||
#endif
|
||||
|
||||
#if defined(__NEED___isoc_va_list) && !defined(__DEFINED___isoc_va_list)
|
||||
typedef __builtin_va_list __isoc_va_list;
|
||||
#define __DEFINED___isoc_va_list
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
#if defined(__NEED_wchar_t) && !defined(__DEFINED_wchar_t)
|
||||
typedef int wchar_t;
|
||||
#define __DEFINED_wchar_t
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_float_t) && !defined(__DEFINED_float_t)
|
||||
typedef float float_t;
|
||||
#define __DEFINED_float_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_double_t) && !defined(__DEFINED_double_t)
|
||||
typedef double double_t;
|
||||
#define __DEFINED_double_t
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__NEED_max_align_t) && !defined(__DEFINED_max_align_t)
|
||||
typedef struct { long long __ll; long double __ld; } max_align_t;
|
||||
#define __DEFINED_max_align_t
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__NEED_time_t) && !defined(__DEFINED_time_t)
|
||||
typedef long time_t;
|
||||
#define __DEFINED_time_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_suseconds_t) && !defined(__DEFINED_suseconds_t)
|
||||
typedef long suseconds_t;
|
||||
#define __DEFINED_suseconds_t
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__NEED_pthread_attr_t) && !defined(__DEFINED_pthread_attr_t)
|
||||
typedef struct { union { int __i[9]; volatile int __vi[9]; unsigned __s[9]; } __u; } pthread_attr_t;
|
||||
#define __DEFINED_pthread_attr_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_pthread_mutex_t) && !defined(__DEFINED_pthread_mutex_t)
|
||||
typedef struct { union { int __i[6]; volatile int __vi[6]; volatile void *volatile __p[6]; } __u; } pthread_mutex_t;
|
||||
#define __DEFINED_pthread_mutex_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_mtx_t) && !defined(__DEFINED_mtx_t)
|
||||
typedef struct { union { int __i[6]; volatile int __vi[6]; volatile void *volatile __p[6]; } __u; } mtx_t;
|
||||
#define __DEFINED_mtx_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_pthread_cond_t) && !defined(__DEFINED_pthread_cond_t)
|
||||
typedef struct { union { int __i[12]; volatile int __vi[12]; void *__p[12]; } __u; } pthread_cond_t;
|
||||
#define __DEFINED_pthread_cond_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_cnd_t) && !defined(__DEFINED_cnd_t)
|
||||
typedef struct { union { int __i[12]; volatile int __vi[12]; void *__p[12]; } __u; } cnd_t;
|
||||
#define __DEFINED_cnd_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_pthread_rwlock_t) && !defined(__DEFINED_pthread_rwlock_t)
|
||||
typedef struct { union { int __i[8]; volatile int __vi[8]; void *__p[8]; } __u; } pthread_rwlock_t;
|
||||
#define __DEFINED_pthread_rwlock_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_pthread_barrier_t) && !defined(__DEFINED_pthread_barrier_t)
|
||||
typedef struct { union { int __i[5]; volatile int __vi[5]; void *__p[5]; } __u; } pthread_barrier_t;
|
||||
#define __DEFINED_pthread_barrier_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_size_t) && !defined(__DEFINED_size_t)
|
||||
typedef unsigned _Addr size_t;
|
||||
#define __DEFINED_size_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_uintptr_t) && !defined(__DEFINED_uintptr_t)
|
||||
typedef unsigned _Addr uintptr_t;
|
||||
#define __DEFINED_uintptr_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_ptrdiff_t) && !defined(__DEFINED_ptrdiff_t)
|
||||
typedef _Addr ptrdiff_t;
|
||||
#define __DEFINED_ptrdiff_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_ssize_t) && !defined(__DEFINED_ssize_t)
|
||||
typedef _Addr ssize_t;
|
||||
#define __DEFINED_ssize_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_intptr_t) && !defined(__DEFINED_intptr_t)
|
||||
typedef _Addr intptr_t;
|
||||
#define __DEFINED_intptr_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_regoff_t) && !defined(__DEFINED_regoff_t)
|
||||
typedef _Addr regoff_t;
|
||||
#define __DEFINED_regoff_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_register_t) && !defined(__DEFINED_register_t)
|
||||
typedef _Reg register_t;
|
||||
#define __DEFINED_register_t
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__NEED_int8_t) && !defined(__DEFINED_int8_t)
|
||||
typedef signed char int8_t;
|
||||
#define __DEFINED_int8_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_int16_t) && !defined(__DEFINED_int16_t)
|
||||
typedef signed short int16_t;
|
||||
#define __DEFINED_int16_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_int32_t) && !defined(__DEFINED_int32_t)
|
||||
typedef signed int int32_t;
|
||||
#define __DEFINED_int32_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_int64_t) && !defined(__DEFINED_int64_t)
|
||||
typedef signed _Int64 int64_t;
|
||||
#define __DEFINED_int64_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_intmax_t) && !defined(__DEFINED_intmax_t)
|
||||
typedef signed _Int64 intmax_t;
|
||||
#define __DEFINED_intmax_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_uint8_t) && !defined(__DEFINED_uint8_t)
|
||||
typedef unsigned char uint8_t;
|
||||
#define __DEFINED_uint8_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_uint16_t) && !defined(__DEFINED_uint16_t)
|
||||
typedef unsigned short uint16_t;
|
||||
#define __DEFINED_uint16_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_uint32_t) && !defined(__DEFINED_uint32_t)
|
||||
typedef unsigned int uint32_t;
|
||||
#define __DEFINED_uint32_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_uint64_t) && !defined(__DEFINED_uint64_t)
|
||||
typedef unsigned _Int64 uint64_t;
|
||||
#define __DEFINED_uint64_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_u_int64_t) && !defined(__DEFINED_u_int64_t)
|
||||
typedef unsigned _Int64 u_int64_t;
|
||||
#define __DEFINED_u_int64_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_uintmax_t) && !defined(__DEFINED_uintmax_t)
|
||||
typedef unsigned _Int64 uintmax_t;
|
||||
#define __DEFINED_uintmax_t
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__NEED_mode_t) && !defined(__DEFINED_mode_t)
|
||||
typedef unsigned mode_t;
|
||||
#define __DEFINED_mode_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_nlink_t) && !defined(__DEFINED_nlink_t)
|
||||
typedef unsigned _Reg nlink_t;
|
||||
#define __DEFINED_nlink_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_off_t) && !defined(__DEFINED_off_t)
|
||||
typedef _Int64 off_t;
|
||||
#define __DEFINED_off_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_ino_t) && !defined(__DEFINED_ino_t)
|
||||
typedef unsigned _Int64 ino_t;
|
||||
#define __DEFINED_ino_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_dev_t) && !defined(__DEFINED_dev_t)
|
||||
typedef unsigned _Int64 dev_t;
|
||||
#define __DEFINED_dev_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_blksize_t) && !defined(__DEFINED_blksize_t)
|
||||
typedef long blksize_t;
|
||||
#define __DEFINED_blksize_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_blkcnt_t) && !defined(__DEFINED_blkcnt_t)
|
||||
typedef _Int64 blkcnt_t;
|
||||
#define __DEFINED_blkcnt_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_fsblkcnt_t) && !defined(__DEFINED_fsblkcnt_t)
|
||||
typedef unsigned _Int64 fsblkcnt_t;
|
||||
#define __DEFINED_fsblkcnt_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_fsfilcnt_t) && !defined(__DEFINED_fsfilcnt_t)
|
||||
typedef unsigned _Int64 fsfilcnt_t;
|
||||
#define __DEFINED_fsfilcnt_t
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__NEED_wint_t) && !defined(__DEFINED_wint_t)
|
||||
typedef unsigned wint_t;
|
||||
#define __DEFINED_wint_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_wctype_t) && !defined(__DEFINED_wctype_t)
|
||||
typedef unsigned long wctype_t;
|
||||
#define __DEFINED_wctype_t
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__NEED_timer_t) && !defined(__DEFINED_timer_t)
|
||||
typedef void * timer_t;
|
||||
#define __DEFINED_timer_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_clockid_t) && !defined(__DEFINED_clockid_t)
|
||||
typedef int clockid_t;
|
||||
#define __DEFINED_clockid_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_clock_t) && !defined(__DEFINED_clock_t)
|
||||
typedef long clock_t;
|
||||
#define __DEFINED_clock_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_struct_timeval) && !defined(__DEFINED_struct_timeval)
|
||||
struct timeval { time_t tv_sec; suseconds_t tv_usec; };
|
||||
#define __DEFINED_struct_timeval
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_struct_timespec) && !defined(__DEFINED_struct_timespec)
|
||||
struct timespec { time_t tv_sec; long tv_nsec; };
|
||||
#define __DEFINED_struct_timespec
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__NEED_pid_t) && !defined(__DEFINED_pid_t)
|
||||
typedef int pid_t;
|
||||
#define __DEFINED_pid_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_id_t) && !defined(__DEFINED_id_t)
|
||||
typedef unsigned id_t;
|
||||
#define __DEFINED_id_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_uid_t) && !defined(__DEFINED_uid_t)
|
||||
typedef unsigned uid_t;
|
||||
#define __DEFINED_uid_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_gid_t) && !defined(__DEFINED_gid_t)
|
||||
typedef unsigned gid_t;
|
||||
#define __DEFINED_gid_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_key_t) && !defined(__DEFINED_key_t)
|
||||
typedef int key_t;
|
||||
#define __DEFINED_key_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_useconds_t) && !defined(__DEFINED_useconds_t)
|
||||
typedef unsigned useconds_t;
|
||||
#define __DEFINED_useconds_t
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if defined(__NEED_pthread_t) && !defined(__DEFINED_pthread_t)
|
||||
typedef unsigned long pthread_t;
|
||||
#define __DEFINED_pthread_t
|
||||
#endif
|
||||
|
||||
#else
|
||||
#if defined(__NEED_pthread_t) && !defined(__DEFINED_pthread_t)
|
||||
typedef struct __pthread * pthread_t;
|
||||
#define __DEFINED_pthread_t
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#if defined(__NEED_pthread_once_t) && !defined(__DEFINED_pthread_once_t)
|
||||
typedef int pthread_once_t;
|
||||
#define __DEFINED_pthread_once_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_pthread_key_t) && !defined(__DEFINED_pthread_key_t)
|
||||
typedef unsigned pthread_key_t;
|
||||
#define __DEFINED_pthread_key_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_pthread_spinlock_t) && !defined(__DEFINED_pthread_spinlock_t)
|
||||
typedef int pthread_spinlock_t;
|
||||
#define __DEFINED_pthread_spinlock_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_pthread_mutexattr_t) && !defined(__DEFINED_pthread_mutexattr_t)
|
||||
typedef struct { unsigned __attr; } pthread_mutexattr_t;
|
||||
#define __DEFINED_pthread_mutexattr_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_pthread_condattr_t) && !defined(__DEFINED_pthread_condattr_t)
|
||||
typedef struct { unsigned __attr; } pthread_condattr_t;
|
||||
#define __DEFINED_pthread_condattr_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_pthread_barrierattr_t) && !defined(__DEFINED_pthread_barrierattr_t)
|
||||
typedef struct { unsigned __attr; } pthread_barrierattr_t;
|
||||
#define __DEFINED_pthread_barrierattr_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_pthread_rwlockattr_t) && !defined(__DEFINED_pthread_rwlockattr_t)
|
||||
typedef struct { unsigned __attr[2]; } pthread_rwlockattr_t;
|
||||
#define __DEFINED_pthread_rwlockattr_t
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__NEED_FILE) && !defined(__DEFINED_FILE)
|
||||
typedef struct _IO_FILE FILE;
|
||||
#define __DEFINED_FILE
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__NEED_mbstate_t) && !defined(__DEFINED_mbstate_t)
|
||||
typedef struct __mbstate_t { unsigned __opaque1, __opaque2; } mbstate_t;
|
||||
#define __DEFINED_mbstate_t
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__NEED_locale_t) && !defined(__DEFINED_locale_t)
|
||||
typedef struct __locale_struct * locale_t;
|
||||
#define __DEFINED_locale_t
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__NEED_sigset_t) && !defined(__DEFINED_sigset_t)
|
||||
typedef struct __sigset_t { unsigned long __bits[128/sizeof(long)]; } sigset_t;
|
||||
#define __DEFINED_sigset_t
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__NEED_struct_iovec) && !defined(__DEFINED_struct_iovec)
|
||||
struct iovec { void *iov_base; size_t iov_len; };
|
||||
#define __DEFINED_struct_iovec
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__NEED_socklen_t) && !defined(__DEFINED_socklen_t)
|
||||
typedef unsigned socklen_t;
|
||||
#define __DEFINED_socklen_t
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_sa_family_t) && !defined(__DEFINED_sa_family_t)
|
||||
typedef unsigned short sa_family_t;
|
||||
#define __DEFINED_sa_family_t
|
||||
#endif
|
||||
|
||||
|
||||
#undef _Addr
|
||||
#undef _Int64
|
||||
#undef _Reg
|
||||
24
lib/libc/include/wasm-freestanding-musl/errno.h
Normal file
24
lib/libc/include/wasm-freestanding-musl/errno.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef _ERRNO_H
|
||||
#define _ERRNO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef WASM_THREAD_MODEL_SINGLE
|
||||
extern int errno;
|
||||
#else
|
||||
#ifdef __cplusplus
|
||||
extern thread_local int errno;
|
||||
#else
|
||||
extern _Thread_local int errno;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define errno errno
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
354
lib/libc/mingw/lib-common/iphlpapi.def
Normal file
354
lib/libc/mingw/lib-common/iphlpapi.def
Normal file
@@ -0,0 +1,354 @@
|
||||
;
|
||||
; Definition file of IPHLPAPI.DLL
|
||||
; Automatic generated by gendef
|
||||
; written by Kai Tietz 2008
|
||||
;
|
||||
LIBRARY "IPHLPAPI.DLL"
|
||||
EXPORTS
|
||||
AddIPAddress
|
||||
AllocateAndGetArpEntTableFromStack
|
||||
AllocateAndGetIfTableFromStack
|
||||
AllocateAndGetInterfaceInfoFromStack
|
||||
AllocateAndGetIpAddrTableFromStack
|
||||
AllocateAndGetIpForwardTableFromStack
|
||||
AllocateAndGetIpNetTableFromStack
|
||||
AllocateAndGetTcpExTable2FromStack
|
||||
AllocateAndGetTcpExTableFromStack
|
||||
AllocateAndGetTcpTableFromStack
|
||||
AllocateAndGetUdpExTable2FromStack
|
||||
AllocateAndGetUdpExTableFromStack
|
||||
AllocateAndGetUdpTableFromStack
|
||||
CPNatfwtCreateProviderInstance
|
||||
CPNatfwtDeregisterProviderInstance
|
||||
CPNatfwtDestroyProviderInstance
|
||||
CPNatfwtIndicateReceivedBuffers
|
||||
CPNatfwtRegisterProviderInstance
|
||||
CancelIfTimestampConfigChange
|
||||
CancelIPChangeNotify
|
||||
CancelSecurityHealthChangeNotify
|
||||
CancelMibChangeNotify2
|
||||
CaptureInterfaceHardwareCrossTimestamp
|
||||
CloseCompartment
|
||||
CloseGetIPPhysicalInterfaceForDestination
|
||||
ConvertCompartmentGuidToId
|
||||
ConvertCompartmentIdToGuid
|
||||
ConvertGuidToStringA
|
||||
ConvertGuidToStringW
|
||||
ConvertInterfaceAliasToLuid
|
||||
ConvertInterfaceGuidToLuid
|
||||
ConvertInterfaceIndexToLuid
|
||||
ConvertInterfaceLuidToAlias
|
||||
ConvertInterfaceLuidToGuid
|
||||
ConvertInterfaceLuidToIndex
|
||||
ConvertInterfaceLuidToNameA
|
||||
ConvertInterfaceLuidToNameW
|
||||
ConvertInterfaceNameToLuidA
|
||||
ConvertInterfaceNameToLuidW
|
||||
ConvertInterfacePhysicalAddressToLuid
|
||||
ConvertIpv4MaskToLength
|
||||
ConvertLengthToIpv4Mask
|
||||
ConvertRemoteInterfaceAliasToLuid
|
||||
ConvertRemoteInterfaceGuidToLuid
|
||||
ConvertRemoteInterfaceIndexToLuid
|
||||
ConvertRemoteInterfaceLuidToAlias
|
||||
ConvertRemoteInterfaceLuidToGuid
|
||||
ConvertRemoteInterfaceLuidToIndex
|
||||
ConvertStringToGuidA
|
||||
ConvertStringToGuidW
|
||||
ConvertStringToInterfacePhysicalAddress
|
||||
CreateAnycastIpAddressEntry
|
||||
CreateCompartment
|
||||
CreateIpForwardEntry
|
||||
CreateIpForwardEntry2
|
||||
CreateIpNetEntry
|
||||
CreateIpNetEntry2
|
||||
CreatePersistentTcpPortReservation
|
||||
CreatePersistentUdpPortReservation
|
||||
CreateProxyArpEntry
|
||||
CreateSortedAddressPairs
|
||||
CreateUnicastIpAddressEntry
|
||||
DeleteAnycastIpAddressEntry
|
||||
DeleteCompartment
|
||||
DeleteIPAddress
|
||||
DeleteIpForwardEntry
|
||||
DeleteIpForwardEntry2
|
||||
DeleteIpNetEntry
|
||||
DeleteIpNetEntry2
|
||||
DeletePersistentTcpPortReservation
|
||||
DeletePersistentUdpPortReservation
|
||||
DeleteProxyArpEntry
|
||||
DeleteUnicastIpAddressEntry
|
||||
DisableMediaSense
|
||||
EnableRouter
|
||||
FlushIpNetTable
|
||||
FlushIpNetTable2
|
||||
FlushIpNetTableFromStack
|
||||
FlushIpPathTable
|
||||
FreeDnsSettings
|
||||
FreeInterfaceDnsSettings
|
||||
FreeMibTable
|
||||
GetAdapterIndex
|
||||
GetAdapterOrderMap
|
||||
GetAdaptersAddresses
|
||||
GetAdaptersInfo
|
||||
GetAnycastIpAddressEntry
|
||||
GetAnycastIpAddressTable
|
||||
GetBestInterface
|
||||
GetBestInterfaceEx
|
||||
GetBestInterfaceFromStack
|
||||
GetBestRoute
|
||||
GetBestRoute2
|
||||
GetBestRouteFromStack
|
||||
GetCurrentThreadCompartmentId
|
||||
GetCurrentThreadCompartmentScope
|
||||
GetDefaultCompartmentId
|
||||
GetDnsSettings
|
||||
GetExtendedTcpTable
|
||||
GetExtendedUdpTable
|
||||
GetFriendlyIfIndex
|
||||
GetIcmpStatistics
|
||||
GetIcmpStatisticsEx
|
||||
GetIcmpStatsFromStack
|
||||
GetIcmpStatsFromStackEx
|
||||
GetIfEntry
|
||||
GetIfEntry2
|
||||
GetIfEntry2Ex
|
||||
GetIfEntryFromStack
|
||||
GetIfStackTable
|
||||
GetIfTable
|
||||
GetIfTableFromStack
|
||||
GetIgmpList
|
||||
GetIfTable2
|
||||
GetIfTable2Ex
|
||||
GetInterfaceCompartmentId
|
||||
GetInterfaceCurrentTimestampCapabilities
|
||||
GetInterfaceDnsSettings
|
||||
GetInterfaceHardwareTimestampCapabilities
|
||||
GetInterfaceInfo
|
||||
GetInvertedIfStackTable
|
||||
GetIpAddrTable
|
||||
GetIpAddrTableFromStack
|
||||
GetIpErrorString
|
||||
GetIpForwardEntry2
|
||||
GetIpForwardTable
|
||||
GetIpForwardTableFromStack
|
||||
GetIpForwardTable2
|
||||
GetIpInterfaceEntry
|
||||
GetIpInterfaceTable
|
||||
GetIpNetEntry2
|
||||
GetIpNetTable
|
||||
GetIpNetTable2
|
||||
GetIpNetTableFromStack
|
||||
GetIpNetworkConnectionBandwidthEstimates
|
||||
GetIpPathEntry
|
||||
GetIpPathTable
|
||||
GetIpStatistics
|
||||
GetIpStatisticsEx
|
||||
GetIpStatsFromStack
|
||||
GetIpStatsFromStackEx
|
||||
GetJobCompartmentId
|
||||
GetMulticastIpAddressEntry
|
||||
GetMulticastIpAddressTable
|
||||
GetNetworkConnectivityHint
|
||||
GetNetworkConnectivityHintForInterface
|
||||
GetNetworkInformation
|
||||
GetNetworkParams
|
||||
GetNumberOfInterfaces
|
||||
GetOwnerModuleFromPidAndInfo
|
||||
GetOwnerModuleFromTcp6Entry
|
||||
GetOwnerModuleFromTcpEntry
|
||||
GetOwnerModuleFromUdp6Entry
|
||||
GetOwnerModuleFromUdpEntry
|
||||
GetPerAdapterInfo
|
||||
GetPerTcp6ConnectionEStats
|
||||
GetPerTcp6ConnectionStats
|
||||
GetPerTcpConnectionEStats
|
||||
GetPerTcpConnectionStats
|
||||
GetRTTAndHopCount
|
||||
GetTcpExTable2FromStack
|
||||
GetSessionCompartmentId
|
||||
GetTcp6Table
|
||||
GetTcp6Table2
|
||||
GetTcpStatistics
|
||||
GetTcpStatisticsEx
|
||||
GetTcpStatisticsEx2
|
||||
GetTcpStatsFromStack
|
||||
GetTcpStatsFromStackEx
|
||||
GetTcpTable
|
||||
GetTcpTable2
|
||||
GetTcpTableFromStack
|
||||
GetUdpExTable2FromStack
|
||||
GetTeredoPort
|
||||
GetUdp6Table
|
||||
GetUdpStatistics
|
||||
GetUdpStatisticsEx
|
||||
GetUdpStatisticsEx2
|
||||
GetUdpStatsFromStack
|
||||
GetUdpStatsFromStackEx
|
||||
GetUdpTable
|
||||
GetUdpTableFromStack
|
||||
GetUniDirectionalAdapterInfo
|
||||
GetUnicastIpAddressEntry
|
||||
GetUnicastIpAddressTable
|
||||
GetWPAOACSupportLevel
|
||||
Icmp6CreateFile
|
||||
Icmp6ParseReplies
|
||||
Icmp6SendEcho2
|
||||
IcmpCloseHandle
|
||||
IcmpCreateFile
|
||||
IcmpParseReplies
|
||||
IcmpSendEcho
|
||||
IcmpSendEcho2
|
||||
IcmpSendEcho2Ex
|
||||
InitializeCompartmentEntry
|
||||
InitializeIpForwardEntry
|
||||
InitializeIpInterfaceEntry
|
||||
InitializeUnicastIpAddressEntry
|
||||
InternalCleanupPersistentStore
|
||||
InternalCreateAnycastIpAddressEntry
|
||||
InternalCreateIpForwardEntry
|
||||
InternalCreateIpForwardEntry2
|
||||
InternalCreateIpNetEntry
|
||||
InternalCreateIpNetEntry2
|
||||
InternalCreateUnicastIpAddressEntry
|
||||
InternalDeleteAnycastIpAddressEntry
|
||||
InternalDeleteIpForwardEntry
|
||||
InternalDeleteIpForwardEntry2
|
||||
InternalDeleteIpNetEntry
|
||||
InternalDeleteIpNetEntry2
|
||||
InternalDeleteUnicastIpAddressEntry
|
||||
InternalFindInterfaceByAddress
|
||||
InternalGetAnycastIpAddressEntry
|
||||
InternalGetAnycastIpAddressTable
|
||||
InternalGetBoundTcp6EndpointTable
|
||||
InternalGetBoundTcpEndpointTable
|
||||
InternalGetForwardIpTable2
|
||||
InternalGetIPPhysicalInterfaceForDestination
|
||||
InternalGetIfEntry2
|
||||
InternalGetIfTable
|
||||
InternalGetIfTable2
|
||||
InternalGetIpAddrTable
|
||||
InternalGetIpForwardEntry2
|
||||
InternalGetIpForwardTable
|
||||
InternalGetIpInterfaceEntry
|
||||
InternalGetIpInterfaceTable
|
||||
InternalGetIpNetEntry2
|
||||
InternalGetIpNetTable
|
||||
InternalGetIpNetTable2
|
||||
InternalGetMulticastIpAddressEntry
|
||||
InternalGetMulticastIpAddressTable
|
||||
InternalGetRtcSlotInformation
|
||||
InternalGetTcp6Table2
|
||||
InternalGetTcp6TableWithOwnerModule
|
||||
InternalGetTcp6TableWithOwnerPid
|
||||
InternalGetTcpTable
|
||||
InternalGetTcpTable2
|
||||
InternalGetTcpTableEx
|
||||
InternalGetTcpTableWithOwnerModule
|
||||
InternalGetTcpTableWithOwnerPid
|
||||
InternalGetTunnelPhysicalAdapter
|
||||
InternalGetUdp6TableWithOwnerModule
|
||||
InternalGetUdp6TableWithOwnerPid
|
||||
InternalGetUdpTable
|
||||
InternalGetUdpTableEx
|
||||
InternalGetUdpTableWithOwnerModule
|
||||
InternalGetUdpTableWithOwnerPid
|
||||
InternalGetUnicastIpAddressEntry
|
||||
InternalGetUnicastIpAddressTable
|
||||
InternalIcmpCreateFileEx
|
||||
InternalSetIfEntry
|
||||
InternalSetIpForwardEntry
|
||||
InternalSetIpForwardEntry2
|
||||
InternalSetIpInterfaceEntry
|
||||
InternalSetIpNetEntry
|
||||
InternalSetIpNetEntry2
|
||||
InternalSetIpStats
|
||||
InternalSetTcpEntry
|
||||
InternalSetTeredoPort
|
||||
InternalSetUnicastIpAddressEntry
|
||||
IpReleaseAddress
|
||||
IpRenewAddress
|
||||
IsLocalAddress
|
||||
LookupPersistentTcpPortReservation
|
||||
LookupPersistentUdpPortReservation
|
||||
NTPTimeToNTFileTime
|
||||
NTTimeToNTPTime
|
||||
NhGetGuidFromInterfaceName
|
||||
NhGetInterfaceDescriptionFromGuid
|
||||
NhGetInterfaceNameFromDeviceGuid
|
||||
NhGetInterfaceNameFromGuid
|
||||
NhpAllocateAndGetInterfaceInfoFromStack
|
||||
NhpGetInterfaceIndexFromStack
|
||||
NotifyAddrChange
|
||||
NotifyCompartmentChange
|
||||
NotifyIfTimestampConfigChange
|
||||
NotifyIpInterfaceChange
|
||||
NotifyNetworkConnectivityHintChange
|
||||
NotifyRouteChange
|
||||
NotifyRouteChange2
|
||||
NotifyRouteChangeEx
|
||||
NotifySecurityHealthChange
|
||||
NotifyStableUnicastIpAddressTable
|
||||
NotifyTeredoPortChange
|
||||
NotifyUnicastIpAddressChange
|
||||
OpenCompartment
|
||||
ParseNetworkString
|
||||
PfAddFiltersToInterface
|
||||
PfAddGlobalFilterToInterface
|
||||
PfBindInterfaceToIPAddress
|
||||
PfBindInterfaceToIndex
|
||||
PfCreateInterface
|
||||
PfDeleteInterface
|
||||
PfDeleteLog
|
||||
PfGetInterfaceStatistics
|
||||
PfMakeLog
|
||||
PfRebindFilters
|
||||
PfRemoveFilterHandles
|
||||
PfRemoveFiltersFromInterface
|
||||
PfRemoveGlobalFilterFromInterface
|
||||
PfSetLogBuffer
|
||||
PfTestPacket
|
||||
PfUnBindInterface
|
||||
ResolveIpNetEntry2
|
||||
ResolveNeighbor
|
||||
RestoreMediaSense
|
||||
SendARP
|
||||
SetAdapterIpAddress
|
||||
SetBlockRoutes
|
||||
SetCurrentThreadCompartmentId
|
||||
SetCurrentThreadCompartmentScope
|
||||
SetDnsSettings
|
||||
SetIfEntry
|
||||
SetIfEntryToStack
|
||||
SetInterfaceDnsSettings
|
||||
SetIpForwardEntry
|
||||
SetIpForwardEntry2
|
||||
SetIpForwardEntryToStack
|
||||
SetIpMultihopRouteEntryToStack
|
||||
SetIpInterfaceEntry
|
||||
SetIpNetEntry
|
||||
SetIpNetEntry2
|
||||
SetIpNetEntryToStack
|
||||
SetIpRouteEntryToStack
|
||||
SetIpStatistics
|
||||
SetIpStatsToStack
|
||||
SetIpStatisticsEx
|
||||
SetIpTTL
|
||||
SetJobCompartmentId
|
||||
SetProxyArpEntryToStack
|
||||
SetRouteWithRef
|
||||
SetNetworkInformation
|
||||
SetPerTcp6ConnectionEStats
|
||||
SetPerTcp6ConnectionStats
|
||||
SetPerTcpConnectionEStats
|
||||
SetPerTcpConnectionStats
|
||||
SetSessionCompartmentId
|
||||
SetTcpEntry
|
||||
SetTcpEntryToStack
|
||||
SetUnicastIpAddressEntry
|
||||
UnenableRouter
|
||||
do_echo_rep
|
||||
do_echo_req
|
||||
if_indextoname
|
||||
if_nametoindex
|
||||
register_icmp
|
||||
62
lib/libc/mingw/lib-common/userenv.def
Normal file
62
lib/libc/mingw/lib-common/userenv.def
Normal file
@@ -0,0 +1,62 @@
|
||||
;
|
||||
; Definition file of USERENV.dll
|
||||
; Automatic generated by gendef
|
||||
; written by Kai Tietz 2008-2014
|
||||
;
|
||||
LIBRARY "USERENV.dll"
|
||||
EXPORTS
|
||||
RsopLoggingEnabled
|
||||
AreThereVisibleLogoffScripts
|
||||
AreThereVisibleShutdownScripts
|
||||
CreateAppContainerProfile
|
||||
CreateEnvironmentBlock
|
||||
CreateProfile
|
||||
DeleteAppContainerProfile
|
||||
DeleteProfileA
|
||||
DeleteProfileW
|
||||
DeriveAppContainerSidFromAppContainerName
|
||||
DestroyEnvironmentBlock
|
||||
DllGetContractDescription
|
||||
EnterCriticalPolicySection
|
||||
ExpandEnvironmentStringsForUserA
|
||||
ExpandEnvironmentStringsForUserW
|
||||
ForceSyncFgPolicy
|
||||
FreeGPOListA
|
||||
FreeGPOListW
|
||||
GenerateRsopPolicy
|
||||
GenerateGPNotification
|
||||
GetAllUsersProfileDirectoryA
|
||||
GetAllUsersProfileDirectoryW
|
||||
GetAppContainerFolderPath
|
||||
GetAppContainerRegistryLocation
|
||||
GetAppliedGPOListA
|
||||
GetAppliedGPOListW
|
||||
GetDefaultUserProfileDirectoryA
|
||||
GetDefaultUserProfileDirectoryW
|
||||
GetGPOListA
|
||||
GetGPOListW
|
||||
GetNextFgPolicyRefreshInfo
|
||||
GetPreviousFgPolicyRefreshInfo
|
||||
GetProfileType
|
||||
GetProfilesDirectoryA
|
||||
GetProfilesDirectoryW
|
||||
GetUserProfileDirectoryA
|
||||
GetUserProfileDirectoryW
|
||||
HasPolicyForegroundProcessingCompleted
|
||||
LeaveCriticalPolicySection
|
||||
LoadUserProfileA
|
||||
LoadUserProfileW
|
||||
ProcessGroupPolicyCompleted
|
||||
ProcessGroupPolicyCompletedEx
|
||||
RefreshPolicy
|
||||
RefreshPolicyEx
|
||||
RegisterGPNotification
|
||||
RsopAccessCheckByType
|
||||
RsopFileAccessCheck
|
||||
RsopLoggingEnabled
|
||||
RsopResetPolicySettingStatus
|
||||
RsopSetPolicySettingStatus
|
||||
UnloadUserProfile
|
||||
UnregisterGPNotification
|
||||
WaitForMachinePolicyForegroundProcessing
|
||||
WaitForUserPolicyForegroundProcessing
|
||||
253
lib/libc/mingw/lib-common/wldap32.def
Normal file
253
lib/libc/mingw/lib-common/wldap32.def
Normal file
@@ -0,0 +1,253 @@
|
||||
;
|
||||
; Exports of file WLDAP32.dll
|
||||
;
|
||||
; Autogenerated by gen_exportdef
|
||||
; Written by Kai Tietz, 2007
|
||||
;
|
||||
LIBRARY WLDAP32.dll
|
||||
EXPORTS
|
||||
ldap_abandon
|
||||
ldap_add
|
||||
ldap_get_optionW
|
||||
ldap_unbind
|
||||
ldap_set_optionW
|
||||
LdapGetLastError
|
||||
cldap_open
|
||||
LdapMapErrorToWin32
|
||||
ldap_compare
|
||||
ldap_delete
|
||||
ldap_result2error
|
||||
ldap_err2string
|
||||
ldap_modify
|
||||
ldap_modrdn
|
||||
ldap_open
|
||||
ldap_first_entry
|
||||
ldap_next_entry
|
||||
cldap_openW
|
||||
LdapUTF8ToUnicode
|
||||
ldap_get_dn
|
||||
ldap_dn2ufn
|
||||
ldap_first_attribute
|
||||
ldap_next_attribute
|
||||
ldap_get_values
|
||||
ldap_get_values_len
|
||||
ldap_count_entries
|
||||
ldap_count_values
|
||||
ldap_value_free
|
||||
ldap_explode_dn
|
||||
ldap_result
|
||||
ldap_msgfree
|
||||
ldap_addW
|
||||
ldap_search
|
||||
ldap_add_s
|
||||
ldap_bind_s
|
||||
ldap_unbind_s
|
||||
ldap_delete_s
|
||||
ldap_modify_s
|
||||
ldap_modrdn_s
|
||||
ldap_search_s
|
||||
ldap_search_st
|
||||
ldap_compare_s
|
||||
LdapUnicodeToUTF8
|
||||
ber_bvfree
|
||||
cldap_openA
|
||||
ldap_addA
|
||||
ldap_add_ext
|
||||
ldap_add_extA
|
||||
ldap_simple_bind
|
||||
ldap_simple_bind_s
|
||||
ldap_bind
|
||||
ldap_add_extW
|
||||
ldap_add_ext_s
|
||||
ldap_add_ext_sA
|
||||
ldap_add_ext_sW
|
||||
ldap_add_sA
|
||||
ldap_modrdn2
|
||||
ldap_modrdn2_s
|
||||
ldap_add_sW
|
||||
ldap_bindA
|
||||
ldap_bindW
|
||||
ldap_bind_sA
|
||||
ldap_bind_sW
|
||||
ldap_close_extended_op
|
||||
ldap_compareA
|
||||
ldap_compareW
|
||||
ldap_count_values_len
|
||||
ldap_compare_ext
|
||||
ldap_value_free_len
|
||||
ldap_compare_extA
|
||||
ldap_compare_extW
|
||||
ldap_perror
|
||||
ldap_compare_ext_s
|
||||
ldap_compare_ext_sA
|
||||
ldap_compare_ext_sW
|
||||
ldap_compare_sA
|
||||
ldap_compare_sW
|
||||
ldap_connect
|
||||
ldap_control_free
|
||||
ldap_control_freeA
|
||||
ldap_control_freeW
|
||||
ldap_controls_free
|
||||
ldap_controls_freeA
|
||||
ldap_controls_freeW
|
||||
ldap_count_references
|
||||
ldap_count_valuesA
|
||||
ldap_count_valuesW
|
||||
ldap_create_page_control
|
||||
ldap_create_page_controlA
|
||||
ldap_create_page_controlW
|
||||
ldap_create_sort_control
|
||||
ldap_create_sort_controlA
|
||||
ldap_create_sort_controlW
|
||||
ldap_deleteA
|
||||
ldap_deleteW
|
||||
ldap_delete_ext
|
||||
ldap_delete_extA
|
||||
ldap_delete_extW
|
||||
ldap_delete_ext_s
|
||||
ldap_delete_ext_sA
|
||||
ldap_delete_ext_sW
|
||||
ldap_delete_sA
|
||||
ldap_delete_sW
|
||||
ldap_dn2ufnW
|
||||
ldap_encode_sort_controlA
|
||||
ldap_encode_sort_controlW
|
||||
ldap_err2stringA
|
||||
ldap_err2stringW
|
||||
ldap_escape_filter_elementA
|
||||
ldap_escape_filter_elementW
|
||||
ldap_explode_dnA
|
||||
ldap_explode_dnW
|
||||
ldap_extended_operation
|
||||
ldap_extended_operationA
|
||||
ldap_extended_operationW
|
||||
ldap_first_attributeA
|
||||
ldap_first_attributeW
|
||||
ldap_first_reference
|
||||
ldap_free_controls
|
||||
ldap_free_controlsA
|
||||
ldap_free_controlsW
|
||||
ldap_get_dnA
|
||||
ldap_get_dnW
|
||||
ldap_get_next_page
|
||||
ldap_get_next_page_s
|
||||
ldap_get_option
|
||||
ldap_get_optionA
|
||||
ldap_get_paged_count
|
||||
ldap_get_valuesA
|
||||
ldap_get_valuesW
|
||||
ldap_get_values_lenA
|
||||
ldap_get_values_lenW
|
||||
ldap_init
|
||||
ldap_initA
|
||||
ldap_initW
|
||||
ldap_memfreeA
|
||||
ldap_memfreeW
|
||||
ldap_modifyA
|
||||
ldap_modifyW
|
||||
ldap_modify_ext
|
||||
ldap_modify_extA
|
||||
ldap_modify_extW
|
||||
ldap_modify_ext_s
|
||||
ldap_modify_ext_sA
|
||||
ldap_modify_ext_sW
|
||||
ldap_modify_sA
|
||||
ldap_modify_sW
|
||||
ldap_modrdn2A
|
||||
ldap_modrdn2W
|
||||
ldap_modrdn2_sA
|
||||
ldap_modrdn2_sW
|
||||
ldap_modrdnA
|
||||
ldap_modrdnW
|
||||
ldap_modrdn_sA
|
||||
ldap_modrdn_sW
|
||||
ldap_next_attributeA
|
||||
ldap_next_attributeW
|
||||
ldap_next_reference
|
||||
ldap_openA
|
||||
ldap_openW
|
||||
ldap_parse_page_control
|
||||
ldap_parse_page_controlA
|
||||
ldap_parse_page_controlW
|
||||
ldap_parse_reference
|
||||
ldap_parse_referenceA
|
||||
ldap_parse_referenceW
|
||||
ldap_parse_result
|
||||
ldap_parse_resultA
|
||||
ldap_parse_resultW
|
||||
ldap_parse_sort_control
|
||||
ldap_parse_sort_controlA
|
||||
ldap_parse_sort_controlW
|
||||
ldap_rename_ext
|
||||
ldap_rename_extA
|
||||
ldap_rename_extW
|
||||
ldap_rename_ext_s
|
||||
ldap_rename_ext_sA
|
||||
ldap_rename_ext_sW
|
||||
ldap_searchA
|
||||
ldap_searchW
|
||||
ldap_search_abandon_page
|
||||
ldap_search_ext
|
||||
ldap_search_extA
|
||||
ldap_search_extW
|
||||
ldap_search_ext_s
|
||||
ldap_search_ext_sA
|
||||
ldap_escape_filter_element
|
||||
ldap_set_dbg_flags
|
||||
ldap_set_dbg_routine
|
||||
ldap_memfree
|
||||
ldap_startup
|
||||
ldap_cleanup
|
||||
ldap_search_ext_sW
|
||||
ldap_search_init_page
|
||||
ldap_search_init_pageA
|
||||
ldap_search_init_pageW
|
||||
ldap_search_sA
|
||||
ldap_search_sW
|
||||
ldap_search_stA
|
||||
ldap_search_stW
|
||||
ldap_set_option
|
||||
ldap_set_optionA
|
||||
ldap_simple_bindA
|
||||
ldap_simple_bindW
|
||||
ldap_simple_bind_sA
|
||||
ldap_simple_bind_sW
|
||||
ldap_sslinit
|
||||
ldap_sslinitA
|
||||
ldap_sslinitW
|
||||
ldap_ufn2dn
|
||||
ldap_ufn2dnA
|
||||
ldap_ufn2dnW
|
||||
ldap_value_freeA
|
||||
ldap_value_freeW
|
||||
ldap_check_filterA
|
||||
ldap_check_filterW
|
||||
ldap_dn2ufnA
|
||||
ber_init
|
||||
ber_free
|
||||
ber_bvecfree
|
||||
ber_bvdup
|
||||
ber_alloc_t
|
||||
ber_skip_tag
|
||||
ber_peek_tag
|
||||
ber_first_element
|
||||
ber_next_element
|
||||
ber_flatten
|
||||
ber_printf
|
||||
ber_scanf
|
||||
ldap_conn_from_msg
|
||||
ldap_sasl_bindW
|
||||
ldap_sasl_bind_sW
|
||||
ldap_sasl_bindA
|
||||
ldap_sasl_bind_sA
|
||||
ldap_parse_extended_resultW
|
||||
ldap_parse_extended_resultA
|
||||
ldap_create_vlv_controlW
|
||||
ldap_create_vlv_controlA
|
||||
ldap_parse_vlv_controlW
|
||||
ldap_parse_vlv_controlA
|
||||
ldap_start_tls_sW
|
||||
ldap_start_tls_sA
|
||||
ldap_stop_tls_s
|
||||
ldap_extended_operation_sW
|
||||
ldap_extended_operation_sA
|
||||
21
lib/libc/mingw/lib-common/xinput1_4.def
Normal file
21
lib/libc/mingw/lib-common/xinput1_4.def
Normal file
@@ -0,0 +1,21 @@
|
||||
;
|
||||
; Definition file of XINPUT1_4.dll
|
||||
; Automatic generated by gendef
|
||||
; written by Kai Tietz 2008
|
||||
;
|
||||
LIBRARY "XINPUT1_4.dll"
|
||||
EXPORTS
|
||||
;DllMain
|
||||
XInputGetState
|
||||
XInputSetState
|
||||
XInputGetCapabilities
|
||||
XInputEnable
|
||||
XInputGetBatteryInformation
|
||||
XInputGetKeystroke
|
||||
XInputGetAudioDeviceIds
|
||||
;ord_100 @100
|
||||
;ord_101 @101
|
||||
;ord_102 @102
|
||||
;ord_103 @103
|
||||
;ord_104 @104
|
||||
;ord_108 @108
|
||||
308
lib/libc/mingw/lib32/iphlpapi.def
Normal file
308
lib/libc/mingw/lib32/iphlpapi.def
Normal file
@@ -0,0 +1,308 @@
|
||||
;
|
||||
; Definition file of IPHLPAPI.DLL
|
||||
; Automatic generated by gendef
|
||||
; written by Kai Tietz 2008
|
||||
;
|
||||
LIBRARY "IPHLPAPI.DLL"
|
||||
EXPORTS
|
||||
AddIPAddress@20
|
||||
AllocateAndGetInterfaceInfoFromStack@20
|
||||
AllocateAndGetIpAddrTableFromStack@16
|
||||
CPNatfwtCreateProviderInstance@20
|
||||
CPNatfwtDeregisterProviderInstance@4
|
||||
CPNatfwtDestroyProviderInstance@4
|
||||
CPNatfwtIndicateReceivedBuffers@24
|
||||
CPNatfwtRegisterProviderInstance@20
|
||||
CancelIPChangeNotify@4
|
||||
CancelIfTimestampConfigChange@4
|
||||
CancelMibChangeNotify2@4
|
||||
CaptureInterfaceHardwareCrossTimestamp@8
|
||||
CloseCompartment@4
|
||||
CloseGetIPPhysicalInterfaceForDestination@4
|
||||
ConvertCompartmentGuidToId@8
|
||||
ConvertCompartmentIdToGuid@8
|
||||
ConvertGuidToStringA@12
|
||||
ConvertGuidToStringW@12
|
||||
ConvertInterfaceAliasToLuid@8
|
||||
ConvertInterfaceGuidToLuid@8
|
||||
ConvertInterfaceIndexToLuid@8
|
||||
ConvertInterfaceLuidToAlias@12
|
||||
ConvertInterfaceLuidToGuid@8
|
||||
ConvertInterfaceLuidToIndex@8
|
||||
ConvertInterfaceLuidToNameA@12
|
||||
ConvertInterfaceLuidToNameW@12
|
||||
ConvertInterfaceNameToLuidA@8
|
||||
ConvertInterfaceNameToLuidW@8
|
||||
ConvertInterfacePhysicalAddressToLuid@12
|
||||
ConvertIpv4MaskToLength@8
|
||||
ConvertLengthToIpv4Mask@8
|
||||
ConvertRemoteInterfaceAliasToLuid@12
|
||||
ConvertRemoteInterfaceGuidToLuid@12
|
||||
ConvertRemoteInterfaceIndexToLuid@12
|
||||
ConvertRemoteInterfaceLuidToAlias@16
|
||||
ConvertRemoteInterfaceLuidToGuid@12
|
||||
ConvertRemoteInterfaceLuidToIndex@12
|
||||
ConvertStringToGuidA@8
|
||||
ConvertStringToGuidW@8
|
||||
ConvertStringToInterfacePhysicalAddress@8
|
||||
CreateAnycastIpAddressEntry@4
|
||||
CreateCompartment@4
|
||||
CreateIpForwardEntry2@4
|
||||
CreateIpForwardEntry@4
|
||||
CreateIpNetEntry2@4
|
||||
CreateIpNetEntry@4
|
||||
CreatePersistentTcpPortReservation@12
|
||||
CreatePersistentUdpPortReservation@12
|
||||
CreateProxyArpEntry@12
|
||||
CreateSortedAddressPairs@28
|
||||
CreateUnicastIpAddressEntry@4
|
||||
DeleteAnycastIpAddressEntry@4
|
||||
DeleteCompartment@4
|
||||
DeleteIPAddress@4
|
||||
DeleteIpForwardEntry2@4
|
||||
DeleteIpForwardEntry@4
|
||||
DeleteIpNetEntry2@4
|
||||
DeleteIpNetEntry@4
|
||||
DeletePersistentTcpPortReservation@8
|
||||
DeletePersistentUdpPortReservation@8
|
||||
DeleteProxyArpEntry@12
|
||||
DeleteUnicastIpAddressEntry@4
|
||||
DisableMediaSense@8
|
||||
EnableRouter@8
|
||||
FlushIpNetTable2@8
|
||||
FlushIpNetTable@4
|
||||
FlushIpPathTable@4
|
||||
FreeDnsSettings@4
|
||||
FreeInterfaceDnsSettings@4
|
||||
FreeMibTable@4
|
||||
GetAdapterIndex@8
|
||||
GetAdapterOrderMap@0
|
||||
GetAdaptersAddresses@20
|
||||
GetAdaptersInfo@8
|
||||
GetAnycastIpAddressEntry@4
|
||||
GetAnycastIpAddressTable@8
|
||||
GetBestInterface@8
|
||||
GetBestInterfaceEx@8
|
||||
GetBestRoute2@28
|
||||
GetBestRoute@12
|
||||
GetCurrentThreadCompartmentId@0
|
||||
GetCurrentThreadCompartmentScope@8
|
||||
GetDefaultCompartmentId@0
|
||||
GetDnsSettings@4
|
||||
GetExtendedTcpTable@24
|
||||
GetExtendedUdpTable@24
|
||||
GetFriendlyIfIndex@4
|
||||
GetIcmpStatistics@4
|
||||
GetIcmpStatisticsEx@8
|
||||
GetIfEntry2@4
|
||||
GetIfEntry2Ex@8
|
||||
GetIfEntry@4
|
||||
GetIfStackTable@4
|
||||
GetIfTable2@4
|
||||
GetIfTable2Ex@8
|
||||
GetIfTable@12
|
||||
GetInterfaceCompartmentId@4
|
||||
GetInterfaceCurrentTimestampCapabilities@8
|
||||
GetInterfaceDnsSettings@20
|
||||
GetInterfaceHardwareTimestampCapabilities@8
|
||||
GetInterfaceInfo@8
|
||||
GetInvertedIfStackTable@4
|
||||
GetIpAddrTable@12
|
||||
GetIpErrorString@12
|
||||
GetIpForwardEntry2@4
|
||||
GetIpForwardTable2@8
|
||||
GetIpForwardTable@12
|
||||
GetIpInterfaceEntry@4
|
||||
GetIpInterfaceTable@8
|
||||
GetIpNetEntry2@4
|
||||
GetIpNetTable2@8
|
||||
GetIpNetTable@12
|
||||
GetIpNetworkConnectionBandwidthEstimates@12
|
||||
GetIpPathEntry@4
|
||||
GetIpPathTable@8
|
||||
GetIpStatistics@4
|
||||
GetIpStatisticsEx@8
|
||||
GetJobCompartmentId@4
|
||||
GetMulticastIpAddressEntry@4
|
||||
GetMulticastIpAddressTable@8
|
||||
GetNetworkConnectivityHint@4
|
||||
GetNetworkConnectivityHintForInterface@8
|
||||
GetNetworkInformation@20
|
||||
GetNetworkParams@8
|
||||
GetNumberOfInterfaces@4
|
||||
GetOwnerModuleFromPidAndInfo@20
|
||||
GetOwnerModuleFromTcp6Entry@16
|
||||
GetOwnerModuleFromTcpEntry@16
|
||||
GetOwnerModuleFromUdp6Entry@16
|
||||
GetOwnerModuleFromUdpEntry@16
|
||||
GetPerAdapterInfo@12
|
||||
GetPerTcp6ConnectionEStats@44
|
||||
GetPerTcp6ConnectionStats@32
|
||||
GetPerTcpConnectionEStats@44
|
||||
GetPerTcpConnectionStats@32
|
||||
GetRTTAndHopCount@16
|
||||
GetSessionCompartmentId@4
|
||||
GetTcp6Table2@12
|
||||
GetTcp6Table@12
|
||||
GetTcpStatistics@4
|
||||
GetTcpStatisticsEx2@8
|
||||
GetTcpStatisticsEx@8
|
||||
GetTcpTable2@12
|
||||
GetTcpTable@12
|
||||
GetTeredoPort@4
|
||||
GetUdp6Table@12
|
||||
GetUdpStatistics@4
|
||||
GetUdpStatisticsEx2@8
|
||||
GetUdpStatisticsEx@8
|
||||
GetUdpTable@12
|
||||
GetUniDirectionalAdapterInfo@8
|
||||
GetUnicastIpAddressEntry@4
|
||||
GetUnicastIpAddressTable@8
|
||||
GetWPAOACSupportLevel@0
|
||||
Icmp6CreateFile@0
|
||||
Icmp6ParseReplies@8
|
||||
Icmp6SendEcho2@48
|
||||
IcmpCloseHandle@4
|
||||
IcmpCreateFile@0
|
||||
IcmpParseReplies@8
|
||||
IcmpSendEcho2@44
|
||||
IcmpSendEcho2Ex@48
|
||||
IcmpSendEcho@32
|
||||
InitializeCompartmentEntry@4
|
||||
InitializeIpForwardEntry@4
|
||||
InitializeIpInterfaceEntry@4
|
||||
InitializeUnicastIpAddressEntry@4
|
||||
InternalCleanupPersistentStore@8
|
||||
InternalCreateAnycastIpAddressEntry@8
|
||||
InternalCreateIpForwardEntry2@8
|
||||
InternalCreateIpForwardEntry@4
|
||||
InternalCreateIpNetEntry2@8
|
||||
InternalCreateIpNetEntry@4
|
||||
InternalCreateUnicastIpAddressEntry@8
|
||||
InternalDeleteAnycastIpAddressEntry@8
|
||||
InternalDeleteIpForwardEntry2@8
|
||||
InternalDeleteIpForwardEntry@4
|
||||
InternalDeleteIpNetEntry2@8
|
||||
InternalDeleteIpNetEntry@4
|
||||
InternalDeleteUnicastIpAddressEntry@8
|
||||
InternalFindInterfaceByAddress@8
|
||||
InternalGetAnycastIpAddressEntry@8
|
||||
InternalGetAnycastIpAddressTable@12
|
||||
InternalGetBoundTcp6EndpointTable@12
|
||||
InternalGetBoundTcpEndpointTable@12
|
||||
InternalGetForwardIpTable2@12
|
||||
InternalGetIPPhysicalInterfaceForDestination@28
|
||||
InternalGetIfEntry2@8
|
||||
InternalGetIfTable2@8
|
||||
InternalGetIfTable@12
|
||||
InternalGetIpAddrTable@12
|
||||
InternalGetIpForwardEntry2@8
|
||||
InternalGetIpForwardTable@12
|
||||
InternalGetIpInterfaceEntry@8
|
||||
InternalGetIpInterfaceTable@12
|
||||
InternalGetIpNetEntry2@8
|
||||
InternalGetIpNetTable2@12
|
||||
InternalGetIpNetTable@12
|
||||
InternalGetMulticastIpAddressEntry@8
|
||||
InternalGetMulticastIpAddressTable@12
|
||||
InternalGetRtcSlotInformation@12
|
||||
InternalGetTcp6Table2@12
|
||||
InternalGetTcp6TableWithOwnerModule@12
|
||||
InternalGetTcp6TableWithOwnerPid@12
|
||||
InternalGetTcpTable2@12
|
||||
InternalGetTcpTable@12
|
||||
InternalGetTcpTableEx@12
|
||||
InternalGetTcpTableWithOwnerModule@12
|
||||
InternalGetTcpTableWithOwnerPid@12
|
||||
InternalGetTunnelPhysicalAdapter@8
|
||||
InternalGetUdp6TableWithOwnerModule@12
|
||||
InternalGetUdp6TableWithOwnerPid@12
|
||||
InternalGetUdpTable@12
|
||||
InternalGetUdpTableEx@12
|
||||
InternalGetUdpTableWithOwnerModule@12
|
||||
InternalGetUdpTableWithOwnerPid@12
|
||||
InternalGetUnicastIpAddressEntry@8
|
||||
InternalGetUnicastIpAddressTable@12
|
||||
InternalIcmpCreateFileEx@4
|
||||
InternalSetIfEntry@4
|
||||
InternalSetIpForwardEntry2@8
|
||||
InternalSetIpForwardEntry@4
|
||||
InternalSetIpInterfaceEntry@8
|
||||
InternalSetIpNetEntry2@8
|
||||
InternalSetIpNetEntry@4
|
||||
InternalSetIpStats@4
|
||||
InternalSetTcpEntry@4
|
||||
InternalSetTeredoPort@4
|
||||
InternalSetUnicastIpAddressEntry@8
|
||||
IpReleaseAddress@4
|
||||
IpRenewAddress@4
|
||||
LookupPersistentTcpPortReservation@12
|
||||
LookupPersistentUdpPortReservation@12
|
||||
NTPTimeToNTFileTime@12
|
||||
NTTimeToNTPTime@8
|
||||
NhGetGuidFromInterfaceName@16
|
||||
NhGetInterfaceDescriptionFromGuid@20
|
||||
NhGetInterfaceNameFromDeviceGuid@20
|
||||
NhGetInterfaceNameFromGuid@20
|
||||
NhpAllocateAndGetInterfaceInfoFromStack@20
|
||||
NotifyAddrChange@8
|
||||
NotifyCompartmentChange@16
|
||||
NotifyIfTimestampConfigChange@12
|
||||
NotifyIpInterfaceChange@20
|
||||
NotifyNetworkConnectivityHintChange@16
|
||||
NotifyRouteChange2@20
|
||||
NotifyRouteChange@8
|
||||
NotifyStableUnicastIpAddressTable@20
|
||||
NotifyTeredoPortChange@16
|
||||
NotifyUnicastIpAddressChange@20
|
||||
OpenCompartment@8
|
||||
ParseNetworkString@20
|
||||
_PfAddFiltersToInterface@24
|
||||
_PfAddGlobalFilterToInterface@8
|
||||
_PfBindInterfaceToIPAddress@12
|
||||
_PfBindInterfaceToIndex@16
|
||||
_PfCreateInterface@24
|
||||
_PfDeleteInterface@4
|
||||
_PfDeleteLog@0
|
||||
_PfGetInterfaceStatistics@16
|
||||
_PfMakeLog@4
|
||||
_PfRebindFilters@8
|
||||
_PfRemoveFilterHandles@12
|
||||
_PfRemoveFiltersFromInterface@20
|
||||
_PfRemoveGlobalFilterFromInterface@8
|
||||
_PfSetLogBuffer@28
|
||||
_PfTestPacket@20
|
||||
_PfUnBindInterface@4
|
||||
ResolveIpNetEntry2@8
|
||||
ResolveNeighbor@12
|
||||
RestoreMediaSense@8
|
||||
SendARP@16
|
||||
SetAdapterIpAddress@20
|
||||
SetCurrentThreadCompartmentId@4
|
||||
SetCurrentThreadCompartmentScope@4
|
||||
SetDnsSettings@4
|
||||
SetIfEntry@4
|
||||
SetInterfaceDnsSettings@20
|
||||
SetIpForwardEntry2@4
|
||||
SetIpForwardEntry@4
|
||||
SetIpInterfaceEntry@4
|
||||
SetIpNetEntry2@4
|
||||
SetIpNetEntry@4
|
||||
SetIpStatistics@4
|
||||
SetIpStatisticsEx@8
|
||||
SetIpTTL@4
|
||||
SetJobCompartmentId@8
|
||||
SetNetworkInformation@12
|
||||
SetPerTcp6ConnectionEStats@24
|
||||
SetPerTcp6ConnectionStats@20
|
||||
SetPerTcpConnectionEStats@24
|
||||
SetPerTcpConnectionStats@20
|
||||
SetSessionCompartmentId@8
|
||||
SetTcpEntry@4
|
||||
SetUnicastIpAddressEntry@4
|
||||
UnenableRouter@8
|
||||
do_echo_rep@40
|
||||
do_echo_req@40
|
||||
if_indextoname@8
|
||||
if_nametoindex@4
|
||||
register_icmp@0
|
||||
55
lib/libc/mingw/lib32/userenv.def
Normal file
55
lib/libc/mingw/lib32/userenv.def
Normal file
@@ -0,0 +1,55 @@
|
||||
;
|
||||
; Definition file of USERENV.dll
|
||||
; Automatic generated by gendef
|
||||
; written by Kai Tietz 2008
|
||||
;
|
||||
LIBRARY "USERENV.dll"
|
||||
EXPORTS
|
||||
RsopLoggingEnabled@0
|
||||
CreateEnvironmentBlock@12
|
||||
CreateProfile@16
|
||||
DeleteProfileA@12
|
||||
DeleteProfileW@12
|
||||
DestroyEnvironmentBlock@4
|
||||
;DllCanUnloadNow@0
|
||||
;DllGetClassObject@12
|
||||
;DllGetContractDescription@8
|
||||
;DllRegisterServer@0
|
||||
;DllUnregisterServer@0
|
||||
EnterCriticalPolicySection@4
|
||||
ExpandEnvironmentStringsForUserA@16
|
||||
ExpandEnvironmentStringsForUserW@16
|
||||
ForceSyncFgPolicy@4
|
||||
FreeGPOListA@4
|
||||
FreeGPOListW@4
|
||||
GetAllUsersProfileDirectoryA@8
|
||||
GetAllUsersProfileDirectoryW@8
|
||||
GetAppliedGPOListA@20
|
||||
GetAppliedGPOListW@20
|
||||
GetDefaultUserProfileDirectoryA@8
|
||||
GetDefaultUserProfileDirectoryW@8
|
||||
GetGPOListA@24
|
||||
GetGPOListW@24
|
||||
GetNextFgPolicyRefreshInfo@8
|
||||
GetPreviousFgPolicyRefreshInfo@8
|
||||
GetProfileType@4
|
||||
GetProfilesDirectoryA@8
|
||||
GetProfilesDirectoryW@8
|
||||
GetUserProfileDirectoryA@12
|
||||
GetUserProfileDirectoryW@12
|
||||
LeaveCriticalPolicySection@4
|
||||
LoadUserProfileA@8
|
||||
LoadUserProfileW@8
|
||||
ProcessGroupPolicyCompleted@12
|
||||
ProcessGroupPolicyCompletedEx@16
|
||||
RefreshPolicy@4
|
||||
RefreshPolicyEx@8
|
||||
RegisterGPNotification@8
|
||||
RsopAccessCheckByType@44
|
||||
RsopFileAccessCheck@20
|
||||
RsopResetPolicySettingStatus@12
|
||||
RsopSetPolicySettingStatus@20
|
||||
UnloadUserProfile@8
|
||||
UnregisterGPNotification@4
|
||||
WaitForMachinePolicyForegroundProcessing@0
|
||||
WaitForUserPolicyForegroundProcessing@0
|
||||
257
lib/libc/mingw/lib32/wldap32.def
Normal file
257
lib/libc/mingw/lib32/wldap32.def
Normal file
@@ -0,0 +1,257 @@
|
||||
;
|
||||
; wldap32.def - Import definition file for the Windows LDAP API
|
||||
;
|
||||
; Written by Filip Navara <xnavara@volny.cz>
|
||||
;
|
||||
; This library is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
;
|
||||
|
||||
LIBRARY wldap32.dll
|
||||
EXPORTS
|
||||
ldap_abandon
|
||||
ldap_add
|
||||
ldap_get_optionW
|
||||
ldap_unbind
|
||||
ldap_set_optionW
|
||||
LdapGetLastError
|
||||
cldap_open
|
||||
LdapMapErrorToWin32
|
||||
ldap_compare
|
||||
ldap_delete
|
||||
ldap_result2error
|
||||
ldap_err2string
|
||||
ldap_modify
|
||||
ldap_modrdn
|
||||
ldap_open
|
||||
ldap_first_entry
|
||||
ldap_next_entry
|
||||
cldap_openW
|
||||
LdapUTF8ToUnicode
|
||||
ldap_get_dn
|
||||
ldap_dn2ufn
|
||||
ldap_first_attribute
|
||||
ldap_next_attribute
|
||||
ldap_get_values
|
||||
ldap_get_values_len
|
||||
ldap_count_entries
|
||||
ldap_count_values
|
||||
ldap_value_free
|
||||
ldap_explode_dn
|
||||
ldap_result
|
||||
ldap_msgfree
|
||||
ldap_addW
|
||||
ldap_search
|
||||
ldap_add_s
|
||||
ldap_bind_s
|
||||
ldap_unbind_s
|
||||
ldap_delete_s
|
||||
ldap_modify_s
|
||||
ldap_modrdn_s
|
||||
ldap_search_s
|
||||
ldap_search_st
|
||||
ldap_compare_s
|
||||
LdapUnicodeToUTF8
|
||||
ber_bvfree
|
||||
cldap_openA
|
||||
ldap_addA
|
||||
ldap_add_ext
|
||||
ldap_add_extA
|
||||
ldap_simple_bind
|
||||
ldap_simple_bind_s
|
||||
ldap_bind
|
||||
ldap_add_extW
|
||||
ldap_add_ext_s
|
||||
ldap_add_ext_sA
|
||||
ldap_add_ext_sW
|
||||
ldap_add_sA
|
||||
ldap_modrdn2
|
||||
ldap_modrdn2_s
|
||||
ldap_add_sW
|
||||
ldap_bindA
|
||||
ldap_bindW
|
||||
ldap_bind_sA
|
||||
ldap_bind_sW
|
||||
ldap_close_extended_op
|
||||
ldap_compareA
|
||||
ldap_compareW
|
||||
ldap_count_values_len
|
||||
ldap_compare_ext
|
||||
ldap_value_free_len
|
||||
ldap_compare_extA
|
||||
ldap_compare_extW
|
||||
ldap_perror
|
||||
ldap_compare_ext_s
|
||||
ldap_compare_ext_sA
|
||||
ldap_compare_ext_sW
|
||||
ldap_compare_sA
|
||||
ldap_compare_sW
|
||||
ldap_connect
|
||||
ldap_control_free
|
||||
ldap_control_freeA
|
||||
ldap_control_freeW
|
||||
ldap_controls_free
|
||||
ldap_controls_freeA
|
||||
ldap_controls_freeW
|
||||
ldap_count_references
|
||||
ldap_count_valuesA
|
||||
ldap_count_valuesW
|
||||
ldap_create_page_control
|
||||
ldap_create_page_controlA
|
||||
ldap_create_page_controlW
|
||||
ldap_create_sort_control
|
||||
ldap_create_sort_controlA
|
||||
ldap_create_sort_controlW
|
||||
ldap_deleteA
|
||||
ldap_deleteW
|
||||
ldap_delete_ext
|
||||
ldap_delete_extA
|
||||
ldap_delete_extW
|
||||
ldap_delete_ext_s
|
||||
ldap_delete_ext_sA
|
||||
ldap_delete_ext_sW
|
||||
ldap_delete_sA
|
||||
ldap_delete_sW
|
||||
ldap_dn2ufnW
|
||||
ldap_encode_sort_controlA
|
||||
ldap_encode_sort_controlW
|
||||
ldap_err2stringA
|
||||
ldap_err2stringW
|
||||
ldap_escape_filter_elementA
|
||||
ldap_escape_filter_elementW
|
||||
ldap_explode_dnA
|
||||
ldap_explode_dnW
|
||||
ldap_extended_operation
|
||||
ldap_extended_operationA
|
||||
ldap_extended_operationW
|
||||
ldap_first_attributeA
|
||||
ldap_first_attributeW
|
||||
ldap_first_reference
|
||||
ldap_free_controls
|
||||
ldap_free_controlsA
|
||||
ldap_free_controlsW
|
||||
ldap_get_dnA
|
||||
ldap_get_dnW
|
||||
ldap_get_next_page
|
||||
ldap_get_next_page_s
|
||||
ldap_get_option
|
||||
ldap_get_optionA
|
||||
ldap_get_paged_count
|
||||
ldap_get_valuesA
|
||||
ldap_get_valuesW
|
||||
ldap_get_values_lenA
|
||||
ldap_get_values_lenW
|
||||
ldap_init
|
||||
ldap_initA
|
||||
ldap_initW
|
||||
ldap_memfreeA
|
||||
ldap_memfreeW
|
||||
ldap_modifyA
|
||||
ldap_modifyW
|
||||
ldap_modify_ext
|
||||
ldap_modify_extA
|
||||
ldap_modify_extW
|
||||
ldap_modify_ext_s
|
||||
ldap_modify_ext_sA
|
||||
ldap_modify_ext_sW
|
||||
ldap_modify_sA
|
||||
ldap_modify_sW
|
||||
ldap_modrdn2A
|
||||
ldap_modrdn2W
|
||||
ldap_modrdn2_sA
|
||||
ldap_modrdn2_sW
|
||||
ldap_modrdnA
|
||||
ldap_modrdnW
|
||||
ldap_modrdn_sA
|
||||
ldap_modrdn_sW
|
||||
ldap_next_attributeA
|
||||
ldap_next_attributeW
|
||||
ldap_next_reference
|
||||
ldap_openA
|
||||
ldap_openW
|
||||
ldap_parse_page_control
|
||||
ldap_parse_page_controlA
|
||||
ldap_parse_page_controlW
|
||||
ldap_parse_reference
|
||||
ldap_parse_referenceA
|
||||
ldap_parse_referenceW
|
||||
ldap_parse_result
|
||||
ldap_parse_resultA
|
||||
ldap_parse_resultW
|
||||
ldap_parse_sort_control
|
||||
ldap_parse_sort_controlA
|
||||
ldap_parse_sort_controlW
|
||||
ldap_rename_ext
|
||||
ldap_rename_extA
|
||||
ldap_rename_extW
|
||||
ldap_rename_ext_s
|
||||
ldap_rename_ext_sA
|
||||
ldap_rename_ext_sW
|
||||
ldap_searchA
|
||||
ldap_searchW
|
||||
ldap_search_abandon_page
|
||||
ldap_search_ext
|
||||
ldap_search_extA
|
||||
ldap_search_extW
|
||||
ldap_search_ext_s
|
||||
ldap_search_ext_sA
|
||||
ldap_escape_filter_element
|
||||
ldap_set_dbg_flags
|
||||
ldap_set_dbg_routine
|
||||
ldap_memfree
|
||||
ldap_startup
|
||||
ldap_cleanup
|
||||
ldap_search_ext_sW
|
||||
ldap_search_init_page
|
||||
ldap_search_init_pageA
|
||||
ldap_search_init_pageW
|
||||
ldap_search_sA
|
||||
ldap_search_sW
|
||||
ldap_search_stA
|
||||
ldap_search_stW
|
||||
ldap_set_option
|
||||
ldap_set_optionA
|
||||
ldap_simple_bindA
|
||||
ldap_simple_bindW
|
||||
ldap_simple_bind_sA
|
||||
ldap_simple_bind_sW
|
||||
ldap_sslinit
|
||||
ldap_sslinitA
|
||||
ldap_sslinitW
|
||||
ldap_ufn2dn
|
||||
ldap_ufn2dnA
|
||||
ldap_ufn2dnW
|
||||
ldap_value_freeA
|
||||
ldap_value_freeW
|
||||
ldap_check_filterA
|
||||
ldap_check_filterW
|
||||
ldap_dn2ufnA
|
||||
ber_init
|
||||
ber_free
|
||||
ber_bvecfree
|
||||
ber_bvdup
|
||||
ber_alloc_t
|
||||
ber_skip_tag
|
||||
ber_peek_tag
|
||||
ber_first_element
|
||||
ber_next_element
|
||||
ber_flatten
|
||||
ber_printf
|
||||
ber_scanf
|
||||
ldap_conn_from_msg
|
||||
ldap_sasl_bindW
|
||||
ldap_sasl_bind_sW
|
||||
ldap_sasl_bindA
|
||||
ldap_sasl_bind_sA
|
||||
ldap_parse_extended_resultW
|
||||
ldap_parse_extended_resultA
|
||||
ldap_create_vlv_controlW
|
||||
ldap_create_vlv_controlA
|
||||
ldap_parse_vlv_controlW
|
||||
ldap_parse_vlv_controlA
|
||||
ldap_start_tls_sW
|
||||
ldap_start_tls_sA
|
||||
ldap_stop_tls_s
|
||||
ldap_extended_operation_sW
|
||||
ldap_extended_operation_sA
|
||||
21
lib/libc/mingw/lib32/xinput1_4.def
Normal file
21
lib/libc/mingw/lib32/xinput1_4.def
Normal file
@@ -0,0 +1,21 @@
|
||||
;
|
||||
; Definition file of XINPUT1_4.dll
|
||||
; Automatic generated by gendef
|
||||
; written by Kai Tietz 2008
|
||||
;
|
||||
LIBRARY "XINPUT1_4.dll"
|
||||
EXPORTS
|
||||
;DllMain@12
|
||||
XInputGetState@8
|
||||
XInputSetState@8
|
||||
XInputGetCapabilities@12
|
||||
XInputEnable@4
|
||||
XInputGetBatteryInformation@12
|
||||
XInputGetKeystroke@12
|
||||
XInputGetAudioDeviceIds@20
|
||||
;ord_100@8 @100
|
||||
;ord_101@12 @101
|
||||
;ord_102@4 @102
|
||||
;ord_103@4 @103
|
||||
;ord_104@8 @104
|
||||
;ord_108@16 @108
|
||||
@@ -33,8 +33,13 @@ vsprintf_s (char *_DstBuf, size_t _Size, const char *_Format, va_list _ArgList)
|
||||
return _stub (_DstBuf, _Size, _Format, _ArgList);
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wimplicit-function-declaration"
|
||||
|
||||
static int __cdecl
|
||||
_int_vsprintf_s (char *_DstBuf, size_t _Size, const char *_Format, va_list _ArgList)
|
||||
{
|
||||
return __ms_vsnprintf (_DstBuf, _Size, _Format, _ArgList);
|
||||
}
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
@@ -10,7 +10,12 @@
|
||||
#include <wchar.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wimplicit-function-declaration"
|
||||
|
||||
int __ms_vwscanf (const wchar_t * __restrict__ format, va_list arg)
|
||||
{
|
||||
return __ms_vfwscanf(stdin, format, arg);
|
||||
}
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
5097
lib/libc/musl/libc.s
Normal file
5097
lib/libc/musl/libc.s
Normal file
File diff suppressed because it is too large
Load Diff
@@ -39,6 +39,7 @@ pub const BufMap = struct {
|
||||
const get_or_put = try self.hash_map.getOrPut(key);
|
||||
if (get_or_put.found_existing) {
|
||||
self.free(get_or_put.entry.key);
|
||||
self.free(get_or_put.entry.value);
|
||||
get_or_put.entry.key = key;
|
||||
}
|
||||
get_or_put.entry.value = value;
|
||||
@@ -88,7 +89,8 @@ pub const BufMap = struct {
|
||||
};
|
||||
|
||||
test "BufMap" {
|
||||
var bufmap = BufMap.init(std.testing.allocator);
|
||||
const allocator = std.testing.allocator;
|
||||
var bufmap = BufMap.init(allocator);
|
||||
defer bufmap.deinit();
|
||||
|
||||
try bufmap.set("x", "1");
|
||||
@@ -105,4 +107,7 @@ test "BufMap" {
|
||||
|
||||
bufmap.delete("x");
|
||||
testing.expect(0 == bufmap.count());
|
||||
|
||||
try bufmap.setMove(try allocator.dupe(u8, "k"), try allocator.dupe(u8, "v1"));
|
||||
try bufmap.setMove(try allocator.dupe(u8, "k"), try allocator.dupe(u8, "v2"));
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ pub const Builder = struct {
|
||||
installed_files: ArrayList(InstalledFile),
|
||||
build_root: []const u8,
|
||||
cache_root: []const u8,
|
||||
global_cache_root: []const u8,
|
||||
release_mode: ?builtin.Mode,
|
||||
is_release: bool,
|
||||
override_lib_dir: ?[]const u8,
|
||||
@@ -126,6 +127,7 @@ pub const Builder = struct {
|
||||
zig_exe: []const u8,
|
||||
build_root: []const u8,
|
||||
cache_root: []const u8,
|
||||
global_cache_root: []const u8,
|
||||
) !*Builder {
|
||||
const env_map = try allocator.create(BufMap);
|
||||
env_map.* = try process.getEnvMap(allocator);
|
||||
@@ -135,6 +137,7 @@ pub const Builder = struct {
|
||||
.zig_exe = zig_exe,
|
||||
.build_root = build_root,
|
||||
.cache_root = try fs.path.relative(allocator, build_root, cache_root),
|
||||
.global_cache_root = global_cache_root,
|
||||
.verbose = false,
|
||||
.verbose_tokenize = false,
|
||||
.verbose_ast = false,
|
||||
@@ -1128,7 +1131,13 @@ test "builder.findProgram compiles" {
|
||||
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||
defer arena.deinit();
|
||||
|
||||
const builder = try Builder.create(&arena.allocator, "zig", "zig-cache", "zig-cache");
|
||||
const builder = try Builder.create(
|
||||
&arena.allocator,
|
||||
"zig",
|
||||
"zig-cache",
|
||||
"zig-cache",
|
||||
"zig-cache",
|
||||
);
|
||||
defer builder.destroy();
|
||||
_ = builder.findProgram(&[_][]const u8{}, &[_][]const u8{}) catch null;
|
||||
}
|
||||
@@ -1216,7 +1225,7 @@ pub const LibExeObjStep = struct {
|
||||
emit_bin: bool = true,
|
||||
emit_docs: bool = false,
|
||||
emit_h: bool = false,
|
||||
bundle_compiler_rt: bool,
|
||||
bundle_compiler_rt: ?bool = null,
|
||||
disable_stack_probing: bool,
|
||||
disable_sanitize_c: bool,
|
||||
rdynamic: bool,
|
||||
@@ -1392,7 +1401,6 @@ pub const LibExeObjStep = struct {
|
||||
.exec_cmd_args = null,
|
||||
.name_prefix = "",
|
||||
.filter = null,
|
||||
.bundle_compiler_rt = false,
|
||||
.disable_stack_probing = false,
|
||||
.disable_sanitize_c = false,
|
||||
.rdynamic = false,
|
||||
@@ -1430,24 +1438,24 @@ pub const LibExeObjStep = struct {
|
||||
self.out_lib_filename = self.out_filename;
|
||||
} else if (self.version) |version| {
|
||||
if (target.isDarwin()) {
|
||||
self.major_only_filename = self.builder.fmt("lib{}.{d}.dylib", .{
|
||||
self.major_only_filename = self.builder.fmt("lib{s}.{d}.dylib", .{
|
||||
self.name,
|
||||
version.major,
|
||||
});
|
||||
self.name_only_filename = self.builder.fmt("lib{}.dylib", .{self.name});
|
||||
self.name_only_filename = self.builder.fmt("lib{s}.dylib", .{self.name});
|
||||
self.out_lib_filename = self.out_filename;
|
||||
} else if (target.os.tag == .windows) {
|
||||
self.out_lib_filename = self.builder.fmt("{}.lib", .{self.name});
|
||||
self.out_lib_filename = self.builder.fmt("{s}.lib", .{self.name});
|
||||
} else {
|
||||
self.major_only_filename = self.builder.fmt("lib{}.so.{d}", .{ self.name, version.major });
|
||||
self.name_only_filename = self.builder.fmt("lib{}.so", .{self.name});
|
||||
self.major_only_filename = self.builder.fmt("lib{s}.so.{d}", .{ self.name, version.major });
|
||||
self.name_only_filename = self.builder.fmt("lib{s}.so", .{self.name});
|
||||
self.out_lib_filename = self.out_filename;
|
||||
}
|
||||
} else {
|
||||
if (target.isDarwin()) {
|
||||
self.out_lib_filename = self.out_filename;
|
||||
} else if (target.os.tag == .windows) {
|
||||
self.out_lib_filename = self.builder.fmt("{}.lib", .{self.name});
|
||||
self.out_lib_filename = self.builder.fmt("{s}.lib", .{self.name});
|
||||
} else {
|
||||
self.out_lib_filename = self.out_filename;
|
||||
}
|
||||
@@ -1806,6 +1814,29 @@ pub const LibExeObjStep = struct {
|
||||
}
|
||||
return;
|
||||
},
|
||||
std.SemanticVersion => {
|
||||
out.print(
|
||||
\\pub const {z}: @import("std").SemanticVersion = .{{
|
||||
\\ .major = {d},
|
||||
\\ .minor = {d},
|
||||
\\ .patch = {d},
|
||||
\\
|
||||
, .{
|
||||
name,
|
||||
|
||||
value.major,
|
||||
value.minor,
|
||||
value.patch,
|
||||
}) catch unreachable;
|
||||
if (value.pre) |some| {
|
||||
out.print(" .pre = \"{Z}\",\n", .{some}) catch unreachable;
|
||||
}
|
||||
if (value.build) |some| {
|
||||
out.print(" .build = \"{Z}\",\n", .{some}) catch unreachable;
|
||||
}
|
||||
out.writeAll("};\n") catch unreachable;
|
||||
return;
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
switch (@typeInfo(T)) {
|
||||
@@ -1978,13 +2009,10 @@ pub const LibExeObjStep = struct {
|
||||
try zig_args.append(other.getOutputPath());
|
||||
},
|
||||
.Lib => {
|
||||
if (!other.is_dynamic or self.target.isWindows()) {
|
||||
try zig_args.append(other.getOutputLibPath());
|
||||
} else {
|
||||
const full_path_lib = other.getOutputPath();
|
||||
try zig_args.append("--library");
|
||||
try zig_args.append(full_path_lib);
|
||||
const full_path_lib = other.getOutputLibPath();
|
||||
try zig_args.append(full_path_lib);
|
||||
|
||||
if (other.is_dynamic and !self.target.isWindows()) {
|
||||
if (fs.path.dirname(full_path_lib)) |dirname| {
|
||||
try zig_args.append("-rpath");
|
||||
try zig_args.append(dirname);
|
||||
@@ -2105,6 +2133,9 @@ pub const LibExeObjStep = struct {
|
||||
try zig_args.append("--cache-dir");
|
||||
try zig_args.append(builder.pathFromRoot(builder.cache_root));
|
||||
|
||||
try zig_args.append("--global-cache-dir");
|
||||
try zig_args.append(builder.pathFromRoot(builder.global_cache_root));
|
||||
|
||||
zig_args.append("--name") catch unreachable;
|
||||
zig_args.append(self.name) catch unreachable;
|
||||
|
||||
@@ -2117,8 +2148,12 @@ pub const LibExeObjStep = struct {
|
||||
if (self.is_dynamic) {
|
||||
try zig_args.append("-dynamic");
|
||||
}
|
||||
if (self.bundle_compiler_rt) {
|
||||
try zig_args.append("--bundle-compiler-rt");
|
||||
if (self.bundle_compiler_rt) |x| {
|
||||
if (x) {
|
||||
try zig_args.append("-fcompiler-rt");
|
||||
} else {
|
||||
try zig_args.append("-fno-compiler-rt");
|
||||
}
|
||||
}
|
||||
if (self.disable_stack_probing) {
|
||||
try zig_args.append("-fno-stack-check");
|
||||
@@ -2131,7 +2166,7 @@ pub const LibExeObjStep = struct {
|
||||
}
|
||||
|
||||
if (self.code_model != .default) {
|
||||
try zig_args.append("-code-model");
|
||||
try zig_args.append("-mcmodel");
|
||||
try zig_args.append(@tagName(self.code_model));
|
||||
}
|
||||
|
||||
@@ -2712,6 +2747,7 @@ test "Builder.dupePkg()" {
|
||||
"test",
|
||||
"test",
|
||||
"test",
|
||||
"test",
|
||||
);
|
||||
defer builder.destroy();
|
||||
|
||||
@@ -2755,6 +2791,7 @@ test "LibExeObjStep.addBuildOption" {
|
||||
"test",
|
||||
"test",
|
||||
"test",
|
||||
"test",
|
||||
);
|
||||
defer builder.destroy();
|
||||
|
||||
@@ -2763,12 +2800,20 @@ test "LibExeObjStep.addBuildOption" {
|
||||
exe.addBuildOption(?usize, "option2", null);
|
||||
exe.addBuildOption([]const u8, "string", "zigisthebest");
|
||||
exe.addBuildOption(?[]const u8, "optional_string", null);
|
||||
exe.addBuildOption(std.SemanticVersion, "semantic_version", try std.SemanticVersion.parse("0.1.2-foo+bar"));
|
||||
|
||||
std.testing.expectEqualStrings(
|
||||
\\pub const option1: usize = 1;
|
||||
\\pub const option2: ?usize = null;
|
||||
\\pub const string: []const u8 = "zigisthebest";
|
||||
\\pub const optional_string: ?[]const u8 = null;
|
||||
\\pub const semantic_version: @import("std").SemanticVersion = .{
|
||||
\\ .major = 0,
|
||||
\\ .minor = 1,
|
||||
\\ .patch = 2,
|
||||
\\ .pre = "foo",
|
||||
\\ .build = "bar",
|
||||
\\};
|
||||
\\
|
||||
, exe.build_options_contents.items);
|
||||
}
|
||||
@@ -2784,6 +2829,7 @@ test "LibExeObjStep.addPackage" {
|
||||
"test",
|
||||
"test",
|
||||
"test",
|
||||
"test",
|
||||
);
|
||||
defer builder.destroy();
|
||||
|
||||
|
||||
@@ -490,11 +490,26 @@ pub const Version = struct {
|
||||
}
|
||||
|
||||
pub fn parse(text: []const u8) !Version {
|
||||
var it = std.mem.split(text, ".");
|
||||
var end: usize = 0;
|
||||
while (end < text.len) : (end += 1) {
|
||||
const c = text[end];
|
||||
if (!std.ascii.isDigit(c) and c != '.') break;
|
||||
}
|
||||
// found no digits or '.' before unexpected character
|
||||
if (end == 0) return error.InvalidVersion;
|
||||
|
||||
var it = std.mem.split(text[0..end], ".");
|
||||
// substring is not empty, first call will succeed
|
||||
const major = it.next().?;
|
||||
if (major.len == 0) return error.InvalidVersion;
|
||||
const minor = it.next() orelse "0";
|
||||
// ignore 'patch' if 'minor' is invalid
|
||||
const patch = if (minor.len == 0) "0" else (it.next() orelse "0");
|
||||
|
||||
return Version{
|
||||
.major = try std.fmt.parseInt(u32, it.next() orelse return error.InvalidVersion, 10),
|
||||
.minor = try std.fmt.parseInt(u32, it.next() orelse "0", 10),
|
||||
.patch = try std.fmt.parseInt(u32, it.next() orelse "0", 10),
|
||||
.major = try std.fmt.parseUnsigned(u32, major, 10),
|
||||
.minor = try std.fmt.parseUnsigned(u32, if (minor.len == 0) "0" else minor, 10),
|
||||
.patch = try std.fmt.parseUnsigned(u32, if (patch.len == 0) "0" else patch, 10),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -520,6 +535,56 @@ pub const Version = struct {
|
||||
}
|
||||
};
|
||||
|
||||
test "Version.parse" {
|
||||
@setEvalBranchQuota(3000);
|
||||
try testVersionParse();
|
||||
comptime (try testVersionParse());
|
||||
}
|
||||
|
||||
pub fn testVersionParse() !void {
|
||||
const f = struct {
|
||||
fn eql(text: []const u8, v1: u32, v2: u32, v3: u32) !void {
|
||||
const v = try Version.parse(text);
|
||||
std.testing.expect(v.major == v1 and v.minor == v2 and v.patch == v3);
|
||||
}
|
||||
|
||||
fn err(text: []const u8, expected_err: anyerror) !void {
|
||||
_ = Version.parse(text) catch |actual_err| {
|
||||
if (actual_err == expected_err) return;
|
||||
return actual_err;
|
||||
};
|
||||
return error.Unreachable;
|
||||
}
|
||||
};
|
||||
|
||||
try f.eql("2.6.32.11-svn21605", 2, 6, 32); // Debian PPC
|
||||
try f.eql("2.11.2(0.329/5/3)", 2, 11, 2); // MinGW
|
||||
try f.eql("5.4.0-1018-raspi", 5, 4, 0); // Ubuntu
|
||||
try f.eql("5.7.12_3", 5, 7, 12); // Void
|
||||
try f.eql("2.13-DEVELOPMENT", 2, 13, 0); // DragonFly
|
||||
try f.eql("2.3-35", 2, 3, 0);
|
||||
try f.eql("1a.4", 1, 0, 0);
|
||||
try f.eql("3.b1.0", 3, 0, 0);
|
||||
try f.eql("1.4beta", 1, 4, 0);
|
||||
try f.eql("2.7.pre", 2, 7, 0);
|
||||
try f.eql("0..3", 0, 0, 0);
|
||||
try f.eql("8.008.", 8, 8, 0);
|
||||
try f.eql("01...", 1, 0, 0);
|
||||
try f.eql("55", 55, 0, 0);
|
||||
try f.eql("4294967295.0.1", 4294967295, 0, 1);
|
||||
try f.eql("429496729_6", 429496729, 0, 0);
|
||||
|
||||
try f.err("foobar", error.InvalidVersion);
|
||||
try f.err("", error.InvalidVersion);
|
||||
try f.err("-1", error.InvalidVersion);
|
||||
try f.err("+4", error.InvalidVersion);
|
||||
try f.err(".", error.InvalidVersion);
|
||||
try f.err("....3", error.InvalidVersion);
|
||||
try f.err("4294967296", error.Overflow);
|
||||
try f.err("5000877755", error.Overflow);
|
||||
// error.InvalidCharacter is not possible anymore
|
||||
}
|
||||
|
||||
/// This data structure is used by the Zig language code generation and
|
||||
/// therefore must be kept in sync with the compiler implementation.
|
||||
pub const CallOptions = struct {
|
||||
|
||||
@@ -259,7 +259,7 @@ pub usingnamespace switch (builtin.os.tag) {
|
||||
};
|
||||
|
||||
pub extern "c" fn realloc(?*c_void, usize) ?*c_void;
|
||||
pub extern "c" fn free(*c_void) void;
|
||||
pub extern "c" fn free(?*c_void) void;
|
||||
pub extern "c" fn posix_memalign(memptr: **c_void, alignment: usize, size: usize) c_int;
|
||||
|
||||
pub extern "c" fn futimes(fd: fd_t, times: *[2]timeval) c_int;
|
||||
@@ -271,6 +271,7 @@ pub extern "c" fn futimens(fd: fd_t, times: *const [2]timespec) c_int;
|
||||
pub extern "c" fn pthread_create(noalias newthread: *pthread_t, noalias attr: ?*const pthread_attr_t, start_routine: fn (?*c_void) callconv(.C) ?*c_void, noalias arg: ?*c_void) c_int;
|
||||
pub extern "c" fn pthread_attr_init(attr: *pthread_attr_t) c_int;
|
||||
pub extern "c" fn pthread_attr_setstack(attr: *pthread_attr_t, stackaddr: *c_void, stacksize: usize) c_int;
|
||||
pub extern "c" fn pthread_attr_setstacksize(attr: *pthread_attr_t, stacksize: usize) c_int;
|
||||
pub extern "c" fn pthread_attr_setguardsize(attr: *pthread_attr_t, guardsize: usize) c_int;
|
||||
pub extern "c" fn pthread_attr_destroy(attr: *pthread_attr_t) c_int;
|
||||
pub extern "c" fn pthread_self() pthread_t;
|
||||
|
||||
@@ -144,7 +144,7 @@ pub const Edwards25519 = struct {
|
||||
|
||||
inline fn pcSelect(pc: [16]Edwards25519, b: u8) Edwards25519 {
|
||||
var t = Edwards25519.identityElement;
|
||||
comptime var i: u8 = 0;
|
||||
comptime var i: u8 = 1;
|
||||
inline while (i < 16) : (i += 1) {
|
||||
t.cMov(pc[i], ((@as(usize, b ^ i) -% 1) >> 8) & 1);
|
||||
}
|
||||
@@ -155,7 +155,6 @@ pub const Edwards25519 = struct {
|
||||
var q = Edwards25519.identityElement;
|
||||
var pos: usize = 252;
|
||||
while (true) : (pos -= 4) {
|
||||
q = q.dbl().dbl().dbl().dbl();
|
||||
const bit = (s[pos >> 3] >> @truncate(u3, pos)) & 0xf;
|
||||
if (vartime) {
|
||||
if (bit != 0) {
|
||||
@@ -165,6 +164,7 @@ pub const Edwards25519 = struct {
|
||||
q = q.add(pcSelect(pc, bit));
|
||||
}
|
||||
if (pos == 0) break;
|
||||
q = q.dbl().dbl().dbl().dbl();
|
||||
}
|
||||
try q.rejectIdentity();
|
||||
return q;
|
||||
@@ -181,32 +181,31 @@ pub const Edwards25519 = struct {
|
||||
return pc;
|
||||
}
|
||||
|
||||
const basePointPc = comptime pc: {
|
||||
@setEvalBranchQuota(10000);
|
||||
break :pc precompute(Edwards25519.basePoint);
|
||||
};
|
||||
|
||||
/// Multiply an Edwards25519 point by a scalar without clamping it.
|
||||
/// Return error.WeakPublicKey if the resulting point is
|
||||
/// the identity element.
|
||||
pub fn mul(p: Edwards25519, s: [32]u8) !Edwards25519 {
|
||||
var pc: [16]Edwards25519 = undefined;
|
||||
if (p.is_base) {
|
||||
@setEvalBranchQuota(10000);
|
||||
pc = comptime precompute(Edwards25519.basePoint);
|
||||
} else {
|
||||
pc = precompute(p);
|
||||
pc[4].rejectIdentity() catch |_| return error.WeakPublicKey;
|
||||
}
|
||||
const pc = if (p.is_base) basePointPc else pc: {
|
||||
const xpc = precompute(p);
|
||||
xpc[4].rejectIdentity() catch |_| return error.WeakPublicKey;
|
||||
break :pc xpc;
|
||||
};
|
||||
return pcMul(pc, s, false);
|
||||
}
|
||||
|
||||
/// Multiply an Edwards25519 point by a *PUBLIC* scalar *IN VARIABLE TIME*
|
||||
/// This can be used for signature verification.
|
||||
pub fn mulPublic(p: Edwards25519, s: [32]u8) !Edwards25519 {
|
||||
var pc: [16]Edwards25519 = undefined;
|
||||
if (p.is_base) {
|
||||
@setEvalBranchQuota(10000);
|
||||
pc = comptime precompute(Edwards25519.basePoint);
|
||||
} else {
|
||||
pc = precompute(p);
|
||||
pc[4].rejectIdentity() catch |_| return error.WeakPublicKey;
|
||||
}
|
||||
const pc = if (p.is_base) basePointPc else pc: {
|
||||
const xpc = precompute(p);
|
||||
xpc[4].rejectIdentity() catch |_| return error.WeakPublicKey;
|
||||
break :pc xpc;
|
||||
};
|
||||
return pcMul(pc, s, true);
|
||||
}
|
||||
|
||||
@@ -215,18 +214,15 @@ pub const Edwards25519 = struct {
|
||||
pub fn mulMulti(comptime count: usize, ps: [count]Edwards25519, ss: [count][32]u8) !Edwards25519 {
|
||||
var pcs: [count][16]Edwards25519 = undefined;
|
||||
for (ps) |p, i| {
|
||||
if (p.is_base) {
|
||||
@setEvalBranchQuota(10000);
|
||||
pcs[i] = comptime precompute(Edwards25519.basePoint);
|
||||
} else {
|
||||
pcs[i] = precompute(p);
|
||||
pcs[i][4].rejectIdentity() catch |_| return error.WeakPublicKey;
|
||||
}
|
||||
pcs[i] = if (p.is_base) basePointPc else pc: {
|
||||
const xpc = precompute(p);
|
||||
xpc[4].rejectIdentity() catch |_| return error.WeakPublicKey;
|
||||
break :pc xpc;
|
||||
};
|
||||
}
|
||||
var q = Edwards25519.identityElement;
|
||||
var pos: usize = 252;
|
||||
while (true) : (pos -= 4) {
|
||||
q = q.dbl().dbl().dbl().dbl();
|
||||
for (ss) |s, i| {
|
||||
const bit = (s[pos >> 3] >> @truncate(u3, pos)) & 0xf;
|
||||
if (bit != 0) {
|
||||
@@ -234,6 +230,7 @@ pub const Edwards25519 = struct {
|
||||
}
|
||||
}
|
||||
if (pos == 0) break;
|
||||
q = q.dbl().dbl().dbl().dbl();
|
||||
}
|
||||
try q.rejectIdentity();
|
||||
return q;
|
||||
|
||||
@@ -666,7 +666,7 @@ pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo {
|
||||
.macos,
|
||||
.windows,
|
||||
=> return DebugInfo.init(allocator),
|
||||
else => @compileError("openSelfDebugInfo unsupported for this platform"),
|
||||
else => return error.UnsupportedDebugInfo,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1762,12 +1762,18 @@ fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const c_v
|
||||
.netbsd => @ptrToInt(info.info.reason.fault.addr),
|
||||
else => unreachable,
|
||||
};
|
||||
switch (sig) {
|
||||
os.SIGSEGV => std.debug.warn("Segmentation fault at address 0x{x}\n", .{addr}),
|
||||
os.SIGILL => std.debug.warn("Illegal instruction at address 0x{x}\n", .{addr}),
|
||||
os.SIGBUS => std.debug.warn("Bus error at address 0x{x}\n", .{addr}),
|
||||
else => unreachable,
|
||||
|
||||
// Don't use std.debug.print() as stderr_mutex may still be locked.
|
||||
nosuspend {
|
||||
const stderr = io.getStdErr().writer();
|
||||
_ = switch (sig) {
|
||||
os.SIGSEGV => stderr.print("Segmentation fault at address 0x{x}\n", .{addr}),
|
||||
os.SIGILL => stderr.print("Illegal instruction at address 0x{x}\n", .{addr}),
|
||||
os.SIGBUS => stderr.print("Bus error at address 0x{x}\n", .{addr}),
|
||||
else => unreachable,
|
||||
} catch os.abort();
|
||||
}
|
||||
|
||||
switch (builtin.arch) {
|
||||
.i386 => {
|
||||
const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr));
|
||||
@@ -1818,11 +1824,15 @@ fn handleSegfaultWindowsExtra(info: *windows.EXCEPTION_POINTERS, comptime msg: u
|
||||
const exception_address = @ptrToInt(info.ExceptionRecord.ExceptionAddress);
|
||||
if (@hasDecl(windows, "CONTEXT")) {
|
||||
const regs = info.ContextRecord.getRegs();
|
||||
switch (msg) {
|
||||
0 => std.debug.warn("{}\n", .{format.?}),
|
||||
1 => std.debug.warn("Segmentation fault at address 0x{x}\n", .{info.ExceptionRecord.ExceptionInformation[1]}),
|
||||
2 => std.debug.warn("Illegal instruction at address 0x{x}\n", .{regs.ip}),
|
||||
else => unreachable,
|
||||
// Don't use std.debug.print() as stderr_mutex may still be locked.
|
||||
nosuspend {
|
||||
const stderr = io.getStdErr().writer();
|
||||
_ = switch (msg) {
|
||||
0 => stderr.print("{s}\n", .{format.?}),
|
||||
1 => stderr.print("Segmentation fault at address 0x{x}\n", .{info.ExceptionRecord.ExceptionInformation[1]}),
|
||||
2 => stderr.print("Illegal instruction at address 0x{x}\n", .{regs.ip}),
|
||||
else => unreachable,
|
||||
} catch os.abort();
|
||||
}
|
||||
|
||||
dumpStackTraceFromBase(regs.bp, regs.ip);
|
||||
|
||||
@@ -344,9 +344,14 @@ pub const WindowsDynLib = struct {
|
||||
}
|
||||
|
||||
pub fn openW(path_w: [*:0]const u16) !WindowsDynLib {
|
||||
return WindowsDynLib{
|
||||
var offset: usize = 0;
|
||||
if (path_w[0] == '\\' and path_w[1] == '?' and path_w[2] == '?' and path_w[3] == '\\') {
|
||||
// + 4 to skip over the \??\
|
||||
.dll = try windows.LoadLibraryW(path_w + 4),
|
||||
offset = 4;
|
||||
}
|
||||
|
||||
return WindowsDynLib{
|
||||
.dll = try windows.LoadLibraryW(path_w + offset),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ pub const Locked = @import("event/locked.zig").Locked;
|
||||
pub const RwLock = @import("event/rwlock.zig").RwLock;
|
||||
pub const RwLocked = @import("event/rwlocked.zig").RwLocked;
|
||||
pub const Loop = @import("event/loop.zig").Loop;
|
||||
pub const WaitGroup = @import("event/WaitGroup.zig").WaitGroup;
|
||||
pub const WaitGroup = @import("event/wait_group.zig").WaitGroup;
|
||||
|
||||
test "import event tests" {
|
||||
_ = @import("event/channel.zig");
|
||||
|
||||
@@ -687,7 +687,7 @@ pub const Dir = struct {
|
||||
return self.openFileZ(&path_c, flags);
|
||||
}
|
||||
|
||||
/// Save as `openFile` but WASI only.
|
||||
/// Same as `openFile` but WASI only.
|
||||
pub fn openFileWasi(self: Dir, sub_path: []const u8, flags: File.OpenFlags) File.OpenError!File {
|
||||
const w = os.wasi;
|
||||
var fdflags: w.fdflags_t = 0x0;
|
||||
|
||||
@@ -394,7 +394,7 @@ pub const File = struct {
|
||||
var array_list = try std.ArrayListAligned(u8, alignment).initCapacity(allocator, initial_cap);
|
||||
defer array_list.deinit();
|
||||
|
||||
self.reader().readAllArrayList(&array_list, max_bytes) catch |err| switch (err) {
|
||||
self.reader().readAllArrayListAligned(alignment, &array_list, max_bytes) catch |err| switch (err) {
|
||||
error.StreamTooLong => return error.FileTooBig,
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
@@ -28,6 +28,7 @@ pub const delimiter_windows = ';';
|
||||
pub const delimiter_posix = ':';
|
||||
pub const delimiter = if (builtin.os.tag == .windows) delimiter_windows else delimiter_posix;
|
||||
|
||||
/// Returns if the given byte is a valid path separator
|
||||
pub fn isSep(byte: u8) bool {
|
||||
if (builtin.os.tag == .windows) {
|
||||
return byte == '/' or byte == '\\';
|
||||
@@ -749,8 +750,12 @@ fn testResolvePosix(paths: []const []const u8, expected: []const u8) !void {
|
||||
return testing.expect(mem.eql(u8, actual, expected));
|
||||
}
|
||||
|
||||
/// Strip the last component from a file path.
|
||||
///
|
||||
/// If the path is a file in the current directory (no directory component)
|
||||
/// then returns null
|
||||
/// then returns null.
|
||||
///
|
||||
/// If the path is the root directory, returns null.
|
||||
pub fn dirname(path: []const u8) ?[]const u8 {
|
||||
if (builtin.os.tag == .windows) {
|
||||
return dirnameWindows(path);
|
||||
@@ -765,19 +770,19 @@ pub fn dirnameWindows(path: []const u8) ?[]const u8 {
|
||||
|
||||
const root_slice = diskDesignatorWindows(path);
|
||||
if (path.len == root_slice.len)
|
||||
return path;
|
||||
return null;
|
||||
|
||||
const have_root_slash = path.len > root_slice.len and (path[root_slice.len] == '/' or path[root_slice.len] == '\\');
|
||||
|
||||
var end_index: usize = path.len - 1;
|
||||
|
||||
while ((path[end_index] == '/' or path[end_index] == '\\') and end_index > root_slice.len) {
|
||||
while (path[end_index] == '/' or path[end_index] == '\\') {
|
||||
if (end_index == 0)
|
||||
return null;
|
||||
end_index -= 1;
|
||||
}
|
||||
|
||||
while (path[end_index] != '/' and path[end_index] != '\\' and end_index > root_slice.len) {
|
||||
while (path[end_index] != '/' and path[end_index] != '\\') {
|
||||
if (end_index == 0)
|
||||
return null;
|
||||
end_index -= 1;
|
||||
@@ -800,7 +805,7 @@ pub fn dirnamePosix(path: []const u8) ?[]const u8 {
|
||||
var end_index: usize = path.len - 1;
|
||||
while (path[end_index] == '/') {
|
||||
if (end_index == 0)
|
||||
return path[0..1];
|
||||
return null;
|
||||
end_index -= 1;
|
||||
}
|
||||
|
||||
@@ -810,7 +815,7 @@ pub fn dirnamePosix(path: []const u8) ?[]const u8 {
|
||||
end_index -= 1;
|
||||
}
|
||||
|
||||
if (end_index == 0 and path[end_index] == '/')
|
||||
if (end_index == 0 and path[0] == '/')
|
||||
return path[0..1];
|
||||
|
||||
if (end_index == 0)
|
||||
@@ -823,8 +828,10 @@ test "dirnamePosix" {
|
||||
testDirnamePosix("/a/b/c", "/a/b");
|
||||
testDirnamePosix("/a/b/c///", "/a/b");
|
||||
testDirnamePosix("/a", "/");
|
||||
testDirnamePosix("/", "/");
|
||||
testDirnamePosix("////", "/");
|
||||
testDirnamePosix("/", null);
|
||||
testDirnamePosix("//", null);
|
||||
testDirnamePosix("///", null);
|
||||
testDirnamePosix("////", null);
|
||||
testDirnamePosix("", null);
|
||||
testDirnamePosix("a", null);
|
||||
testDirnamePosix("a/", null);
|
||||
@@ -832,27 +839,27 @@ test "dirnamePosix" {
|
||||
}
|
||||
|
||||
test "dirnameWindows" {
|
||||
testDirnameWindows("c:\\", "c:\\");
|
||||
testDirnameWindows("c:\\", null);
|
||||
testDirnameWindows("c:\\foo", "c:\\");
|
||||
testDirnameWindows("c:\\foo\\", "c:\\");
|
||||
testDirnameWindows("c:\\foo\\bar", "c:\\foo");
|
||||
testDirnameWindows("c:\\foo\\bar\\", "c:\\foo");
|
||||
testDirnameWindows("c:\\foo\\bar\\baz", "c:\\foo\\bar");
|
||||
testDirnameWindows("\\", "\\");
|
||||
testDirnameWindows("\\", null);
|
||||
testDirnameWindows("\\foo", "\\");
|
||||
testDirnameWindows("\\foo\\", "\\");
|
||||
testDirnameWindows("\\foo\\bar", "\\foo");
|
||||
testDirnameWindows("\\foo\\bar\\", "\\foo");
|
||||
testDirnameWindows("\\foo\\bar\\baz", "\\foo\\bar");
|
||||
testDirnameWindows("c:", "c:");
|
||||
testDirnameWindows("c:foo", "c:");
|
||||
testDirnameWindows("c:foo\\", "c:");
|
||||
testDirnameWindows("c:", null);
|
||||
testDirnameWindows("c:foo", null);
|
||||
testDirnameWindows("c:foo\\", null);
|
||||
testDirnameWindows("c:foo\\bar", "c:foo");
|
||||
testDirnameWindows("c:foo\\bar\\", "c:foo");
|
||||
testDirnameWindows("c:foo\\bar\\baz", "c:foo\\bar");
|
||||
testDirnameWindows("file:stream", null);
|
||||
testDirnameWindows("dir\\file:stream", "dir");
|
||||
testDirnameWindows("\\\\unc\\share", "\\\\unc\\share");
|
||||
testDirnameWindows("\\\\unc\\share", null);
|
||||
testDirnameWindows("\\\\unc\\share\\foo", "\\\\unc\\share\\");
|
||||
testDirnameWindows("\\\\unc\\share\\foo\\", "\\\\unc\\share\\");
|
||||
testDirnameWindows("\\\\unc\\share\\foo\\bar", "\\\\unc\\share\\foo");
|
||||
@@ -862,8 +869,8 @@ test "dirnameWindows" {
|
||||
testDirnameWindows("/a/b", "/a");
|
||||
testDirnameWindows("/a", "/");
|
||||
testDirnameWindows("", null);
|
||||
testDirnameWindows("/", "/");
|
||||
testDirnameWindows("////", "/");
|
||||
testDirnameWindows("/", null);
|
||||
testDirnameWindows("////", null);
|
||||
testDirnameWindows("foo", null);
|
||||
}
|
||||
|
||||
@@ -1182,3 +1189,68 @@ fn testRelativeWindows(from: []const u8, to: []const u8, expected_output: []cons
|
||||
defer testing.allocator.free(result);
|
||||
testing.expectEqualSlices(u8, expected_output, result);
|
||||
}
|
||||
|
||||
/// Returns the extension of the file name (if any).
|
||||
/// This function will search for the file extension (separated by a `.`) and will return the text after the `.`.
|
||||
/// Files that end with `.` are considered to have no extension, files that start with `.`
|
||||
/// Examples:
|
||||
/// - `"main.zig"` ⇒ `".zig"`
|
||||
/// - `"src/main.zig"` ⇒ `".zig"`
|
||||
/// - `".gitignore"` ⇒ `""`
|
||||
/// - `"keep."` ⇒ `"."`
|
||||
/// - `"src.keep.me"` ⇒ `".me"`
|
||||
/// - `"/src/keep.me"` ⇒ `".me"`
|
||||
/// - `"/src/keep.me/"` ⇒ `".me"`
|
||||
/// The returned slice is guaranteed to have its pointer within the start and end
|
||||
/// pointer address range of `path`, even if it is length zero.
|
||||
pub fn extension(path: []const u8) []const u8 {
|
||||
const filename = basename(path);
|
||||
const index = mem.lastIndexOf(u8, filename, ".") orelse return path[path.len..];
|
||||
if (index == 0) return path[path.len..];
|
||||
return filename[index..];
|
||||
}
|
||||
|
||||
fn testExtension(path: []const u8, expected: []const u8) void {
|
||||
std.testing.expectEqualStrings(expected, extension(path));
|
||||
}
|
||||
|
||||
test "extension" {
|
||||
testExtension("", "");
|
||||
testExtension(".", "");
|
||||
testExtension("a.", ".");
|
||||
testExtension("abc.", ".");
|
||||
testExtension(".a", "");
|
||||
testExtension(".file", "");
|
||||
testExtension(".gitignore", "");
|
||||
testExtension("file.ext", ".ext");
|
||||
testExtension("file.ext.", ".");
|
||||
testExtension("very-long-file.bruh", ".bruh");
|
||||
testExtension("a.b.c", ".c");
|
||||
testExtension("a.b.c/", ".c");
|
||||
|
||||
testExtension("/", "");
|
||||
testExtension("/.", "");
|
||||
testExtension("/a.", ".");
|
||||
testExtension("/abc.", ".");
|
||||
testExtension("/.a", "");
|
||||
testExtension("/.file", "");
|
||||
testExtension("/.gitignore", "");
|
||||
testExtension("/file.ext", ".ext");
|
||||
testExtension("/file.ext.", ".");
|
||||
testExtension("/very-long-file.bruh", ".bruh");
|
||||
testExtension("/a.b.c", ".c");
|
||||
testExtension("/a.b.c/", ".c");
|
||||
|
||||
testExtension("/foo/bar/bam/", "");
|
||||
testExtension("/foo/bar/bam/.", "");
|
||||
testExtension("/foo/bar/bam/a.", ".");
|
||||
testExtension("/foo/bar/bam/abc.", ".");
|
||||
testExtension("/foo/bar/bam/.a", "");
|
||||
testExtension("/foo/bar/bam/.file", "");
|
||||
testExtension("/foo/bar/bam/.gitignore", "");
|
||||
testExtension("/foo/bar/bam/file.ext", ".ext");
|
||||
testExtension("/foo/bar/bam/file.ext.", ".");
|
||||
testExtension("/foo/bar/bam/very-long-file.bruh", ".bruh");
|
||||
testExtension("/foo/bar/bam/a.b.c", ".c");
|
||||
testExtension("/foo/bar/bam/a.b.c/", ".c");
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ pub const Murmur2_64 = struct {
|
||||
return @call(.{ .modifier = .always_inline }, Self.hashUint32WithSeed, .{ v, default_seed });
|
||||
}
|
||||
|
||||
pub fn hashUint32WithSeed(v: u32, seed: u32) u64 {
|
||||
pub fn hashUint32WithSeed(v: u32, seed: u64) u64 {
|
||||
const m: u64 = 0xc6a4a7935bd1e995;
|
||||
const len: u64 = 4;
|
||||
var h1: u64 = seed ^ (len *% m);
|
||||
@@ -152,7 +152,7 @@ pub const Murmur2_64 = struct {
|
||||
return @call(.{ .modifier = .always_inline }, Self.hashUint64WithSeed, .{ v, default_seed });
|
||||
}
|
||||
|
||||
pub fn hashUint64WithSeed(v: u64, seed: u32) u64 {
|
||||
pub fn hashUint64WithSeed(v: u64, seed: u64) u64 {
|
||||
const m: u64 = 0xc6a4a7935bd1e995;
|
||||
const len: u64 = 8;
|
||||
var h1: u64 = seed ^ (len *% m);
|
||||
|
||||
@@ -428,7 +428,7 @@ pub fn HashMapUnmanaged(
|
||||
if (self.metadata) |_| {
|
||||
self.initMetadatas();
|
||||
self.size = 0;
|
||||
self.available = 0;
|
||||
self.available = @truncate(u32, (self.capacity() * MaxLoadPercentage) / 100);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -468,41 +468,12 @@ pub fn HashMapUnmanaged(
|
||||
self.putAssumeCapacityNoClobber(key, value);
|
||||
}
|
||||
|
||||
/// Asserts there is enough capacity to store the new key-value pair.
|
||||
/// Clobbers any existing data. To detect if a put would clobber
|
||||
/// existing data, see `getOrPutAssumeCapacity`.
|
||||
pub fn putAssumeCapacity(self: *Self, key: K, value: V) void {
|
||||
const hash = hashFn(key);
|
||||
const mask = self.capacity() - 1;
|
||||
const fingerprint = Metadata.takeFingerprint(hash);
|
||||
var idx = @truncate(usize, hash & mask);
|
||||
|
||||
var first_tombstone_idx: usize = self.capacity(); // invalid index
|
||||
var metadata = self.metadata.? + idx;
|
||||
while (metadata[0].isUsed() or metadata[0].isTombstone()) {
|
||||
if (metadata[0].isUsed() and metadata[0].fingerprint == fingerprint) {
|
||||
const entry = &self.entries()[idx];
|
||||
if (eqlFn(entry.key, key)) {
|
||||
return;
|
||||
}
|
||||
} else if (first_tombstone_idx == self.capacity() and metadata[0].isTombstone()) {
|
||||
first_tombstone_idx = idx;
|
||||
}
|
||||
|
||||
idx = (idx + 1) & mask;
|
||||
metadata = self.metadata.? + idx;
|
||||
}
|
||||
|
||||
if (first_tombstone_idx < self.capacity()) {
|
||||
// Cheap try to lower probing lengths after deletions. Recycle a tombstone.
|
||||
idx = first_tombstone_idx;
|
||||
metadata = self.metadata.? + idx;
|
||||
} else {
|
||||
// We're using a slot previously free.
|
||||
self.available -= 1;
|
||||
}
|
||||
|
||||
metadata[0].fill(fingerprint);
|
||||
const entry = &self.entries()[idx];
|
||||
entry.* = .{ .key = key, .value = undefined };
|
||||
self.size += 1;
|
||||
const gop = self.getOrPutAssumeCapacity(key);
|
||||
gop.entry.value = value;
|
||||
}
|
||||
|
||||
/// Insert an entry in the map. Assumes it is not already present,
|
||||
@@ -893,6 +864,11 @@ test "std.hash_map clearRetainingCapacity" {
|
||||
expectEqual(map.get(1).?, 1);
|
||||
expectEqual(map.count(), 1);
|
||||
|
||||
map.clearRetainingCapacity();
|
||||
map.putAssumeCapacity(1, 1);
|
||||
expectEqual(map.get(1).?, 1);
|
||||
expectEqual(map.count(), 1);
|
||||
|
||||
const cap = map.capacity();
|
||||
expect(cap > 0);
|
||||
|
||||
@@ -1148,6 +1124,36 @@ test "std.hash_map put" {
|
||||
}
|
||||
}
|
||||
|
||||
test "std.hash_map putAssumeCapacity" {
|
||||
var map = AutoHashMap(u32, u32).init(std.testing.allocator);
|
||||
defer map.deinit();
|
||||
|
||||
try map.ensureCapacity(20);
|
||||
var i: u32 = 0;
|
||||
while (i < 20) : (i += 1) {
|
||||
map.putAssumeCapacityNoClobber(i, i);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
var sum = i;
|
||||
while (i < 20) : (i += 1) {
|
||||
sum += map.get(i).?;
|
||||
}
|
||||
expectEqual(sum, 190);
|
||||
|
||||
i = 0;
|
||||
while (i < 20) : (i += 1) {
|
||||
map.putAssumeCapacity(i, 1);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
sum = i;
|
||||
while (i < 20) : (i += 1) {
|
||||
sum += map.get(i).?;
|
||||
}
|
||||
expectEqual(sum, 20);
|
||||
}
|
||||
|
||||
test "std.hash_map getOrPut" {
|
||||
var map = AutoHashMap(u32, u32).init(std.testing.allocator);
|
||||
defer map.deinit();
|
||||
|
||||
@@ -517,7 +517,11 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
|
||||
second_free_stack_trace,
|
||||
});
|
||||
if (new_size == 0) {
|
||||
// Recoverable.
|
||||
// Recoverable. Restore self.total_requested_bytes if needed, as we
|
||||
// don't return an error value so the errdefer above does not run.
|
||||
if (config.enable_memory_limit) {
|
||||
self.total_requested_bytes = prev_req_bytes;
|
||||
}
|
||||
return @as(usize, 0);
|
||||
}
|
||||
@panic("Unrecoverable double free");
|
||||
|
||||
@@ -57,6 +57,15 @@ pub fn Reader(
|
||||
/// If the number of bytes appended would exceed `max_append_size`, `error.StreamTooLong` is returned
|
||||
/// and the `std.ArrayList` has exactly `max_append_size` bytes appended.
|
||||
pub fn readAllArrayList(self: Self, array_list: *std.ArrayList(u8), max_append_size: usize) !void {
|
||||
return self.readAllArrayListAligned(null, array_list, max_append_size);
|
||||
}
|
||||
|
||||
pub fn readAllArrayListAligned(
|
||||
self: Self,
|
||||
comptime alignment: ?u29,
|
||||
array_list: *std.ArrayListAligned(u8, alignment),
|
||||
max_append_size: usize
|
||||
) !void {
|
||||
try array_list.ensureCapacity(math.min(max_append_size, 4096));
|
||||
const original_len = array_list.items.len;
|
||||
var start_index: usize = original_len;
|
||||
|
||||
@@ -375,7 +375,7 @@ pub const StreamingParser = struct {
|
||||
'}' => {
|
||||
// unlikely
|
||||
if (p.stack & 1 != object_bit) {
|
||||
return error.UnexpectedClosingBracket;
|
||||
return error.UnexpectedClosingBrace;
|
||||
}
|
||||
if (p.stack_used == 0) {
|
||||
return error.TooManyClosingItems;
|
||||
@@ -401,7 +401,7 @@ pub const StreamingParser = struct {
|
||||
},
|
||||
']' => {
|
||||
if (p.stack & 1 != array_bit) {
|
||||
return error.UnexpectedClosingBrace;
|
||||
return error.UnexpectedClosingBracket;
|
||||
}
|
||||
if (p.stack_used == 0) {
|
||||
return error.TooManyClosingItems;
|
||||
@@ -571,8 +571,11 @@ pub const StreamingParser = struct {
|
||||
p.state = .ValueBeginNoClosing;
|
||||
},
|
||||
']' => {
|
||||
if (p.stack & 1 != array_bit) {
|
||||
return error.UnexpectedClosingBracket;
|
||||
}
|
||||
if (p.stack_used == 0) {
|
||||
return error.UnbalancedBrackets;
|
||||
return error.TooManyClosingItems;
|
||||
}
|
||||
|
||||
p.state = .ValueEnd;
|
||||
@@ -589,8 +592,12 @@ pub const StreamingParser = struct {
|
||||
token.* = Token.ArrayEnd;
|
||||
},
|
||||
'}' => {
|
||||
// unlikely
|
||||
if (p.stack & 1 != object_bit) {
|
||||
return error.UnexpectedClosingBrace;
|
||||
}
|
||||
if (p.stack_used == 0) {
|
||||
return error.UnbalancedBraces;
|
||||
return error.TooManyClosingItems;
|
||||
}
|
||||
|
||||
p.state = .ValueEnd;
|
||||
@@ -1189,6 +1196,15 @@ test "json.token" {
|
||||
testing.expect((try p.next()) == null);
|
||||
}
|
||||
|
||||
test "json.token mismatched close" {
|
||||
var p = TokenStream.init("[102, 111, 111 }");
|
||||
checkNext(&p, .ArrayBegin);
|
||||
checkNext(&p, .Number);
|
||||
checkNext(&p, .Number);
|
||||
checkNext(&p, .Number);
|
||||
testing.expectError(error.UnexpectedClosingBrace, p.next());
|
||||
}
|
||||
|
||||
/// Validate a JSON string. This does not limit number precision so a decoder may not necessarily
|
||||
/// be able to decode the string even if this returns true.
|
||||
pub fn validate(s: []const u8) bool {
|
||||
@@ -1207,7 +1223,12 @@ pub fn validate(s: []const u8) bool {
|
||||
}
|
||||
|
||||
test "json.validate" {
|
||||
testing.expect(validate("{}"));
|
||||
testing.expectEqual(true, validate("{}"));
|
||||
testing.expectEqual(true, validate("[]"));
|
||||
testing.expectEqual(true, validate("[{[[[[{}]]]]}]"));
|
||||
testing.expectEqual(false, validate("{]"));
|
||||
testing.expectEqual(false, validate("[}"));
|
||||
testing.expectEqual(false, validate("{{{{[]}}}]"));
|
||||
}
|
||||
|
||||
const Allocator = std.mem.Allocator;
|
||||
@@ -2080,7 +2101,7 @@ pub const Parser = struct {
|
||||
// Unescape a JSON string
|
||||
// Only to be used on strings already validated by the parser
|
||||
// (note the unreachable statements and lack of bounds checking)
|
||||
fn unescapeString(output: []u8, input: []const u8) !void {
|
||||
pub fn unescapeString(output: []u8, input: []const u8) !void {
|
||||
var inIndex: usize = 0;
|
||||
var outIndex: usize = 0;
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ fn exp2_32(x: f32) f32 {
|
||||
uf -= redux;
|
||||
|
||||
const z: f64 = x - uf;
|
||||
var r: f64 = exp2ft[i_0];
|
||||
var r: f64 = exp2ft[@intCast(usize, i_0)];
|
||||
const t: f64 = r * z;
|
||||
r = r + t * (P1 + z * P2) + t * (z * z) * (P3 + z * P4);
|
||||
return @floatCast(f32, r * uk);
|
||||
@@ -418,8 +418,8 @@ fn exp2_64(x: f64) f64 {
|
||||
|
||||
// r = exp2(y) = exp2t[i_0] * p(z - eps[i])
|
||||
var z = x - uf;
|
||||
const t = exp2dt[2 * i_0];
|
||||
z -= exp2dt[2 * i_0 + 1];
|
||||
const t = exp2dt[@intCast(usize, 2 * i_0)];
|
||||
z -= exp2dt[@intCast(usize, 2 * i_0 + 1)];
|
||||
const r = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * P5))));
|
||||
|
||||
return math.scalbn(r, ik);
|
||||
|
||||
123
lib/std/mem.zig
123
lib/std/mem.zig
@@ -7,13 +7,14 @@ const std = @import("std.zig");
|
||||
const debug = std.debug;
|
||||
const assert = debug.assert;
|
||||
const math = std.math;
|
||||
const builtin = @import("builtin");
|
||||
const builtin = std.builtin;
|
||||
const mem = @This();
|
||||
const meta = std.meta;
|
||||
const trait = meta.trait;
|
||||
const testing = std.testing;
|
||||
|
||||
/// https://github.com/ziglang/zig/issues/2564
|
||||
/// Compile time known minimum page size.
|
||||
/// https://github.com/ziglang/zig/issues/4082
|
||||
pub const page_size = switch (builtin.arch) {
|
||||
.wasm32, .wasm64 => 64 * 1024,
|
||||
.aarch64 => switch (builtin.os.tag) {
|
||||
@@ -139,7 +140,7 @@ test "mem.Allocator basics" {
|
||||
|
||||
/// Copy all of source into dest at position 0.
|
||||
/// dest.len must be >= source.len.
|
||||
/// dest.ptr must be <= src.ptr.
|
||||
/// If the slices overlap, dest.ptr must be <= src.ptr.
|
||||
pub fn copy(comptime T: type, dest: []T, source: []const T) void {
|
||||
// TODO instead of manually doing this check for the whole array
|
||||
// and turning off runtime safety, the compiler should detect loops like
|
||||
@@ -152,7 +153,7 @@ pub fn copy(comptime T: type, dest: []T, source: []const T) void {
|
||||
|
||||
/// Copy all of source into dest at position 0.
|
||||
/// dest.len must be >= source.len.
|
||||
/// dest.ptr must be >= src.ptr.
|
||||
/// If the slices overlap, dest.ptr must be >= src.ptr.
|
||||
pub fn copyBackwards(comptime T: type, dest: []T, source: []const T) void {
|
||||
// TODO instead of manually doing this check for the whole array
|
||||
// and turning off runtime safety, the compiler should detect loops like
|
||||
@@ -1936,25 +1937,31 @@ pub fn nativeToBig(comptime T: type, x: T) T {
|
||||
};
|
||||
}
|
||||
|
||||
fn CopyPtrAttrs(comptime source: type, comptime size: builtin.TypeInfo.Pointer.Size, comptime child: type) type {
|
||||
const info = @typeInfo(source).Pointer;
|
||||
return @Type(.{
|
||||
.Pointer = .{
|
||||
.size = size,
|
||||
.is_const = info.is_const,
|
||||
.is_volatile = info.is_volatile,
|
||||
.is_allowzero = info.is_allowzero,
|
||||
.alignment = info.alignment,
|
||||
.child = child,
|
||||
.sentinel = null,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
fn AsBytesReturnType(comptime P: type) type {
|
||||
if (!trait.isSingleItemPtr(P))
|
||||
@compileError("expected single item pointer, passed " ++ @typeName(P));
|
||||
|
||||
const size = @sizeOf(meta.Child(P));
|
||||
const alignment = meta.alignment(P);
|
||||
|
||||
if (alignment == 0) {
|
||||
if (trait.isConstPtr(P))
|
||||
return *const [size]u8;
|
||||
return *[size]u8;
|
||||
}
|
||||
|
||||
if (trait.isConstPtr(P))
|
||||
return *align(alignment) const [size]u8;
|
||||
return *align(alignment) [size]u8;
|
||||
return CopyPtrAttrs(P, .One, [size]u8);
|
||||
}
|
||||
|
||||
/// Given a pointer to a single item, returns a slice of the underlying bytes, preserving constness.
|
||||
/// Given a pointer to a single item, returns a slice of the underlying bytes, preserving pointer attributes.
|
||||
pub fn asBytes(ptr: anytype) AsBytesReturnType(@TypeOf(ptr)) {
|
||||
const P = @TypeOf(ptr);
|
||||
return @ptrCast(AsBytesReturnType(P), ptr);
|
||||
@@ -1994,6 +2001,20 @@ test "asBytes" {
|
||||
testing.expect(eql(u8, asBytes(&zero), ""));
|
||||
}
|
||||
|
||||
test "asBytes preserves pointer attributes" {
|
||||
const inArr: u32 align(16) = 0xDEADBEEF;
|
||||
const inPtr = @ptrCast(*align(16) const volatile u32, &inArr);
|
||||
const outSlice = asBytes(inPtr);
|
||||
|
||||
const in = @typeInfo(@TypeOf(inPtr)).Pointer;
|
||||
const out = @typeInfo(@TypeOf(outSlice)).Pointer;
|
||||
|
||||
testing.expectEqual(in.is_const, out.is_const);
|
||||
testing.expectEqual(in.is_volatile, out.is_volatile);
|
||||
testing.expectEqual(in.is_allowzero, out.is_allowzero);
|
||||
testing.expectEqual(in.alignment, out.alignment);
|
||||
}
|
||||
|
||||
/// Given any value, returns a copy of its bytes in an array.
|
||||
pub fn toBytes(value: anytype) [@sizeOf(@TypeOf(value))]u8 {
|
||||
return asBytes(&value).*;
|
||||
@@ -2023,13 +2044,11 @@ fn BytesAsValueReturnType(comptime T: type, comptime B: type) type {
|
||||
@compileError(std.fmt.bufPrint(&buf, "expected *[{}]u8, passed " ++ @typeName(B), .{size}) catch unreachable);
|
||||
}
|
||||
|
||||
const alignment = comptime meta.alignment(B);
|
||||
|
||||
return if (comptime trait.isConstPtr(B)) *align(alignment) const T else *align(alignment) T;
|
||||
return CopyPtrAttrs(B, .One, T);
|
||||
}
|
||||
|
||||
/// Given a pointer to an array of bytes, returns a pointer to a value of the specified type
|
||||
/// backed by those bytes, preserving constness.
|
||||
/// backed by those bytes, preserving pointer attributes.
|
||||
pub fn bytesAsValue(comptime T: type, bytes: anytype) BytesAsValueReturnType(T, @TypeOf(bytes)) {
|
||||
return @ptrCast(BytesAsValueReturnType(T, @TypeOf(bytes)), bytes);
|
||||
}
|
||||
@@ -2071,6 +2090,20 @@ test "bytesAsValue" {
|
||||
testing.expect(meta.eql(inst, inst2.*));
|
||||
}
|
||||
|
||||
test "bytesAsValue preserves pointer attributes" {
|
||||
const inArr align(16) = [4]u8{ 0xDE, 0xAD, 0xBE, 0xEF };
|
||||
const inSlice = @ptrCast(*align(16) const volatile [4]u8, &inArr)[0..];
|
||||
const outPtr = bytesAsValue(u32, inSlice);
|
||||
|
||||
const in = @typeInfo(@TypeOf(inSlice)).Pointer;
|
||||
const out = @typeInfo(@TypeOf(outPtr)).Pointer;
|
||||
|
||||
testing.expectEqual(in.is_const, out.is_const);
|
||||
testing.expectEqual(in.is_volatile, out.is_volatile);
|
||||
testing.expectEqual(in.is_allowzero, out.is_allowzero);
|
||||
testing.expectEqual(in.alignment, out.alignment);
|
||||
}
|
||||
|
||||
/// Given a pointer to an array of bytes, returns a value of the specified type backed by a
|
||||
/// copy of those bytes.
|
||||
pub fn bytesToValue(comptime T: type, bytes: anytype) T {
|
||||
@@ -2086,9 +2119,8 @@ test "bytesToValue" {
|
||||
testing.expect(deadbeef == @as(u32, 0xDEADBEEF));
|
||||
}
|
||||
|
||||
//TODO copy also is_volatile, etc. I tried to use @typeInfo, modify child type, use @Type, but ran into issues.
|
||||
fn BytesAsSliceReturnType(comptime T: type, comptime bytesType: type) type {
|
||||
if (!(trait.isSlice(bytesType) and meta.Child(bytesType) == u8) and !(trait.isPtrTo(.Array)(bytesType) and meta.Child(meta.Child(bytesType)) == u8)) {
|
||||
if (!(trait.isSlice(bytesType) or trait.isPtrTo(.Array)(bytesType)) or meta.Elem(bytesType) != u8) {
|
||||
@compileError("expected []u8 or *[_]u8, passed " ++ @typeName(bytesType));
|
||||
}
|
||||
|
||||
@@ -2096,11 +2128,11 @@ fn BytesAsSliceReturnType(comptime T: type, comptime bytesType: type) type {
|
||||
@compileError("number of bytes in " ++ @typeName(bytesType) ++ " is not divisible by size of " ++ @typeName(T));
|
||||
}
|
||||
|
||||
const alignment = meta.alignment(bytesType);
|
||||
|
||||
return if (trait.isConstPtr(bytesType)) []align(alignment) const T else []align(alignment) T;
|
||||
return CopyPtrAttrs(bytesType, .Slice, T);
|
||||
}
|
||||
|
||||
/// Given a slice of bytes, returns a slice of the specified type
|
||||
/// backed by those bytes, preserving pointer attributes.
|
||||
pub fn bytesAsSlice(comptime T: type, bytes: anytype) BytesAsSliceReturnType(T, @TypeOf(bytes)) {
|
||||
// let's not give an undefined pointer to @ptrCast
|
||||
// it may be equal to zero and fail a null check
|
||||
@@ -2108,10 +2140,7 @@ pub fn bytesAsSlice(comptime T: type, bytes: anytype) BytesAsSliceReturnType(T,
|
||||
return &[0]T{};
|
||||
}
|
||||
|
||||
const Bytes = @TypeOf(bytes);
|
||||
const alignment = comptime meta.alignment(Bytes);
|
||||
|
||||
const cast_target = if (comptime trait.isConstPtr(Bytes)) [*]align(alignment) const T else [*]align(alignment) T;
|
||||
const cast_target = CopyPtrAttrs(@TypeOf(bytes), .Many, T);
|
||||
|
||||
return @ptrCast(cast_target, bytes)[0..@divExact(bytes.len, @sizeOf(T))];
|
||||
}
|
||||
@@ -2169,17 +2198,29 @@ test "bytesAsSlice with specified alignment" {
|
||||
testing.expect(slice[0] == 0x33333333);
|
||||
}
|
||||
|
||||
//TODO copy also is_volatile, etc. I tried to use @typeInfo, modify child type, use @Type, but ran into issues.
|
||||
test "bytesAsSlice preserves pointer attributes" {
|
||||
const inArr align(16) = [4]u8{ 0xDE, 0xAD, 0xBE, 0xEF };
|
||||
const inSlice = @ptrCast(*align(16) const volatile [4]u8, &inArr)[0..];
|
||||
const outSlice = bytesAsSlice(u16, inSlice);
|
||||
|
||||
const in = @typeInfo(@TypeOf(inSlice)).Pointer;
|
||||
const out = @typeInfo(@TypeOf(outSlice)).Pointer;
|
||||
|
||||
testing.expectEqual(in.is_const, out.is_const);
|
||||
testing.expectEqual(in.is_volatile, out.is_volatile);
|
||||
testing.expectEqual(in.is_allowzero, out.is_allowzero);
|
||||
testing.expectEqual(in.alignment, out.alignment);
|
||||
}
|
||||
|
||||
fn SliceAsBytesReturnType(comptime sliceType: type) type {
|
||||
if (!trait.isSlice(sliceType) and !trait.isPtrTo(.Array)(sliceType)) {
|
||||
@compileError("expected []T or *[_]T, passed " ++ @typeName(sliceType));
|
||||
}
|
||||
|
||||
const alignment = meta.alignment(sliceType);
|
||||
|
||||
return if (trait.isConstPtr(sliceType)) []align(alignment) const u8 else []align(alignment) u8;
|
||||
return CopyPtrAttrs(sliceType, .Slice, u8);
|
||||
}
|
||||
|
||||
/// Given a slice, returns a slice of the underlying bytes, preserving pointer attributes.
|
||||
pub fn sliceAsBytes(slice: anytype) SliceAsBytesReturnType(@TypeOf(slice)) {
|
||||
const Slice = @TypeOf(slice);
|
||||
|
||||
@@ -2189,9 +2230,7 @@ pub fn sliceAsBytes(slice: anytype) SliceAsBytesReturnType(@TypeOf(slice)) {
|
||||
return &[0]u8{};
|
||||
}
|
||||
|
||||
const alignment = comptime meta.alignment(Slice);
|
||||
|
||||
const cast_target = if (comptime trait.isConstPtr(Slice)) [*]align(alignment) const u8 else [*]align(alignment) u8;
|
||||
const cast_target = CopyPtrAttrs(Slice, .Many, u8);
|
||||
|
||||
return @ptrCast(cast_target, slice)[0 .. slice.len * @sizeOf(meta.Elem(Slice))];
|
||||
}
|
||||
@@ -2263,6 +2302,20 @@ test "sliceAsBytes and bytesAsSlice back" {
|
||||
testing.expect(bytes[11] == math.maxInt(u8));
|
||||
}
|
||||
|
||||
test "sliceAsBytes preserves pointer attributes" {
|
||||
const inArr align(16) = [2]u16{ 0xDEAD, 0xBEEF };
|
||||
const inSlice = @ptrCast(*align(16) const volatile [2]u16, &inArr)[0..];
|
||||
const outSlice = sliceAsBytes(inSlice);
|
||||
|
||||
const in = @typeInfo(@TypeOf(inSlice)).Pointer;
|
||||
const out = @typeInfo(@TypeOf(outSlice)).Pointer;
|
||||
|
||||
testing.expectEqual(in.is_const, out.is_const);
|
||||
testing.expectEqual(in.is_volatile, out.is_volatile);
|
||||
testing.expectEqual(in.is_allowzero, out.is_allowzero);
|
||||
testing.expectEqual(in.alignment, out.alignment);
|
||||
}
|
||||
|
||||
/// Round an address up to the nearest aligned address
|
||||
/// The alignment must be a power of 2 and greater than 0.
|
||||
pub fn alignForward(addr: usize, alignment: usize) usize {
|
||||
|
||||
@@ -19,9 +19,6 @@ pub const Address = extern union {
|
||||
in6: Ip6Address,
|
||||
un: if (has_unix_sockets) os.sockaddr_un else void,
|
||||
|
||||
// TODO this crashed the compiler. https://github.com/ziglang/zig/issues/3512
|
||||
//pub const localhost = initIp4(parseIp4("127.0.0.1") catch unreachable, 0);
|
||||
|
||||
/// Parse the given IP address string into an Address value.
|
||||
/// It is recommended to use `resolveIp` instead, to handle
|
||||
/// IPv6 link-local unix addresses.
|
||||
@@ -839,6 +836,20 @@ fn linuxLookupName(
|
||||
if (addrs.items.len == 0) {
|
||||
try linuxLookupNameFromDnsSearch(addrs, canon, name, family, port);
|
||||
}
|
||||
if (addrs.items.len == 0) {
|
||||
// RFC 6761 Section 6.3
|
||||
// Name resolution APIs and libraries SHOULD recognize localhost
|
||||
// names as special and SHOULD always return the IP loopback address
|
||||
// for address queries and negative responses for all other query
|
||||
// types.
|
||||
|
||||
// Check for equal to "localhost" or ends in ".localhost"
|
||||
if (mem.endsWith(u8, name, "localhost") and (name.len == "localhost".len or name[name.len - "localhost".len] == '.')) {
|
||||
try addrs.append(LookupAddr{ .addr = .{ .in = Ip4Address.parse("127.0.0.1", port) catch unreachable } });
|
||||
try addrs.append(LookupAddr{ .addr = .{ .in6 = Ip6Address.parse("::1", port) catch unreachable } });
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try canon.resize(0);
|
||||
|
||||
@@ -3734,6 +3734,7 @@ pub fn faccessatW(dirfd: fd_t, sub_path_w: [*:0]const u16, mode: u32, flags: u32
|
||||
.SUCCESS => return,
|
||||
.OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
|
||||
.OBJECT_PATH_NOT_FOUND => return error.FileNotFound,
|
||||
.OBJECT_NAME_INVALID => unreachable,
|
||||
.INVALID_PARAMETER => unreachable,
|
||||
.ACCESS_DENIED => return error.PermissionDenied,
|
||||
.OBJECT_PATH_SYNTAX_BAD => unreachable,
|
||||
|
||||
@@ -86,27 +86,27 @@ pub const PR = extern enum(i32) {
|
||||
_,
|
||||
};
|
||||
|
||||
pub const PR_SET_PDEATHSIG = @enumToInt(PR.PR_SET_PDEATHSIG);
|
||||
pub const PR_GET_PDEATHSIG = @enumToInt(PR.PR_GET_PDEATHSIG);
|
||||
pub const PR_SET_PDEATHSIG = @enumToInt(PR.SET_PDEATHSIG);
|
||||
pub const PR_GET_PDEATHSIG = @enumToInt(PR.GET_PDEATHSIG);
|
||||
|
||||
pub const PR_GET_DUMPABLE = @enumToInt(PR.PR_GET_DUMPABLE);
|
||||
pub const PR_SET_DUMPABLE = @enumToInt(PR.PR_SET_DUMPABLE);
|
||||
pub const PR_GET_DUMPABLE = @enumToInt(PR.GET_DUMPABLE);
|
||||
pub const PR_SET_DUMPABLE = @enumToInt(PR.SET_DUMPABLE);
|
||||
|
||||
pub const PR_GET_UNALIGN = @enumToInt(PR.PR_GET_UNALIGN);
|
||||
pub const PR_SET_UNALIGN = @enumToInt(PR.PR_SET_UNALIGN);
|
||||
pub const PR_GET_UNALIGN = @enumToInt(PR.GET_UNALIGN);
|
||||
pub const PR_SET_UNALIGN = @enumToInt(PR.SET_UNALIGN);
|
||||
pub const PR_UNALIGN_NOPRINT = 1;
|
||||
pub const PR_UNALIGN_SIGBUS = 2;
|
||||
|
||||
pub const PR_GET_KEEPCAPS = @enumToInt(PR.PR_GET_KEEPCAPS);
|
||||
pub const PR_SET_KEEPCAPS = @enumToInt(PR.PR_SET_KEEPCAPS);
|
||||
pub const PR_GET_KEEPCAPS = @enumToInt(PR.GET_KEEPCAPS);
|
||||
pub const PR_SET_KEEPCAPS = @enumToInt(PR.SET_KEEPCAPS);
|
||||
|
||||
pub const PR_GET_FPEMU = @enumToInt(PR.PR_GET_FPEMU);
|
||||
pub const PR_SET_FPEMU = @enumToInt(PR.PR_SET_FPEMU);
|
||||
pub const PR_GET_FPEMU = @enumToInt(PR.GET_FPEMU);
|
||||
pub const PR_SET_FPEMU = @enumToInt(PR.SET_FPEMU);
|
||||
pub const PR_FPEMU_NOPRINT = 1;
|
||||
pub const PR_FPEMU_SIGFPE = 2;
|
||||
|
||||
pub const PR_GET_FPEXC = @enumToInt(PR.PR_GET_FPEXC);
|
||||
pub const PR_SET_FPEXC = @enumToInt(PR.PR_SET_FPEXC);
|
||||
pub const PR_GET_FPEXC = @enumToInt(PR.GET_FPEXC);
|
||||
pub const PR_SET_FPEXC = @enumToInt(PR.SET_FPEXC);
|
||||
pub const PR_FP_EXC_SW_ENABLE = 0x80;
|
||||
pub const PR_FP_EXC_DIV = 0x010000;
|
||||
pub const PR_FP_EXC_OVF = 0x020000;
|
||||
@@ -118,41 +118,41 @@ pub const PR_FP_EXC_NONRECOV = 1;
|
||||
pub const PR_FP_EXC_ASYNC = 2;
|
||||
pub const PR_FP_EXC_PRECISE = 3;
|
||||
|
||||
pub const PR_GET_TIMING = @enumToInt(PR.PR_GET_TIMING);
|
||||
pub const PR_SET_TIMING = @enumToInt(PR.PR_SET_TIMING);
|
||||
pub const PR_GET_TIMING = @enumToInt(PR.GET_TIMING);
|
||||
pub const PR_SET_TIMING = @enumToInt(PR.SET_TIMING);
|
||||
pub const PR_TIMING_STATISTICAL = 0;
|
||||
pub const PR_TIMING_TIMESTAMP = 1;
|
||||
|
||||
pub const PR_SET_NAME = @enumToInt(PR.PR_SET_NAME);
|
||||
pub const PR_GET_NAME = @enumToInt(PR.PR_GET_NAME);
|
||||
pub const PR_SET_NAME = @enumToInt(PR.SET_NAME);
|
||||
pub const PR_GET_NAME = @enumToInt(PR.GET_NAME);
|
||||
|
||||
pub const PR_GET_ENDIAN = @enumToInt(PR.PR_GET_ENDIAN);
|
||||
pub const PR_SET_ENDIAN = @enumToInt(PR.PR_SET_ENDIAN);
|
||||
pub const PR_GET_ENDIAN = @enumToInt(PR.GET_ENDIAN);
|
||||
pub const PR_SET_ENDIAN = @enumToInt(PR.SET_ENDIAN);
|
||||
pub const PR_ENDIAN_BIG = 0;
|
||||
pub const PR_ENDIAN_LITTLE = 1;
|
||||
pub const PR_ENDIAN_PPC_LITTLE = 2;
|
||||
|
||||
pub const PR_GET_SECCOMP = @enumToInt(PR.PR_GET_SECCOMP);
|
||||
pub const PR_SET_SECCOMP = @enumToInt(PR.PR_SET_SECCOMP);
|
||||
pub const PR_GET_SECCOMP = @enumToInt(PR.GET_SECCOMP);
|
||||
pub const PR_SET_SECCOMP = @enumToInt(PR.SET_SECCOMP);
|
||||
|
||||
pub const PR_CAPBSET_READ = @enumToInt(PR.PR_CAPBSET_READ);
|
||||
pub const PR_CAPBSET_DROP = @enumToInt(PR.PR_CAPBSET_DROP);
|
||||
pub const PR_CAPBSET_READ = @enumToInt(PR.CAPBSET_READ);
|
||||
pub const PR_CAPBSET_DROP = @enumToInt(PR.CAPBSET_DROP);
|
||||
|
||||
pub const PR_GET_TSC = @enumToInt(PR.PR_GET_TSC);
|
||||
pub const PR_SET_TSC = @enumToInt(PR.PR_SET_TSC);
|
||||
pub const PR_GET_TSC = @enumToInt(PR.GET_TSC);
|
||||
pub const PR_SET_TSC = @enumToInt(PR.SET_TSC);
|
||||
pub const PR_TSC_ENABLE = 1;
|
||||
pub const PR_TSC_SIGSEGV = 2;
|
||||
|
||||
pub const PR_GET_SECUREBITS = @enumToInt(PR.PR_GET_SECUREBITS);
|
||||
pub const PR_SET_SECUREBITS = @enumToInt(PR.PR_SET_SECUREBITS);
|
||||
pub const PR_GET_SECUREBITS = @enumToInt(PR.GET_SECUREBITS);
|
||||
pub const PR_SET_SECUREBITS = @enumToInt(PR.SET_SECUREBITS);
|
||||
|
||||
pub const PR_SET_TIMERSLACK = @enumToInt(PR.PR_SET_TIMERSLACK);
|
||||
pub const PR_GET_TIMERSLACK = @enumToInt(PR.PR_GET_TIMERSLACK);
|
||||
pub const PR_SET_TIMERSLACK = @enumToInt(PR.SET_TIMERSLACK);
|
||||
pub const PR_GET_TIMERSLACK = @enumToInt(PR.GET_TIMERSLACK);
|
||||
|
||||
pub const PR_TASK_PERF_EVENTS_DISABLE = @enumToInt(PR.PR_TASK_PERF_EVENTS_DISABLE);
|
||||
pub const PR_TASK_PERF_EVENTS_ENABLE = @enumToInt(PR.PR_TASK_PERF_EVENTS_ENABLE);
|
||||
pub const PR_TASK_PERF_EVENTS_DISABLE = @enumToInt(PR.TASK_PERF_EVENTS_DISABLE);
|
||||
pub const PR_TASK_PERF_EVENTS_ENABLE = @enumToInt(PR.TASK_PERF_EVENTS_ENABLE);
|
||||
|
||||
pub const PR_MCE_KILL = @enumToInt(PR.PR_MCE_KILL);
|
||||
pub const PR_MCE_KILL = @enumToInt(PR.MCE_KILL);
|
||||
pub const PR_MCE_KILL_CLEAR = 0;
|
||||
pub const PR_MCE_KILL_SET = 1;
|
||||
|
||||
@@ -160,9 +160,9 @@ pub const PR_MCE_KILL_LATE = 0;
|
||||
pub const PR_MCE_KILL_EARLY = 1;
|
||||
pub const PR_MCE_KILL_DEFAULT = 2;
|
||||
|
||||
pub const PR_MCE_KILL_GET = @enumToInt(PR.PR_MCE_KILL_GET);
|
||||
pub const PR_MCE_KILL_GET = @enumToInt(PR.MCE_KILL_GET);
|
||||
|
||||
pub const PR_SET_MM = @enumToInt(PR.PR_SET_MM);
|
||||
pub const PR_SET_MM = @enumToInt(PR.SET_MM);
|
||||
pub const PR_SET_MM_START_CODE = 1;
|
||||
pub const PR_SET_MM_END_CODE = 2;
|
||||
pub const PR_SET_MM_START_DATA = 3;
|
||||
@@ -196,42 +196,42 @@ pub const prctl_mm_map = extern struct {
|
||||
exe_fd: u32,
|
||||
};
|
||||
|
||||
pub const PR_SET_PTRACER = @enumToInt(PR.PR_SET_PTRACER);
|
||||
pub const PR_SET_PTRACER = @enumToInt(PR.SET_PTRACER);
|
||||
pub const PR_SET_PTRACER_ANY = std.math.maxInt(c_ulong);
|
||||
|
||||
pub const PR_SET_CHILD_SUBREAPER = @enumToInt(PR.PR_SET_CHILD_SUBREAPER);
|
||||
pub const PR_GET_CHILD_SUBREAPER = @enumToInt(PR.PR_GET_CHILD_SUBREAPER);
|
||||
pub const PR_SET_CHILD_SUBREAPER = @enumToInt(PR.SET_CHILD_SUBREAPER);
|
||||
pub const PR_GET_CHILD_SUBREAPER = @enumToInt(PR.GET_CHILD_SUBREAPER);
|
||||
|
||||
pub const PR_SET_NO_NEW_PRIVS = @enumToInt(PR.PR_SET_NO_NEW_PRIVS);
|
||||
pub const PR_GET_NO_NEW_PRIVS = @enumToInt(PR.PR_GET_NO_NEW_PRIVS);
|
||||
pub const PR_SET_NO_NEW_PRIVS = @enumToInt(PR.SET_NO_NEW_PRIVS);
|
||||
pub const PR_GET_NO_NEW_PRIVS = @enumToInt(PR.GET_NO_NEW_PRIVS);
|
||||
|
||||
pub const PR_GET_TID_ADDRESS = @enumToInt(PR.PR_GET_TID_ADDRESS);
|
||||
pub const PR_GET_TID_ADDRESS = @enumToInt(PR.GET_TID_ADDRESS);
|
||||
|
||||
pub const PR_SET_THP_DISABLE = @enumToInt(PR.PR_SET_THP_DISABLE);
|
||||
pub const PR_GET_THP_DISABLE = @enumToInt(PR.PR_GET_THP_DISABLE);
|
||||
pub const PR_SET_THP_DISABLE = @enumToInt(PR.SET_THP_DISABLE);
|
||||
pub const PR_GET_THP_DISABLE = @enumToInt(PR.GET_THP_DISABLE);
|
||||
|
||||
pub const PR_MPX_ENABLE_MANAGEMENT = @enumToInt(PR.PR_MPX_ENABLE_MANAGEMENT);
|
||||
pub const PR_MPX_DISABLE_MANAGEMENT = @enumToInt(PR.PR_MPX_DISABLE_MANAGEMENT);
|
||||
pub const PR_MPX_ENABLE_MANAGEMENT = @enumToInt(PR.MPX_ENABLE_MANAGEMENT);
|
||||
pub const PR_MPX_DISABLE_MANAGEMENT = @enumToInt(PR.MPX_DISABLE_MANAGEMENT);
|
||||
|
||||
pub const PR_SET_FP_MODE = @enumToInt(PR.PR_SET_FP_MODE);
|
||||
pub const PR_GET_FP_MODE = @enumToInt(PR.PR_GET_FP_MODE);
|
||||
pub const PR_SET_FP_MODE = @enumToInt(PR.SET_FP_MODE);
|
||||
pub const PR_GET_FP_MODE = @enumToInt(PR.GET_FP_MODE);
|
||||
pub const PR_FP_MODE_FR = 1 << 0;
|
||||
pub const PR_FP_MODE_FRE = 1 << 1;
|
||||
|
||||
pub const PR_CAP_AMBIENT = @enumToInt(PR.PR_CAP_AMBIENT);
|
||||
pub const PR_CAP_AMBIENT = @enumToInt(PR.CAP_AMBIENT);
|
||||
pub const PR_CAP_AMBIENT_IS_SET = 1;
|
||||
pub const PR_CAP_AMBIENT_RAISE = 2;
|
||||
pub const PR_CAP_AMBIENT_LOWER = 3;
|
||||
pub const PR_CAP_AMBIENT_CLEAR_ALL = 4;
|
||||
|
||||
pub const PR_SVE_SET_VL = @enumToInt(PR.PR_SVE_SET_VL);
|
||||
pub const PR_SVE_SET_VL = @enumToInt(PR.SVE_SET_VL);
|
||||
pub const PR_SVE_SET_VL_ONEXEC = 1 << 18;
|
||||
pub const PR_SVE_GET_VL = @enumToInt(PR.PR_SVE_GET_VL);
|
||||
pub const PR_SVE_GET_VL = @enumToInt(PR.SVE_GET_VL);
|
||||
pub const PR_SVE_VL_LEN_MASK = 0xffff;
|
||||
pub const PR_SVE_VL_INHERIT = 1 << 17;
|
||||
|
||||
pub const PR_GET_SPECULATION_CTRL = @enumToInt(PR.PR_GET_SPECULATION_CTRL);
|
||||
pub const PR_SET_SPECULATION_CTRL = @enumToInt(PR.PR_SET_SPECULATION_CTRL);
|
||||
pub const PR_GET_SPECULATION_CTRL = @enumToInt(PR.GET_SPECULATION_CTRL);
|
||||
pub const PR_SET_SPECULATION_CTRL = @enumToInt(PR.SET_SPECULATION_CTRL);
|
||||
pub const PR_SPEC_STORE_BYPASS = 0;
|
||||
pub const PR_SPEC_NOT_AFFECTED = 0;
|
||||
pub const PR_SPEC_PRCTL = 1 << 0;
|
||||
|
||||
@@ -19,6 +19,7 @@ const iovec = linux.iovec;
|
||||
const iovec_const = linux.iovec_const;
|
||||
|
||||
pub const mode_t = usize;
|
||||
pub const time_t = isize;
|
||||
|
||||
pub const SYS = extern enum(usize) {
|
||||
read = 0,
|
||||
@@ -511,10 +512,11 @@ pub const msghdr_const = extern struct {
|
||||
|
||||
pub const off_t = i64;
|
||||
pub const ino_t = u64;
|
||||
pub const dev_t = u64;
|
||||
|
||||
// The `stat` definition used by the Linux kernel.
|
||||
pub const kernel_stat = extern struct {
|
||||
dev: u64,
|
||||
dev: dev_t,
|
||||
ino: ino_t,
|
||||
nlink: usize,
|
||||
|
||||
@@ -522,7 +524,7 @@ pub const kernel_stat = extern struct {
|
||||
uid: uid_t,
|
||||
gid: gid_t,
|
||||
__pad0: u32,
|
||||
rdev: u64,
|
||||
rdev: dev_t,
|
||||
size: off_t,
|
||||
blksize: isize,
|
||||
blocks: i64,
|
||||
|
||||
@@ -442,33 +442,30 @@ pub fn ReadFile(in_hFile: HANDLE, buffer: []u8, offset: ?u64, io_mode: std.io.Mo
|
||||
}
|
||||
return @as(usize, bytes_transferred);
|
||||
} else {
|
||||
var index: usize = 0;
|
||||
while (index < buffer.len) {
|
||||
const want_read_count = @intCast(DWORD, math.min(@as(DWORD, maxInt(DWORD)), buffer.len - index));
|
||||
while (true) {
|
||||
const want_read_count = @intCast(DWORD, math.min(@as(DWORD, maxInt(DWORD)), buffer.len));
|
||||
var amt_read: DWORD = undefined;
|
||||
var overlapped_data: OVERLAPPED = undefined;
|
||||
const overlapped: ?*OVERLAPPED = if (offset) |off| blk: {
|
||||
overlapped_data = .{
|
||||
.Internal = 0,
|
||||
.InternalHigh = 0,
|
||||
.Offset = @truncate(u32, off + index),
|
||||
.OffsetHigh = @truncate(u32, (off + index) >> 32),
|
||||
.Offset = @truncate(u32, off),
|
||||
.OffsetHigh = @truncate(u32, off >> 32),
|
||||
.hEvent = null,
|
||||
};
|
||||
break :blk &overlapped_data;
|
||||
} else null;
|
||||
if (kernel32.ReadFile(in_hFile, buffer.ptr + index, want_read_count, &amt_read, overlapped) == 0) {
|
||||
if (kernel32.ReadFile(in_hFile, buffer.ptr, want_read_count, &amt_read, overlapped) == 0) {
|
||||
switch (kernel32.GetLastError()) {
|
||||
.OPERATION_ABORTED => continue,
|
||||
.BROKEN_PIPE => return index,
|
||||
.HANDLE_EOF => return index,
|
||||
.BROKEN_PIPE => return 0,
|
||||
.HANDLE_EOF => return 0,
|
||||
else => |err| return unexpectedError(err),
|
||||
}
|
||||
}
|
||||
if (amt_read == 0) return index;
|
||||
index += amt_read;
|
||||
return amt_read;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -831,7 +828,7 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil
|
||||
}
|
||||
}
|
||||
|
||||
pub const MoveFileError = error{ FileNotFound, Unexpected };
|
||||
pub const MoveFileError = error{ FileNotFound, AccessDenied, Unexpected };
|
||||
|
||||
pub fn MoveFileEx(old_path: []const u8, new_path: []const u8, flags: DWORD) MoveFileError!void {
|
||||
const old_path_w = try sliceToPrefixedFileW(old_path);
|
||||
@@ -843,6 +840,7 @@ pub fn MoveFileExW(old_path: [*:0]const u16, new_path: [*:0]const u16, flags: DW
|
||||
if (kernel32.MoveFileExW(old_path, new_path, flags) == 0) {
|
||||
switch (kernel32.GetLastError()) {
|
||||
.FILE_NOT_FOUND => return error.FileNotFound,
|
||||
.ACCESS_DENIED => return error.AccessDenied,
|
||||
else => |err| return unexpectedError(err),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,7 +360,7 @@ const AtomicEvent = struct {
|
||||
};
|
||||
|
||||
test "ResetEvent" {
|
||||
if (std.Target.current.os.tag == .macos) {
|
||||
if (std.Target.current.os.tag == .macos or std.Target.current.os.tag == .windows) {
|
||||
// https://github.com/ziglang/zig/issues/7009
|
||||
return error.SkipZigTest;
|
||||
}
|
||||
|
||||
@@ -41,8 +41,18 @@ pub fn main() !void {
|
||||
warn("Expected third argument to be cache root directory path\n", .{});
|
||||
return error.InvalidArgs;
|
||||
};
|
||||
const global_cache_root = nextArg(args, &arg_idx) orelse {
|
||||
warn("Expected third argument to be global cache root directory path\n", .{});
|
||||
return error.InvalidArgs;
|
||||
};
|
||||
|
||||
const builder = try Builder.create(allocator, zig_exe, build_root, cache_root);
|
||||
const builder = try Builder.create(
|
||||
allocator,
|
||||
zig_exe,
|
||||
build_root,
|
||||
cache_root,
|
||||
global_cache_root,
|
||||
);
|
||||
defer builder.destroy();
|
||||
|
||||
var targets = ArrayList([]const u8).init(allocator);
|
||||
@@ -69,7 +79,7 @@ pub fn main() !void {
|
||||
} else if (mem.startsWith(u8, arg, "-")) {
|
||||
if (mem.eql(u8, arg, "--verbose")) {
|
||||
builder.verbose = true;
|
||||
} else if (mem.eql(u8, arg, "--help")) {
|
||||
} else if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
|
||||
return usage(builder, false, stdout_stream);
|
||||
} else if (mem.eql(u8, arg, "--prefix")) {
|
||||
builder.install_prefix = nextArg(args, &arg_idx) orelse {
|
||||
@@ -176,7 +186,7 @@ fn usage(builder: *Builder, already_ran_build: bool, out_stream: anytype) !void
|
||||
try out_stream.writeAll(
|
||||
\\
|
||||
\\General Options:
|
||||
\\ --help Print this help and exit
|
||||
\\ -h, --help Print this help and exit
|
||||
\\ --verbose Print commands before executing them
|
||||
\\ --prefix [path] Override default install prefix
|
||||
\\ --search-prefix [path] Add a path to look for binaries, libraries, headers
|
||||
|
||||
@@ -8,6 +8,31 @@ const builtin = std.builtin;
|
||||
|
||||
const linkage: builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
|
||||
|
||||
// This parameter is true iff the target architecture supports the bare minimum
|
||||
// to implement the atomic load/store intrinsics.
|
||||
// Some architectures support atomic load/stores but no CAS, but we ignore this
|
||||
// detail to keep the export logic clean and because we need some kind of CAS to
|
||||
// implement the spinlocks.
|
||||
const supports_atomic_ops = switch (builtin.arch) {
|
||||
.msp430, .avr => false,
|
||||
.arm, .armeb, .thumb, .thumbeb =>
|
||||
// The ARM v6m ISA has no ldrex/strex and so it's impossible to do CAS
|
||||
// operations (unless we're targeting Linux, the kernel provides a way to
|
||||
// perform CAS operations).
|
||||
// XXX: The Linux code path is not implemented yet.
|
||||
!std.Target.arm.featureSetHas(std.Target.current.cpu.features, .has_v6m),
|
||||
else => true,
|
||||
};
|
||||
|
||||
// The size (in bytes) of the biggest object that the architecture can
|
||||
// load/store atomically.
|
||||
// Objects bigger than this threshold require the use of a lock.
|
||||
const largest_atomic_size = switch (builtin.arch) {
|
||||
// XXX: On x86/x86_64 we could check the presence of cmpxchg8b/cmpxchg16b
|
||||
// and set this parameter accordingly.
|
||||
else => @sizeOf(usize),
|
||||
};
|
||||
|
||||
const cache_line_size = 64;
|
||||
|
||||
const SpinlockTable = struct {
|
||||
@@ -94,40 +119,18 @@ fn __atomic_compare_exchange(
|
||||
}
|
||||
|
||||
comptime {
|
||||
@export(__atomic_load, .{ .name = "__atomic_load", .linkage = linkage });
|
||||
@export(__atomic_store, .{ .name = "__atomic_store", .linkage = linkage });
|
||||
@export(__atomic_exchange, .{ .name = "__atomic_exchange", .linkage = linkage });
|
||||
@export(__atomic_compare_exchange, .{ .name = "__atomic_compare_exchange", .linkage = linkage });
|
||||
if (supports_atomic_ops) {
|
||||
@export(__atomic_load, .{ .name = "__atomic_load", .linkage = linkage });
|
||||
@export(__atomic_store, .{ .name = "__atomic_store", .linkage = linkage });
|
||||
@export(__atomic_exchange, .{ .name = "__atomic_exchange", .linkage = linkage });
|
||||
@export(__atomic_compare_exchange, .{ .name = "__atomic_compare_exchange", .linkage = linkage });
|
||||
}
|
||||
}
|
||||
|
||||
// Specialized versions of the GCC atomic builtin functions.
|
||||
// LLVM emits those iff the object size is known and the pointers are correctly
|
||||
// aligned.
|
||||
|
||||
// The size (in bytes) of the biggest object that the architecture can
|
||||
// load/store atomically.
|
||||
// Objects bigger than this threshold require the use of a lock.
|
||||
const largest_atomic_size = switch (builtin.arch) {
|
||||
.x86_64 => 16,
|
||||
else => @sizeOf(usize),
|
||||
};
|
||||
|
||||
// The size (in bytes) of the biggest object that the architecture can perform
|
||||
// an atomic CAS operation with.
|
||||
// Objects bigger than this threshold require the use of a lock.
|
||||
const largest_atomic_cas_size = switch (builtin.arch) {
|
||||
.arm, .armeb, .thumb, .thumbeb =>
|
||||
// The ARM v6m ISA has no ldrex/strex and so it's impossible to do CAS
|
||||
// operations unless we're targeting Linux or the user provides the missing
|
||||
// builtin functions.
|
||||
if (std.Target.arm.featureSetHas(std.Target.current.cpu.features, .has_v6m) and
|
||||
std.Target.current.os.tag != .linux)
|
||||
0
|
||||
else
|
||||
@sizeOf(usize),
|
||||
else => @sizeOf(usize),
|
||||
};
|
||||
|
||||
fn atomicLoadFn(comptime T: type) fn (*T, i32) callconv(.C) T {
|
||||
return struct {
|
||||
fn atomic_load_N(src: *T, model: i32) callconv(.C) T {
|
||||
@@ -143,10 +146,12 @@ fn atomicLoadFn(comptime T: type) fn (*T, i32) callconv(.C) T {
|
||||
}
|
||||
|
||||
comptime {
|
||||
@export(atomicLoadFn(u8), .{ .name = "__atomic_load_1", .linkage = linkage });
|
||||
@export(atomicLoadFn(u16), .{ .name = "__atomic_load_2", .linkage = linkage });
|
||||
@export(atomicLoadFn(u32), .{ .name = "__atomic_load_4", .linkage = linkage });
|
||||
@export(atomicLoadFn(u64), .{ .name = "__atomic_load_8", .linkage = linkage });
|
||||
if (supports_atomic_ops) {
|
||||
@export(atomicLoadFn(u8), .{ .name = "__atomic_load_1", .linkage = linkage });
|
||||
@export(atomicLoadFn(u16), .{ .name = "__atomic_load_2", .linkage = linkage });
|
||||
@export(atomicLoadFn(u32), .{ .name = "__atomic_load_4", .linkage = linkage });
|
||||
@export(atomicLoadFn(u64), .{ .name = "__atomic_load_8", .linkage = linkage });
|
||||
}
|
||||
}
|
||||
|
||||
fn atomicStoreFn(comptime T: type) fn (*T, T, i32) callconv(.C) void {
|
||||
@@ -164,16 +169,18 @@ fn atomicStoreFn(comptime T: type) fn (*T, T, i32) callconv(.C) void {
|
||||
}
|
||||
|
||||
comptime {
|
||||
@export(atomicStoreFn(u8), .{ .name = "__atomic_store_1", .linkage = linkage });
|
||||
@export(atomicStoreFn(u16), .{ .name = "__atomic_store_2", .linkage = linkage });
|
||||
@export(atomicStoreFn(u32), .{ .name = "__atomic_store_4", .linkage = linkage });
|
||||
@export(atomicStoreFn(u64), .{ .name = "__atomic_store_8", .linkage = linkage });
|
||||
if (supports_atomic_ops) {
|
||||
@export(atomicStoreFn(u8), .{ .name = "__atomic_store_1", .linkage = linkage });
|
||||
@export(atomicStoreFn(u16), .{ .name = "__atomic_store_2", .linkage = linkage });
|
||||
@export(atomicStoreFn(u32), .{ .name = "__atomic_store_4", .linkage = linkage });
|
||||
@export(atomicStoreFn(u64), .{ .name = "__atomic_store_8", .linkage = linkage });
|
||||
}
|
||||
}
|
||||
|
||||
fn atomicExchangeFn(comptime T: type) fn (*T, T, i32) callconv(.C) T {
|
||||
return struct {
|
||||
fn atomic_exchange_N(ptr: *T, val: T, model: i32) callconv(.C) T {
|
||||
if (@sizeOf(T) > largest_atomic_cas_size) {
|
||||
if (@sizeOf(T) > largest_atomic_size) {
|
||||
var sl = spinlocks.get(@ptrToInt(ptr));
|
||||
defer sl.release();
|
||||
const value = ptr.*;
|
||||
@@ -187,16 +194,18 @@ fn atomicExchangeFn(comptime T: type) fn (*T, T, i32) callconv(.C) T {
|
||||
}
|
||||
|
||||
comptime {
|
||||
@export(atomicExchangeFn(u8), .{ .name = "__atomic_exchange_1", .linkage = linkage });
|
||||
@export(atomicExchangeFn(u16), .{ .name = "__atomic_exchange_2", .linkage = linkage });
|
||||
@export(atomicExchangeFn(u32), .{ .name = "__atomic_exchange_4", .linkage = linkage });
|
||||
@export(atomicExchangeFn(u64), .{ .name = "__atomic_exchange_8", .linkage = linkage });
|
||||
if (supports_atomic_ops) {
|
||||
@export(atomicExchangeFn(u8), .{ .name = "__atomic_exchange_1", .linkage = linkage });
|
||||
@export(atomicExchangeFn(u16), .{ .name = "__atomic_exchange_2", .linkage = linkage });
|
||||
@export(atomicExchangeFn(u32), .{ .name = "__atomic_exchange_4", .linkage = linkage });
|
||||
@export(atomicExchangeFn(u64), .{ .name = "__atomic_exchange_8", .linkage = linkage });
|
||||
}
|
||||
}
|
||||
|
||||
fn atomicCompareExchangeFn(comptime T: type) fn (*T, *T, T, i32, i32) callconv(.C) i32 {
|
||||
return struct {
|
||||
fn atomic_compare_exchange_N(ptr: *T, expected: *T, desired: T, success: i32, failure: i32) callconv(.C) i32 {
|
||||
if (@sizeOf(T) > largest_atomic_cas_size) {
|
||||
if (@sizeOf(T) > largest_atomic_size) {
|
||||
var sl = spinlocks.get(@ptrToInt(ptr));
|
||||
defer sl.release();
|
||||
const value = ptr.*;
|
||||
@@ -218,16 +227,18 @@ fn atomicCompareExchangeFn(comptime T: type) fn (*T, *T, T, i32, i32) callconv(.
|
||||
}
|
||||
|
||||
comptime {
|
||||
@export(atomicCompareExchangeFn(u8), .{ .name = "__atomic_compare_exchange_1", .linkage = linkage });
|
||||
@export(atomicCompareExchangeFn(u16), .{ .name = "__atomic_compare_exchange_2", .linkage = linkage });
|
||||
@export(atomicCompareExchangeFn(u32), .{ .name = "__atomic_compare_exchange_4", .linkage = linkage });
|
||||
@export(atomicCompareExchangeFn(u64), .{ .name = "__atomic_compare_exchange_8", .linkage = linkage });
|
||||
if (supports_atomic_ops) {
|
||||
@export(atomicCompareExchangeFn(u8), .{ .name = "__atomic_compare_exchange_1", .linkage = linkage });
|
||||
@export(atomicCompareExchangeFn(u16), .{ .name = "__atomic_compare_exchange_2", .linkage = linkage });
|
||||
@export(atomicCompareExchangeFn(u32), .{ .name = "__atomic_compare_exchange_4", .linkage = linkage });
|
||||
@export(atomicCompareExchangeFn(u64), .{ .name = "__atomic_compare_exchange_8", .linkage = linkage });
|
||||
}
|
||||
}
|
||||
|
||||
fn fetchFn(comptime T: type, comptime op: builtin.AtomicRmwOp) fn (*T, T, i32) callconv(.C) T {
|
||||
return struct {
|
||||
pub fn fetch_op_N(ptr: *T, val: T, model: i32) callconv(.C) T {
|
||||
if (@sizeOf(T) > largest_atomic_cas_size) {
|
||||
if (@sizeOf(T) > largest_atomic_size) {
|
||||
var sl = spinlocks.get(@ptrToInt(ptr));
|
||||
defer sl.release();
|
||||
|
||||
@@ -251,33 +262,35 @@ fn fetchFn(comptime T: type, comptime op: builtin.AtomicRmwOp) fn (*T, T, i32) c
|
||||
}
|
||||
|
||||
comptime {
|
||||
@export(fetchFn(u8, .Add), .{ .name = "__atomic_fetch_add_1", .linkage = linkage });
|
||||
@export(fetchFn(u16, .Add), .{ .name = "__atomic_fetch_add_2", .linkage = linkage });
|
||||
@export(fetchFn(u32, .Add), .{ .name = "__atomic_fetch_add_4", .linkage = linkage });
|
||||
@export(fetchFn(u64, .Add), .{ .name = "__atomic_fetch_add_8", .linkage = linkage });
|
||||
if (supports_atomic_ops) {
|
||||
@export(fetchFn(u8, .Add), .{ .name = "__atomic_fetch_add_1", .linkage = linkage });
|
||||
@export(fetchFn(u16, .Add), .{ .name = "__atomic_fetch_add_2", .linkage = linkage });
|
||||
@export(fetchFn(u32, .Add), .{ .name = "__atomic_fetch_add_4", .linkage = linkage });
|
||||
@export(fetchFn(u64, .Add), .{ .name = "__atomic_fetch_add_8", .linkage = linkage });
|
||||
|
||||
@export(fetchFn(u8, .Sub), .{ .name = "__atomic_fetch_sub_1", .linkage = linkage });
|
||||
@export(fetchFn(u16, .Sub), .{ .name = "__atomic_fetch_sub_2", .linkage = linkage });
|
||||
@export(fetchFn(u32, .Sub), .{ .name = "__atomic_fetch_sub_4", .linkage = linkage });
|
||||
@export(fetchFn(u64, .Sub), .{ .name = "__atomic_fetch_sub_8", .linkage = linkage });
|
||||
@export(fetchFn(u8, .Sub), .{ .name = "__atomic_fetch_sub_1", .linkage = linkage });
|
||||
@export(fetchFn(u16, .Sub), .{ .name = "__atomic_fetch_sub_2", .linkage = linkage });
|
||||
@export(fetchFn(u32, .Sub), .{ .name = "__atomic_fetch_sub_4", .linkage = linkage });
|
||||
@export(fetchFn(u64, .Sub), .{ .name = "__atomic_fetch_sub_8", .linkage = linkage });
|
||||
|
||||
@export(fetchFn(u8, .And), .{ .name = "__atomic_fetch_and_1", .linkage = linkage });
|
||||
@export(fetchFn(u16, .And), .{ .name = "__atomic_fetch_and_2", .linkage = linkage });
|
||||
@export(fetchFn(u32, .And), .{ .name = "__atomic_fetch_and_4", .linkage = linkage });
|
||||
@export(fetchFn(u64, .And), .{ .name = "__atomic_fetch_and_8", .linkage = linkage });
|
||||
@export(fetchFn(u8, .And), .{ .name = "__atomic_fetch_and_1", .linkage = linkage });
|
||||
@export(fetchFn(u16, .And), .{ .name = "__atomic_fetch_and_2", .linkage = linkage });
|
||||
@export(fetchFn(u32, .And), .{ .name = "__atomic_fetch_and_4", .linkage = linkage });
|
||||
@export(fetchFn(u64, .And), .{ .name = "__atomic_fetch_and_8", .linkage = linkage });
|
||||
|
||||
@export(fetchFn(u8, .Or), .{ .name = "__atomic_fetch_or_1", .linkage = linkage });
|
||||
@export(fetchFn(u16, .Or), .{ .name = "__atomic_fetch_or_2", .linkage = linkage });
|
||||
@export(fetchFn(u32, .Or), .{ .name = "__atomic_fetch_or_4", .linkage = linkage });
|
||||
@export(fetchFn(u64, .Or), .{ .name = "__atomic_fetch_or_8", .linkage = linkage });
|
||||
@export(fetchFn(u8, .Or), .{ .name = "__atomic_fetch_or_1", .linkage = linkage });
|
||||
@export(fetchFn(u16, .Or), .{ .name = "__atomic_fetch_or_2", .linkage = linkage });
|
||||
@export(fetchFn(u32, .Or), .{ .name = "__atomic_fetch_or_4", .linkage = linkage });
|
||||
@export(fetchFn(u64, .Or), .{ .name = "__atomic_fetch_or_8", .linkage = linkage });
|
||||
|
||||
@export(fetchFn(u8, .Xor), .{ .name = "__atomic_fetch_xor_1", .linkage = linkage });
|
||||
@export(fetchFn(u16, .Xor), .{ .name = "__atomic_fetch_xor_2", .linkage = linkage });
|
||||
@export(fetchFn(u32, .Xor), .{ .name = "__atomic_fetch_xor_4", .linkage = linkage });
|
||||
@export(fetchFn(u64, .Xor), .{ .name = "__atomic_fetch_xor_8", .linkage = linkage });
|
||||
@export(fetchFn(u8, .Xor), .{ .name = "__atomic_fetch_xor_1", .linkage = linkage });
|
||||
@export(fetchFn(u16, .Xor), .{ .name = "__atomic_fetch_xor_2", .linkage = linkage });
|
||||
@export(fetchFn(u32, .Xor), .{ .name = "__atomic_fetch_xor_4", .linkage = linkage });
|
||||
@export(fetchFn(u64, .Xor), .{ .name = "__atomic_fetch_xor_8", .linkage = linkage });
|
||||
|
||||
@export(fetchFn(u8, .Nand), .{ .name = "__atomic_fetch_nand_1", .linkage = linkage });
|
||||
@export(fetchFn(u16, .Nand), .{ .name = "__atomic_fetch_nand_2", .linkage = linkage });
|
||||
@export(fetchFn(u32, .Nand), .{ .name = "__atomic_fetch_nand_4", .linkage = linkage });
|
||||
@export(fetchFn(u64, .Nand), .{ .name = "__atomic_fetch_nand_8", .linkage = linkage });
|
||||
@export(fetchFn(u8, .Nand), .{ .name = "__atomic_fetch_nand_1", .linkage = linkage });
|
||||
@export(fetchFn(u16, .Nand), .{ .name = "__atomic_fetch_nand_2", .linkage = linkage });
|
||||
@export(fetchFn(u32, .Nand), .{ .name = "__atomic_fetch_nand_4", .linkage = linkage });
|
||||
@export(fetchFn(u64, .Nand), .{ .name = "__atomic_fetch_nand_8", .linkage = linkage });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
|
||||
// The MIT license requires this copyright notice to be included in all copies
|
||||
// and substantial portions of the software.
|
||||
const builtin = @import("builtin");
|
||||
const std = @import("std");
|
||||
const builtin = std.builtin;
|
||||
|
||||
fn __clzsi2_generic(a: i32) callconv(.C) i32 {
|
||||
@setRuntimeSafety(builtin.is_test);
|
||||
@@ -25,8 +26,6 @@ fn __clzsi2_generic(a: i32) callconv(.C) i32 {
|
||||
}
|
||||
|
||||
fn __clzsi2_thumb1() callconv(.Naked) void {
|
||||
@setRuntimeSafety(builtin.is_test);
|
||||
|
||||
// Similar to the generic version with the last two rounds replaced by a LUT
|
||||
asm volatile (
|
||||
\\ movs r1, #32
|
||||
@@ -59,8 +58,6 @@ fn __clzsi2_thumb1() callconv(.Naked) void {
|
||||
}
|
||||
|
||||
fn __clzsi2_arm32() callconv(.Naked) void {
|
||||
@setRuntimeSafety(builtin.is_test);
|
||||
|
||||
asm volatile (
|
||||
\\ // Assumption: n != 0
|
||||
\\ // r0: n
|
||||
@@ -107,14 +104,13 @@ fn __clzsi2_arm32() callconv(.Naked) void {
|
||||
unreachable;
|
||||
}
|
||||
|
||||
pub const __clzsi2 = blk: {
|
||||
if (builtin.arch.isARM()) {
|
||||
break :blk __clzsi2_arm32;
|
||||
} else if (builtin.arch.isThumb()) {
|
||||
break :blk __clzsi2_thumb1;
|
||||
} else {
|
||||
break :blk __clzsi2_generic;
|
||||
}
|
||||
pub const __clzsi2 = switch (std.Target.current.cpu.arch) {
|
||||
.arm, .armeb => if (std.Target.arm.featureSetHas(std.Target.current.cpu.features, .noarm))
|
||||
__clzsi2_thumb1
|
||||
else
|
||||
__clzsi2_arm32,
|
||||
.thumb, .thumbeb => __clzsi2_thumb1,
|
||||
else => __clzsi2_generic,
|
||||
};
|
||||
|
||||
test "test clzsi2" {
|
||||
|
||||
@@ -54,7 +54,7 @@ fn _DllMainCRTStartup(
|
||||
fdwReason: std.os.windows.DWORD,
|
||||
lpReserved: std.os.windows.LPVOID,
|
||||
) callconv(.Stdcall) std.os.windows.BOOL {
|
||||
if (!builtin.single_threaded) {
|
||||
if (!builtin.single_threaded and !builtin.link_libc) {
|
||||
_ = @import("start_windows_tls.zig");
|
||||
}
|
||||
|
||||
|
||||
@@ -237,7 +237,7 @@ pub const Target = struct {
|
||||
.macos => return .{
|
||||
.semver = .{
|
||||
.min = .{ .major = 10, .minor = 13 },
|
||||
.max = .{ .major = 10, .minor = 15, .patch = 3 },
|
||||
.max = .{ .major = 10, .minor = 15, .patch = 7 },
|
||||
},
|
||||
},
|
||||
.ios => return .{
|
||||
|
||||
@@ -247,6 +247,7 @@ test "expectWithinEpsilon" {
|
||||
/// This function is intended to be used only in tests. When the two slices are not
|
||||
/// equal, prints diagnostics to stderr to show exactly how they are not equal,
|
||||
/// then aborts.
|
||||
/// If your inputs are UTF-8 encoded strings, consider calling `expectEqualStrings` instead.
|
||||
pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const T) void {
|
||||
// TODO better printing of the difference
|
||||
// If the arrays are small enough we could print the whole thing
|
||||
@@ -368,6 +369,26 @@ pub fn expectEqualStrings(expected: []const u8, actual: []const u8) void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expectStringEndsWith(actual: []const u8, expected_ends_with: []const u8) void {
|
||||
if (std.mem.endsWith(u8, actual, expected_ends_with))
|
||||
return;
|
||||
|
||||
const shortened_actual = if (actual.len >= expected_ends_with.len)
|
||||
actual[0..expected_ends_with.len]
|
||||
else
|
||||
actual;
|
||||
|
||||
print("\n====== expected to end with: =========\n", .{});
|
||||
printWithVisibleNewlines(expected_ends_with);
|
||||
print("\n====== instead ended with: ===========\n", .{});
|
||||
printWithVisibleNewlines(shortened_actual);
|
||||
print("\n========= full output: ==============\n", .{});
|
||||
printWithVisibleNewlines(actual);
|
||||
print("\n======================================\n", .{});
|
||||
|
||||
@panic("test failure");
|
||||
}
|
||||
|
||||
fn printIndicatorLine(source: []const u8, indicator_index: usize) void {
|
||||
const line_begin_index = if (std.mem.lastIndexOfScalar(u8, source[0..indicator_index], '\n')) |line_begin|
|
||||
line_begin + 1
|
||||
|
||||
@@ -40,7 +40,7 @@ pub const Thread = struct {
|
||||
pub const Data = if (use_pthreads)
|
||||
struct {
|
||||
handle: Thread.Handle,
|
||||
memory: []align(mem.page_size) u8,
|
||||
memory: []u8,
|
||||
}
|
||||
else switch (std.Target.current.os.tag) {
|
||||
.linux => struct {
|
||||
@@ -63,10 +63,10 @@ pub const Thread = struct {
|
||||
return c.pthread_self();
|
||||
} else
|
||||
return switch (std.Target.current.os.tag) {
|
||||
.linux => os.linux.gettid(),
|
||||
.windows => windows.kernel32.GetCurrentThreadId(),
|
||||
else => @compileError("Unsupported OS"),
|
||||
};
|
||||
.linux => os.linux.gettid(),
|
||||
.windows => windows.kernel32.GetCurrentThreadId(),
|
||||
else => @compileError("Unsupported OS"),
|
||||
};
|
||||
}
|
||||
|
||||
/// Returns the handle of this thread.
|
||||
@@ -79,7 +79,7 @@ pub const Thread = struct {
|
||||
return self.data.handle;
|
||||
}
|
||||
|
||||
pub fn wait(self: *const Thread) void {
|
||||
pub fn wait(self: *Thread) void {
|
||||
if (use_pthreads) {
|
||||
const err = c.pthread_join(self.data.handle, null);
|
||||
switch (err) {
|
||||
@@ -89,7 +89,8 @@ pub const Thread = struct {
|
||||
os.EDEADLK => unreachable,
|
||||
else => unreachable,
|
||||
}
|
||||
os.munmap(self.data.memory);
|
||||
std.heap.c_allocator.free(self.data.memory);
|
||||
std.heap.c_allocator.destroy(self);
|
||||
} else switch (std.Target.current.os.tag) {
|
||||
.linux => {
|
||||
while (true) {
|
||||
@@ -292,6 +293,47 @@ pub const Thread = struct {
|
||||
}
|
||||
};
|
||||
|
||||
if (Thread.use_pthreads) {
|
||||
var attr: c.pthread_attr_t = undefined;
|
||||
if (c.pthread_attr_init(&attr) != 0) return error.SystemResources;
|
||||
defer assert(c.pthread_attr_destroy(&attr) == 0);
|
||||
|
||||
const thread_obj = try std.heap.c_allocator.create(Thread);
|
||||
errdefer std.heap.c_allocator.destroy(thread_obj);
|
||||
if (@sizeOf(Context) > 0) {
|
||||
thread_obj.data.memory = try std.heap.c_allocator.allocAdvanced(
|
||||
u8,
|
||||
@alignOf(Context),
|
||||
@sizeOf(Context),
|
||||
.at_least,
|
||||
);
|
||||
errdefer std.heap.c_allocator.free(thread_obj.data.memory);
|
||||
mem.copy(u8, thread_obj.data.memory, mem.asBytes(&context));
|
||||
} else {
|
||||
thread_obj.data.memory = @as([*]u8, undefined)[0..0];
|
||||
}
|
||||
|
||||
// Use the same set of parameters used by the libc-less impl.
|
||||
assert(c.pthread_attr_setstacksize(&attr, default_stack_size) == 0);
|
||||
assert(c.pthread_attr_setguardsize(&attr, mem.page_size) == 0);
|
||||
|
||||
const err = c.pthread_create(
|
||||
&thread_obj.data.handle,
|
||||
&attr,
|
||||
MainFuncs.posixThreadMain,
|
||||
thread_obj.data.memory.ptr,
|
||||
);
|
||||
switch (err) {
|
||||
0 => return thread_obj,
|
||||
os.EAGAIN => return error.SystemResources,
|
||||
os.EPERM => unreachable,
|
||||
os.EINVAL => unreachable,
|
||||
else => return os.unexpectedErrno(@intCast(usize, err)),
|
||||
}
|
||||
|
||||
return thread_obj;
|
||||
}
|
||||
|
||||
var guard_end_offset: usize = undefined;
|
||||
var stack_end_offset: usize = undefined;
|
||||
var thread_start_offset: usize = undefined;
|
||||
@@ -315,74 +357,41 @@ pub const Thread = struct {
|
||||
l += @sizeOf(Context);
|
||||
}
|
||||
// Finally, the Thread Local Storage, if any.
|
||||
if (!Thread.use_pthreads) {
|
||||
l = mem.alignForward(l, os.linux.tls.tls_image.alloc_align);
|
||||
tls_start_offset = l;
|
||||
l += os.linux.tls.tls_image.alloc_size;
|
||||
}
|
||||
l = mem.alignForward(l, os.linux.tls.tls_image.alloc_align);
|
||||
tls_start_offset = l;
|
||||
l += os.linux.tls.tls_image.alloc_size;
|
||||
// Round the size to the page size.
|
||||
break :blk mem.alignForward(l, mem.page_size);
|
||||
};
|
||||
|
||||
const mmap_slice = mem: {
|
||||
if (std.Target.current.os.tag != .netbsd) {
|
||||
// Map the whole stack with no rw permissions to avoid
|
||||
// committing the whole region right away
|
||||
const mmap_slice = os.mmap(
|
||||
null,
|
||||
mmap_len,
|
||||
os.PROT_NONE,
|
||||
os.MAP_PRIVATE | os.MAP_ANONYMOUS,
|
||||
-1,
|
||||
0,
|
||||
) catch |err| switch (err) {
|
||||
error.MemoryMappingNotSupported => unreachable,
|
||||
error.AccessDenied => unreachable,
|
||||
error.PermissionDenied => unreachable,
|
||||
else => |e| return e,
|
||||
};
|
||||
errdefer os.munmap(mmap_slice);
|
||||
// Map the whole stack with no rw permissions to avoid
|
||||
// committing the whole region right away
|
||||
const mmap_slice = os.mmap(
|
||||
null,
|
||||
mmap_len,
|
||||
os.PROT_NONE,
|
||||
os.MAP_PRIVATE | os.MAP_ANONYMOUS,
|
||||
-1,
|
||||
0,
|
||||
) catch |err| switch (err) {
|
||||
error.MemoryMappingNotSupported => unreachable,
|
||||
error.AccessDenied => unreachable,
|
||||
error.PermissionDenied => unreachable,
|
||||
else => |e| return e,
|
||||
};
|
||||
errdefer os.munmap(mmap_slice);
|
||||
|
||||
// Map everything but the guard page as rw
|
||||
os.mprotect(
|
||||
mmap_slice[guard_end_offset..],
|
||||
os.PROT_READ | os.PROT_WRITE,
|
||||
) catch |err| switch (err) {
|
||||
error.AccessDenied => unreachable,
|
||||
else => |e| return e,
|
||||
};
|
||||
// Map everything but the guard page as rw
|
||||
os.mprotect(
|
||||
mmap_slice[guard_end_offset..],
|
||||
os.PROT_READ | os.PROT_WRITE,
|
||||
) catch |err| switch (err) {
|
||||
error.AccessDenied => unreachable,
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
break :mem mmap_slice;
|
||||
} else {
|
||||
// NetBSD mprotect is very strict and doesn't allow to "upgrade"
|
||||
// a PROT_NONE mapping to a RW one so let's allocate everything
|
||||
// right away
|
||||
const mmap_slice = os.mmap(
|
||||
null,
|
||||
mmap_len,
|
||||
os.PROT_READ | os.PROT_WRITE,
|
||||
os.MAP_PRIVATE | os.MAP_ANONYMOUS,
|
||||
-1,
|
||||
0,
|
||||
) catch |err| switch (err) {
|
||||
error.MemoryMappingNotSupported => unreachable,
|
||||
error.AccessDenied => unreachable,
|
||||
error.PermissionDenied => unreachable,
|
||||
else => |e| return e,
|
||||
};
|
||||
errdefer os.munmap(mmap_slice);
|
||||
|
||||
// Remap the guard page with no permissions
|
||||
os.mprotect(
|
||||
mmap_slice[0..guard_end_offset],
|
||||
os.PROT_NONE,
|
||||
) catch |err| switch (err) {
|
||||
error.AccessDenied => unreachable,
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
break :mem mmap_slice;
|
||||
}
|
||||
break :mem mmap_slice;
|
||||
};
|
||||
|
||||
const mmap_addr = @ptrToInt(mmap_slice.ptr);
|
||||
@@ -397,33 +406,7 @@ pub const Thread = struct {
|
||||
context_ptr.* = context;
|
||||
}
|
||||
|
||||
if (Thread.use_pthreads) {
|
||||
// use pthreads
|
||||
var attr: c.pthread_attr_t = undefined;
|
||||
if (c.pthread_attr_init(&attr) != 0) return error.SystemResources;
|
||||
defer assert(c.pthread_attr_destroy(&attr) == 0);
|
||||
|
||||
// Tell pthread where the effective stack start is and its size
|
||||
assert(c.pthread_attr_setstack(
|
||||
&attr,
|
||||
mmap_slice.ptr + guard_end_offset,
|
||||
stack_end_offset - guard_end_offset,
|
||||
) == 0);
|
||||
// Even though pthread's man pages state that the guard size is
|
||||
// ignored when the stack address is explicitly given, on some
|
||||
// plaforms such as NetBSD we still have to zero it to prevent
|
||||
// random crashes in pthread_join calls
|
||||
assert(c.pthread_attr_setguardsize(&attr, 0) == 0);
|
||||
|
||||
const err = c.pthread_create(&thread_ptr.data.handle, &attr, MainFuncs.posixThreadMain, @intToPtr(*c_void, arg));
|
||||
switch (err) {
|
||||
0 => return thread_ptr,
|
||||
os.EAGAIN => return error.SystemResources,
|
||||
os.EPERM => unreachable,
|
||||
os.EINVAL => unreachable,
|
||||
else => return os.unexpectedErrno(@intCast(usize, err)),
|
||||
}
|
||||
} else if (std.Target.current.os.tag == .linux) {
|
||||
if (std.Target.current.os.tag == .linux) {
|
||||
const flags: u32 = os.CLONE_VM | os.CLONE_FS | os.CLONE_FILES |
|
||||
os.CLONE_SIGHAND | os.CLONE_THREAD | os.CLONE_SYSVSEM |
|
||||
os.CLONE_PARENT_SETTID | os.CLONE_CHILD_CLEARTID |
|
||||
|
||||
@@ -500,8 +500,12 @@ pub const CrossTarget = struct {
|
||||
self.dynamic_linker.get() == null and self.glibc_version == null;
|
||||
}
|
||||
|
||||
pub fn isNativeAbi(self: CrossTarget) bool {
|
||||
return self.os_tag == null and self.abi == null;
|
||||
}
|
||||
|
||||
pub fn isNative(self: CrossTarget) bool {
|
||||
return self.isNativeCpu() and self.isNativeOs() and self.abi == null;
|
||||
return self.isNativeCpu() and self.isNativeOs() and self.isNativeAbi();
|
||||
}
|
||||
|
||||
pub fn zigTriple(self: CrossTarget, allocator: *mem.Allocator) error{OutOfMemory}![]u8 {
|
||||
|
||||
@@ -274,6 +274,51 @@ test "recovery: missing block after for/while loops" {
|
||||
});
|
||||
}
|
||||
|
||||
test "zig fmt: respect line breaks after var declarations" {
|
||||
try testCanonical(
|
||||
\\const crc =
|
||||
\\ lookup_tables[0][p[7]] ^
|
||||
\\ lookup_tables[1][p[6]] ^
|
||||
\\ lookup_tables[2][p[5]] ^
|
||||
\\ lookup_tables[3][p[4]] ^
|
||||
\\ lookup_tables[4][@truncate(u8, self.crc >> 24)] ^
|
||||
\\ lookup_tables[5][@truncate(u8, self.crc >> 16)] ^
|
||||
\\ lookup_tables[6][@truncate(u8, self.crc >> 8)] ^
|
||||
\\ lookup_tables[7][@truncate(u8, self.crc >> 0)];
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: multiline string mixed with comments" {
|
||||
try testCanonical(
|
||||
\\const s1 =
|
||||
\\ //\\one
|
||||
\\ \\two)
|
||||
\\ \\three
|
||||
\\;
|
||||
\\const s2 =
|
||||
\\ \\one
|
||||
\\ \\two)
|
||||
\\ //\\three
|
||||
\\;
|
||||
\\const s3 =
|
||||
\\ \\one
|
||||
\\ //\\two)
|
||||
\\ \\three
|
||||
\\;
|
||||
\\const s4 =
|
||||
\\ \\one
|
||||
\\ //\\two
|
||||
\\ \\three
|
||||
\\ //\\four
|
||||
\\ \\five
|
||||
\\;
|
||||
\\const a =
|
||||
\\ 1;
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: empty file" {
|
||||
try testCanonical(
|
||||
\\
|
||||
@@ -518,6 +563,24 @@ test "zig fmt: anon literal in array" {
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: alignment in anonymous literal" {
|
||||
try testTransform(
|
||||
\\const a = .{
|
||||
\\ "U", "L", "F",
|
||||
\\ "U'",
|
||||
\\ "L'",
|
||||
\\ "F'",
|
||||
\\};
|
||||
\\
|
||||
,
|
||||
\\const a = .{
|
||||
\\ "U", "L", "F",
|
||||
\\ "U'", "L'", "F'",
|
||||
\\};
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: anon struct literal syntax" {
|
||||
try testCanonical(
|
||||
\\const x = .{
|
||||
@@ -3224,7 +3287,8 @@ test "zig fmt: integer literals with underscore separators" {
|
||||
\\ 1_234_567
|
||||
\\ +(0b0_1-0o7_0+0xff_FF ) + 0_0;
|
||||
,
|
||||
\\const x = 1_234_567 + (0b0_1 - 0o7_0 + 0xff_FF) + 0_0;
|
||||
\\const x =
|
||||
\\ 1_234_567 + (0b0_1 - 0o7_0 + 0xff_FF) + 0_0;
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
@@ -813,12 +813,10 @@ fn renderExpression(
|
||||
const expr_last_token = expr.*.lastToken() + 1;
|
||||
const next_expr = section_exprs[i + 1];
|
||||
const loc = tree.tokenLocation(tree.token_locs[expr_last_token].start, next_expr.*.firstToken());
|
||||
if (loc.line == 0) {
|
||||
column_counter += 1;
|
||||
} else {
|
||||
single_line = false;
|
||||
column_counter = 0;
|
||||
}
|
||||
|
||||
column_counter += 1;
|
||||
|
||||
if (loc.line != 0) single_line = false;
|
||||
} else {
|
||||
single_line = false;
|
||||
column_counter = 0;
|
||||
@@ -2209,10 +2207,10 @@ fn renderAsmOutput(
|
||||
try ais.writer().writeAll(" (");
|
||||
|
||||
switch (asm_output.kind) {
|
||||
ast.Node.Asm.Output.Kind.Variable => |variable_name| {
|
||||
.Variable => |variable_name| {
|
||||
try renderExpression(allocator, ais, tree, &variable_name.base, Space.None);
|
||||
},
|
||||
ast.Node.Asm.Output.Kind.Return => |return_type| {
|
||||
.Return => |return_type| {
|
||||
try ais.writer().writeAll("-> ");
|
||||
try renderExpression(allocator, ais, tree, return_type, Space.None);
|
||||
},
|
||||
@@ -2304,8 +2302,17 @@ fn renderVarDecl(
|
||||
}
|
||||
|
||||
if (var_decl.getInitNode()) |init_node| {
|
||||
const s = if (init_node.tag == .MultilineStringLiteral) Space.None else Space.Space;
|
||||
try renderToken(tree, ais, var_decl.getEqToken().?, s); // =
|
||||
const eq_token = var_decl.getEqToken().?;
|
||||
const eq_space = blk: {
|
||||
const loc = tree.tokenLocation(tree.token_locs[eq_token].end, tree.nextToken(eq_token));
|
||||
break :blk if (loc.line == 0) Space.Space else Space.Newline;
|
||||
};
|
||||
|
||||
{
|
||||
ais.pushIndent();
|
||||
defer ais.popIndent();
|
||||
try renderToken(tree, ais, eq_token, eq_space); // =
|
||||
}
|
||||
ais.pushIndentOneShot();
|
||||
try renderExpression(allocator, ais, tree, init_node, Space.None);
|
||||
}
|
||||
@@ -2470,20 +2477,20 @@ fn renderTokenOffset(
|
||||
|
||||
var loc = tree.tokenLocationLoc(token_loc.end, next_token_loc);
|
||||
if (loc.line == 0) {
|
||||
try ais.writer().print(" {}", .{mem.trimRight(u8, tree.tokenSliceLoc(next_token_loc), " ")});
|
||||
if (tree.token_ids[token_index] != .MultilineStringLiteralLine) {
|
||||
try ais.writer().writeByte(' ');
|
||||
}
|
||||
try ais.writer().writeAll(mem.trimRight(u8, tree.tokenSliceLoc(next_token_loc), " "));
|
||||
offset = 2;
|
||||
token_loc = next_token_loc;
|
||||
next_token_loc = tree.token_locs[token_index + offset];
|
||||
next_token_id = tree.token_ids[token_index + offset];
|
||||
if (next_token_id != .LineComment) {
|
||||
switch (space) {
|
||||
Space.None, Space.Space => {
|
||||
.None, .Space, .SpaceOrOutdent => {
|
||||
try ais.insertNewline();
|
||||
},
|
||||
Space.SpaceOrOutdent => {
|
||||
try ais.insertNewline();
|
||||
},
|
||||
Space.Newline => {
|
||||
.Newline => {
|
||||
if (next_token_id == .MultilineStringLiteralLine) {
|
||||
return;
|
||||
} else {
|
||||
@@ -2491,8 +2498,8 @@ fn renderTokenOffset(
|
||||
return;
|
||||
}
|
||||
},
|
||||
Space.NoNewline => {},
|
||||
Space.NoComment, Space.Comma, Space.BlockStart => unreachable,
|
||||
.NoNewline => {},
|
||||
.NoComment, .Comma, .BlockStart => unreachable,
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -2513,7 +2520,7 @@ fn renderTokenOffset(
|
||||
next_token_id = tree.token_ids[token_index + offset];
|
||||
if (next_token_id != .LineComment) {
|
||||
switch (space) {
|
||||
Space.Newline => {
|
||||
.Newline => {
|
||||
if (next_token_id == .MultilineStringLiteralLine) {
|
||||
return;
|
||||
} else {
|
||||
@@ -2521,14 +2528,11 @@ fn renderTokenOffset(
|
||||
return;
|
||||
}
|
||||
},
|
||||
Space.None, Space.Space => {
|
||||
.None, .Space, .SpaceOrOutdent => {
|
||||
try ais.insertNewline();
|
||||
},
|
||||
Space.SpaceOrOutdent => {
|
||||
try ais.insertNewline();
|
||||
},
|
||||
Space.NoNewline => {},
|
||||
Space.NoComment, Space.Comma, Space.BlockStart => unreachable,
|
||||
.NoNewline => {},
|
||||
.NoComment, .Comma, .BlockStart => unreachable,
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -2649,6 +2653,8 @@ fn copyFixingWhitespace(ais: anytype, slice: []const u8) @TypeOf(ais.*).Error!vo
|
||||
};
|
||||
}
|
||||
|
||||
// Returns the number of nodes in `expr` that are on the same line as `rtoken`,
|
||||
// or null if they all are on the same line.
|
||||
fn rowSize(tree: *ast.Tree, exprs: []*ast.Node, rtoken: ast.TokenIndex) ?usize {
|
||||
const first_token = exprs[0].firstToken();
|
||||
const first_loc = tree.tokenLocation(tree.token_locs[first_token].start, rtoken);
|
||||
|
||||
@@ -211,16 +211,9 @@ pub const NativeTargetInfo = struct {
|
||||
.linux => {
|
||||
const uts = std.os.uname();
|
||||
const release = mem.spanZ(&uts.release);
|
||||
// The release field may have several other fields after the
|
||||
// kernel version
|
||||
const kernel_version = if (mem.indexOfScalar(u8, release, '-')) |pos|
|
||||
release[0..pos]
|
||||
else if (mem.indexOfScalar(u8, release, '_')) |pos|
|
||||
release[0..pos]
|
||||
else
|
||||
release;
|
||||
|
||||
if (std.builtin.Version.parse(kernel_version)) |ver| {
|
||||
// The release field sometimes has a weird format,
|
||||
// `Version.parse` will attempt to find some meaningful interpretation.
|
||||
if (std.builtin.Version.parse(release)) |ver| {
|
||||
os.version_range.linux.range.min = ver;
|
||||
os.version_range.linux.range.max = ver;
|
||||
} else |err| switch (err) {
|
||||
|
||||
@@ -26,6 +26,7 @@ pub fn obtain(cache: *const Cache) Manifest {
|
||||
/// This is 128 bits - Even with 2^54 cache entries, the probably of a collision would be under 10^-6
|
||||
pub const bin_digest_len = 16;
|
||||
pub const hex_digest_len = bin_digest_len * 2;
|
||||
pub const BinDigest = [bin_digest_len]u8;
|
||||
|
||||
const manifest_file_size_max = 50 * 1024 * 1024;
|
||||
|
||||
@@ -41,7 +42,7 @@ pub const File = struct {
|
||||
path: ?[]const u8,
|
||||
max_file_size: ?usize,
|
||||
stat: fs.File.Stat,
|
||||
bin_digest: [bin_digest_len]u8,
|
||||
bin_digest: BinDigest,
|
||||
contents: ?[]const u8,
|
||||
|
||||
pub fn deinit(self: *File, allocator: *Allocator) void {
|
||||
@@ -60,6 +61,8 @@ pub const File = struct {
|
||||
pub const HashHelper = struct {
|
||||
hasher: Hasher = hasher_init,
|
||||
|
||||
const EmitLoc = @import("Compilation.zig").EmitLoc;
|
||||
|
||||
/// Record a slice of bytes as an dependency of the process being cached
|
||||
pub fn addBytes(hh: *HashHelper, bytes: []const u8) void {
|
||||
hh.hasher.update(mem.asBytes(&bytes.len));
|
||||
@@ -71,6 +74,15 @@ pub const HashHelper = struct {
|
||||
hh.addBytes(optional_bytes orelse return);
|
||||
}
|
||||
|
||||
pub fn addEmitLoc(hh: *HashHelper, emit_loc: EmitLoc) void {
|
||||
hh.addBytes(emit_loc.basename);
|
||||
}
|
||||
|
||||
pub fn addOptionalEmitLoc(hh: *HashHelper, optional_emit_loc: ?EmitLoc) void {
|
||||
hh.add(optional_emit_loc != null);
|
||||
hh.addEmitLoc(optional_emit_loc orelse return);
|
||||
}
|
||||
|
||||
pub fn addListOfBytes(hh: *HashHelper, list_of_bytes: []const []const u8) void {
|
||||
hh.add(list_of_bytes.len);
|
||||
for (list_of_bytes) |bytes| hh.addBytes(bytes);
|
||||
@@ -128,16 +140,16 @@ pub const HashHelper = struct {
|
||||
return copy.final();
|
||||
}
|
||||
|
||||
pub fn peekBin(hh: HashHelper) [bin_digest_len]u8 {
|
||||
pub fn peekBin(hh: HashHelper) BinDigest {
|
||||
var copy = hh;
|
||||
var bin_digest: [bin_digest_len]u8 = undefined;
|
||||
var bin_digest: BinDigest = undefined;
|
||||
copy.hasher.final(&bin_digest);
|
||||
return bin_digest;
|
||||
}
|
||||
|
||||
/// Returns a hex encoded hash of the inputs, mutating the state of the hasher.
|
||||
pub fn final(hh: *HashHelper) [hex_digest_len]u8 {
|
||||
var bin_digest: [bin_digest_len]u8 = undefined;
|
||||
var bin_digest: BinDigest = undefined;
|
||||
hh.hasher.final(&bin_digest);
|
||||
|
||||
var out_digest: [hex_digest_len]u8 = undefined;
|
||||
@@ -230,7 +242,7 @@ pub const Manifest = struct {
|
||||
const ext = ".txt";
|
||||
var manifest_file_path: [self.hex_digest.len + ext.len]u8 = undefined;
|
||||
|
||||
var bin_digest: [bin_digest_len]u8 = undefined;
|
||||
var bin_digest: BinDigest = undefined;
|
||||
self.hash.hasher.final(&bin_digest);
|
||||
|
||||
_ = std.fmt.bufPrint(&self.hex_digest, "{x}", .{bin_digest}) catch unreachable;
|
||||
@@ -336,7 +348,7 @@ pub const Manifest = struct {
|
||||
cache_hash_file.stat.inode = 0;
|
||||
}
|
||||
|
||||
var actual_digest: [bin_digest_len]u8 = undefined;
|
||||
var actual_digest: BinDigest = undefined;
|
||||
try hashFile(this_file, &actual_digest);
|
||||
|
||||
if (!mem.eql(u8, &cache_hash_file.bin_digest, &actual_digest)) {
|
||||
@@ -370,7 +382,7 @@ pub const Manifest = struct {
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn unhit(self: *Manifest, bin_digest: [bin_digest_len]u8, input_file_count: usize) void {
|
||||
pub fn unhit(self: *Manifest, bin_digest: BinDigest, input_file_count: usize) void {
|
||||
// Reset the hash.
|
||||
self.hash.hasher = hasher_init;
|
||||
self.hash.hasher.update(&bin_digest);
|
||||
@@ -519,7 +531,7 @@ pub const Manifest = struct {
|
||||
// cache_release is called we still might be working on creating
|
||||
// the artifacts to cache.
|
||||
|
||||
var bin_digest: [bin_digest_len]u8 = undefined;
|
||||
var bin_digest: BinDigest = undefined;
|
||||
self.hash.hasher.final(&bin_digest);
|
||||
|
||||
var out_digest: [hex_digest_len]u8 = undefined;
|
||||
|
||||
@@ -33,6 +33,7 @@ gpa: *Allocator,
|
||||
arena_state: std.heap.ArenaAllocator.State,
|
||||
bin_file: *link.File,
|
||||
c_object_table: std.AutoArrayHashMapUnmanaged(*CObject, void) = .{},
|
||||
c_object_cache_digest_set: std.AutoHashMapUnmanaged(Cache.BinDigest, void) = .{},
|
||||
stage1_lock: ?Cache.Lock = null,
|
||||
stage1_cache_manifest: *Cache.Manifest = undefined,
|
||||
|
||||
@@ -93,6 +94,9 @@ libc_static_lib: ?CRTFile = null,
|
||||
/// Populated when we build the libcompiler_rt static library. A Job to build this is placed in the queue
|
||||
/// and resolved before calling linker.flush().
|
||||
compiler_rt_static_lib: ?CRTFile = null,
|
||||
/// Populated when we build the compiler_rt_obj object. A Job to build this is placed in the queue
|
||||
/// and resolved before calling linker.flush().
|
||||
compiler_rt_obj: ?CRTFile = null,
|
||||
|
||||
glibc_so_files: ?glibc.BuiltSharedObjects = null,
|
||||
|
||||
@@ -164,8 +168,8 @@ const Job = union(enum) {
|
||||
libcxx: void,
|
||||
libcxxabi: void,
|
||||
libssp: void,
|
||||
/// needed when producing a dynamic library or executable
|
||||
libcompiler_rt: void,
|
||||
compiler_rt_lib: void,
|
||||
compiler_rt_obj: void,
|
||||
/// needed when not linking libc and using LLVM for code generation because it generates
|
||||
/// calls to, for example, memcpy and memset.
|
||||
zig_libc: void,
|
||||
@@ -346,6 +350,7 @@ pub const InitOptions = struct {
|
||||
want_sanitize_c: ?bool = null,
|
||||
want_stack_check: ?bool = null,
|
||||
want_valgrind: ?bool = null,
|
||||
want_compiler_rt: ?bool = null,
|
||||
use_llvm: ?bool = null,
|
||||
use_lld: ?bool = null,
|
||||
use_clang: ?bool = null,
|
||||
@@ -354,13 +359,14 @@ pub const InitOptions = struct {
|
||||
single_threaded: bool = false,
|
||||
function_sections: bool = false,
|
||||
is_native_os: bool,
|
||||
is_native_abi: bool,
|
||||
time_report: bool = false,
|
||||
stack_report: bool = false,
|
||||
link_eh_frame_hdr: bool = false,
|
||||
link_emit_relocs: bool = false,
|
||||
linker_script: ?[]const u8 = null,
|
||||
version_script: ?[]const u8 = null,
|
||||
override_soname: ?[]const u8 = null,
|
||||
soname: ?[]const u8 = null,
|
||||
linker_gc_sections: ?bool = null,
|
||||
linker_allow_shlib_undefined: ?bool = null,
|
||||
linker_bind_global_refs_locally: ?bool = null,
|
||||
@@ -395,6 +401,50 @@ pub const InitOptions = struct {
|
||||
subsystem: ?std.Target.SubSystem = null,
|
||||
};
|
||||
|
||||
fn addPackageTableToCacheHash(
|
||||
hash: *Cache.HashHelper,
|
||||
arena: *std.heap.ArenaAllocator,
|
||||
pkg_table: Package.Table,
|
||||
hash_type: union(enum) { path_bytes, files: *Cache.Manifest },
|
||||
) (error{OutOfMemory} || std.os.GetCwdError)!void {
|
||||
const allocator = &arena.allocator;
|
||||
|
||||
const packages = try allocator.alloc(Package.Table.Entry, pkg_table.count());
|
||||
{
|
||||
// Copy over the hashmap entries to our slice
|
||||
var table_it = pkg_table.iterator();
|
||||
var idx: usize = 0;
|
||||
while (table_it.next()) |entry| : (idx += 1) {
|
||||
packages[idx] = entry.*;
|
||||
}
|
||||
}
|
||||
// Sort the slice by package name
|
||||
std.sort.sort(Package.Table.Entry, packages, {}, struct {
|
||||
fn lessThan(_: void, lhs: Package.Table.Entry, rhs: Package.Table.Entry) bool {
|
||||
return std.mem.lessThan(u8, lhs.key, rhs.key);
|
||||
}
|
||||
}.lessThan);
|
||||
|
||||
for (packages) |pkg| {
|
||||
// Finally insert the package name and path to the cache hash.
|
||||
hash.addBytes(pkg.key);
|
||||
switch (hash_type) {
|
||||
.path_bytes => {
|
||||
hash.addBytes(pkg.value.root_src_path);
|
||||
hash.addOptionalBytes(pkg.value.root_src_directory.path);
|
||||
},
|
||||
.files => |man| {
|
||||
const pkg_zig_file = try pkg.value.root_src_directory.join(allocator, &[_][]const u8{
|
||||
pkg.value.root_src_path,
|
||||
});
|
||||
_ = try man.addFile(pkg_zig_file, null);
|
||||
},
|
||||
}
|
||||
// Recurse to handle the package's dependencies
|
||||
try addPackageTableToCacheHash(hash, arena, pkg.value.table, hash_type);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
const is_dyn_lib = switch (options.output_mode) {
|
||||
.Obj, .Exe => false,
|
||||
@@ -405,6 +455,9 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
.Lib => is_dyn_lib,
|
||||
.Exe => true,
|
||||
};
|
||||
const needs_c_symbols = !options.is_compiler_rt_or_libc and
|
||||
(is_exe_or_dyn_lib or (options.target.isWasm() and options.output_mode != .Obj));
|
||||
|
||||
const comp: *Compilation = comp: {
|
||||
// For allocations that have the same lifetime as Compilation. This arena is used only during this
|
||||
// initialization and then is freed in deinit().
|
||||
@@ -479,7 +532,10 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
|
||||
const darwin_options: DarwinOptions = if (build_options.have_llvm and comptime std.Target.current.isDarwin()) outer: {
|
||||
const opts: DarwinOptions = if (use_lld and options.is_native_os and options.target.isDarwin()) inner: {
|
||||
const syslibroot = try std.zig.system.getSDKPath(arena);
|
||||
// TODO Revisit this targeting versions lower than macOS 11 when LLVM 12 is out.
|
||||
// See https://github.com/ziglang/zig/issues/6996
|
||||
const at_least_big_sur = options.target.os.getVersionRange().semver.min.major >= 11;
|
||||
const syslibroot = if (at_least_big_sur) try std.zig.system.getSDKPath(arena) else null;
|
||||
const system_linker_hack = std.os.getenv("ZIG_SYSTEM_LINKER_HACK") != null;
|
||||
break :inner .{
|
||||
.syslibroot = syslibroot,
|
||||
@@ -499,8 +555,19 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
{
|
||||
break :dl true;
|
||||
}
|
||||
if (options.system_libs.len != 0) {
|
||||
// when creating a executable that links to system libraries,
|
||||
const any_dyn_libs: bool = x: {
|
||||
if (options.system_libs.len != 0)
|
||||
break :x true;
|
||||
for (options.link_objects) |obj| {
|
||||
switch (classifyFileExt(obj)) {
|
||||
.shared_library => break :x true,
|
||||
else => continue,
|
||||
}
|
||||
}
|
||||
break :x false;
|
||||
};
|
||||
if (any_dyn_libs) {
|
||||
// When creating a executable that links to system libraries,
|
||||
// we require dynamic linking, but we must not link static libraries
|
||||
// or object files dynamically!
|
||||
break :dl (options.output_mode == .Exe);
|
||||
@@ -508,7 +575,19 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
|
||||
break :dl false;
|
||||
};
|
||||
const default_link_mode: std.builtin.LinkMode = if (must_dynamic_link) .Dynamic else .Static;
|
||||
const default_link_mode: std.builtin.LinkMode = blk: {
|
||||
if (must_dynamic_link) {
|
||||
break :blk .Dynamic;
|
||||
} else if (is_exe_or_dyn_lib and link_libc and
|
||||
options.is_native_abi and options.target.abi.isMusl())
|
||||
{
|
||||
// If targeting the system's native ABI and the system's
|
||||
// libc is musl, link dynamically by default.
|
||||
break :blk .Dynamic;
|
||||
} else {
|
||||
break :blk .Static;
|
||||
}
|
||||
};
|
||||
const link_mode: std.builtin.LinkMode = if (options.link_mode) |lm| blk: {
|
||||
if (lm == .Static and must_dynamic_link) {
|
||||
return error.UnableToStaticLink;
|
||||
@@ -568,6 +647,8 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
break :b options.want_valgrind orelse (options.optimize_mode == .Debug);
|
||||
};
|
||||
|
||||
const include_compiler_rt = options.want_compiler_rt orelse needs_c_symbols;
|
||||
|
||||
const single_threaded = options.single_threaded or target_util.isSingleThreaded(options.target);
|
||||
|
||||
const llvm_cpu_features: ?[*:0]const u8 = if (build_options.have_llvm and use_llvm) blk: {
|
||||
@@ -613,6 +694,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
cache.hash.addBytes(options.target.cpu.model.name);
|
||||
cache.hash.add(options.target.cpu.features.ints);
|
||||
cache.hash.add(options.target.os.tag);
|
||||
cache.hash.add(options.target.os.getVersionRange());
|
||||
cache.hash.add(options.is_native_os);
|
||||
cache.hash.add(options.target.abi);
|
||||
cache.hash.add(ofmt);
|
||||
@@ -625,7 +707,8 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
cache.hash.add(options.link_libcpp);
|
||||
cache.hash.add(options.output_mode);
|
||||
cache.hash.add(options.machine_code_model);
|
||||
cache.hash.add(options.emit_bin != null);
|
||||
cache.hash.addOptionalEmitLoc(options.emit_bin);
|
||||
cache.hash.addBytes(options.root_name);
|
||||
// TODO audit this and make sure everything is in it
|
||||
|
||||
const module: ?*Module = if (options.root_pkg) |root_pkg| blk: {
|
||||
@@ -640,9 +723,13 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
// would be likely to cause cache hits.
|
||||
hash.addBytes(root_pkg.root_src_path);
|
||||
hash.addOptionalBytes(root_pkg.root_src_directory.path);
|
||||
{
|
||||
var local_arena = std.heap.ArenaAllocator.init(gpa);
|
||||
defer local_arena.deinit();
|
||||
try addPackageTableToCacheHash(&hash, &local_arena, root_pkg.table, .path_bytes);
|
||||
}
|
||||
hash.add(valgrind);
|
||||
hash.add(single_threaded);
|
||||
hash.add(options.target.os.getVersionRange());
|
||||
hash.add(dll_export_fns);
|
||||
hash.add(options.is_test);
|
||||
hash.add(options.is_compiler_rt_or_libc);
|
||||
@@ -796,6 +883,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
.rpath_list = options.rpath_list,
|
||||
.strip = strip,
|
||||
.is_native_os = options.is_native_os,
|
||||
.is_native_abi = options.is_native_abi,
|
||||
.function_sections = options.function_sections,
|
||||
.allow_shlib_undefined = options.linker_allow_shlib_undefined,
|
||||
.bind_global_refs_locally = options.linker_bind_global_refs_locally orelse false,
|
||||
@@ -803,6 +891,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
.z_defs = options.linker_z_defs,
|
||||
.stack_size_override = options.stack_size_override,
|
||||
.image_base_override = options.image_base_override,
|
||||
.include_compiler_rt = include_compiler_rt,
|
||||
.linker_script = options.linker_script,
|
||||
.version_script = options.version_script,
|
||||
.gc_sections = options.linker_gc_sections,
|
||||
@@ -810,7 +899,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
.emit_relocs = options.link_emit_relocs,
|
||||
.rdynamic = options.rdynamic,
|
||||
.extra_lld_args = options.lld_argv,
|
||||
.override_soname = options.override_soname,
|
||||
.soname = options.soname,
|
||||
.version = options.version,
|
||||
.libc_installation = libc_dirs.libc_installation,
|
||||
.pic = pic,
|
||||
@@ -908,7 +997,10 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
comp.work_queue.writeAssumeCapacity(&[_]Job{
|
||||
.{ .musl_crt_file = .crt1_o },
|
||||
.{ .musl_crt_file = .scrt1_o },
|
||||
.{ .musl_crt_file = .libc_a },
|
||||
switch (comp.bin_file.options.link_mode) {
|
||||
.Static => .{ .musl_crt_file = .libc_a },
|
||||
.Dynamic => .{ .musl_crt_file = .libc_so },
|
||||
},
|
||||
});
|
||||
}
|
||||
if (comp.wantBuildMinGWFromSource()) {
|
||||
@@ -947,16 +1039,35 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
try comp.work_queue.writeItem(.libcxxabi);
|
||||
}
|
||||
|
||||
const needs_compiler_rt_and_c = is_exe_or_dyn_lib or
|
||||
(comp.getTarget().isWasm() and comp.bin_file.options.output_mode != .Obj);
|
||||
if (needs_compiler_rt_and_c and build_options.is_stage1) {
|
||||
try comp.work_queue.writeItem(.{ .libcompiler_rt = {} });
|
||||
// MinGW provides no libssp, use our own implementation.
|
||||
if (comp.getTarget().isMinGW()) {
|
||||
try comp.work_queue.writeItem(.{ .libssp = {} });
|
||||
// The `is_stage1` condition is here only because stage2 cannot yet build compiler-rt.
|
||||
// Once it is capable this condition should be removed.
|
||||
if (build_options.is_stage1) {
|
||||
if (comp.bin_file.options.include_compiler_rt) {
|
||||
if (is_exe_or_dyn_lib or comp.getTarget().isWasm()) {
|
||||
try comp.work_queue.writeItem(.{ .compiler_rt_lib = {} });
|
||||
} else {
|
||||
try comp.work_queue.writeItem(.{ .compiler_rt_obj = {} });
|
||||
if (comp.bin_file.options.object_format != .elf and
|
||||
comp.bin_file.options.output_mode == .Obj)
|
||||
{
|
||||
// For ELF we can rely on using -r to link multiple objects together into one,
|
||||
// but to truly support `build-obj -fcompiler-rt` will require virtually
|
||||
// injecting `_ = @import("compiler_rt.zig")` into the root source file of
|
||||
// the compilation.
|
||||
fatal("Embedding compiler-rt into {s} objects is not yet implemented.", .{
|
||||
@tagName(comp.bin_file.options.object_format),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!comp.bin_file.options.link_libc) {
|
||||
try comp.work_queue.writeItem(.{ .zig_libc = {} });
|
||||
if (needs_c_symbols) {
|
||||
// MinGW provides no libssp, use our own implementation.
|
||||
if (comp.getTarget().isMinGW()) {
|
||||
try comp.work_queue.writeItem(.{ .libssp = {} });
|
||||
}
|
||||
if (!comp.bin_file.options.link_libc) {
|
||||
try comp.work_queue.writeItem(.{ .zig_libc = {} });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1017,6 +1128,7 @@ pub fn destroy(self: *Compilation) void {
|
||||
entry.key.destroy(gpa);
|
||||
}
|
||||
self.c_object_table.deinit(gpa);
|
||||
self.c_object_cache_digest_set.deinit(gpa);
|
||||
|
||||
for (self.failed_c_objects.items()) |entry| {
|
||||
entry.value.destroy(gpa);
|
||||
@@ -1298,7 +1410,7 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor
|
||||
self.failed_c_objects.putAssumeCapacityNoClobber(c_object, try ErrorMsg.create(
|
||||
self.gpa,
|
||||
0,
|
||||
"unable to build C object: {}",
|
||||
"unable to build C object: {s}",
|
||||
.{@errorName(err)},
|
||||
));
|
||||
c_object.status = .{ .failure = {} };
|
||||
@@ -1354,20 +1466,26 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor
|
||||
fatal("unable to build libcxxabi: {}", .{@errorName(err)});
|
||||
};
|
||||
},
|
||||
.libcompiler_rt => {
|
||||
self.buildStaticLibFromZig("compiler_rt.zig", &self.compiler_rt_static_lib) catch |err| {
|
||||
.compiler_rt_lib => {
|
||||
self.buildOutputFromZig("compiler_rt.zig", .Lib, &self.compiler_rt_static_lib) catch |err| {
|
||||
// TODO Expose this as a normal compile error rather than crashing here.
|
||||
fatal("unable to build compiler_rt: {}", .{@errorName(err)});
|
||||
fatal("unable to build compiler_rt: {s}", .{@errorName(err)});
|
||||
};
|
||||
},
|
||||
.compiler_rt_obj => {
|
||||
self.buildOutputFromZig("compiler_rt.zig", .Obj, &self.compiler_rt_obj) catch |err| {
|
||||
// TODO Expose this as a normal compile error rather than crashing here.
|
||||
fatal("unable to build compiler_rt: {s}", .{@errorName(err)});
|
||||
};
|
||||
},
|
||||
.libssp => {
|
||||
self.buildStaticLibFromZig("ssp.zig", &self.libssp_static_lib) catch |err| {
|
||||
self.buildOutputFromZig("ssp.zig", .Lib, &self.libssp_static_lib) catch |err| {
|
||||
// TODO Expose this as a normal compile error rather than crashing here.
|
||||
fatal("unable to build libssp: {}", .{@errorName(err)});
|
||||
};
|
||||
},
|
||||
.zig_libc => {
|
||||
self.buildStaticLibFromZig("c.zig", &self.libc_static_lib) catch |err| {
|
||||
self.buildOutputFromZig("c.zig", .Lib, &self.libc_static_lib) catch |err| {
|
||||
// TODO Expose this as a normal compile error rather than crashing here.
|
||||
fatal("unable to build zig's multitarget libc: {}", .{@errorName(err)});
|
||||
};
|
||||
@@ -1512,6 +1630,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
|
||||
|
||||
const dep_basename = std.fs.path.basename(out_dep_path);
|
||||
try man.addDepFilePost(zig_cache_tmp_dir, dep_basename);
|
||||
try comp.stage1_cache_manifest.addDepFilePost(zig_cache_tmp_dir, dep_basename);
|
||||
|
||||
const digest = man.final();
|
||||
const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest });
|
||||
@@ -1582,6 +1701,17 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_comp_progress_node: *
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const gop = try comp.c_object_cache_digest_set.getOrPut(comp.gpa, man.hash.peekBin());
|
||||
if (gop.found_existing) {
|
||||
return comp.failCObj(
|
||||
c_object,
|
||||
"the same source file was already added to the same compilation with the same flags",
|
||||
.{},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
|
||||
defer arena_allocator.deinit();
|
||||
const arena = &arena_allocator.allocator;
|
||||
@@ -1601,7 +1731,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_comp_progress_node: *
|
||||
const o_basename_noext = if (direct_o)
|
||||
comp.bin_file.options.root_name
|
||||
else
|
||||
mem.split(c_source_basename, ".").next().?;
|
||||
c_source_basename[0 .. c_source_basename.len - std.fs.path.extension(c_source_basename).len];
|
||||
const o_basename = try std.fmt.allocPrint(arena, "{s}{s}", .{ o_basename_noext, comp.getTarget().oFileExt() });
|
||||
|
||||
const digest = if (!comp.disable_c_depfile and try man.hit()) man.final() else blk: {
|
||||
@@ -1619,7 +1749,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_comp_progress_node: *
|
||||
const out_dep_path: ?[]const u8 = if (comp.disable_c_depfile or !ext.clangSupportsDepFile())
|
||||
null
|
||||
else
|
||||
try std.fmt.allocPrint(arena, "{}.d", .{out_obj_path});
|
||||
try std.fmt.allocPrint(arena, "{s}.d", .{out_obj_path});
|
||||
try comp.addCCArgs(arena, &argv, ext, out_dep_path);
|
||||
|
||||
try argv.ensureCapacity(argv.items.len + 3);
|
||||
@@ -1656,7 +1786,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_comp_progress_node: *
|
||||
if (comp.clang_preprocessor_mode == .stdout)
|
||||
std.process.exit(0);
|
||||
},
|
||||
else => std.process.exit(1),
|
||||
else => std.process.abort(),
|
||||
}
|
||||
} else {
|
||||
child.stdin_behavior = .Ignore;
|
||||
@@ -1702,6 +1832,9 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_comp_progress_node: *
|
||||
};
|
||||
}
|
||||
|
||||
// We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.
|
||||
if (comp.disable_c_depfile) _ = try man.hit();
|
||||
|
||||
// Rename into place.
|
||||
const digest = man.final();
|
||||
const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest });
|
||||
@@ -1849,14 +1982,47 @@ pub fn addCCArgs(
|
||||
try argv.append(try std.fmt.allocPrint(arena, "-mcmodel={}", .{@tagName(mcmodel)}));
|
||||
}
|
||||
|
||||
// windows.h has files such as pshpack1.h which do #pragma packing, triggering a clang warning.
|
||||
// So for this target, we disable this warning.
|
||||
if (target.os.tag == .windows and target.abi.isGnu()) {
|
||||
try argv.append("-Wno-pragma-pack");
|
||||
switch (target.os.tag) {
|
||||
.windows => {
|
||||
// windows.h has files such as pshpack1.h which do #pragma packing,
|
||||
// triggering a clang warning. So for this target, we disable this warning.
|
||||
if (target.abi.isGnu()) {
|
||||
try argv.append("-Wno-pragma-pack");
|
||||
}
|
||||
},
|
||||
.macos => {
|
||||
// Pass the proper -m<os>-version-min argument for darwin.
|
||||
const ver = target.os.version_range.semver.min;
|
||||
try argv.append(try std.fmt.allocPrint(arena, "-mmacos-version-min={d}.{d}.{d}", .{
|
||||
ver.major, ver.minor, ver.patch,
|
||||
}));
|
||||
},
|
||||
.ios, .tvos, .watchos => switch (target.cpu.arch) {
|
||||
// Pass the proper -m<os>-version-min argument for darwin.
|
||||
.i386, .x86_64 => {
|
||||
const ver = target.os.version_range.semver.min;
|
||||
try argv.append(try std.fmt.allocPrint(
|
||||
arena,
|
||||
"-m{s}-simulator-version-min={d}.{d}.{d}",
|
||||
.{ @tagName(target.os.tag), ver.major, ver.minor, ver.patch },
|
||||
));
|
||||
},
|
||||
else => {
|
||||
const ver = target.os.version_range.semver.min;
|
||||
try argv.append(try std.fmt.allocPrint(arena, "-m{s}-version-min={d}.{d}.{d}", .{
|
||||
@tagName(target.os.tag), ver.major, ver.minor, ver.patch,
|
||||
}));
|
||||
},
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
if (!comp.bin_file.options.strip) {
|
||||
try argv.append("-g");
|
||||
switch (comp.bin_file.options.object_format) {
|
||||
.coff, .pe => try argv.append("-gcodeview"),
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
if (comp.haveFramePointer()) {
|
||||
@@ -2263,7 +2429,8 @@ fn wantBuildGLibCFromSource(comp: Compilation) bool {
|
||||
}
|
||||
|
||||
fn wantBuildMuslFromSource(comp: Compilation) bool {
|
||||
return comp.wantBuildLibCFromSource() and comp.getTarget().isMusl();
|
||||
return comp.wantBuildLibCFromSource() and comp.getTarget().isMusl() and
|
||||
!comp.getTarget().isWasm();
|
||||
}
|
||||
|
||||
fn wantBuildMinGWFromSource(comp: Compilation) bool {
|
||||
@@ -2502,10 +2669,16 @@ pub fn updateSubCompilation(sub_compilation: *Compilation) !void {
|
||||
}
|
||||
}
|
||||
|
||||
fn buildStaticLibFromZig(comp: *Compilation, src_basename: []const u8, out: *?CRTFile) !void {
|
||||
fn buildOutputFromZig(
|
||||
comp: *Compilation,
|
||||
src_basename: []const u8,
|
||||
output_mode: std.builtin.OutputMode,
|
||||
out: *?CRTFile,
|
||||
) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
std.debug.assert(output_mode != .Exe);
|
||||
const special_sub = "std" ++ std.fs.path.sep_str ++ "special";
|
||||
const special_path = try comp.zig_lib_directory.join(comp.gpa, &[_][]const u8{special_sub});
|
||||
defer comp.gpa.free(special_path);
|
||||
@@ -2520,13 +2693,13 @@ fn buildStaticLibFromZig(comp: *Compilation, src_basename: []const u8, out: *?CR
|
||||
},
|
||||
.root_src_path = src_basename,
|
||||
};
|
||||
const root_name = mem.split(src_basename, ".").next().?;
|
||||
const root_name = src_basename[0 .. src_basename.len - std.fs.path.extension(src_basename).len];
|
||||
const target = comp.getTarget();
|
||||
const output_mode: std.builtin.OutputMode = if (target.cpu.arch.isWasm()) .Obj else .Lib;
|
||||
const fixed_output_mode = if (target.cpu.arch.isWasm()) .Obj else output_mode;
|
||||
const bin_basename = try std.zig.binNameAlloc(comp.gpa, .{
|
||||
.root_name = root_name,
|
||||
.target = target,
|
||||
.output_mode = output_mode,
|
||||
.output_mode = fixed_output_mode,
|
||||
});
|
||||
defer comp.gpa.free(bin_basename);
|
||||
|
||||
@@ -2549,7 +2722,7 @@ fn buildStaticLibFromZig(comp: *Compilation, src_basename: []const u8, out: *?CR
|
||||
.target = target,
|
||||
.root_name = root_name,
|
||||
.root_pkg = &root_pkg,
|
||||
.output_mode = output_mode,
|
||||
.output_mode = fixed_output_mode,
|
||||
.rand = comp.rand,
|
||||
.libc_installation = comp.bin_file.options.libc_installation,
|
||||
.emit_bin = emit_bin,
|
||||
@@ -2563,6 +2736,7 @@ fn buildStaticLibFromZig(comp: *Compilation, src_basename: []const u8, out: *?CR
|
||||
.emit_h = null,
|
||||
.strip = comp.bin_file.options.strip,
|
||||
.is_native_os = comp.bin_file.options.is_native_os,
|
||||
.is_native_abi = comp.bin_file.options.is_native_abi,
|
||||
.self_exe_path = comp.self_exe_path,
|
||||
.verbose_cc = comp.verbose_cc,
|
||||
.verbose_link = comp.bin_file.options.verbose_link,
|
||||
@@ -2621,6 +2795,11 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node
|
||||
defer man.deinit();
|
||||
|
||||
_ = try man.addFile(main_zig_file, null);
|
||||
{
|
||||
var local_arena = std.heap.ArenaAllocator.init(comp.gpa);
|
||||
defer local_arena.deinit();
|
||||
try addPackageTableToCacheHash(&man.hash, &local_arena, mod.root_pkg.table, .{ .files = &man });
|
||||
}
|
||||
man.hash.add(comp.bin_file.options.valgrind);
|
||||
man.hash.add(comp.bin_file.options.single_threaded);
|
||||
man.hash.add(target.os.getVersionRange());
|
||||
@@ -2628,11 +2807,11 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node
|
||||
man.hash.add(comp.bin_file.options.function_sections);
|
||||
man.hash.add(comp.bin_file.options.is_test);
|
||||
man.hash.add(comp.bin_file.options.emit != null);
|
||||
man.hash.add(comp.emit_h != null);
|
||||
man.hash.add(comp.emit_asm != null);
|
||||
man.hash.add(comp.emit_llvm_ir != null);
|
||||
man.hash.add(comp.emit_analysis != null);
|
||||
man.hash.add(comp.emit_docs != null);
|
||||
man.hash.addOptionalEmitLoc(comp.emit_h);
|
||||
man.hash.addOptionalEmitLoc(comp.emit_asm);
|
||||
man.hash.addOptionalEmitLoc(comp.emit_llvm_ir);
|
||||
man.hash.addOptionalEmitLoc(comp.emit_analysis);
|
||||
man.hash.addOptionalEmitLoc(comp.emit_docs);
|
||||
man.hash.addOptionalBytes(comp.test_filter);
|
||||
man.hash.addOptionalBytes(comp.test_name_prefix);
|
||||
|
||||
@@ -2926,6 +3105,7 @@ pub fn build_crt_file(
|
||||
.emit_h = null,
|
||||
.strip = comp.bin_file.options.strip,
|
||||
.is_native_os = comp.bin_file.options.is_native_os,
|
||||
.is_native_abi = comp.bin_file.options.is_native_abi,
|
||||
.self_exe_path = comp.self_exe_path,
|
||||
.c_source_files = c_source_files,
|
||||
.verbose_cc = comp.verbose_cc,
|
||||
@@ -2955,6 +3135,11 @@ pub fn build_crt_file(
|
||||
}
|
||||
|
||||
pub fn stage1AddLinkLib(comp: *Compilation, lib_name: []const u8) !void {
|
||||
// Avoid deadlocking on building import libs such as kernel32.lib
|
||||
// This can happen when the user uses `build-exe foo.obj -lkernel32` and then
|
||||
// when we create a sub-Compilation for zig libc, it also tries to build kernel32.lib.
|
||||
if (comp.bin_file.options.is_compiler_rt_or_libc) return;
|
||||
|
||||
// This happens when an `extern "foo"` function is referenced by the stage1 backend.
|
||||
// If we haven't seen this library yet and we're targeting Windows, we need to queue up
|
||||
// a work item to produce the DLL import library for this.
|
||||
|
||||
@@ -911,13 +911,14 @@ fn buildSharedLib(
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const basename = try std.fmt.allocPrint(arena, "lib{s}.so.{d}", .{ lib.name, lib.sover });
|
||||
const emit_bin = Compilation.EmitLoc{
|
||||
.directory = bin_directory,
|
||||
.basename = try std.fmt.allocPrint(arena, "lib{s}.so.{d}", .{ lib.name, lib.sover }),
|
||||
.basename = basename,
|
||||
};
|
||||
const version: std.builtin.Version = .{ .major = lib.sover, .minor = 0, .patch = 0 };
|
||||
const ld_basename = path.basename(comp.getTarget().standardDynamicLinkerPath().get().?);
|
||||
const override_soname = if (mem.eql(u8, lib.name, "ld")) ld_basename else null;
|
||||
const soname = if (mem.eql(u8, lib.name, "ld")) ld_basename else basename;
|
||||
const map_file_path = try path.join(arena, &[_][]const u8{ bin_directory.path.?, all_map_basename });
|
||||
const c_source_files = [1]Compilation.CSourceFile{
|
||||
.{
|
||||
@@ -943,6 +944,7 @@ fn buildSharedLib(
|
||||
.emit_h = null,
|
||||
.strip = comp.bin_file.options.strip,
|
||||
.is_native_os = false,
|
||||
.is_native_abi = false,
|
||||
.self_exe_path = comp.self_exe_path,
|
||||
.verbose_cc = comp.verbose_cc,
|
||||
.verbose_link = comp.bin_file.options.verbose_link,
|
||||
@@ -955,7 +957,7 @@ fn buildSharedLib(
|
||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||
.version = version,
|
||||
.version_script = map_file_path,
|
||||
.override_soname = override_soname,
|
||||
.soname = soname,
|
||||
.c_source_files = &c_source_files,
|
||||
.is_compiler_rt_or_libc = true,
|
||||
});
|
||||
|
||||
@@ -174,6 +174,7 @@ pub fn buildLibCXX(comp: *Compilation) !void {
|
||||
.emit_h = null,
|
||||
.strip = comp.bin_file.options.strip,
|
||||
.is_native_os = comp.bin_file.options.is_native_os,
|
||||
.is_native_abi = comp.bin_file.options.is_native_abi,
|
||||
.self_exe_path = comp.self_exe_path,
|
||||
.c_source_files = c_source_files.items,
|
||||
.verbose_cc = comp.verbose_cc,
|
||||
@@ -291,6 +292,7 @@ pub fn buildLibCXXABI(comp: *Compilation) !void {
|
||||
.emit_h = null,
|
||||
.strip = comp.bin_file.options.strip,
|
||||
.is_native_os = comp.bin_file.options.is_native_os,
|
||||
.is_native_abi = comp.bin_file.options.is_native_abi,
|
||||
.self_exe_path = comp.self_exe_path,
|
||||
.c_source_files = &c_source_files,
|
||||
.verbose_cc = comp.verbose_cc,
|
||||
|
||||
@@ -107,6 +107,7 @@ pub fn buildStaticLib(comp: *Compilation) !void {
|
||||
.emit_h = null,
|
||||
.strip = comp.bin_file.options.strip,
|
||||
.is_native_os = comp.bin_file.options.is_native_os,
|
||||
.is_native_abi = comp.bin_file.options.is_native_abi,
|
||||
.self_exe_path = comp.self_exe_path,
|
||||
.c_source_files = &c_source_files,
|
||||
.verbose_cc = comp.verbose_cc,
|
||||
|
||||
102
src/link.zig
102
src/link.zig
@@ -46,6 +46,7 @@ pub const Options = struct {
|
||||
entry_addr: ?u64 = null,
|
||||
stack_size_override: ?u64,
|
||||
image_base_override: ?u64,
|
||||
include_compiler_rt: bool,
|
||||
/// Set to `true` to omit debug info.
|
||||
strip: bool,
|
||||
/// If this is true then this link code is responsible for outputting an object
|
||||
@@ -70,6 +71,7 @@ pub const Options = struct {
|
||||
z_defs: bool,
|
||||
bind_global_refs_locally: bool,
|
||||
is_native_os: bool,
|
||||
is_native_abi: bool,
|
||||
pic: bool,
|
||||
valgrind: bool,
|
||||
stack_check: bool,
|
||||
@@ -87,7 +89,7 @@ pub const Options = struct {
|
||||
subsystem: ?std.Target.SubSystem,
|
||||
linker_script: ?[]const u8,
|
||||
version_script: ?[]const u8,
|
||||
override_soname: ?[]const u8,
|
||||
soname: ?[]const u8,
|
||||
llvm_cpu_features: ?[*:0]const u8,
|
||||
/// Extra args passed directly to LLD. Ignored when not linking with LLD.
|
||||
extra_lld_args: []const []const u8,
|
||||
@@ -450,52 +452,65 @@ pub const File = struct {
|
||||
break :blk full_obj_path;
|
||||
} else null;
|
||||
|
||||
const compiler_rt_path: ?[]const u8 = if (base.options.include_compiler_rt)
|
||||
comp.compiler_rt_obj.?.full_object_path
|
||||
else
|
||||
null;
|
||||
|
||||
// This function follows the same pattern as link.Elf.linkWithLLD so if you want some
|
||||
// insight as to what's going on here you can read that function body which is more
|
||||
// well-commented.
|
||||
|
||||
const id_symlink_basename = "llvm-ar.id";
|
||||
|
||||
base.releaseLock();
|
||||
var man: Cache.Manifest = undefined;
|
||||
defer if (!base.options.disable_lld_caching) man.deinit();
|
||||
|
||||
var ch = comp.cache_parent.obtain();
|
||||
defer ch.deinit();
|
||||
var digest: [Cache.hex_digest_len]u8 = undefined;
|
||||
|
||||
try ch.addListOfFiles(base.options.objects);
|
||||
for (comp.c_object_table.items()) |entry| {
|
||||
_ = try ch.addFile(entry.key.status.success.object_path, null);
|
||||
if (!base.options.disable_lld_caching) {
|
||||
man = comp.cache_parent.obtain();
|
||||
|
||||
// We are about to obtain this lock, so here we give other processes a chance first.
|
||||
base.releaseLock();
|
||||
|
||||
try man.addListOfFiles(base.options.objects);
|
||||
for (comp.c_object_table.items()) |entry| {
|
||||
_ = try man.addFile(entry.key.status.success.object_path, null);
|
||||
}
|
||||
try man.addOptionalFile(module_obj_path);
|
||||
try man.addOptionalFile(compiler_rt_path);
|
||||
|
||||
// We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.
|
||||
_ = try man.hit();
|
||||
digest = man.final();
|
||||
|
||||
var prev_digest_buf: [digest.len]u8 = undefined;
|
||||
const prev_digest: []u8 = Cache.readSmallFile(
|
||||
directory.handle,
|
||||
id_symlink_basename,
|
||||
&prev_digest_buf,
|
||||
) catch |err| b: {
|
||||
log.debug("archive new_digest={} readFile error: {}", .{ digest, @errorName(err) });
|
||||
break :b prev_digest_buf[0..0];
|
||||
};
|
||||
if (mem.eql(u8, prev_digest, &digest)) {
|
||||
log.debug("archive digest={} match - skipping invocation", .{digest});
|
||||
base.lock = man.toOwnedLock();
|
||||
return;
|
||||
}
|
||||
|
||||
// We are about to change the output file to be different, so we invalidate the build hash now.
|
||||
directory.handle.deleteFile(id_symlink_basename) catch |err| switch (err) {
|
||||
error.FileNotFound => {},
|
||||
else => |e| return e,
|
||||
};
|
||||
}
|
||||
try ch.addOptionalFile(module_obj_path);
|
||||
|
||||
// We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.
|
||||
_ = try ch.hit();
|
||||
const digest = ch.final();
|
||||
|
||||
var prev_digest_buf: [digest.len]u8 = undefined;
|
||||
const prev_digest: []u8 = Cache.readSmallFile(
|
||||
directory.handle,
|
||||
id_symlink_basename,
|
||||
&prev_digest_buf,
|
||||
) catch |err| b: {
|
||||
log.debug("archive new_digest={} readFile error: {}", .{ digest, @errorName(err) });
|
||||
break :b prev_digest_buf[0..0];
|
||||
};
|
||||
if (mem.eql(u8, prev_digest, &digest)) {
|
||||
log.debug("archive digest={} match - skipping invocation", .{digest});
|
||||
base.lock = ch.toOwnedLock();
|
||||
return;
|
||||
}
|
||||
|
||||
// We are about to change the output file to be different, so we invalidate the build hash now.
|
||||
directory.handle.deleteFile(id_symlink_basename) catch |err| switch (err) {
|
||||
error.FileNotFound => {},
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
var object_files = std.ArrayList([*:0]const u8).init(base.allocator);
|
||||
defer object_files.deinit();
|
||||
|
||||
try object_files.ensureCapacity(base.options.objects.len + comp.c_object_table.items().len + 1);
|
||||
try object_files.ensureCapacity(base.options.objects.len + comp.c_object_table.items().len + 2);
|
||||
for (base.options.objects) |obj_path| {
|
||||
object_files.appendAssumeCapacity(try arena.dupeZ(u8, obj_path));
|
||||
}
|
||||
@@ -505,6 +520,9 @@ pub const File = struct {
|
||||
if (module_obj_path) |p| {
|
||||
object_files.appendAssumeCapacity(try arena.dupeZ(u8, p));
|
||||
}
|
||||
if (compiler_rt_path) |p| {
|
||||
object_files.appendAssumeCapacity(try arena.dupeZ(u8, p));
|
||||
}
|
||||
|
||||
const full_out_path = try directory.join(arena, &[_][]const u8{base.options.emit.?.sub_path});
|
||||
const full_out_path_z = try arena.dupeZ(u8, full_out_path);
|
||||
@@ -522,15 +540,17 @@ pub const File = struct {
|
||||
const bad = llvm.WriteArchive(full_out_path_z, object_files.items.ptr, object_files.items.len, os_type);
|
||||
if (bad) return error.UnableToWriteArchive;
|
||||
|
||||
Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| {
|
||||
std.log.warn("failed to save archive hash digest file: {}", .{@errorName(err)});
|
||||
};
|
||||
if (!base.options.disable_lld_caching) {
|
||||
Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| {
|
||||
std.log.warn("failed to save archive hash digest file: {}", .{@errorName(err)});
|
||||
};
|
||||
|
||||
ch.writeManifest() catch |err| {
|
||||
std.log.warn("failed to write cache manifest when archiving: {}", .{@errorName(err)});
|
||||
};
|
||||
man.writeManifest() catch |err| {
|
||||
std.log.warn("failed to write cache manifest when archiving: {}", .{@errorName(err)});
|
||||
};
|
||||
|
||||
base.lock = ch.toOwnedLock();
|
||||
base.lock = man.toOwnedLock();
|
||||
}
|
||||
}
|
||||
|
||||
pub const Tag = enum {
|
||||
|
||||
@@ -907,8 +907,10 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
|
||||
// Create an LLD command line and invoke it.
|
||||
var argv = std.ArrayList([]const u8).init(self.base.allocator);
|
||||
defer argv.deinit();
|
||||
// Even though we're calling LLD as a library it thinks the first argument is its own exe name.
|
||||
try argv.append("lld");
|
||||
// We will invoke ourselves as a child process to gain access to LLD.
|
||||
// This is necessary because LLD does not behave properly as a library -
|
||||
// it calls exit() and does not reset all global data between invocations.
|
||||
try argv.appendSlice(&[_][]const u8{ comp.self_exe_path.?, "lld-link" });
|
||||
|
||||
try argv.append("-ERRORLIMIT:0");
|
||||
try argv.append("-NOLOGO");
|
||||
@@ -1146,45 +1148,65 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
|
||||
}
|
||||
|
||||
if (self.base.options.verbose_link) {
|
||||
Compilation.dump_argv(argv.items);
|
||||
// Skip over our own name so that the LLD linker name is the first argv item.
|
||||
Compilation.dump_argv(argv.items[1..]);
|
||||
}
|
||||
|
||||
const new_argv = try arena.allocSentinel(?[*:0]const u8, argv.items.len, null);
|
||||
for (argv.items) |arg, i| {
|
||||
new_argv[i] = try arena.dupeZ(u8, arg);
|
||||
}
|
||||
// Sadly, we must run LLD as a child process because it does not behave
|
||||
// properly as a library.
|
||||
const child = try std.ChildProcess.init(argv.items, arena);
|
||||
defer child.deinit();
|
||||
|
||||
var stderr_context: LLDContext = .{
|
||||
.coff = self,
|
||||
.data = std.ArrayList(u8).init(self.base.allocator),
|
||||
};
|
||||
defer stderr_context.data.deinit();
|
||||
var stdout_context: LLDContext = .{
|
||||
.coff = self,
|
||||
.data = std.ArrayList(u8).init(self.base.allocator),
|
||||
};
|
||||
defer stdout_context.data.deinit();
|
||||
const llvm = @import("../llvm.zig");
|
||||
const ok = llvm.Link(
|
||||
.COFF,
|
||||
new_argv.ptr,
|
||||
new_argv.len,
|
||||
append_diagnostic,
|
||||
@ptrToInt(&stdout_context),
|
||||
@ptrToInt(&stderr_context),
|
||||
);
|
||||
if (stderr_context.oom or stdout_context.oom) return error.OutOfMemory;
|
||||
if (stdout_context.data.items.len != 0) {
|
||||
std.log.warn("unexpected LLD stdout: {}", .{stdout_context.data.items});
|
||||
}
|
||||
if (!ok) {
|
||||
// TODO parse this output and surface with the Compilation API rather than
|
||||
// directly outputting to stderr here.
|
||||
std.debug.print("{}", .{stderr_context.data.items});
|
||||
return error.LLDReportedFailure;
|
||||
}
|
||||
if (stderr_context.data.items.len != 0) {
|
||||
std.log.warn("unexpected LLD stderr: {}", .{stderr_context.data.items});
|
||||
if (comp.clang_passthrough_mode) {
|
||||
child.stdin_behavior = .Inherit;
|
||||
child.stdout_behavior = .Inherit;
|
||||
child.stderr_behavior = .Inherit;
|
||||
|
||||
const term = child.spawnAndWait() catch |err| {
|
||||
log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) });
|
||||
return error.UnableToSpawnSelf;
|
||||
};
|
||||
switch (term) {
|
||||
.Exited => |code| {
|
||||
if (code != 0) {
|
||||
// TODO https://github.com/ziglang/zig/issues/6342
|
||||
std.process.exit(1);
|
||||
}
|
||||
},
|
||||
else => std.process.abort(),
|
||||
}
|
||||
} else {
|
||||
child.stdin_behavior = .Ignore;
|
||||
child.stdout_behavior = .Ignore;
|
||||
child.stderr_behavior = .Pipe;
|
||||
|
||||
try child.spawn();
|
||||
|
||||
const stderr = try child.stderr.?.reader().readAllAlloc(arena, 10 * 1024 * 1024);
|
||||
|
||||
const term = child.wait() catch |err| {
|
||||
log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) });
|
||||
return error.UnableToSpawnSelf;
|
||||
};
|
||||
|
||||
switch (term) {
|
||||
.Exited => |code| {
|
||||
if (code != 0) {
|
||||
// TODO parse this output and surface with the Compilation API rather than
|
||||
// directly outputting to stderr here.
|
||||
std.debug.print("{s}", .{stderr});
|
||||
return error.LLDReportedFailure;
|
||||
}
|
||||
},
|
||||
else => {
|
||||
log.err("{s} terminated with stderr:\n{s}", .{ argv.items[0], stderr });
|
||||
return error.LLDCrashed;
|
||||
},
|
||||
}
|
||||
|
||||
if (stderr.len != 0) {
|
||||
std.log.warn("unexpected LLD stderr:\n{s}", .{stderr});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1204,20 +1226,6 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
|
||||
}
|
||||
}
|
||||
|
||||
const LLDContext = struct {
|
||||
data: std.ArrayList(u8),
|
||||
coff: *Coff,
|
||||
oom: bool = false,
|
||||
};
|
||||
|
||||
fn append_diagnostic(context: usize, ptr: [*]const u8, len: usize) callconv(.C) void {
|
||||
const lld_context = @intToPtr(*LLDContext, context);
|
||||
const msg = ptr[0..len];
|
||||
lld_context.data.appendSlice(msg) catch |err| switch (err) {
|
||||
error.OutOfMemory => lld_context.oom = true,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn getDeclVAddr(self: *Coff, decl: *const Module.Decl) u64 {
|
||||
return self.text_section_virtual_address + decl.link.coff.text_offset;
|
||||
}
|
||||
|
||||
180
src/link/Elf.zig
180
src/link/Elf.zig
@@ -1260,6 +1260,13 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
|
||||
const gc_sections = self.base.options.gc_sections orelse !is_obj;
|
||||
const stack_size = self.base.options.stack_size_override orelse 16777216;
|
||||
const allow_shlib_undefined = self.base.options.allow_shlib_undefined orelse !self.base.options.is_native_os;
|
||||
const compiler_rt_path: ?[]const u8 = if (self.base.options.include_compiler_rt) blk: {
|
||||
if (is_exe_or_dyn_lib) {
|
||||
break :blk comp.compiler_rt_static_lib.?.full_object_path;
|
||||
} else {
|
||||
break :blk comp.compiler_rt_obj.?.full_object_path;
|
||||
}
|
||||
} else null;
|
||||
|
||||
// Here we want to determine whether we can save time by not invoking LLD when the
|
||||
// output is unchanged. None of the linker options or the object files that are being
|
||||
@@ -1289,6 +1296,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
|
||||
_ = try man.addFile(entry.key.status.success.object_path, null);
|
||||
}
|
||||
try man.addOptionalFile(module_obj_path);
|
||||
try man.addOptionalFile(compiler_rt_path);
|
||||
|
||||
// We can skip hashing libc and libc++ components that we are in charge of building from Zig
|
||||
// installation sources because they are always a product of the compiler version + target information.
|
||||
man.hash.add(stack_size);
|
||||
@@ -1313,10 +1322,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
|
||||
man.hash.addOptionalBytes(self.base.options.dynamic_linker);
|
||||
}
|
||||
}
|
||||
if (is_dyn_lib) {
|
||||
man.hash.addOptionalBytes(self.base.options.override_soname);
|
||||
man.hash.addOptional(self.base.options.version);
|
||||
}
|
||||
man.hash.addOptionalBytes(self.base.options.soname);
|
||||
man.hash.addOptional(self.base.options.version);
|
||||
man.hash.addStringSet(self.base.options.system_libs);
|
||||
man.hash.add(allow_shlib_undefined);
|
||||
man.hash.add(self.base.options.bind_global_refs_locally);
|
||||
@@ -1353,8 +1360,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
|
||||
// Create an LLD command line and invoke it.
|
||||
var argv = std.ArrayList([]const u8).init(self.base.allocator);
|
||||
defer argv.deinit();
|
||||
// Even though we're calling LLD as a library it thinks the first argument is its own exe name.
|
||||
try argv.append("lld");
|
||||
// We will invoke ourselves as a child process to gain access to LLD.
|
||||
// This is necessary because LLD does not behave properly as a library -
|
||||
// it calls exit() and does not reset all global data between invocations.
|
||||
try argv.appendSlice(&[_][]const u8{ comp.self_exe_path.?, "ld.lld" });
|
||||
if (is_obj) {
|
||||
try argv.append("-r");
|
||||
}
|
||||
@@ -1505,13 +1514,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
|
||||
}
|
||||
|
||||
if (is_dyn_lib) {
|
||||
const soname = self.base.options.override_soname orelse if (self.base.options.version) |ver|
|
||||
try std.fmt.allocPrint(arena, "lib{}.so.{}", .{ self.base.options.root_name, ver.major })
|
||||
else
|
||||
try std.fmt.allocPrint(arena, "lib{}.so", .{self.base.options.root_name});
|
||||
try argv.append("-soname");
|
||||
try argv.append(soname);
|
||||
|
||||
if (self.base.options.soname) |soname| {
|
||||
try argv.append("-soname");
|
||||
try argv.append(soname);
|
||||
}
|
||||
if (self.base.options.version_script) |version_script| {
|
||||
try argv.append("-version-script");
|
||||
try argv.append(version_script);
|
||||
@@ -1529,25 +1535,29 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
|
||||
try argv.append(p);
|
||||
}
|
||||
|
||||
// compiler-rt and libc
|
||||
if (is_exe_or_dyn_lib and !self.base.options.is_compiler_rt_or_libc) {
|
||||
if (!self.base.options.link_libc) {
|
||||
try argv.append(comp.libc_static_lib.?.full_object_path);
|
||||
}
|
||||
try argv.append(comp.compiler_rt_static_lib.?.full_object_path);
|
||||
// libc
|
||||
if (is_exe_or_dyn_lib and !self.base.options.is_compiler_rt_or_libc and !self.base.options.link_libc) {
|
||||
try argv.append(comp.libc_static_lib.?.full_object_path);
|
||||
}
|
||||
|
||||
// compiler-rt
|
||||
if (compiler_rt_path) |p| {
|
||||
try argv.append(p);
|
||||
}
|
||||
|
||||
// Shared libraries.
|
||||
const system_libs = self.base.options.system_libs.items();
|
||||
try argv.ensureCapacity(argv.items.len + system_libs.len);
|
||||
for (system_libs) |entry| {
|
||||
const link_lib = entry.key;
|
||||
// By this time, we depend on these libs being dynamically linked libraries and not static libraries
|
||||
// (the check for that needs to be earlier), but they could be full paths to .so files, in which
|
||||
// case we want to avoid prepending "-l".
|
||||
const ext = Compilation.classifyFileExt(link_lib);
|
||||
const arg = if (ext == .shared_library) link_lib else try std.fmt.allocPrint(arena, "-l{}", .{link_lib});
|
||||
argv.appendAssumeCapacity(arg);
|
||||
if (is_exe_or_dyn_lib) {
|
||||
const system_libs = self.base.options.system_libs.items();
|
||||
try argv.ensureCapacity(argv.items.len + system_libs.len);
|
||||
for (system_libs) |entry| {
|
||||
const link_lib = entry.key;
|
||||
// By this time, we depend on these libs being dynamically linked libraries and not static libraries
|
||||
// (the check for that needs to be earlier), but they could be full paths to .so files, in which
|
||||
// case we want to avoid prepending "-l".
|
||||
const ext = Compilation.classifyFileExt(link_lib);
|
||||
const arg = if (ext == .shared_library) link_lib else try std.fmt.allocPrint(arena, "-l{}", .{link_lib});
|
||||
argv.appendAssumeCapacity(arg);
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_obj) {
|
||||
@@ -1584,7 +1594,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
|
||||
try argv.append(try comp.get_libc_crt_file(arena, "libc_nonshared.a"));
|
||||
} else if (target.isMusl()) {
|
||||
try argv.append(comp.libunwind_static_lib.?.full_object_path);
|
||||
try argv.append(try comp.get_libc_crt_file(arena, "libc.a"));
|
||||
try argv.append(try comp.get_libc_crt_file(arena, switch (self.base.options.link_mode) {
|
||||
.Static => "libc.a",
|
||||
.Dynamic => "libc.so",
|
||||
}));
|
||||
} else if (self.base.options.link_libcpp) {
|
||||
try argv.append(comp.libunwind_static_lib.?.full_object_path);
|
||||
} else {
|
||||
@@ -1613,46 +1626,65 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
|
||||
}
|
||||
|
||||
if (self.base.options.verbose_link) {
|
||||
Compilation.dump_argv(argv.items);
|
||||
// Skip over our own name so that the LLD linker name is the first argv item.
|
||||
Compilation.dump_argv(argv.items[1..]);
|
||||
}
|
||||
|
||||
// Oh, snapplesauce! We need null terminated argv.
|
||||
const new_argv = try arena.allocSentinel(?[*:0]const u8, argv.items.len, null);
|
||||
for (argv.items) |arg, i| {
|
||||
new_argv[i] = try arena.dupeZ(u8, arg);
|
||||
}
|
||||
// Sadly, we must run LLD as a child process because it does not behave
|
||||
// properly as a library.
|
||||
const child = try std.ChildProcess.init(argv.items, arena);
|
||||
defer child.deinit();
|
||||
|
||||
var stderr_context: LLDContext = .{
|
||||
.elf = self,
|
||||
.data = std.ArrayList(u8).init(self.base.allocator),
|
||||
};
|
||||
defer stderr_context.data.deinit();
|
||||
var stdout_context: LLDContext = .{
|
||||
.elf = self,
|
||||
.data = std.ArrayList(u8).init(self.base.allocator),
|
||||
};
|
||||
defer stdout_context.data.deinit();
|
||||
const llvm = @import("../llvm.zig");
|
||||
const ok = llvm.Link(
|
||||
.ELF,
|
||||
new_argv.ptr,
|
||||
new_argv.len,
|
||||
append_diagnostic,
|
||||
@ptrToInt(&stdout_context),
|
||||
@ptrToInt(&stderr_context),
|
||||
);
|
||||
if (stderr_context.oom or stdout_context.oom) return error.OutOfMemory;
|
||||
if (stdout_context.data.items.len != 0) {
|
||||
std.log.warn("unexpected LLD stdout: {}", .{stdout_context.data.items});
|
||||
}
|
||||
if (!ok) {
|
||||
// TODO parse this output and surface with the Compilation API rather than
|
||||
// directly outputting to stderr here.
|
||||
std.debug.print("{}", .{stderr_context.data.items});
|
||||
return error.LLDReportedFailure;
|
||||
}
|
||||
if (stderr_context.data.items.len != 0) {
|
||||
std.log.warn("unexpected LLD stderr: {}", .{stderr_context.data.items});
|
||||
if (comp.clang_passthrough_mode) {
|
||||
child.stdin_behavior = .Inherit;
|
||||
child.stdout_behavior = .Inherit;
|
||||
child.stderr_behavior = .Inherit;
|
||||
|
||||
const term = child.spawnAndWait() catch |err| {
|
||||
log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) });
|
||||
return error.UnableToSpawnSelf;
|
||||
};
|
||||
switch (term) {
|
||||
.Exited => |code| {
|
||||
if (code != 0) {
|
||||
// TODO https://github.com/ziglang/zig/issues/6342
|
||||
std.process.exit(1);
|
||||
}
|
||||
},
|
||||
else => std.process.abort(),
|
||||
}
|
||||
} else {
|
||||
child.stdin_behavior = .Ignore;
|
||||
child.stdout_behavior = .Ignore;
|
||||
child.stderr_behavior = .Pipe;
|
||||
|
||||
try child.spawn();
|
||||
|
||||
const stderr = try child.stderr.?.reader().readAllAlloc(arena, 10 * 1024 * 1024);
|
||||
|
||||
const term = child.wait() catch |err| {
|
||||
log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) });
|
||||
return error.UnableToSpawnSelf;
|
||||
};
|
||||
|
||||
switch (term) {
|
||||
.Exited => |code| {
|
||||
if (code != 0) {
|
||||
// TODO parse this output and surface with the Compilation API rather than
|
||||
// directly outputting to stderr here.
|
||||
std.debug.print("{s}", .{stderr});
|
||||
return error.LLDReportedFailure;
|
||||
}
|
||||
},
|
||||
else => {
|
||||
log.err("{s} terminated with stderr:\n{s}", .{ argv.items[0], stderr });
|
||||
return error.LLDCrashed;
|
||||
},
|
||||
}
|
||||
|
||||
if (stderr.len != 0) {
|
||||
std.log.warn("unexpected LLD stderr:\n{s}", .{stderr});
|
||||
}
|
||||
}
|
||||
|
||||
if (!self.base.options.disable_lld_caching) {
|
||||
@@ -1671,20 +1703,6 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
|
||||
}
|
||||
}
|
||||
|
||||
const LLDContext = struct {
|
||||
data: std.ArrayList(u8),
|
||||
elf: *Elf,
|
||||
oom: bool = false,
|
||||
};
|
||||
|
||||
fn append_diagnostic(context: usize, ptr: [*]const u8, len: usize) callconv(.C) void {
|
||||
const lld_context = @intToPtr(*LLDContext, context);
|
||||
const msg = ptr[0..len];
|
||||
lld_context.data.appendSlice(msg) catch |err| switch (err) {
|
||||
error.OutOfMemory => lld_context.oom = true,
|
||||
};
|
||||
}
|
||||
|
||||
fn writeDwarfAddrAssumeCapacity(self: *Elf, buf: *std.ArrayList(u8), addr: u64) void {
|
||||
const target_endian = self.base.options.target.cpu.arch.endian();
|
||||
switch (self.ptr_width) {
|
||||
|
||||
@@ -256,7 +256,10 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio
|
||||
errdefer file.close();
|
||||
|
||||
const self = try createEmpty(allocator, options);
|
||||
errdefer self.base.destroy();
|
||||
errdefer {
|
||||
self.base.file = null;
|
||||
self.base.destroy();
|
||||
}
|
||||
|
||||
self.base.file = file;
|
||||
|
||||
@@ -473,6 +476,8 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
|
||||
man.hash.addStringSet(self.base.options.system_libs);
|
||||
man.hash.add(allow_shlib_undefined);
|
||||
man.hash.add(self.base.options.bind_global_refs_locally);
|
||||
man.hash.add(self.base.options.system_linker_hack);
|
||||
man.hash.addOptionalBytes(self.base.options.syslibroot);
|
||||
|
||||
// We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.
|
||||
_ = try man.hit();
|
||||
@@ -539,8 +544,10 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
|
||||
if (self.base.options.system_linker_hack) {
|
||||
try argv.append("ld");
|
||||
} else {
|
||||
// Even though we're calling LLD as a library it thinks the first argument is its own exe name.
|
||||
try argv.append("lld");
|
||||
// We will invoke ourselves as a child process to gain access to LLD.
|
||||
// This is necessary because LLD does not behave properly as a library -
|
||||
// it calls exit() and does not reset all global data between invocations.
|
||||
try argv.appendSlice(&[_][]const u8{ comp.self_exe_path.?, "ld64.lld" });
|
||||
|
||||
try argv.append("-error-limit");
|
||||
try argv.append("0");
|
||||
@@ -582,11 +589,9 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
|
||||
try argv.append(cur_vers);
|
||||
}
|
||||
|
||||
// TODO getting an error when running an executable when doing this rpath thing
|
||||
//Buf *dylib_install_name = buf_sprintf("@rpath/lib%s.%" ZIG_PRI_usize ".dylib",
|
||||
// buf_ptr(g->root_out_name), g->version_major);
|
||||
//try argv.append("-install_name");
|
||||
//try argv.append(buf_ptr(dylib_install_name));
|
||||
const dylib_install_name = try std.fmt.allocPrint(arena, "@rpath/{}", .{self.base.options.emit.?.sub_path});
|
||||
try argv.append("-install_name");
|
||||
try argv.append(dylib_install_name);
|
||||
}
|
||||
|
||||
try argv.append("-arch");
|
||||
@@ -708,7 +713,9 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
|
||||
}
|
||||
|
||||
if (self.base.options.verbose_link) {
|
||||
Compilation.dump_argv(argv.items);
|
||||
// Potentially skip over our own name so that the LLD linker name is the first argv item.
|
||||
const adjusted_argv = if (self.base.options.system_linker_hack) argv.items else argv.items[1..];
|
||||
Compilation.dump_argv(adjusted_argv);
|
||||
}
|
||||
|
||||
// TODO https://github.com/ziglang/zig/issues/6971
|
||||
@@ -733,42 +740,61 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
|
||||
return error.LDReportedFailure;
|
||||
}
|
||||
} else {
|
||||
const new_argv = try arena.allocSentinel(?[*:0]const u8, argv.items.len, null);
|
||||
for (argv.items) |arg, i| {
|
||||
new_argv[i] = try arena.dupeZ(u8, arg);
|
||||
}
|
||||
// Sadly, we must run LLD as a child process because it does not behave
|
||||
// properly as a library.
|
||||
const child = try std.ChildProcess.init(argv.items, arena);
|
||||
defer child.deinit();
|
||||
|
||||
var stderr_context: LLDContext = .{
|
||||
.macho = self,
|
||||
.data = std.ArrayList(u8).init(self.base.allocator),
|
||||
};
|
||||
defer stderr_context.data.deinit();
|
||||
var stdout_context: LLDContext = .{
|
||||
.macho = self,
|
||||
.data = std.ArrayList(u8).init(self.base.allocator),
|
||||
};
|
||||
defer stdout_context.data.deinit();
|
||||
const llvm = @import("../llvm.zig");
|
||||
const ok = llvm.Link(
|
||||
.MachO,
|
||||
new_argv.ptr,
|
||||
new_argv.len,
|
||||
append_diagnostic,
|
||||
@ptrToInt(&stdout_context),
|
||||
@ptrToInt(&stderr_context),
|
||||
);
|
||||
if (stderr_context.oom or stdout_context.oom) return error.OutOfMemory;
|
||||
if (stdout_context.data.items.len != 0) {
|
||||
std.log.warn("unexpected LLD stdout: {}", .{stdout_context.data.items});
|
||||
}
|
||||
if (!ok) {
|
||||
// TODO parse this output and surface with the Compilation API rather than
|
||||
// directly outputting to stderr here.
|
||||
std.debug.print("{}", .{stderr_context.data.items});
|
||||
return error.LLDReportedFailure;
|
||||
}
|
||||
if (stderr_context.data.items.len != 0) {
|
||||
std.log.warn("unexpected LLD stderr: {}", .{stderr_context.data.items});
|
||||
if (comp.clang_passthrough_mode) {
|
||||
child.stdin_behavior = .Inherit;
|
||||
child.stdout_behavior = .Inherit;
|
||||
child.stderr_behavior = .Inherit;
|
||||
|
||||
const term = child.spawnAndWait() catch |err| {
|
||||
log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) });
|
||||
return error.UnableToSpawnSelf;
|
||||
};
|
||||
switch (term) {
|
||||
.Exited => |code| {
|
||||
if (code != 0) {
|
||||
// TODO https://github.com/ziglang/zig/issues/6342
|
||||
std.process.exit(1);
|
||||
}
|
||||
},
|
||||
else => std.process.abort(),
|
||||
}
|
||||
} else {
|
||||
child.stdin_behavior = .Ignore;
|
||||
child.stdout_behavior = .Ignore;
|
||||
child.stderr_behavior = .Pipe;
|
||||
|
||||
try child.spawn();
|
||||
|
||||
const stderr = try child.stderr.?.reader().readAllAlloc(arena, 10 * 1024 * 1024);
|
||||
|
||||
const term = child.wait() catch |err| {
|
||||
log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) });
|
||||
return error.UnableToSpawnSelf;
|
||||
};
|
||||
|
||||
switch (term) {
|
||||
.Exited => |code| {
|
||||
if (code != 0) {
|
||||
// TODO parse this output and surface with the Compilation API rather than
|
||||
// directly outputting to stderr here.
|
||||
std.debug.print("{s}", .{stderr});
|
||||
return error.LLDReportedFailure;
|
||||
}
|
||||
},
|
||||
else => {
|
||||
log.err("{s} terminated with stderr:\n{s}", .{ argv.items[0], stderr });
|
||||
return error.LLDCrashed;
|
||||
},
|
||||
}
|
||||
|
||||
if (stderr.len != 0) {
|
||||
std.log.warn("unexpected LLD stderr:\n{s}", .{stderr});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -789,20 +815,6 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
|
||||
}
|
||||
}
|
||||
|
||||
const LLDContext = struct {
|
||||
data: std.ArrayList(u8),
|
||||
macho: *MachO,
|
||||
oom: bool = false,
|
||||
};
|
||||
|
||||
fn append_diagnostic(context: usize, ptr: [*]const u8, len: usize) callconv(.C) void {
|
||||
const lld_context = @intToPtr(*LLDContext, context);
|
||||
const msg = ptr[0..len];
|
||||
lld_context.data.appendSlice(msg) catch |err| switch (err) {
|
||||
error.OutOfMemory => lld_context.oom = true,
|
||||
};
|
||||
}
|
||||
|
||||
fn darwinArchString(arch: std.Target.Cpu.Arch) []const u8 {
|
||||
return switch (arch) {
|
||||
.aarch64, .aarch64_be, .aarch64_32 => "arm64",
|
||||
|
||||
@@ -282,6 +282,11 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
|
||||
break :blk full_obj_path;
|
||||
} else null;
|
||||
|
||||
const compiler_rt_path: ?[]const u8 = if (self.base.options.include_compiler_rt)
|
||||
comp.compiler_rt_static_lib.?.full_object_path
|
||||
else
|
||||
null;
|
||||
|
||||
const target = self.base.options.target;
|
||||
|
||||
const id_symlink_basename = "lld.id";
|
||||
@@ -302,6 +307,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
|
||||
_ = try man.addFile(entry.key.status.success.object_path, null);
|
||||
}
|
||||
try man.addOptionalFile(module_obj_path);
|
||||
try man.addOptionalFile(compiler_rt_path);
|
||||
man.hash.addOptional(self.base.options.stack_size_override);
|
||||
man.hash.addListOfBytes(self.base.options.extra_lld_args);
|
||||
|
||||
@@ -339,8 +345,10 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
|
||||
// Create an LLD command line and invoke it.
|
||||
var argv = std.ArrayList([]const u8).init(self.base.allocator);
|
||||
defer argv.deinit();
|
||||
// Even though we're calling LLD as a library it thinks the first argument is its own exe name.
|
||||
try argv.append("lld");
|
||||
// We will invoke ourselves as a child process to gain access to LLD.
|
||||
// This is necessary because LLD does not behave properly as a library -
|
||||
// it calls exit() and does not reset all global data between invocations.
|
||||
try argv.appendSlice(&[_][]const u8{ comp.self_exe_path.?, "wasm-ld" });
|
||||
if (is_obj) {
|
||||
try argv.append("-r");
|
||||
}
|
||||
@@ -378,53 +386,77 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
|
||||
try argv.append(p);
|
||||
}
|
||||
|
||||
if (self.base.options.output_mode != .Obj and !self.base.options.is_compiler_rt_or_libc) {
|
||||
if (!self.base.options.link_libc) {
|
||||
try argv.append(comp.libc_static_lib.?.full_object_path);
|
||||
}
|
||||
try argv.append(comp.compiler_rt_static_lib.?.full_object_path);
|
||||
if (self.base.options.output_mode != .Obj and
|
||||
!self.base.options.is_compiler_rt_or_libc and
|
||||
!self.base.options.link_libc)
|
||||
{
|
||||
try argv.append(comp.libc_static_lib.?.full_object_path);
|
||||
}
|
||||
|
||||
if (compiler_rt_path) |p| {
|
||||
try argv.append(p);
|
||||
}
|
||||
|
||||
if (self.base.options.verbose_link) {
|
||||
Compilation.dump_argv(argv.items);
|
||||
// Skip over our own name so that the LLD linker name is the first argv item.
|
||||
Compilation.dump_argv(argv.items[1..]);
|
||||
}
|
||||
|
||||
const new_argv = try arena.allocSentinel(?[*:0]const u8, argv.items.len, null);
|
||||
for (argv.items) |arg, i| {
|
||||
new_argv[i] = try arena.dupeZ(u8, arg);
|
||||
}
|
||||
// Sadly, we must run LLD as a child process because it does not behave
|
||||
// properly as a library.
|
||||
const child = try std.ChildProcess.init(argv.items, arena);
|
||||
defer child.deinit();
|
||||
|
||||
var stderr_context: LLDContext = .{
|
||||
.wasm = self,
|
||||
.data = std.ArrayList(u8).init(self.base.allocator),
|
||||
};
|
||||
defer stderr_context.data.deinit();
|
||||
var stdout_context: LLDContext = .{
|
||||
.wasm = self,
|
||||
.data = std.ArrayList(u8).init(self.base.allocator),
|
||||
};
|
||||
defer stdout_context.data.deinit();
|
||||
const llvm = @import("../llvm.zig");
|
||||
const ok = llvm.Link(
|
||||
.Wasm,
|
||||
new_argv.ptr,
|
||||
new_argv.len,
|
||||
append_diagnostic,
|
||||
@ptrToInt(&stdout_context),
|
||||
@ptrToInt(&stderr_context),
|
||||
);
|
||||
if (stderr_context.oom or stdout_context.oom) return error.OutOfMemory;
|
||||
if (stdout_context.data.items.len != 0) {
|
||||
std.log.warn("unexpected LLD stdout: {}", .{stdout_context.data.items});
|
||||
}
|
||||
if (!ok) {
|
||||
// TODO parse this output and surface with the Compilation API rather than
|
||||
// directly outputting to stderr here.
|
||||
std.debug.print("{}", .{stderr_context.data.items});
|
||||
return error.LLDReportedFailure;
|
||||
}
|
||||
if (stderr_context.data.items.len != 0) {
|
||||
std.log.warn("unexpected LLD stderr: {}", .{stderr_context.data.items});
|
||||
if (comp.clang_passthrough_mode) {
|
||||
child.stdin_behavior = .Inherit;
|
||||
child.stdout_behavior = .Inherit;
|
||||
child.stderr_behavior = .Inherit;
|
||||
|
||||
const term = child.spawnAndWait() catch |err| {
|
||||
log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) });
|
||||
return error.UnableToSpawnSelf;
|
||||
};
|
||||
switch (term) {
|
||||
.Exited => |code| {
|
||||
if (code != 0) {
|
||||
// TODO https://github.com/ziglang/zig/issues/6342
|
||||
std.process.exit(1);
|
||||
}
|
||||
},
|
||||
else => std.process.abort(),
|
||||
}
|
||||
} else {
|
||||
child.stdin_behavior = .Ignore;
|
||||
child.stdout_behavior = .Ignore;
|
||||
child.stderr_behavior = .Pipe;
|
||||
|
||||
try child.spawn();
|
||||
|
||||
const stderr = try child.stderr.?.reader().readAllAlloc(arena, 10 * 1024 * 1024);
|
||||
|
||||
const term = child.wait() catch |err| {
|
||||
log.err("unable to spawn {s}: {s}", .{ argv.items[0], @errorName(err) });
|
||||
return error.UnableToSpawnSelf;
|
||||
};
|
||||
|
||||
switch (term) {
|
||||
.Exited => |code| {
|
||||
if (code != 0) {
|
||||
// TODO parse this output and surface with the Compilation API rather than
|
||||
// directly outputting to stderr here.
|
||||
std.debug.print("{s}", .{stderr});
|
||||
return error.LLDReportedFailure;
|
||||
}
|
||||
},
|
||||
else => {
|
||||
log.err("{s} terminated with stderr:\n{s}", .{ argv.items[0], stderr });
|
||||
return error.LLDCrashed;
|
||||
},
|
||||
}
|
||||
|
||||
if (stderr.len != 0) {
|
||||
std.log.warn("unexpected LLD stderr:\n{s}", .{stderr});
|
||||
}
|
||||
}
|
||||
|
||||
if (!self.base.options.disable_lld_caching) {
|
||||
@@ -443,20 +475,6 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
|
||||
}
|
||||
}
|
||||
|
||||
const LLDContext = struct {
|
||||
data: std.ArrayList(u8),
|
||||
wasm: *Wasm,
|
||||
oom: bool = false,
|
||||
};
|
||||
|
||||
fn append_diagnostic(context: usize, ptr: [*]const u8, len: usize) callconv(.C) void {
|
||||
const lld_context = @intToPtr(*LLDContext, context);
|
||||
const msg = ptr[0..len];
|
||||
lld_context.data.appendSlice(msg) catch |err| switch (err) {
|
||||
error.OutOfMemory => lld_context.oom = true,
|
||||
};
|
||||
}
|
||||
|
||||
/// Get the current index of a given Decl in the function list
|
||||
/// TODO: we could maintain a hash map to potentially make this
|
||||
fn getFuncidx(self: Wasm, decl: *Module.Decl) ?u32 {
|
||||
|
||||
18
src/llvm.zig
18
src/llvm.zig
@@ -1,15 +1,15 @@
|
||||
//! We do this instead of @cImport because the self-hosted compiler is easier
|
||||
//! to bootstrap if it does not depend on translate-c.
|
||||
|
||||
pub const Link = ZigLLDLink;
|
||||
extern fn ZigLLDLink(
|
||||
oformat: ObjectFormatType,
|
||||
args: [*:null]const ?[*:0]const u8,
|
||||
arg_count: usize,
|
||||
append_diagnostic: fn (context: usize, ptr: [*]const u8, len: usize) callconv(.C) void,
|
||||
context_stdout: usize,
|
||||
context_stderr: usize,
|
||||
) bool;
|
||||
extern fn ZigLLDLinkCOFF(argc: c_int, argv: [*:null]const ?[*:0]const u8, can_exit_early: bool) c_int;
|
||||
extern fn ZigLLDLinkELF(argc: c_int, argv: [*:null]const ?[*:0]const u8, can_exit_early: bool) c_int;
|
||||
extern fn ZigLLDLinkMachO(argc: c_int, argv: [*:null]const ?[*:0]const u8, can_exit_early: bool) c_int;
|
||||
extern fn ZigLLDLinkWasm(argc: c_int, argv: [*:null]const ?[*:0]const u8, can_exit_early: bool) c_int;
|
||||
|
||||
pub const LinkCOFF = ZigLLDLinkCOFF;
|
||||
pub const LinkELF = ZigLLDLinkELF;
|
||||
pub const LinkMachO = ZigLLDLinkMachO;
|
||||
pub const LinkWasm = ZigLLDLinkWasm;
|
||||
|
||||
pub const ObjectFormatType = extern enum(c_int) {
|
||||
Unknown,
|
||||
|
||||
203
src/main.zig
203
src/main.zig
@@ -41,11 +41,12 @@ const usage =
|
||||
\\ build Build project from build.zig
|
||||
\\ build-exe Create executable from source or object files
|
||||
\\ build-lib Create library from source or object files
|
||||
\\ build-obj Create object from source or assembly
|
||||
\\ build-obj Create object from source or object files
|
||||
\\ cc Use Zig as a drop-in C compiler
|
||||
\\ c++ Use Zig as a drop-in C++ compiler
|
||||
\\ env Print lib path, std path, compiler id and version
|
||||
\\ fmt Parse file and render in canonical zig format
|
||||
\\ env Print lib path, std path, cache directory, and version
|
||||
\\ fmt Reformat Zig source into canonical form
|
||||
\\ help Print this help and exit
|
||||
\\ init-exe Initialize a `zig build` application in the cwd
|
||||
\\ init-lib Initialize a `zig build` library in the cwd
|
||||
\\ libc Display native libc paths file or validate one
|
||||
@@ -54,11 +55,11 @@ const usage =
|
||||
\\ targets List available compilation targets
|
||||
\\ test Create and run a test build
|
||||
\\ version Print version number and exit
|
||||
\\ zen Print zen of zig and exit
|
||||
\\ zen Print Zen of Zig and exit
|
||||
\\
|
||||
\\General Options:
|
||||
\\
|
||||
\\ --help Print command-specific usage
|
||||
\\ -h, --help Print command-specific usage
|
||||
\\
|
||||
;
|
||||
|
||||
@@ -175,6 +176,12 @@ pub fn mainArgs(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v
|
||||
mem.eql(u8, cmd, "-cc1") or mem.eql(u8, cmd, "-cc1as"))
|
||||
{
|
||||
return punt_to_clang(arena, args);
|
||||
} else if (mem.eql(u8, cmd, "ld.lld") or
|
||||
mem.eql(u8, cmd, "ld64.lld") or
|
||||
mem.eql(u8, cmd, "lld-link") or
|
||||
mem.eql(u8, cmd, "wasm-ld"))
|
||||
{
|
||||
return punt_to_lld(arena, args);
|
||||
} else if (mem.eql(u8, cmd, "build")) {
|
||||
return cmdBuild(gpa, arena, cmd_args);
|
||||
} else if (mem.eql(u8, cmd, "fmt")) {
|
||||
@@ -195,7 +202,7 @@ pub fn mainArgs(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v
|
||||
try @import("print_env.zig").cmdEnv(arena, cmd_args, io.getStdOut().outStream());
|
||||
} else if (mem.eql(u8, cmd, "zen")) {
|
||||
try io.getStdOut().writeAll(info_zen);
|
||||
} else if (mem.eql(u8, cmd, "help")) {
|
||||
} else if (mem.eql(u8, cmd, "help") or mem.eql(u8, cmd, "-h") or mem.eql(u8, cmd, "--help")) {
|
||||
try io.getStdOut().writeAll(usage);
|
||||
} else {
|
||||
std.log.info("{}", .{usage});
|
||||
@@ -303,6 +310,12 @@ const usage_build_generic =
|
||||
\\ --version-script [path] Provide a version .map file
|
||||
\\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so)
|
||||
\\ --version [ver] Dynamic library semver
|
||||
\\ -fsoname[=name] (Linux) Override the default SONAME value
|
||||
\\ -fno-soname (Linux) Disable emitting a SONAME
|
||||
\\ -fLLD Force using LLD as the linker
|
||||
\\ -fno-LLD Prevent using LLD as the linker
|
||||
\\ -fcompiler-rt Always include compiler-rt symbols in output
|
||||
\\ -fno-compiler-rt Prevent including compiler-rt symbols in output
|
||||
\\ -rdynamic Add all symbols to the dynamic symbol table
|
||||
\\ -rpath [path] Add directory to the runtime library search path
|
||||
\\ -feach-lib-rpath Ensure adding rpath for each used dynamic library
|
||||
@@ -347,6 +360,12 @@ const repl_help =
|
||||
\\
|
||||
;
|
||||
|
||||
const SOName = union(enum) {
|
||||
no,
|
||||
yes_default_value,
|
||||
yes: []const u8,
|
||||
};
|
||||
|
||||
const Emit = union(enum) {
|
||||
no,
|
||||
yes_default_path,
|
||||
@@ -449,6 +468,7 @@ fn buildOutputType(
|
||||
var target_ofmt: ?[]const u8 = null;
|
||||
var output_mode: std.builtin.OutputMode = undefined;
|
||||
var emit_h: Emit = undefined;
|
||||
var soname: SOName = undefined;
|
||||
var ensure_libc_on_non_freestanding = false;
|
||||
var ensure_libcpp_on_non_freestanding = false;
|
||||
var link_libc = false;
|
||||
@@ -459,11 +479,11 @@ fn buildOutputType(
|
||||
var want_sanitize_c: ?bool = null;
|
||||
var want_stack_check: ?bool = null;
|
||||
var want_valgrind: ?bool = null;
|
||||
var want_compiler_rt: ?bool = null;
|
||||
var rdynamic: bool = false;
|
||||
var linker_script: ?[]const u8 = null;
|
||||
var version_script: ?[]const u8 = null;
|
||||
var disable_c_depfile = false;
|
||||
var override_soname: ?[]const u8 = null;
|
||||
var linker_gc_sections: ?bool = null;
|
||||
var linker_allow_shlib_undefined: ?bool = null;
|
||||
var linker_bind_global_refs_locally: ?bool = null;
|
||||
@@ -560,6 +580,8 @@ fn buildOutputType(
|
||||
// .translate_c, .zig_test, .run => emit_h = .no,
|
||||
// else => unreachable,
|
||||
//}
|
||||
|
||||
soname = .yes_default_value;
|
||||
const args = all_args[2..];
|
||||
var i: usize = 0;
|
||||
args_loop: while (i < args.len) : (i += 1) {
|
||||
@@ -774,6 +796,10 @@ fn buildOutputType(
|
||||
if (i + 1 >= args.len) fatal("expected parameter after {}", .{arg});
|
||||
i += 1;
|
||||
override_lib_dir = args[i];
|
||||
} else if (mem.eql(u8, arg, "-fcompiler-rt")) {
|
||||
want_compiler_rt = true;
|
||||
} else if (mem.eql(u8, arg, "-fno-compiler-rt")) {
|
||||
want_compiler_rt = false;
|
||||
} else if (mem.eql(u8, arg, "-feach-lib-rpath")) {
|
||||
each_lib_rpath = true;
|
||||
} else if (mem.eql(u8, arg, "-fno-each-lib-rpath")) {
|
||||
@@ -820,6 +846,12 @@ fn buildOutputType(
|
||||
use_clang = false;
|
||||
} else if (mem.eql(u8, arg, "-rdynamic")) {
|
||||
rdynamic = true;
|
||||
} else if (mem.eql(u8, arg, "-fsoname")) {
|
||||
soname = .yes_default_value;
|
||||
} else if (mem.startsWith(u8, arg, "-fsoname=")) {
|
||||
soname = .{ .yes = arg["-fsoname=".len..] };
|
||||
} else if (mem.eql(u8, arg, "-fno-soname")) {
|
||||
soname = .no;
|
||||
} else if (mem.eql(u8, arg, "-femit-bin")) {
|
||||
emit_bin = .yes_default_path;
|
||||
} else if (mem.startsWith(u8, arg, "-femit-bin=")) {
|
||||
@@ -947,6 +979,7 @@ fn buildOutputType(
|
||||
},
|
||||
.cc, .cpp => {
|
||||
emit_h = .no;
|
||||
soname = .no;
|
||||
strip = true;
|
||||
ensure_libc_on_non_freestanding = true;
|
||||
ensure_libcpp_on_non_freestanding = arg_mode == .cpp;
|
||||
@@ -1090,33 +1123,33 @@ fn buildOutputType(
|
||||
if (i >= linker_args.items.len) {
|
||||
fatal("expected linker arg after '{}'", .{arg});
|
||||
}
|
||||
const soname = linker_args.items[i];
|
||||
override_soname = soname;
|
||||
const name = linker_args.items[i];
|
||||
soname = .{ .yes = name };
|
||||
// Use it as --name.
|
||||
// Example: libsoundio.so.2
|
||||
var prefix: usize = 0;
|
||||
if (mem.startsWith(u8, soname, "lib")) {
|
||||
if (mem.startsWith(u8, name, "lib")) {
|
||||
prefix = 3;
|
||||
}
|
||||
var end: usize = soname.len;
|
||||
if (mem.endsWith(u8, soname, ".so")) {
|
||||
var end: usize = name.len;
|
||||
if (mem.endsWith(u8, name, ".so")) {
|
||||
end -= 3;
|
||||
} else {
|
||||
var found_digit = false;
|
||||
while (end > 0 and std.ascii.isDigit(soname[end - 1])) {
|
||||
while (end > 0 and std.ascii.isDigit(name[end - 1])) {
|
||||
found_digit = true;
|
||||
end -= 1;
|
||||
}
|
||||
if (found_digit and end > 0 and soname[end - 1] == '.') {
|
||||
if (found_digit and end > 0 and name[end - 1] == '.') {
|
||||
end -= 1;
|
||||
} else {
|
||||
end = soname.len;
|
||||
end = name.len;
|
||||
}
|
||||
if (mem.endsWith(u8, soname[prefix..end], ".so")) {
|
||||
if (mem.endsWith(u8, name[prefix..end], ".so")) {
|
||||
end -= 3;
|
||||
}
|
||||
}
|
||||
provided_name = soname[prefix..end];
|
||||
provided_name = name[prefix..end];
|
||||
} else if (mem.eql(u8, arg, "-rpath")) {
|
||||
i += 1;
|
||||
if (i >= linker_args.items.len) {
|
||||
@@ -1277,16 +1310,16 @@ fn buildOutputType(
|
||||
break :blk "test";
|
||||
} else if (root_src_file) |file| {
|
||||
const basename = fs.path.basename(file);
|
||||
break :blk mem.split(basename, ".").next().?;
|
||||
} else if (c_source_files.items.len == 1) {
|
||||
break :blk basename[0 .. basename.len - fs.path.extension(basename).len];
|
||||
} else if (c_source_files.items.len >= 1) {
|
||||
const basename = fs.path.basename(c_source_files.items[0].src_path);
|
||||
break :blk mem.split(basename, ".").next().?;
|
||||
} else if (link_objects.items.len == 1) {
|
||||
break :blk basename[0 .. basename.len - fs.path.extension(basename).len];
|
||||
} else if (link_objects.items.len >= 1) {
|
||||
const basename = fs.path.basename(link_objects.items[0]);
|
||||
break :blk mem.split(basename, ".").next().?;
|
||||
break :blk basename[0 .. basename.len - fs.path.extension(basename).len];
|
||||
} else if (emit_bin == .yes) {
|
||||
const basename = fs.path.basename(emit_bin.yes);
|
||||
break :blk mem.split(basename, ".").next().?;
|
||||
break :blk basename[0 .. basename.len - fs.path.extension(basename).len];
|
||||
} else if (show_builtin) {
|
||||
break :blk "builtin";
|
||||
} else if (arg_mode == .run) {
|
||||
@@ -1356,6 +1389,9 @@ fn buildOutputType(
|
||||
_ = system_libs.orderedRemove(i);
|
||||
continue;
|
||||
}
|
||||
if (std.fs.path.isAbsolute(lib_name)) {
|
||||
fatal("cannot use absolute path as a system library: {s}", .{lib_name});
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
@@ -1418,6 +1454,18 @@ fn buildOutputType(
|
||||
const have_enable_cache = enable_cache orelse false;
|
||||
const optional_version = if (have_version) version else null;
|
||||
|
||||
const resolved_soname: ?[]const u8 = switch (soname) {
|
||||
.yes => |explicit| explicit,
|
||||
.no => null,
|
||||
.yes_default_value => switch (object_format) {
|
||||
.elf => if (have_version)
|
||||
try std.fmt.allocPrint(arena, "lib{s}.so.{d}", .{ root_name, version.major })
|
||||
else
|
||||
try std.fmt.allocPrint(arena, "lib{s}.so", .{root_name}),
|
||||
else => null,
|
||||
},
|
||||
};
|
||||
|
||||
const emit_bin_loc: ?Compilation.EmitLoc = switch (emit_bin) {
|
||||
.no => null,
|
||||
.yes_default_path => Compilation.EmitLoc{
|
||||
@@ -1576,21 +1624,18 @@ fn buildOutputType(
|
||||
if (arg_mode == .run) {
|
||||
break :l global_cache_directory;
|
||||
}
|
||||
const cache_dir_path = blk: {
|
||||
if (root_pkg) |pkg| {
|
||||
if (pkg.root_src_directory.path) |p| {
|
||||
break :blk try fs.path.join(arena, &[_][]const u8{ p, "zig-cache" });
|
||||
}
|
||||
}
|
||||
break :blk "zig-cache";
|
||||
};
|
||||
const cache_parent_dir = if (root_pkg) |pkg| pkg.root_src_directory.handle else fs.cwd();
|
||||
const dir = try cache_parent_dir.makeOpenPath("zig-cache", .{});
|
||||
cleanup_local_cache_dir = dir;
|
||||
break :l .{
|
||||
.handle = dir,
|
||||
.path = cache_dir_path,
|
||||
};
|
||||
if (root_pkg) |pkg| {
|
||||
const cache_dir_path = try pkg.root_src_directory.join(arena, &[_][]const u8{"zig-cache"});
|
||||
const dir = try pkg.root_src_directory.handle.makeOpenPath("zig-cache", .{});
|
||||
cleanup_local_cache_dir = dir;
|
||||
break :l .{
|
||||
.handle = dir,
|
||||
.path = cache_dir_path,
|
||||
};
|
||||
}
|
||||
// Otherwise we really don't have a reasonable place to put the local cache directory,
|
||||
// so we utilize the global one.
|
||||
break :l global_cache_directory;
|
||||
};
|
||||
|
||||
if (build_options.have_llvm and emit_asm != .no) {
|
||||
@@ -1608,6 +1653,7 @@ fn buildOutputType(
|
||||
.root_name = root_name,
|
||||
.target = target_info.target,
|
||||
.is_native_os = cross_target.isNativeOs(),
|
||||
.is_native_abi = cross_target.isNativeAbi(),
|
||||
.dynamic_linker = target_info.dynamic_linker.get(),
|
||||
.output_mode = output_mode,
|
||||
.root_pkg = root_pkg,
|
||||
@@ -1637,6 +1683,7 @@ fn buildOutputType(
|
||||
.want_sanitize_c = want_sanitize_c,
|
||||
.want_stack_check = want_stack_check,
|
||||
.want_valgrind = want_valgrind,
|
||||
.want_compiler_rt = want_compiler_rt,
|
||||
.use_llvm = use_llvm,
|
||||
.use_lld = use_lld,
|
||||
.use_clang = use_clang,
|
||||
@@ -1644,7 +1691,7 @@ fn buildOutputType(
|
||||
.linker_script = linker_script,
|
||||
.version_script = version_script,
|
||||
.disable_c_depfile = disable_c_depfile,
|
||||
.override_soname = override_soname,
|
||||
.soname = resolved_soname,
|
||||
.linker_gc_sections = linker_gc_sections,
|
||||
.linker_allow_shlib_undefined = linker_allow_shlib_undefined,
|
||||
.linker_bind_global_refs_locally = linker_bind_global_refs_locally,
|
||||
@@ -1707,7 +1754,10 @@ fn buildOutputType(
|
||||
}
|
||||
};
|
||||
|
||||
try updateModule(gpa, comp, zir_out_path, hook);
|
||||
updateModule(gpa, comp, zir_out_path, hook) catch |err| switch (err) {
|
||||
error.SemanticAnalyzeFail => process.exit(1),
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
if (build_options.is_stage1 and comp.stage1_lock != null and watch) {
|
||||
warn("--watch is not recommended with the stage1 backend; it leaks memory and is not capable of incremental compilation", .{});
|
||||
@@ -1819,7 +1869,10 @@ fn buildOutputType(
|
||||
if (output_mode == .Exe) {
|
||||
try comp.makeBinFileWritable();
|
||||
}
|
||||
try updateModule(gpa, comp, zir_out_path, hook);
|
||||
updateModule(gpa, comp, zir_out_path, hook) catch |err| switch (err) {
|
||||
error.SemanticAnalyzeFail => continue,
|
||||
else => |e| return e,
|
||||
};
|
||||
} else if (mem.eql(u8, actual_line, "exit")) {
|
||||
break;
|
||||
} else if (mem.eql(u8, actual_line, "help")) {
|
||||
@@ -1849,6 +1902,7 @@ fn updateModule(gpa: *Allocator, comp: *Compilation, zir_out_path: ?[]const u8,
|
||||
for (errors.list) |full_err_msg| {
|
||||
full_err_msg.renderToStdErr();
|
||||
}
|
||||
return error.SemanticAnalyzeFail;
|
||||
} else switch (hook) {
|
||||
.none => {},
|
||||
.print => |bin_path| try io.getStdOut().writer().print("{s}\n", .{bin_path}),
|
||||
@@ -2013,7 +2067,7 @@ pub fn cmdLibC(gpa: *Allocator, args: []const []const u8) !void {
|
||||
while (i < args.len) : (i += 1) {
|
||||
const arg = args[i];
|
||||
if (mem.startsWith(u8, arg, "-")) {
|
||||
if (mem.eql(u8, arg, "--help")) {
|
||||
if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
|
||||
const stdout = io.getStdOut().writer();
|
||||
try stdout.writeAll(usage_libc);
|
||||
return cleanExit();
|
||||
@@ -2055,7 +2109,7 @@ pub const usage_init =
|
||||
\\ directory.
|
||||
\\
|
||||
\\Options:
|
||||
\\ --help Print this help and exit
|
||||
\\ -h, --help Print this help and exit
|
||||
\\
|
||||
\\
|
||||
;
|
||||
@@ -2071,7 +2125,7 @@ pub fn cmdInit(
|
||||
while (i < args.len) : (i += 1) {
|
||||
const arg = args[i];
|
||||
if (mem.startsWith(u8, arg, "-")) {
|
||||
if (mem.eql(u8, arg, "--help")) {
|
||||
if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
|
||||
try io.getStdOut().writeAll(usage_init);
|
||||
return cleanExit();
|
||||
} else {
|
||||
@@ -2144,7 +2198,7 @@ pub const usage_build =
|
||||
\\ Build a project from build.zig.
|
||||
\\
|
||||
\\Options:
|
||||
\\ --help Print this help and exit
|
||||
\\ -h, --help Print this help and exit
|
||||
\\
|
||||
\\
|
||||
;
|
||||
@@ -2152,7 +2206,7 @@ pub const usage_build =
|
||||
pub fn cmdBuild(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !void {
|
||||
// We want to release all the locks before executing the child process, so we make a nice
|
||||
// big block here to ensure the cleanup gets run when we extract out our argv.
|
||||
const lock_and_argv = lock_and_argv: {
|
||||
const child_argv = argv: {
|
||||
const self_exe_path = try fs.selfExePathAlloc(arena);
|
||||
|
||||
var build_file: ?[]const u8 = null;
|
||||
@@ -2172,6 +2226,9 @@ pub fn cmdBuild(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v
|
||||
const argv_index_cache_dir = child_argv.items.len;
|
||||
_ = try child_argv.addOne();
|
||||
|
||||
const argv_index_global_cache_dir = child_argv.items.len;
|
||||
_ = try child_argv.addOne();
|
||||
|
||||
{
|
||||
var i: usize = 0;
|
||||
while (i < args.len) : (i += 1) {
|
||||
@@ -2192,13 +2249,11 @@ pub fn cmdBuild(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v
|
||||
if (i + 1 >= args.len) fatal("expected argument after '{}'", .{arg});
|
||||
i += 1;
|
||||
override_local_cache_dir = args[i];
|
||||
try child_argv.appendSlice(&[_][]const u8{ arg, args[i] });
|
||||
continue;
|
||||
} else if (mem.eql(u8, arg, "--global-cache-dir")) {
|
||||
if (i + 1 >= args.len) fatal("expected argument after '{}'", .{arg});
|
||||
i += 1;
|
||||
override_global_cache_dir = args[i];
|
||||
try child_argv.appendSlice(&[_][]const u8{ arg, args[i] });
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -2283,6 +2338,8 @@ pub fn cmdBuild(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v
|
||||
};
|
||||
defer global_cache_directory.handle.close();
|
||||
|
||||
child_argv.items[argv_index_global_cache_dir] = global_cache_directory.path orelse cwd_path;
|
||||
|
||||
var local_cache_directory: Compilation.Directory = l: {
|
||||
if (override_local_cache_dir) |local_cache_dir_path| {
|
||||
break :l .{
|
||||
@@ -2327,6 +2384,7 @@ pub fn cmdBuild(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v
|
||||
.root_name = "build",
|
||||
.target = target_info.target,
|
||||
.is_native_os = cross_target.isNativeOs(),
|
||||
.is_native_abi = cross_target.isNativeAbi(),
|
||||
.dynamic_linker = target_info.dynamic_linker.get(),
|
||||
.output_mode = .Exe,
|
||||
.root_pkg = &root_pkg,
|
||||
@@ -2347,15 +2405,8 @@ pub fn cmdBuild(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v
|
||||
&[_][]const u8{exe_basename},
|
||||
);
|
||||
|
||||
break :lock_and_argv .{
|
||||
.child_argv = child_argv.items,
|
||||
.lock = comp.bin_file.toOwnedLock(),
|
||||
};
|
||||
break :argv child_argv.items;
|
||||
};
|
||||
const child_argv = lock_and_argv.child_argv;
|
||||
var lock = lock_and_argv.lock;
|
||||
defer lock.release();
|
||||
|
||||
const child = try std.ChildProcess.init(child_argv, gpa);
|
||||
defer child.deinit();
|
||||
|
||||
@@ -2396,7 +2447,7 @@ pub const usage_fmt =
|
||||
\\ recursively.
|
||||
\\
|
||||
\\Options:
|
||||
\\ --help Print this help and exit
|
||||
\\ -h, --help Print this help and exit
|
||||
\\ --color [auto|off|on] Enable or disable colored error messages
|
||||
\\ --stdin Format code from stdin; output to stdout
|
||||
\\ --check List non-conforming files and exit with an error
|
||||
@@ -2428,7 +2479,7 @@ pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void {
|
||||
while (i < args.len) : (i += 1) {
|
||||
const arg = args[i];
|
||||
if (mem.startsWith(u8, arg, "-")) {
|
||||
if (mem.eql(u8, arg, "--help")) {
|
||||
if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
|
||||
const stdout = io.getStdOut().outStream();
|
||||
try stdout.writeAll(usage_fmt);
|
||||
return cleanExit();
|
||||
@@ -2566,6 +2617,9 @@ fn fmtPathDir(
|
||||
var dir_it = dir.iterate();
|
||||
while (try dir_it.next()) |entry| {
|
||||
const is_dir = entry.kind == .Directory;
|
||||
|
||||
if (is_dir and std.mem.eql(u8, entry.name, "zig-cache")) continue;
|
||||
|
||||
if (is_dir or mem.endsWith(u8, entry.name, ".zig")) {
|
||||
const full_path = try fs.path.join(fmt.gpa, &[_][]const u8{ file_path, entry.name });
|
||||
defer fmt.gpa.free(full_path);
|
||||
@@ -2736,6 +2790,39 @@ fn punt_to_clang(arena: *Allocator, args: []const []const u8) error{OutOfMemory}
|
||||
process.exit(@bitCast(u8, @truncate(i8, exit_code)));
|
||||
}
|
||||
|
||||
/// The first argument determines which backend is invoked. The options are:
|
||||
/// * `ld.lld` - ELF
|
||||
/// * `ld64.lld` - Mach-O
|
||||
/// * `lld-link` - COFF
|
||||
/// * `wasm-ld` - WebAssembly
|
||||
/// TODO https://github.com/ziglang/zig/issues/3257
|
||||
pub fn punt_to_lld(arena: *Allocator, args: []const []const u8) error{OutOfMemory} {
|
||||
if (!build_options.have_llvm)
|
||||
fatal("`zig {s}` unavailable: compiler built without LLVM extensions", .{args[0]});
|
||||
// Convert the args to the format LLD expects.
|
||||
// We subtract 1 to shave off the zig binary from args[0].
|
||||
const argv = try arena.allocSentinel(?[*:0]const u8, args.len - 1, null);
|
||||
for (args[1..]) |arg, i| {
|
||||
argv[i] = try arena.dupeZ(u8, arg); // TODO If there was an argsAllocZ we could avoid this allocation.
|
||||
}
|
||||
const exit_code = rc: {
|
||||
const llvm = @import("llvm.zig");
|
||||
const argc = @intCast(c_int, argv.len);
|
||||
if (mem.eql(u8, args[1], "ld.lld")) {
|
||||
break :rc llvm.LinkELF(argc, argv.ptr, true);
|
||||
} else if (mem.eql(u8, args[1], "ld64.lld")) {
|
||||
break :rc llvm.LinkMachO(argc, argv.ptr, true);
|
||||
} else if (mem.eql(u8, args[1], "lld-link")) {
|
||||
break :rc llvm.LinkCOFF(argc, argv.ptr, true);
|
||||
} else if (mem.eql(u8, args[1], "wasm-ld")) {
|
||||
break :rc llvm.LinkWasm(argc, argv.ptr, true);
|
||||
} else {
|
||||
unreachable;
|
||||
}
|
||||
};
|
||||
process.exit(@bitCast(u8, @truncate(i8, exit_code)));
|
||||
}
|
||||
|
||||
const clang_args = @import("clang_options.zig").list;
|
||||
|
||||
pub const ClangArgIterator = struct {
|
||||
|
||||
56
src/musl.zig
56
src/musl.zig
@@ -14,6 +14,7 @@ pub const CRTFile = enum {
|
||||
crt1_o,
|
||||
scrt1_o,
|
||||
libc_a,
|
||||
libc_so,
|
||||
};
|
||||
|
||||
pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
|
||||
@@ -122,7 +123,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
|
||||
|
||||
const dirname = path.dirname(src_file).?;
|
||||
const basename = path.basename(src_file);
|
||||
const noextbasename = mem.split(basename, ".").next().?;
|
||||
const noextbasename = basename[0 .. basename.len - std.fs.path.extension(basename).len];
|
||||
const before_arch_dir = path.dirname(dirname).?;
|
||||
const dirbasename = path.basename(dirname);
|
||||
|
||||
@@ -171,6 +172,59 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
|
||||
}
|
||||
return comp.build_crt_file("c", .Lib, c_source_files.items);
|
||||
},
|
||||
.libc_so => {
|
||||
const sub_compilation = try Compilation.create(comp.gpa, .{
|
||||
.local_cache_directory = comp.global_cache_directory,
|
||||
.global_cache_directory = comp.global_cache_directory,
|
||||
.zig_lib_directory = comp.zig_lib_directory,
|
||||
.target = comp.getTarget(),
|
||||
.root_name = "c",
|
||||
.root_pkg = null,
|
||||
.output_mode = .Lib,
|
||||
.link_mode = .Dynamic,
|
||||
.rand = comp.rand,
|
||||
.libc_installation = comp.bin_file.options.libc_installation,
|
||||
.emit_bin = Compilation.EmitLoc{ .directory = null, .basename = "libc.so" },
|
||||
.optimize_mode = comp.bin_file.options.optimize_mode,
|
||||
.want_sanitize_c = false,
|
||||
.want_stack_check = false,
|
||||
.want_valgrind = false,
|
||||
.emit_h = null,
|
||||
.strip = comp.bin_file.options.strip,
|
||||
.is_native_os = false,
|
||||
.is_native_abi = false,
|
||||
.self_exe_path = comp.self_exe_path,
|
||||
.verbose_cc = comp.verbose_cc,
|
||||
.verbose_link = comp.bin_file.options.verbose_link,
|
||||
.verbose_tokenize = comp.verbose_tokenize,
|
||||
.verbose_ast = comp.verbose_ast,
|
||||
.verbose_ir = comp.verbose_ir,
|
||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||
.verbose_cimport = comp.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||
.c_source_files = &[_]Compilation.CSourceFile{
|
||||
.{ .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "musl", "libc.s" }) },
|
||||
},
|
||||
.is_compiler_rt_or_libc = true,
|
||||
.soname = "libc.so",
|
||||
});
|
||||
defer sub_compilation.destroy();
|
||||
|
||||
try sub_compilation.updateSubCompilation();
|
||||
|
||||
try comp.crt_files.ensureCapacity(comp.gpa, comp.crt_files.count() + 1);
|
||||
|
||||
const basename = try comp.gpa.dupe(u8, "libc.so");
|
||||
errdefer comp.gpa.free(basename);
|
||||
|
||||
comp.crt_files.putAssumeCapacityNoClobber(basename, .{
|
||||
.full_object_path = try sub_compilation.bin_file.options.emit.?.directory.join(comp.gpa, &[_][]const u8{
|
||||
sub_compilation.bin_file.options.emit.?.sub_path,
|
||||
}),
|
||||
.lock = sub_compilation.bin_file.toOwnedLock(),
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -745,8 +745,14 @@ ZigType *get_error_union_type(CodeGen *g, ZigType *err_set_type, ZigType *payloa
|
||||
return existing_entry->value;
|
||||
}
|
||||
|
||||
Error err;
|
||||
if ((err = type_resolve(g, err_set_type, ResolveStatusSizeKnown)))
|
||||
return g->builtin_types.entry_invalid;
|
||||
|
||||
if ((err = type_resolve(g, payload_type, ResolveStatusSizeKnown)))
|
||||
return g->builtin_types.entry_invalid;
|
||||
|
||||
ZigType *entry = new_type_table_entry(ZigTypeIdErrorUnion);
|
||||
assert(type_is_resolved(payload_type, ResolveStatusSizeKnown));
|
||||
|
||||
buf_resize(&entry->name, 0);
|
||||
buf_appendf(&entry->name, "%s!%s", buf_ptr(&err_set_type->name), buf_ptr(&payload_type->name));
|
||||
@@ -1453,7 +1459,12 @@ Error type_val_resolve_abi_align(CodeGen *g, AstNode *source_node, ZigValue *typ
|
||||
case LazyValueIdArrayType: {
|
||||
LazyValueArrayType *lazy_array_type =
|
||||
reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy);
|
||||
return type_val_resolve_abi_align(g, source_node, lazy_array_type->elem_type->value, abi_align);
|
||||
|
||||
if (lazy_array_type->length + (lazy_array_type->sentinel != nullptr) != 0)
|
||||
return type_val_resolve_abi_align(g, source_node, lazy_array_type->elem_type->value, abi_align);
|
||||
|
||||
*abi_align = 0;
|
||||
return ErrorNone;
|
||||
}
|
||||
case LazyValueIdErrUnionType: {
|
||||
LazyValueErrUnionType *lazy_err_union_type =
|
||||
@@ -3473,7 +3484,29 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
|
||||
union_type->abi_size = SIZE_MAX;
|
||||
union_type->size_in_bits = SIZE_MAX;
|
||||
}
|
||||
union_type->data.unionation.resolve_status = zero_bits ? ResolveStatusSizeKnown : ResolveStatusZeroBitsKnown;
|
||||
|
||||
if (zero_bits) {
|
||||
// Don't forget to resolve the types for each union member even though
|
||||
// the type is zero sized.
|
||||
// XXX: Do it in a nicer way in stage2.
|
||||
union_type->data.unionation.resolve_loop_flag_other = true;
|
||||
|
||||
for (uint32_t i = 0; i < field_count; i += 1) {
|
||||
TypeUnionField *union_field = &union_type->data.unionation.fields[i];
|
||||
ZigType *field_type = resolve_union_field_type(g, union_field);
|
||||
if (field_type == nullptr) {
|
||||
union_type->data.unionation.resolve_status = ResolveStatusInvalid;
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
}
|
||||
|
||||
union_type->data.unionation.resolve_loop_flag_other = false;
|
||||
union_type->data.unionation.resolve_status = ResolveStatusSizeKnown;
|
||||
|
||||
return ErrorNone;
|
||||
}
|
||||
|
||||
union_type->data.unionation.resolve_status = ResolveStatusZeroBitsKnown;
|
||||
|
||||
return ErrorNone;
|
||||
}
|
||||
@@ -4375,7 +4408,7 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node, bool all
|
||||
}
|
||||
}
|
||||
|
||||
Tld *find_container_decl(CodeGen *g, ScopeDecls *decls_scope, Buf *name) {
|
||||
void resolve_container_usingnamespace_decls(CodeGen *g, ScopeDecls *decls_scope) {
|
||||
// resolve all the using_namespace decls
|
||||
for (size_t i = 0; i < decls_scope->use_decls.length; i += 1) {
|
||||
TldUsingNamespace *tld_using_namespace = decls_scope->use_decls.at(i);
|
||||
@@ -4385,6 +4418,10 @@ Tld *find_container_decl(CodeGen *g, ScopeDecls *decls_scope, Buf *name) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Tld *find_container_decl(CodeGen *g, ScopeDecls *decls_scope, Buf *name) {
|
||||
resolve_container_usingnamespace_decls(g, decls_scope);
|
||||
auto entry = decls_scope->decl_table.maybe_get(name);
|
||||
return (entry == nullptr) ? nullptr : entry->value;
|
||||
}
|
||||
@@ -6017,7 +6054,7 @@ ZigValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry) {
|
||||
TypeUnionField *only_field = &union_type->data.unionation.fields[0];
|
||||
ZigType *field_type = resolve_union_field_type(g, only_field);
|
||||
assert(field_type);
|
||||
bigint_init_unsigned(&result->data.x_union.tag, 0);
|
||||
bigint_init_bigint(&result->data.x_union.tag, &only_field->enum_field->value);
|
||||
result->data.x_union.payload = g->pass1_arena->create<ZigValue>();
|
||||
copy_const_val(g, result->data.x_union.payload,
|
||||
get_the_one_possible_value(g, field_type));
|
||||
@@ -6026,6 +6063,11 @@ ZigValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry) {
|
||||
result->data.x_ptr.mut = ConstPtrMutComptimeConst;
|
||||
result->data.x_ptr.special = ConstPtrSpecialRef;
|
||||
result->data.x_ptr.data.ref.pointee = get_the_one_possible_value(g, result->type->data.pointer.child_type);
|
||||
} else if (result->type->id == ZigTypeIdEnum) {
|
||||
ZigType *enum_type = result->type;
|
||||
assert(enum_type->data.enumeration.src_field_count == 1);
|
||||
TypeEnumField *only_field = &result->type->data.enumeration.fields[0];
|
||||
bigint_init_bigint(&result->data.x_enum_tag, &only_field->value);
|
||||
}
|
||||
g->one_possible_values.put(type_entry, result);
|
||||
return result;
|
||||
@@ -7079,8 +7121,6 @@ bool const_values_equal(CodeGen *g, ZigValue *a, ZigValue *b) {
|
||||
if (bigint_cmp(&union1->tag, &union2->tag) == CmpEQ) {
|
||||
TypeUnionField *field = find_union_field_by_tag(a->type, &union1->tag);
|
||||
assert(field != nullptr);
|
||||
if (!type_has_bits(g, field->type_entry))
|
||||
return true;
|
||||
assert(find_union_field_by_tag(a->type, &union2->tag) != nullptr);
|
||||
return const_values_equal(g, union1->payload, union2->payload);
|
||||
}
|
||||
|
||||
@@ -79,6 +79,7 @@ ZigVar *find_variable(CodeGen *g, Scope *orig_context, Buf *name, ScopeFnDef **c
|
||||
Tld *find_decl(CodeGen *g, Scope *scope, Buf *name);
|
||||
Tld *find_container_decl(CodeGen *g, ScopeDecls *decls_scope, Buf *name);
|
||||
void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node, bool allow_lazy);
|
||||
void resolve_container_usingnamespace_decls(CodeGen *g, ScopeDecls *decls_scope);
|
||||
|
||||
ZigType *get_src_ptr_type(ZigType *type);
|
||||
uint32_t get_ptr_align(CodeGen *g, ZigType *type);
|
||||
|
||||
@@ -83,7 +83,7 @@ static void render_const_val_global(CodeGen *g, ZigValue *const_val, const char
|
||||
static LLVMValueRef gen_const_val(CodeGen *g, ZigValue *const_val, const char *name);
|
||||
static void generate_error_name_table(CodeGen *g);
|
||||
static bool value_is_all_undef(CodeGen *g, ZigValue *const_val);
|
||||
static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_type, LLVMValueRef ptr);
|
||||
static void gen_undef_init(CodeGen *g, ZigType *ptr_type, ZigType *value_type, LLVMValueRef ptr);
|
||||
static LLVMValueRef build_alloca(CodeGen *g, ZigType *type_entry, const char *name, uint32_t alignment);
|
||||
static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstGen *source_instr,
|
||||
LLVMValueRef target_frame_ptr, ZigType *result_type, ZigType *ptr_result_type,
|
||||
@@ -242,14 +242,24 @@ struct CalcLLVMFieldIndex {
|
||||
static void calc_llvm_field_index_add(CodeGen *g, CalcLLVMFieldIndex *calc, ZigType *ty) {
|
||||
if (!type_has_bits(g, ty)) return;
|
||||
uint32_t ty_align = get_abi_alignment(g, ty);
|
||||
|
||||
if (calc->offset % ty_align != 0) {
|
||||
uint32_t llvm_align = LLVMABIAlignmentOfType(g->target_data_ref, get_llvm_type(g, ty));
|
||||
if (llvm_align >= ty_align) {
|
||||
ty_align = llvm_align; // llvm's padding is sufficient
|
||||
} else if (calc->offset) {
|
||||
calc->field_index += 1; // zig will insert an extra padding field here
|
||||
}
|
||||
calc->offset += ty_align - (calc->offset % ty_align); // padding bytes
|
||||
|
||||
// Alignment according to Zig.
|
||||
uint32_t adj_offset = calc->offset + (ty_align - (calc->offset % ty_align));
|
||||
// Alignment according to LLVM.
|
||||
uint32_t adj_llvm_offset = (calc->offset % llvm_align) ?
|
||||
calc->offset + (llvm_align - (calc->offset % llvm_align)) :
|
||||
calc->offset;
|
||||
// Cannot under-align structure fields.
|
||||
assert(adj_offset >= adj_llvm_offset);
|
||||
|
||||
// Zig will insert an extra padding field here.
|
||||
if (adj_offset != adj_llvm_offset)
|
||||
calc->field_index += 1;
|
||||
|
||||
calc->offset = adj_offset;
|
||||
}
|
||||
calc->offset += ty->abi_size;
|
||||
calc->field_index += 1;
|
||||
@@ -380,9 +390,36 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {
|
||||
LLVMTypeRef fn_llvm_type = fn->raw_type_ref;
|
||||
LLVMValueRef llvm_fn = nullptr;
|
||||
if (fn->body_node == nullptr) {
|
||||
assert(fn->proto_node->type == NodeTypeFnProto);
|
||||
AstNodeFnProto *fn_proto = &fn->proto_node->data.fn_proto;
|
||||
|
||||
const unsigned fn_addrspace = ZigLLVMDataLayoutGetProgramAddressSpace(g->target_data_ref);
|
||||
|
||||
// The compiler tries to deduplicate extern definitions by looking up
|
||||
// their name, this was introduced to allow the declaration of the same
|
||||
// extern function with differing prototypes.
|
||||
// When Wasm is targeted this check becomes a problem as the user may
|
||||
// declare two (or more) extern functions sharing the same name but
|
||||
// imported from different modules!
|
||||
// To overcome this problem we generate a mangled identifier out of the
|
||||
// import and the function name, this name is only visible within the
|
||||
// compiler as we're telling LLVM (using 'wasm-import-name' and
|
||||
// 'wasm-import-name') what the real function name is and where to find
|
||||
// it.
|
||||
const bool use_mangled_name = target_is_wasm(g->zig_target) &&
|
||||
fn_proto->is_extern && fn_proto->lib_name != nullptr;
|
||||
// Pick a weird name to avoid collisions...
|
||||
// This whole function should be burned to the ground.
|
||||
Buf *mangled_symbol_buf = use_mangled_name ?
|
||||
buf_sprintf("%s|%s", unmangled_name, buf_ptr(fn_proto->lib_name)) :
|
||||
nullptr;
|
||||
symbol_name = use_mangled_name ?
|
||||
buf_ptr(mangled_symbol_buf) : unmangled_name;
|
||||
|
||||
LLVMValueRef existing_llvm_fn = LLVMGetNamedFunction(g->module, symbol_name);
|
||||
|
||||
if (existing_llvm_fn) {
|
||||
if (mangled_symbol_buf) buf_destroy(mangled_symbol_buf);
|
||||
return LLVMConstBitCast(existing_llvm_fn, LLVMPointerType(fn_llvm_type, fn_addrspace));
|
||||
} else {
|
||||
Buf *buf_symbol_name = buf_create_from_str(symbol_name);
|
||||
@@ -392,12 +429,9 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {
|
||||
if (entry == nullptr) {
|
||||
llvm_fn = LLVMAddFunction(g->module, symbol_name, fn_llvm_type);
|
||||
|
||||
if (target_is_wasm(g->zig_target)) {
|
||||
assert(fn->proto_node->type == NodeTypeFnProto);
|
||||
AstNodeFnProto *fn_proto = &fn->proto_node->data.fn_proto;
|
||||
if (fn_proto-> is_extern && fn_proto->lib_name != nullptr ) {
|
||||
addLLVMFnAttrStr(llvm_fn, "wasm-import-module", buf_ptr(fn_proto->lib_name));
|
||||
}
|
||||
if (use_mangled_name) {
|
||||
addLLVMFnAttrStr(llvm_fn, "wasm-import-name", unmangled_name);
|
||||
addLLVMFnAttrStr(llvm_fn, "wasm-import-module", buf_ptr(fn_proto->lib_name));
|
||||
}
|
||||
} else {
|
||||
assert(entry->value->id == TldIdFn);
|
||||
@@ -407,8 +441,11 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {
|
||||
tld_fn->fn_entry->llvm_value = LLVMAddFunction(g->module, symbol_name,
|
||||
tld_fn->fn_entry->raw_type_ref);
|
||||
llvm_fn = LLVMConstBitCast(tld_fn->fn_entry->llvm_value, LLVMPointerType(fn_llvm_type, fn_addrspace));
|
||||
if (mangled_symbol_buf) buf_destroy(mangled_symbol_buf);
|
||||
return llvm_fn;
|
||||
}
|
||||
|
||||
if (mangled_symbol_buf) buf_destroy(mangled_symbol_buf);
|
||||
}
|
||||
} else {
|
||||
if (llvm_fn == nullptr) {
|
||||
@@ -484,6 +521,12 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {
|
||||
addLLVMFnAttrInt(llvm_fn, "alignstack", fn->alignstack_value);
|
||||
}
|
||||
|
||||
if (g->build_mode == BuildModeSmallRelease) {
|
||||
// Optimize for small code size.
|
||||
addLLVMFnAttr(llvm_fn, "minsize");
|
||||
addLLVMFnAttr(llvm_fn, "optsize");
|
||||
}
|
||||
|
||||
addLLVMFnAttr(llvm_fn, "nounwind");
|
||||
add_uwtable_attr(g, llvm_fn);
|
||||
addLLVMFnAttr(llvm_fn, "nobuiltin");
|
||||
@@ -1487,7 +1530,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_runtime_safety, Z
|
||||
LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
|
||||
|
||||
LLVMPositionBuilderAtEnd(g->builder, fail_block);
|
||||
gen_safety_crash(g, actual_type->data.integral.is_signed ? PanicMsgIdCastNegativeToUnsigned : PanicMsgIdCastTruncatedData);
|
||||
gen_safety_crash(g, scalar_actual_type->data.integral.is_signed ? PanicMsgIdCastNegativeToUnsigned : PanicMsgIdCastTruncatedData);
|
||||
|
||||
LLVMPositionBuilderAtEnd(g->builder, ok_block);
|
||||
}
|
||||
@@ -3306,9 +3349,9 @@ static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, IrExecutableGen
|
||||
LLVMValueRef expr_val = ir_llvm_value(g, instruction->operand);
|
||||
LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, expr_val, indices, 2, "");
|
||||
gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
|
||||
} else if (ir_want_runtime_safety(g, &instruction->base)) {
|
||||
} else if (ir_want_runtime_safety(g, &instruction->base) && ptr_index != SIZE_MAX) {
|
||||
LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, ptr_index, "");
|
||||
gen_undef_init(g, slice_ptr_type->abi_align, slice_ptr_type, ptr_field_ptr);
|
||||
gen_undef_init(g, slice_ptr_type, slice_ptr_type, ptr_field_ptr);
|
||||
}
|
||||
|
||||
LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, len_index, "");
|
||||
@@ -3773,22 +3816,35 @@ static void gen_valgrind_undef(CodeGen *g, LLVMValueRef dest_ptr, LLVMValueRef b
|
||||
gen_valgrind_client_request(g, zero, req, ptr_as_usize, byte_count, zero, zero, zero);
|
||||
}
|
||||
|
||||
static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_type, LLVMValueRef ptr) {
|
||||
static void gen_undef_init(CodeGen *g, ZigType *ptr_type, ZigType *value_type, LLVMValueRef ptr) {
|
||||
assert(type_has_bits(g, value_type));
|
||||
|
||||
uint64_t ptr_align_bytes = get_ptr_align(g, ptr_type);
|
||||
assert(ptr_align_bytes > 0);
|
||||
uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, get_llvm_type(g, value_type));
|
||||
assert(size_bytes > 0);
|
||||
assert(ptr_align_bytes > 0);
|
||||
// memset uninitialized memory to 0xaa
|
||||
LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
|
||||
LLVMValueRef fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false);
|
||||
LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, ptr, ptr_u8, "");
|
||||
ZigType *usize = g->builtin_types.entry_usize;
|
||||
LLVMValueRef byte_count = LLVMConstInt(usize->llvm_type, size_bytes, false);
|
||||
ZigLLVMBuildMemSet(g->builder, dest_ptr, fill_char, byte_count, ptr_align_bytes, false);
|
||||
// then tell valgrind that the memory is undefined even though we just memset it
|
||||
if (g->valgrind_enabled) {
|
||||
gen_valgrind_undef(g, dest_ptr, byte_count);
|
||||
|
||||
if (ptr_type->data.pointer.host_int_bytes == 0) {
|
||||
// memset uninitialized memory to 0xaa
|
||||
LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
|
||||
LLVMValueRef fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false);
|
||||
LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, ptr, ptr_u8, "");
|
||||
ZigType *usize = g->builtin_types.entry_usize;
|
||||
LLVMValueRef byte_count = LLVMConstInt(usize->llvm_type, size_bytes, false);
|
||||
ZigLLVMBuildMemSet(g->builder, dest_ptr, fill_char, byte_count, ptr_align_bytes, false);
|
||||
// then tell valgrind that the memory is undefined even though we just memset it
|
||||
if (g->valgrind_enabled) {
|
||||
gen_valgrind_undef(g, dest_ptr, byte_count);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// This is a pointer into a packed struct, we can't use memset here.
|
||||
// The jury is still out on what pattern should be written here so clear the
|
||||
// old value and call it a day. Generating a 0xAA...AA mask for this n-bit
|
||||
// value is left as an exercise for the (bored) reader.
|
||||
LLVMValueRef zero = LLVMConstNull(get_llvm_type(g, value_type));
|
||||
gen_assign_raw(g, ptr, ptr_type, zero);
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutableGen *executable, IrInstGenStorePtr *instruction) {
|
||||
@@ -3817,7 +3873,7 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutableGen *executable,
|
||||
LLVMValueRef value = ir_llvm_value(g, instruction->value);
|
||||
gen_assign_raw(g, ptr, ptr_type, value);
|
||||
} else if (ir_want_runtime_safety(g, &instruction->base)) {
|
||||
gen_undef_init(g, get_ptr_align(g, ptr_type), instruction->value->value->type,
|
||||
gen_undef_init(g, ptr_type, instruction->value->value->type,
|
||||
ir_llvm_value(g, instruction->ptr));
|
||||
}
|
||||
return nullptr;
|
||||
@@ -3837,15 +3893,30 @@ static LLVMValueRef ir_render_vector_store_elem(CodeGen *g, IrExecutableGen *exe
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutableGen *executable, IrInstGenVarPtr *instruction) {
|
||||
if (instruction->base.value->special != ConstValSpecialRuntime)
|
||||
return ir_llvm_value(g, &instruction->base);
|
||||
ZigVar *var = instruction->var;
|
||||
if (type_has_bits(g, var->var_type)) {
|
||||
assert(var->value_ref);
|
||||
return var->value_ref;
|
||||
} else {
|
||||
Error err;
|
||||
|
||||
ZigType *ptr_type = instruction->base.value->type;
|
||||
assert(ptr_type->id == ZigTypeIdPointer);
|
||||
bool ptr_type_has_bits;
|
||||
if ((err = type_has_bits2(g, ptr_type, &ptr_type_has_bits)))
|
||||
codegen_report_errors_and_exit(g);
|
||||
|
||||
if (!ptr_type_has_bits) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// The extra bitcasts are needed in case the LLVM value is an unnamed
|
||||
// struct, as it happens when rendering container types with extra alignment
|
||||
// fields.
|
||||
if (instruction->base.value->special != ConstValSpecialRuntime) {
|
||||
return LLVMBuildBitCast(g->builder, ir_llvm_value(g, &instruction->base),
|
||||
get_llvm_type(g, ptr_type), "");
|
||||
}
|
||||
|
||||
ZigVar *var = instruction->var;
|
||||
assert(var->value_ref);
|
||||
return LLVMBuildBitCast(g->builder, var->value_ref,
|
||||
get_llvm_type(g, ptr_type), "");
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_return_ptr(CodeGen *g, IrExecutableGen *executable,
|
||||
@@ -4378,8 +4449,10 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn
|
||||
arg_calc = arg_calc_start;
|
||||
for (size_t arg_i = 0; arg_i < gen_param_values.length; arg_i += 1) {
|
||||
CalcLLVMFieldIndex prev = arg_calc;
|
||||
// Use the declared argument type and not the value one to be
|
||||
// consistent with the assignment operation below.
|
||||
calc_llvm_field_index_add(g, &arg_calc, gen_param_types.at(arg_i));
|
||||
field_types[arg_calc.field_index - 1] = LLVMTypeOf(gen_param_values.at(arg_i));
|
||||
field_types[arg_calc.field_index - 1] = get_llvm_type(g, gen_param_types.at(arg_i));
|
||||
if (arg_calc.field_index - prev.field_index > 1) {
|
||||
// Padding field
|
||||
uint32_t pad_bytes = arg_calc.offset - prev.offset - gen_param_types.at(arg_i)->abi_size;
|
||||
@@ -4793,6 +4866,29 @@ static LLVMValueRef ir_render_asm_gen(CodeGen *g, IrExecutableGen *executable, I
|
||||
}
|
||||
}
|
||||
|
||||
// Add some architecture-specific clobbers.
|
||||
const char *arch_clobbers = nullptr;
|
||||
switch (g->zig_target->arch) {
|
||||
case ZigLLVM_x86:
|
||||
case ZigLLVM_x86_64:
|
||||
arch_clobbers = "~{dirflag},~{fpsr},~{flags}";
|
||||
break;
|
||||
case ZigLLVM_mips:
|
||||
case ZigLLVM_mipsel:
|
||||
case ZigLLVM_mips64:
|
||||
case ZigLLVM_mips64el:
|
||||
arch_clobbers = "~{$1}";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (arch_clobbers != nullptr) {
|
||||
if (buf_len(&constraint_buf))
|
||||
buf_append_char(&constraint_buf, ',');
|
||||
buf_append_str(&constraint_buf, arch_clobbers);
|
||||
}
|
||||
|
||||
LLVMTypeRef ret_type;
|
||||
if (instruction->return_count == 0) {
|
||||
ret_type = LLVMVoidType();
|
||||
@@ -5088,11 +5184,7 @@ static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutableGen *executable, IrIns
|
||||
|
||||
static LLVMValueRef ir_render_err_name(CodeGen *g, IrExecutableGen *executable, IrInstGenErrName *instruction) {
|
||||
assert(g->generate_error_name_table);
|
||||
|
||||
if (g->errors_by_index.length == 1) {
|
||||
LLVMBuildUnreachable(g->builder);
|
||||
return nullptr;
|
||||
}
|
||||
assert(g->errors_by_index.length > 0);
|
||||
|
||||
LLVMValueRef err_val = ir_llvm_value(g, instruction->value);
|
||||
if (ir_want_runtime_safety(g, &instruction->base)) {
|
||||
@@ -5817,7 +5909,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrI
|
||||
if (slice_start_ptr != nullptr) {
|
||||
gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
|
||||
} else if (want_runtime_safety) {
|
||||
gen_undef_init(g, slice_ptr_type->abi_align, slice_ptr_type, ptr_field_ptr);
|
||||
gen_undef_init(g, slice_ptr_type, slice_ptr_type, ptr_field_ptr);
|
||||
} else {
|
||||
gen_store_untyped(g, LLVMGetUndef(get_llvm_type(g, slice_ptr_type)), ptr_field_ptr, 0, false);
|
||||
}
|
||||
@@ -6878,9 +6970,12 @@ static LLVMValueRef gen_parent_ptr(CodeGen *g, ZigValue *val, ConstParent *paren
|
||||
render_const_val(g, val, "");
|
||||
render_const_val_global(g, val, "");
|
||||
return val->llvm_global;
|
||||
case ConstParentIdStruct:
|
||||
return gen_const_ptr_struct_recursive(g, parent->data.p_struct.struct_val,
|
||||
parent->data.p_struct.field_index);
|
||||
case ConstParentIdStruct: {
|
||||
ZigValue *struct_val = parent->data.p_struct.struct_val;
|
||||
size_t src_field_index = parent->data.p_struct.field_index;
|
||||
size_t gen_field_index = struct_val->type->data.structure.fields[src_field_index]->gen_index;
|
||||
return gen_const_ptr_struct_recursive(g, struct_val, gen_field_index);
|
||||
}
|
||||
case ConstParentIdErrUnionCode:
|
||||
return gen_const_ptr_err_union_code_recursive(g, parent->data.p_err_union_code.err_union_val);
|
||||
case ConstParentIdErrUnionPayload:
|
||||
@@ -6934,7 +7029,14 @@ static LLVMValueRef gen_const_ptr_struct_recursive(CodeGen *g, ZigValue *struct_
|
||||
LLVMConstNull(get_llvm_type(g, u32)),
|
||||
LLVMConstInt(get_llvm_type(g, u32), field_index, false),
|
||||
};
|
||||
return LLVMConstInBoundsGEP(base_ptr, indices, 2);
|
||||
|
||||
// The structure pointed by base_ptr may include trailing padding for
|
||||
// alignment purposes and have the following LLVM type: <{ %T, [N x i8] }>.
|
||||
// Add an extra bitcast as we're only interested in the %T part.
|
||||
assert(handle_is_ptr(g, struct_const_val->type));
|
||||
LLVMValueRef casted_base_ptr = LLVMConstBitCast(base_ptr,
|
||||
LLVMPointerType(get_llvm_type(g, struct_const_val->type), 0));
|
||||
return LLVMConstInBoundsGEP(casted_base_ptr, indices, 2);
|
||||
}
|
||||
|
||||
static LLVMValueRef gen_const_ptr_err_union_code_recursive(CodeGen *g, ZigValue *err_union_const_val) {
|
||||
@@ -7764,7 +7866,7 @@ static void render_const_val_global(CodeGen *g, ZigValue *const_val, const char
|
||||
}
|
||||
|
||||
static void generate_error_name_table(CodeGen *g) {
|
||||
if (g->err_name_table != nullptr || !g->generate_error_name_table || g->errors_by_index.length == 1) {
|
||||
if (g->err_name_table != nullptr || !g->generate_error_name_table) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -8485,7 +8587,60 @@ static void define_builtin_types(CodeGen *g) {
|
||||
add_fp_entry(g, "f32", 32, LLVMFloatType(), &g->builtin_types.entry_f32);
|
||||
add_fp_entry(g, "f64", 64, LLVMDoubleType(), &g->builtin_types.entry_f64);
|
||||
add_fp_entry(g, "f128", 128, LLVMFP128Type(), &g->builtin_types.entry_f128);
|
||||
add_fp_entry(g, "c_longdouble", 80, LLVMX86FP80Type(), &g->builtin_types.entry_c_longdouble);
|
||||
|
||||
switch (g->zig_target->arch) {
|
||||
case ZigLLVM_x86:
|
||||
case ZigLLVM_x86_64:
|
||||
if (g->zig_target->abi != ZigLLVM_MSVC)
|
||||
add_fp_entry(g, "c_longdouble", 80, LLVMX86FP80Type(), &g->builtin_types.entry_c_longdouble);
|
||||
else
|
||||
add_fp_entry(g, "c_longdouble", 64, LLVMDoubleType(), &g->builtin_types.entry_c_longdouble);
|
||||
break;
|
||||
case ZigLLVM_arm:
|
||||
case ZigLLVM_armeb:
|
||||
case ZigLLVM_thumb:
|
||||
case ZigLLVM_thumbeb:
|
||||
add_fp_entry(g, "c_longdouble", 64, LLVMDoubleType(), &g->builtin_types.entry_c_longdouble);
|
||||
break;
|
||||
case ZigLLVM_aarch64:
|
||||
case ZigLLVM_aarch64_be:
|
||||
if (g->zig_target->os == OsWindows || target_os_is_darwin(g->zig_target->os))
|
||||
add_fp_entry(g, "c_longdouble", 64, LLVMDoubleType(), &g->builtin_types.entry_c_longdouble);
|
||||
else
|
||||
add_fp_entry(g, "c_longdouble", 128, LLVMFP128Type(), &g->builtin_types.entry_c_longdouble);
|
||||
break;
|
||||
case ZigLLVM_riscv32:
|
||||
case ZigLLVM_riscv64:
|
||||
add_fp_entry(g, "c_longdouble", 128, LLVMFP128Type(), &g->builtin_types.entry_c_longdouble);
|
||||
break;
|
||||
case ZigLLVM_wasm32:
|
||||
case ZigLLVM_wasm64:
|
||||
add_fp_entry(g, "c_longdouble", 128, LLVMFP128Type(), &g->builtin_types.entry_c_longdouble);
|
||||
break;
|
||||
case ZigLLVM_mips:
|
||||
case ZigLLVM_mipsel:
|
||||
// Assume o32 ABI
|
||||
add_fp_entry(g, "c_longdouble", 64, LLVMDoubleType(), &g->builtin_types.entry_c_longdouble);
|
||||
break;
|
||||
case ZigLLVM_mips64:
|
||||
case ZigLLVM_mips64el:
|
||||
add_fp_entry(g, "c_longdouble", 128, LLVMFP128Type(), &g->builtin_types.entry_c_longdouble);
|
||||
break;
|
||||
case ZigLLVM_ppc:
|
||||
case ZigLLVM_ppc64:
|
||||
case ZigLLVM_ppc64le:
|
||||
add_fp_entry(g, "c_longdouble", 128, LLVMFP128Type(), &g->builtin_types.entry_c_longdouble);
|
||||
break;
|
||||
case ZigLLVM_avr:
|
||||
// It's either a float or a double, depending on a toolchain switch
|
||||
add_fp_entry(g, "c_longdouble", 64, LLVMDoubleType(), &g->builtin_types.entry_c_longdouble);
|
||||
break;
|
||||
case ZigLLVM_msp430:
|
||||
add_fp_entry(g, "c_longdouble", 64, LLVMDoubleType(), &g->builtin_types.entry_c_longdouble);
|
||||
break;
|
||||
default:
|
||||
zig_panic("TODO implement mapping for c_longdouble");
|
||||
}
|
||||
|
||||
{
|
||||
ZigType *entry = new_type_table_entry(ZigTypeIdVoid);
|
||||
|
||||
@@ -14123,6 +14123,18 @@ static ZigType *ir_resolve_union_tag_type(IrAnalyze *ira, AstNode *source_node,
|
||||
}
|
||||
}
|
||||
|
||||
static bool can_fold_enum_type(ZigType *ty) {
|
||||
assert(ty->id == ZigTypeIdEnum);
|
||||
// We can fold the enum type (and avoid any check, be it at runtime or at
|
||||
// compile time) iff it has only a single element and its tag type is
|
||||
// zero-sized.
|
||||
ZigType *tag_int_type = ty->data.enumeration.tag_int_type;
|
||||
return ty->data.enumeration.layout == ContainerLayoutAuto &&
|
||||
ty->data.enumeration.src_field_count == 1 &&
|
||||
!ty->data.enumeration.non_exhaustive &&
|
||||
(tag_int_type->id == ZigTypeIdInt && tag_int_type->data.integral.bit_count == 0);
|
||||
}
|
||||
|
||||
static IrInstGen *ir_analyze_enum_to_int(IrAnalyze *ira, IrInst *source_instr, IrInstGen *target) {
|
||||
Error err;
|
||||
|
||||
@@ -14151,10 +14163,7 @@ static IrInstGen *ir_analyze_enum_to_int(IrAnalyze *ira, IrInst *source_instr, I
|
||||
assert(tag_type->id == ZigTypeIdInt || tag_type->id == ZigTypeIdComptimeInt);
|
||||
|
||||
// If there is only one possible tag, then we know at comptime what it is.
|
||||
if (enum_type->data.enumeration.layout == ContainerLayoutAuto &&
|
||||
enum_type->data.enumeration.src_field_count == 1 &&
|
||||
!enum_type->data.enumeration.non_exhaustive)
|
||||
{
|
||||
if (can_fold_enum_type(enum_type)) {
|
||||
IrInstGen *result = ir_const(ira, source_instr, tag_type);
|
||||
init_const_bigint(result->value, tag_type,
|
||||
&enum_type->data.enumeration.fields[0].value);
|
||||
@@ -14192,10 +14201,7 @@ static IrInstGen *ir_analyze_union_to_tag(IrAnalyze *ira, IrInst* source_instr,
|
||||
}
|
||||
|
||||
// If there is only 1 possible tag, then we know at comptime what it is.
|
||||
if (wanted_type->data.enumeration.layout == ContainerLayoutAuto &&
|
||||
wanted_type->data.enumeration.src_field_count == 1 &&
|
||||
!wanted_type->data.enumeration.non_exhaustive)
|
||||
{
|
||||
if (can_fold_enum_type(wanted_type)) {
|
||||
IrInstGen *result = ir_const(ira, source_instr, wanted_type);
|
||||
result->value->special = ConstValSpecialStatic;
|
||||
result->value->type = wanted_type;
|
||||
@@ -17778,7 +17784,7 @@ static bool is_pointer_arithmetic_allowed(ZigType *lhs_type, IrBinOp op) {
|
||||
return false;
|
||||
switch (lhs_type->data.pointer.ptr_len) {
|
||||
case PtrLenSingle:
|
||||
return lhs_type->data.pointer.child_type->id == ZigTypeIdArray;
|
||||
return false;
|
||||
case PtrLenUnknown:
|
||||
case PtrLenC:
|
||||
return true;
|
||||
@@ -23837,7 +23843,8 @@ static IrInstGen *ir_analyze_instruction_switch_target(IrAnalyze *ira,
|
||||
bigint_init_bigint(&result->value->data.x_enum_tag, &pointee_val->data.x_union.tag);
|
||||
return result;
|
||||
}
|
||||
if (tag_type->data.enumeration.src_field_count == 1 && !tag_type->data.enumeration.non_exhaustive) {
|
||||
|
||||
if (can_fold_enum_type(tag_type)) {
|
||||
IrInstGen *result = ir_const(ira, &switch_target_instruction->base.base, tag_type);
|
||||
TypeEnumField *only_field = &tag_type->data.enumeration.fields[0];
|
||||
bigint_init_bigint(&result->value->data.x_enum_tag, &only_field->value);
|
||||
@@ -23852,7 +23859,8 @@ static IrInstGen *ir_analyze_instruction_switch_target(IrAnalyze *ira,
|
||||
case ZigTypeIdEnum: {
|
||||
if ((err = type_resolve(ira->codegen, target_type, ResolveStatusZeroBitsKnown)))
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
if (target_type->data.enumeration.src_field_count == 1 && !target_type->data.enumeration.non_exhaustive) {
|
||||
|
||||
if (can_fold_enum_type(target_type)) {
|
||||
TypeEnumField *only_field = &target_type->data.enumeration.fields[0];
|
||||
IrInstGen *result = ir_const(ira, &switch_target_instruction->base.base, target_type);
|
||||
bigint_init_bigint(&result->value->data.x_enum_tag, &only_field->value);
|
||||
@@ -24587,7 +24595,9 @@ static IrInstGen *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstSrc
|
||||
if (type_is_invalid(target->value->type))
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
|
||||
if (target->value->type->id == ZigTypeIdEnumLiteral) {
|
||||
ZigType *target_type = target->value->type;
|
||||
|
||||
if (target_type->id == ZigTypeIdEnumLiteral) {
|
||||
IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr);
|
||||
Buf *field_name = target->value->data.x_enum_literal;
|
||||
ZigValue *array_val = create_const_str_lit(ira->codegen, field_name)->data.x_ptr.data.ref.pointee;
|
||||
@@ -24595,21 +24605,21 @@ static IrInstGen *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstSrc
|
||||
return result;
|
||||
}
|
||||
|
||||
if (target->value->type->id == ZigTypeIdUnion) {
|
||||
if (target_type->id == ZigTypeIdUnion) {
|
||||
target = ir_analyze_union_tag(ira, &instruction->base.base, target, instruction->base.is_gen);
|
||||
if (type_is_invalid(target->value->type))
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
target_type = target->value->type;
|
||||
}
|
||||
|
||||
if (target->value->type->id != ZigTypeIdEnum) {
|
||||
if (target_type->id != ZigTypeIdEnum) {
|
||||
ir_add_error(ira, &target->base,
|
||||
buf_sprintf("expected enum tag, found '%s'", buf_ptr(&target->value->type->name)));
|
||||
buf_sprintf("expected enum tag, found '%s'", buf_ptr(&target_type->name)));
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
}
|
||||
|
||||
if (target->value->type->data.enumeration.src_field_count == 1 &&
|
||||
!target->value->type->data.enumeration.non_exhaustive) {
|
||||
TypeEnumField *only_field = &target->value->type->data.enumeration.fields[0];
|
||||
if (can_fold_enum_type(target_type)) {
|
||||
TypeEnumField *only_field = &target_type->data.enumeration.fields[0];
|
||||
ZigValue *array_val = create_const_str_lit(ira->codegen, only_field->name)->data.x_ptr.data.ref.pointee;
|
||||
IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr);
|
||||
init_const_slice(ira->codegen, result->value, array_val, 0, buf_len(only_field->name), true);
|
||||
@@ -24617,9 +24627,9 @@ static IrInstGen *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstSrc
|
||||
}
|
||||
|
||||
if (instr_is_comptime(target)) {
|
||||
if ((err = type_resolve(ira->codegen, target->value->type, ResolveStatusZeroBitsKnown)))
|
||||
if ((err = type_resolve(ira->codegen, target_type, ResolveStatusZeroBitsKnown)))
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
TypeEnumField *field = find_enum_field_by_tag(target->value->type, &target->value->data.x_bigint);
|
||||
TypeEnumField *field = find_enum_field_by_tag(target_type, &target->value->data.x_bigint);
|
||||
if (field == nullptr) {
|
||||
Buf *int_buf = buf_alloc();
|
||||
bigint_append_buf(int_buf, &target->value->data.x_bigint, 10);
|
||||
@@ -24890,6 +24900,8 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa
|
||||
if ((err = type_resolve(ira->codegen, type_info_fn_decl_inline_type, ResolveStatusSizeKnown)))
|
||||
return err;
|
||||
|
||||
resolve_container_usingnamespace_decls(ira->codegen, decls_scope);
|
||||
|
||||
// The unresolved declarations are collected in a separate queue to avoid
|
||||
// modifying decl_table while iterating over it
|
||||
ZigList<Tld*> resolve_decl_queue{};
|
||||
@@ -25060,12 +25072,12 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa
|
||||
0, 0, 0, false);
|
||||
fn_decl_fields[5]->type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr));
|
||||
if (fn_node->is_extern && fn_node->lib_name != nullptr && buf_len(fn_node->lib_name) > 0) {
|
||||
fn_decl_fields[5]->data.x_optional = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
ZigValue *slice_val = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
ZigValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name)->data.x_ptr.data.ref.pointee;
|
||||
init_const_slice(ira->codegen, fn_decl_fields[5]->data.x_optional, lib_name, 0,
|
||||
buf_len(fn_node->lib_name), true);
|
||||
init_const_slice(ira->codegen, slice_val, lib_name, 0, buf_len(fn_node->lib_name), true);
|
||||
set_optional_payload(fn_decl_fields[5], slice_val);
|
||||
} else {
|
||||
fn_decl_fields[5]->data.x_optional = nullptr;
|
||||
set_optional_payload(fn_decl_fields[5], nullptr);
|
||||
}
|
||||
// return_type: type
|
||||
ensure_field_index(fn_decl_val->type, "return_type", 6);
|
||||
@@ -25345,8 +25357,12 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
||||
fields[1]->data.x_type = type_entry->data.array.child_type;
|
||||
// sentinel: anytype
|
||||
fields[2]->special = ConstValSpecialStatic;
|
||||
fields[2]->type = get_optional_type(ira->codegen, type_entry->data.array.child_type);
|
||||
fields[2]->data.x_optional = type_entry->data.array.sentinel;
|
||||
if (type_entry->data.array.child_type != nullptr) {
|
||||
fields[2]->type = get_optional_type(ira->codegen, type_entry->data.array.child_type);
|
||||
set_optional_payload(fields[2], type_entry->data.array.sentinel);
|
||||
} else {
|
||||
fields[2]->type = ira->codegen->builtin_types.entry_null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ZigTypeIdVector: {
|
||||
@@ -26022,6 +26038,32 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
|
||||
return ira->codegen->builtin_types.entry_bool;
|
||||
case ZigTypeIdUnreachable:
|
||||
return ira->codegen->builtin_types.entry_unreachable;
|
||||
case ZigTypeIdComptimeFloat:
|
||||
return ira->codegen->builtin_types.entry_num_lit_float;
|
||||
case ZigTypeIdComptimeInt:
|
||||
return ira->codegen->builtin_types.entry_num_lit_int;
|
||||
case ZigTypeIdUndefined:
|
||||
return ira->codegen->builtin_types.entry_undef;
|
||||
case ZigTypeIdNull:
|
||||
return ira->codegen->builtin_types.entry_null;
|
||||
case ZigTypeIdEnumLiteral:
|
||||
return ira->codegen->builtin_types.entry_enum_literal;
|
||||
default:
|
||||
if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, source_instr->source_node, payload, UndefBad)))
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
}
|
||||
switch (tagTypeId) {
|
||||
case ZigTypeIdInvalid:
|
||||
case ZigTypeIdMetaType:
|
||||
case ZigTypeIdVoid:
|
||||
case ZigTypeIdBool:
|
||||
case ZigTypeIdUnreachable:
|
||||
case ZigTypeIdComptimeFloat:
|
||||
case ZigTypeIdComptimeInt:
|
||||
case ZigTypeIdUndefined:
|
||||
case ZigTypeIdNull:
|
||||
case ZigTypeIdEnumLiteral:
|
||||
zig_unreachable();
|
||||
case ZigTypeIdInt: {
|
||||
assert(payload->special == ConstValSpecialStatic);
|
||||
assert(payload->type == ir_type_info_get_type(ira, "Int", nullptr));
|
||||
@@ -26131,14 +26173,6 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
return get_array_type(ira->codegen, elem_type, bigint_as_u64(bi), sentinel);
|
||||
}
|
||||
case ZigTypeIdComptimeFloat:
|
||||
return ira->codegen->builtin_types.entry_num_lit_float;
|
||||
case ZigTypeIdComptimeInt:
|
||||
return ira->codegen->builtin_types.entry_num_lit_int;
|
||||
case ZigTypeIdUndefined:
|
||||
return ira->codegen->builtin_types.entry_undef;
|
||||
case ZigTypeIdNull:
|
||||
return ira->codegen->builtin_types.entry_null;
|
||||
case ZigTypeIdOptional: {
|
||||
assert(payload->special == ConstValSpecialStatic);
|
||||
assert(payload->type == ir_type_info_get_type(ira, "Optional", nullptr));
|
||||
@@ -26204,8 +26238,6 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
|
||||
|
||||
return get_any_frame_type(ira->codegen, child_type);
|
||||
}
|
||||
case ZigTypeIdEnumLiteral:
|
||||
return ira->codegen->builtin_types.entry_enum_literal;
|
||||
case ZigTypeIdFnFrame: {
|
||||
assert(payload->special == ConstValSpecialStatic);
|
||||
assert(payload->type == ir_type_info_get_type(ira, "Frame", nullptr));
|
||||
@@ -26665,7 +26697,7 @@ static IrInstGen *ir_analyze_instruction_set_eval_branch_quota(IrAnalyze *ira,
|
||||
IrInstSrcSetEvalBranchQuota *instruction)
|
||||
{
|
||||
uint64_t new_quota;
|
||||
if (!ir_resolve_usize(ira, instruction->new_quota->child, &new_quota))
|
||||
if (!ir_resolve_unsigned(ira, instruction->new_quota->child, ira->codegen->builtin_types.entry_u32, &new_quota))
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
|
||||
if (new_quota > *ira->new_irb.exec->backward_branch_quota) {
|
||||
@@ -32970,8 +33002,13 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown)))
|
||||
return err;
|
||||
// Avoid resolving the type if the total length is zero.
|
||||
// Matches the logic in get_array_type and in the lazy alignment
|
||||
// resolution routine.
|
||||
if (lazy_array_type->length + (lazy_array_type->sentinel != nullptr) != 0) {
|
||||
if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown)))
|
||||
return err;
|
||||
}
|
||||
|
||||
ZigValue *sentinel_val = nullptr;
|
||||
if (lazy_array_type->sentinel != nullptr) {
|
||||
|
||||
@@ -682,19 +682,6 @@ static Error copy_open_files(FILE *src_f, FILE *dest_f) {
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(ZIG_OS_WINDOWS)
|
||||
static void windows_filetime_to_os_timestamp(FILETIME *ft, OsTimeStamp *mtime) {
|
||||
mtime->sec = (((ULONGLONG) ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
|
||||
mtime->nsec = 0;
|
||||
}
|
||||
static FILETIME windows_os_timestamp_to_filetime(OsTimeStamp mtime) {
|
||||
FILETIME result;
|
||||
result.dwHighDateTime = mtime.sec >> 32;
|
||||
result.dwLowDateTime = mtime.sec;
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
Error os_copy_file(Buf *src_path, Buf *dest_path) {
|
||||
#if defined(ZIG_OS_WINDOWS)
|
||||
PathSpace src_path_space = slice_to_prefixed_file_w(buf_to_slice(src_path));
|
||||
|
||||
@@ -10,6 +10,28 @@
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
// Every OSes seem to define endianness macros in different files.
|
||||
#if defined(__APPLE__)
|
||||
#include <machine/endian.h>
|
||||
#define ZIG_BIG_ENDIAN BIG_ENDIAN
|
||||
#define ZIG_LITTLE_ENDIAN LITTLE_ENDIAN
|
||||
#define ZIG_BYTE_ORDER BYTE_ORDER
|
||||
#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
#include <sys/endian.h>
|
||||
#define ZIG_BIG_ENDIAN _BIG_ENDIAN
|
||||
#define ZIG_LITTLE_ENDIAN _LITTLE_ENDIAN
|
||||
#define ZIG_BYTE_ORDER _BYTE_ORDER
|
||||
#elif defined(_WIN32) || defined(_WIN64)
|
||||
// Assume that Windows installations are always little endian.
|
||||
#define ZIG_LITTLE_ENDIAN 1
|
||||
#define ZIG_BYTE_ORDER ZIG_LITTLE_ENDIAN
|
||||
#else // Linux
|
||||
#include <endian.h>
|
||||
#define ZIG_BIG_ENDIAN __BIG_ENDIAN
|
||||
#define ZIG_LITTLE_ENDIAN __LITTLE_ENDIAN
|
||||
#define ZIG_BYTE_ORDER __BYTE_ORDER
|
||||
#endif
|
||||
|
||||
#define shcnt(f) ((f)->shcnt + ((f)->rpos - (f)->buf))
|
||||
#define shlim(f, lim) __shlim((f), (lim))
|
||||
#define shgetc(f) (((f)->rpos != (f)->shend) ? *(f)->rpos++ : __shgetc(f))
|
||||
@@ -47,8 +69,7 @@
|
||||
|
||||
#define DECIMAL_DIG 36
|
||||
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#if defined(ZIG_BYTE_ORDER) && ZIG_BYTE_ORDER == ZIG_LITTLE_ENDIAN
|
||||
union ldshape {
|
||||
float128_t f;
|
||||
struct {
|
||||
@@ -62,7 +83,7 @@ union ldshape {
|
||||
uint64_t hi;
|
||||
} i2;
|
||||
};
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
#elif defined(ZIG_BYTE_ORDER) && ZIG_BYTE_ORDER == ZIG_BIG_ENDIAN
|
||||
union ldshape {
|
||||
float128_t f;
|
||||
struct {
|
||||
@@ -76,6 +97,7 @@ union ldshape {
|
||||
uint64_t lo;
|
||||
} i2;
|
||||
};
|
||||
#else
|
||||
#error Unsupported endian
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1146,8 +1146,6 @@ bool target_is_libc_lib_name(const ZigTarget *target, const char *name) {
|
||||
return true;
|
||||
if (equal(name, "dl"))
|
||||
return true;
|
||||
if (equal(name, "util"))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (target_os_is_darwin(target->os) && equal(name, "System"))
|
||||
|
||||
@@ -99,6 +99,7 @@ pub fn archMuslName(arch: std.Target.Cpu.Arch) [:0]const u8 {
|
||||
.i386 => return "i386",
|
||||
.x86_64 => return "x86_64",
|
||||
.riscv64 => return "riscv64",
|
||||
.wasm32, .wasm64 => return "wasm",
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
@@ -320,8 +321,6 @@ pub fn is_libc_lib_name(target: std.Target, name: []const u8) bool {
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "dl"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "util"))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (target.os.tag.isDarwin() and eqlIgnoreCase(ignore_case, name, "System"))
|
||||
|
||||
@@ -513,6 +513,7 @@ pub const TestContext = struct {
|
||||
.keep_source_files_loaded = true,
|
||||
.object_format = ofmt,
|
||||
.is_native_os = case.target.isNativeOs(),
|
||||
.is_native_abi = case.target.isNativeAbi(),
|
||||
});
|
||||
defer comp.destroy();
|
||||
|
||||
|
||||
@@ -38,7 +38,6 @@ pub const Type = extern union {
|
||||
.c_ulong,
|
||||
.c_longlong,
|
||||
.c_ulonglong,
|
||||
.c_longdouble,
|
||||
.int_signed,
|
||||
.int_unsigned,
|
||||
=> return .Int,
|
||||
@@ -47,6 +46,7 @@ pub const Type = extern union {
|
||||
.f32,
|
||||
.f64,
|
||||
.f128,
|
||||
.c_longdouble,
|
||||
=> return .Float,
|
||||
|
||||
.c_void => return .Opaque,
|
||||
|
||||
@@ -221,6 +221,7 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
|
||||
PMBuilder->DisableUnrollLoops = is_debug;
|
||||
PMBuilder->SLPVectorize = !is_debug;
|
||||
PMBuilder->LoopVectorize = !is_debug;
|
||||
PMBuilder->LoopsInterleaved = !PMBuilder->DisableUnrollLoops;
|
||||
PMBuilder->RerollLoops = !is_debug;
|
||||
// Leaving NewGVN as default (off) because when on it caused issue #673
|
||||
//PMBuilder->NewGVN = !is_debug;
|
||||
@@ -1047,35 +1048,24 @@ bool ZigLLVMWriteArchive(const char *archive_name, const char **file_names, size
|
||||
return false;
|
||||
}
|
||||
|
||||
int ZigLLDLinkCOFF(int argc, const char **argv, bool can_exit_early) {
|
||||
std::vector<const char *> args(argv, argv + argc);
|
||||
return lld::coff::link(args, can_exit_early, llvm::outs(), llvm::errs());
|
||||
}
|
||||
|
||||
bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count,
|
||||
void (*append_diagnostic)(void *, const char *, size_t),
|
||||
void *context_stdout, void *context_stderr)
|
||||
{
|
||||
ArrayRef<const char *> array_ref_args(args, arg_count);
|
||||
int ZigLLDLinkELF(int argc, const char **argv, bool can_exit_early) {
|
||||
std::vector<const char *> args(argv, argv + argc);
|
||||
return lld::elf::link(args, can_exit_early, llvm::outs(), llvm::errs());
|
||||
}
|
||||
|
||||
MyOStream diag_stdout(append_diagnostic, context_stdout);
|
||||
MyOStream diag_stderr(append_diagnostic, context_stderr);
|
||||
int ZigLLDLinkMachO(int argc, const char **argv, bool can_exit_early) {
|
||||
std::vector<const char *> args(argv, argv + argc);
|
||||
return lld::mach_o::link(args, can_exit_early, llvm::outs(), llvm::errs());
|
||||
}
|
||||
|
||||
switch (oformat) {
|
||||
case ZigLLVM_UnknownObjectFormat:
|
||||
case ZigLLVM_XCOFF:
|
||||
assert(false); // unreachable
|
||||
|
||||
case ZigLLVM_COFF:
|
||||
return lld::coff::link(array_ref_args, false, diag_stdout, diag_stderr);
|
||||
|
||||
case ZigLLVM_ELF:
|
||||
return lld::elf::link(array_ref_args, false, diag_stdout, diag_stderr);
|
||||
|
||||
case ZigLLVM_MachO:
|
||||
return lld::mach_o::link(array_ref_args, false, diag_stdout, diag_stderr);
|
||||
|
||||
case ZigLLVM_Wasm:
|
||||
return lld::wasm::link(array_ref_args, false, diag_stdout, diag_stderr);
|
||||
}
|
||||
assert(false); // unreachable
|
||||
abort();
|
||||
int ZigLLDLinkWasm(int argc, const char **argv, bool can_exit_early) {
|
||||
std::vector<const char *> args(argv, argv + argc);
|
||||
return lld::wasm::link(args, can_exit_early, llvm::outs(), llvm::errs());
|
||||
}
|
||||
|
||||
static AtomicRMWInst::BinOp toLLVMRMWBinOp(enum ZigLLVM_AtomicRMWBinOp BinOp) {
|
||||
|
||||
@@ -505,9 +505,10 @@ ZIG_EXTERN_C const char *ZigLLVMGetVendorTypeName(enum ZigLLVM_VendorType vendor
|
||||
ZIG_EXTERN_C const char *ZigLLVMGetOSTypeName(enum ZigLLVM_OSType os);
|
||||
ZIG_EXTERN_C const char *ZigLLVMGetEnvironmentTypeName(enum ZigLLVM_EnvironmentType abi);
|
||||
|
||||
ZIG_EXTERN_C bool ZigLLDLink(enum ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count,
|
||||
void (*append_diagnostic)(void *, const char *, size_t),
|
||||
void *context_stdout, void *context_stderr);
|
||||
ZIG_EXTERN_C int ZigLLDLinkCOFF(int argc, const char **argv, bool can_exit_early);
|
||||
ZIG_EXTERN_C int ZigLLDLinkELF(int argc, const char **argv, bool can_exit_early);
|
||||
ZIG_EXTERN_C int ZigLLDLinkMachO(int argc, const char **argv, bool can_exit_early);
|
||||
ZIG_EXTERN_C int ZigLLDLinkWasm(int argc, const char **argv, bool can_exit_early);
|
||||
|
||||
ZIG_EXTERN_C bool ZigLLVMWriteArchive(const char *archive_name, const char **file_names, size_t file_name_count,
|
||||
enum ZigLLVM_OSType os_type);
|
||||
|
||||
@@ -92,13 +92,13 @@ fn exec(cwd: []const u8, expect_0: bool, argv: []const []const u8) !ChildProcess
|
||||
fn testZigInitLib(zig_exe: []const u8, dir_path: []const u8) !void {
|
||||
_ = try exec(dir_path, true, &[_][]const u8{ zig_exe, "init-lib" });
|
||||
const test_result = try exec(dir_path, true, &[_][]const u8{ zig_exe, "build", "test" });
|
||||
testing.expect(std.mem.endsWith(u8, test_result.stderr, "All 1 tests passed.\n"));
|
||||
testing.expectStringEndsWith(test_result.stderr, "All 1 tests passed.\n");
|
||||
}
|
||||
|
||||
fn testZigInitExe(zig_exe: []const u8, dir_path: []const u8) !void {
|
||||
_ = try exec(dir_path, true, &[_][]const u8{ zig_exe, "init-exe" });
|
||||
const run_result = try exec(dir_path, true, &[_][]const u8{ zig_exe, "build", "run" });
|
||||
testing.expect(std.mem.eql(u8, run_result.stderr, "info: All your codebase are belong to us.\n"));
|
||||
testing.expectEqualStrings("info: All your codebase are belong to us.\n", run_result.stderr);
|
||||
}
|
||||
|
||||
fn testGodboltApi(zig_exe: []const u8, dir_path: []const u8) anyerror!void {
|
||||
|
||||
@@ -2,6 +2,25 @@ const tests = @import("tests.zig");
|
||||
const std = @import("std");
|
||||
|
||||
pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
cases.add("pointer arithmetic on pointer-to-array",
|
||||
\\export fn foo() void {
|
||||
\\ var x: [10]u8 = undefined;
|
||||
\\ var y = &x;
|
||||
\\ var z = y + 1;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
"tmp.zig:4:17: error: integer value 1 cannot be coerced to type '*[10]u8'",
|
||||
});
|
||||
|
||||
cases.add("@Type() union payload is undefined",
|
||||
\\const Foo = @Type(@import("std").builtin.TypeInfo{
|
||||
\\ .Struct = undefined,
|
||||
\\});
|
||||
\\comptime { _ = Foo; }
|
||||
, &[_][]const u8{
|
||||
"tmp.zig:1:50: error: use of undefined value here causes undefined behavior",
|
||||
});
|
||||
|
||||
cases.add("union with too small explicit signed tag type",
|
||||
\\const U = union(enum(i2)) {
|
||||
\\ A: u8,
|
||||
|
||||
@@ -1,6 +1,85 @@
|
||||
const tests = @import("tests.zig");
|
||||
|
||||
pub fn addCases(cases: *tests.CompareOutputContext) void {
|
||||
{
|
||||
const check_panic_msg =
|
||||
\\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
|
||||
\\ if (std.mem.eql(u8, message, "reached unreachable code")) {
|
||||
\\ std.process.exit(126); // good
|
||||
\\ }
|
||||
\\ std.process.exit(0); // test failed
|
||||
\\}
|
||||
;
|
||||
|
||||
cases.addRuntimeSafety("switch on corrupted enum value",
|
||||
\\const std = @import("std");
|
||||
++ check_panic_msg ++
|
||||
\\const E = enum(u32) {
|
||||
\\ X = 1,
|
||||
\\};
|
||||
\\pub fn main() void {
|
||||
\\ var e: E = undefined;
|
||||
\\ @memset(@ptrCast([*]u8, &e), 0x55, @sizeOf(E));
|
||||
\\ switch (e) {
|
||||
\\ .X => @breakpoint(),
|
||||
\\ }
|
||||
\\}
|
||||
);
|
||||
|
||||
cases.addRuntimeSafety("switch on corrupted union value",
|
||||
\\const std = @import("std");
|
||||
++ check_panic_msg ++
|
||||
\\const U = union(enum(u32)) {
|
||||
\\ X: u8,
|
||||
\\};
|
||||
\\pub fn main() void {
|
||||
\\ var u: U = undefined;
|
||||
\\ @memset(@ptrCast([*]u8, &u), 0x55, @sizeOf(U));
|
||||
\\ switch (u) {
|
||||
\\ .X => @breakpoint(),
|
||||
\\ }
|
||||
\\}
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
const check_panic_msg =
|
||||
\\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
|
||||
\\ if (std.mem.eql(u8, message, "invalid enum value")) {
|
||||
\\ std.process.exit(126); // good
|
||||
\\ }
|
||||
\\ std.process.exit(0); // test failed
|
||||
\\}
|
||||
;
|
||||
|
||||
cases.addRuntimeSafety("@tagName on corrupted enum value",
|
||||
\\const std = @import("std");
|
||||
++ check_panic_msg ++
|
||||
\\const E = enum(u32) {
|
||||
\\ X = 1,
|
||||
\\};
|
||||
\\pub fn main() void {
|
||||
\\ var e: E = undefined;
|
||||
\\ @memset(@ptrCast([*]u8, &e), 0x55, @sizeOf(E));
|
||||
\\ var n = @tagName(e);
|
||||
\\}
|
||||
);
|
||||
|
||||
cases.addRuntimeSafety("@tagName on corrupted union value",
|
||||
\\const std = @import("std");
|
||||
++ check_panic_msg ++
|
||||
\\const U = union(enum(u32)) {
|
||||
\\ X: u8,
|
||||
\\};
|
||||
\\pub fn main() void {
|
||||
\\ var u: U = undefined;
|
||||
\\ @memset(@ptrCast([*]u8, &u), 0x55, @sizeOf(U));
|
||||
\\ var t: @TagType(U) = u;
|
||||
\\ var n = @tagName(t);
|
||||
\\}
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
const check_panic_msg =
|
||||
\\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
|
||||
@@ -89,7 +168,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
|
||||
\\const std = @import("std");
|
||||
\\const V = @import("std").meta.Vector;
|
||||
\\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
|
||||
\\ if (std.mem.eql(u8, message, "attempt to cast negative value to unsigned integer")) {
|
||||
\\ if (std.mem.eql(u8, message, "integer cast truncated bits")) {
|
||||
\\ std.process.exit(126); // good
|
||||
\\ }
|
||||
\\ std.process.exit(0); // test failed
|
||||
@@ -100,6 +179,21 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
|
||||
\\}
|
||||
);
|
||||
|
||||
cases.addRuntimeSafety("signed-unsigned vector cast",
|
||||
\\const std = @import("std");
|
||||
\\const V = @import("std").meta.Vector;
|
||||
\\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
|
||||
\\ if (std.mem.eql(u8, message, "attempt to cast negative value to unsigned integer")) {
|
||||
\\ std.process.exit(126); // good
|
||||
\\ }
|
||||
\\ std.process.exit(0); // test failed
|
||||
\\}
|
||||
\\pub fn main() void {
|
||||
\\ var x = @splat(4, @as(i32, -2147483647));
|
||||
\\ var y = @intCast(V(4, u32), x);
|
||||
\\}
|
||||
);
|
||||
|
||||
cases.addRuntimeSafety("shift left by huge amount",
|
||||
\\const std = @import("std");
|
||||
\\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
|
||||
|
||||
@@ -13,6 +13,7 @@ pub const RunTranslatedCContext = struct {
|
||||
step: *build.Step,
|
||||
test_index: usize,
|
||||
test_filter: ?[]const u8,
|
||||
target: std.zig.CrossTarget,
|
||||
|
||||
const TestCase = struct {
|
||||
name: []const u8,
|
||||
@@ -93,6 +94,7 @@ pub const RunTranslatedCContext = struct {
|
||||
});
|
||||
translate_c.step.name = b.fmt("{} translate-c", .{annotated_case_name});
|
||||
const exe = translate_c.addExecutable();
|
||||
exe.setTarget(self.target);
|
||||
exe.step.name = b.fmt("{} build-exe", .{annotated_case_name});
|
||||
exe.linkLibC();
|
||||
const run = exe.run();
|
||||
|
||||
@@ -50,12 +50,17 @@ comptime {
|
||||
_ = @import("behavior/bugs/4769_b.zig");
|
||||
_ = @import("behavior/bugs/4769_c.zig");
|
||||
_ = @import("behavior/bugs/4954.zig");
|
||||
_ = @import("behavior/bugs/5398.zig");
|
||||
_ = @import("behavior/bugs/5413.zig");
|
||||
_ = @import("behavior/bugs/5474.zig");
|
||||
_ = @import("behavior/bugs/5487.zig");
|
||||
_ = @import("behavior/bugs/6456.zig");
|
||||
_ = @import("behavior/bugs/6781.zig");
|
||||
_ = @import("behavior/bugs/6850.zig");
|
||||
_ = @import("behavior/bugs/7027.zig");
|
||||
_ = @import("behavior/bugs/7047.zig");
|
||||
_ = @import("behavior/bugs/7003.zig");
|
||||
_ = @import("behavior/bugs/7250.zig");
|
||||
_ = @import("behavior/bugs/394.zig");
|
||||
_ = @import("behavior/bugs/421.zig");
|
||||
_ = @import("behavior/bugs/529.zig");
|
||||
|
||||
@@ -413,3 +413,21 @@ test "sentinel element count towards the ABI size calculation" {
|
||||
S.doTheTest();
|
||||
comptime S.doTheTest();
|
||||
}
|
||||
|
||||
test "zero-sized array with recursive type definition" {
|
||||
const U = struct {
|
||||
fn foo(comptime T: type, comptime n: usize) type {
|
||||
return struct {
|
||||
s: [n]T,
|
||||
x: usize = n,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const S = struct {
|
||||
list: U.foo(@This(), 0),
|
||||
};
|
||||
|
||||
var t: S = .{ .list = .{ .s = undefined } };
|
||||
expectEqual(@as(usize, 0), t.list.x);
|
||||
}
|
||||
|
||||
@@ -1559,3 +1559,52 @@ test "avoid forcing frame alignment resolution implicit cast to *c_void" {
|
||||
resume @ptrCast(anyframe->bool, @alignCast(@alignOf(@Frame(S.foo)), S.x));
|
||||
expect(nosuspend await frame);
|
||||
}
|
||||
|
||||
test "@asyncCall with pass-by-value arguments" {
|
||||
const F0: u64 = 0xbeefbeefbeefbeef;
|
||||
const F1: u64 = 0xf00df00df00df00d;
|
||||
const F2: u64 = 0xcafecafecafecafe;
|
||||
|
||||
const S = struct {
|
||||
pub const ST = struct { f0: usize, f1: usize };
|
||||
pub const AT = [5]u8;
|
||||
|
||||
pub fn f(_fill0: u64, s: ST, _fill1: u64, a: AT, _fill2: u64) callconv(.Async) void {
|
||||
// Check that the array and struct arguments passed by value don't
|
||||
// end up overflowing the adjacent fields in the frame structure.
|
||||
expectEqual(F0, _fill0);
|
||||
expectEqual(F1, _fill1);
|
||||
expectEqual(F2, _fill2);
|
||||
}
|
||||
};
|
||||
|
||||
var buffer: [1024]u8 align(@alignOf(@Frame(S.f))) = undefined;
|
||||
// The function pointer must not be comptime-known.
|
||||
var t = S.f;
|
||||
var frame_ptr = @asyncCall(&buffer, {}, t, .{
|
||||
F0,
|
||||
.{ .f0 = 1, .f1 = 2 },
|
||||
F1,
|
||||
[_]u8{ 1, 2, 3, 4, 5 },
|
||||
F2,
|
||||
});
|
||||
}
|
||||
|
||||
test "@asyncCall with arguments having non-standard alignment" {
|
||||
const F0: u64 = 0xbeefbeef;
|
||||
const F1: u64 = 0xf00df00df00df00d;
|
||||
|
||||
const S = struct {
|
||||
pub fn f(_fill0: u32, s: struct { x: u64 align(16) }, _fill1: u64) callconv(.Async) void {
|
||||
// The compiler inserts extra alignment for s, check that the
|
||||
// generated code picks the right slot for fill1.
|
||||
expectEqual(F0, _fill0);
|
||||
expectEqual(F1, _fill1);
|
||||
}
|
||||
};
|
||||
|
||||
var buffer: [1024]u8 align(@alignOf(@Frame(S.f))) = undefined;
|
||||
// The function pointer must not be comptime-known.
|
||||
var t = S.f;
|
||||
var frame_ptr = @asyncCall(&buffer, {}, t, .{ F0, undefined, F1 });
|
||||
}
|
||||
|
||||
31
test/stage1/behavior/bugs/5398.zig
Normal file
31
test/stage1/behavior/bugs/5398.zig
Normal file
@@ -0,0 +1,31 @@
|
||||
const std = @import("std");
|
||||
const testing = std.testing;
|
||||
|
||||
pub const Mesh = struct {
|
||||
id: u32,
|
||||
};
|
||||
pub const Material = struct {
|
||||
transparent: bool = true,
|
||||
emits_shadows: bool = true,
|
||||
render_color: bool = true,
|
||||
};
|
||||
pub const Renderable = struct {
|
||||
material: Material,
|
||||
// The compiler inserts some padding here to ensure Mesh is correctly aligned.
|
||||
mesh: Mesh,
|
||||
};
|
||||
|
||||
var renderable: Renderable = undefined;
|
||||
|
||||
test "assignment of field with padding" {
|
||||
renderable = Renderable{
|
||||
.mesh = Mesh{ .id = 0 },
|
||||
.material = Material{
|
||||
.transparent = false,
|
||||
.emits_shadows = false,
|
||||
},
|
||||
};
|
||||
testing.expectEqual(false, renderable.material.transparent);
|
||||
testing.expectEqual(false, renderable.material.emits_shadows);
|
||||
testing.expectEqual(true, renderable.material.render_color);
|
||||
}
|
||||
8
test/stage1/behavior/bugs/7003.zig
Normal file
8
test/stage1/behavior/bugs/7003.zig
Normal file
@@ -0,0 +1,8 @@
|
||||
test "@Type should resolve its children types" {
|
||||
const sparse = enum(u2) { a, b, c };
|
||||
const dense = enum(u2) { a, b, c, d };
|
||||
|
||||
comptime var sparse_info = @typeInfo(anyerror!sparse);
|
||||
sparse_info.ErrorUnion.payload = dense;
|
||||
const B = @Type(sparse_info);
|
||||
}
|
||||
17
test/stage1/behavior/bugs/7027.zig
Normal file
17
test/stage1/behavior/bugs/7027.zig
Normal file
@@ -0,0 +1,17 @@
|
||||
const Foobar = struct {
|
||||
myTypes: [128]type,
|
||||
str: [1024]u8,
|
||||
|
||||
fn foo() @This() {
|
||||
comptime var foobar: Foobar = undefined;
|
||||
foobar.str = [_]u8{'a'} ** 1024;
|
||||
return foobar;
|
||||
}
|
||||
};
|
||||
|
||||
fn foo(arg: anytype) void {}
|
||||
|
||||
test "" {
|
||||
comptime var foobar = Foobar.foo();
|
||||
foo(foobar.str[0..10]);
|
||||
}
|
||||
22
test/stage1/behavior/bugs/7047.zig
Normal file
22
test/stage1/behavior/bugs/7047.zig
Normal file
@@ -0,0 +1,22 @@
|
||||
const std = @import("std");
|
||||
|
||||
const U = union(enum) {
|
||||
T: type,
|
||||
N: void,
|
||||
};
|
||||
|
||||
fn S(comptime query: U) type {
|
||||
return struct {
|
||||
fn tag() type {
|
||||
return query.T;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
test "compiler doesn't consider equal unions with different 'type' payload" {
|
||||
const s1 = S(U{ .T = u32 }).tag();
|
||||
std.testing.expectEqual(u32, s1);
|
||||
|
||||
const s2 = S(U{ .T = u64 }).tag();
|
||||
std.testing.expectEqual(u64, s2);
|
||||
}
|
||||
15
test/stage1/behavior/bugs/7250.zig
Normal file
15
test/stage1/behavior/bugs/7250.zig
Normal file
@@ -0,0 +1,15 @@
|
||||
const nrfx_uart_t = extern struct {
|
||||
p_reg: [*c]u32,
|
||||
drv_inst_idx: u8,
|
||||
};
|
||||
|
||||
pub fn nrfx_uart_rx(p_instance: [*c]const nrfx_uart_t) void {}
|
||||
|
||||
threadlocal var g_uart0 = nrfx_uart_t{
|
||||
.p_reg = 0,
|
||||
.drv_inst_idx = 0,
|
||||
};
|
||||
|
||||
test "reference a global threadlocal variable" {
|
||||
_ = nrfx_uart_rx(&g_uart0);
|
||||
}
|
||||
@@ -908,3 +908,9 @@ test "cast from ?[*]T to ??[*]T" {
|
||||
const a: ??[*]u8 = @as(?[*]u8, null);
|
||||
expect(a != null and a.? == null);
|
||||
}
|
||||
|
||||
test "cast between *[N]void and []void" {
|
||||
var a: [4]void = undefined;
|
||||
var b: []void = &a;
|
||||
expect(b.len == 4);
|
||||
}
|
||||
|
||||
@@ -884,3 +884,28 @@ test "type coercion of anon struct literal to struct" {
|
||||
S.doTheTest();
|
||||
comptime S.doTheTest();
|
||||
}
|
||||
|
||||
test "packed struct with undefined initializers" {
|
||||
const S = struct {
|
||||
const P = packed struct {
|
||||
a: u3,
|
||||
_a: u3 = undefined,
|
||||
b: u3,
|
||||
_b: u3 = undefined,
|
||||
c: u3,
|
||||
_c: u3 = undefined,
|
||||
};
|
||||
|
||||
fn doTheTest() void {
|
||||
var p: P = undefined;
|
||||
p = P{ .a = 2, .b = 4, .c = 6 };
|
||||
// Make sure the compiler doesn't touch the unprefixed fields.
|
||||
expectEqual(@as(u3, 2), p.a);
|
||||
expectEqual(@as(u3, 4), p.b);
|
||||
expectEqual(@as(u3, 6), p.c);
|
||||
}
|
||||
};
|
||||
|
||||
S.doTheTest();
|
||||
comptime S.doTheTest();
|
||||
}
|
||||
|
||||
@@ -82,9 +82,6 @@ fn testNullTerminatedPtr() void {
|
||||
expect(ptr_info.Pointer.sentinel.? == 0);
|
||||
|
||||
expect(@typeInfo([:0]u8).Pointer.sentinel != null);
|
||||
expect(@typeInfo([10:0]u8).Array.sentinel != null);
|
||||
expect(@typeInfo([10:0]u8).Array.len == 10);
|
||||
expect(@sizeOf([10:0]u8) == 11);
|
||||
}
|
||||
|
||||
test "type info: C pointer type info" {
|
||||
@@ -123,10 +120,21 @@ test "type info: array type info" {
|
||||
}
|
||||
|
||||
fn testArray() void {
|
||||
const arr_info = @typeInfo([42]bool);
|
||||
expect(arr_info == .Array);
|
||||
expect(arr_info.Array.len == 42);
|
||||
expect(arr_info.Array.child == bool);
|
||||
{
|
||||
const info = @typeInfo([42]u8);
|
||||
expect(info == .Array);
|
||||
expect(info.Array.len == 42);
|
||||
expect(info.Array.child == u8);
|
||||
expect(info.Array.sentinel == null);
|
||||
}
|
||||
|
||||
{
|
||||
const info = @typeInfo([10:0]u8);
|
||||
expect(info.Array.len == 10);
|
||||
expect(info.Array.child == u8);
|
||||
expect(info.Array.sentinel.? == @as(u8, 0));
|
||||
expect(@sizeOf([10:0]u8) == info.Array.len + 1);
|
||||
}
|
||||
}
|
||||
|
||||
test "type info: optional type info" {
|
||||
@@ -460,3 +468,17 @@ test "StructField.is_comptime" {
|
||||
expect(!info.fields[0].is_comptime);
|
||||
expect(info.fields[1].is_comptime);
|
||||
}
|
||||
|
||||
test "typeInfo resolves usingnamespace declarations" {
|
||||
const A = struct {
|
||||
pub const f1 = 42;
|
||||
};
|
||||
|
||||
const B = struct {
|
||||
const f0 = 42;
|
||||
usingnamespace A;
|
||||
};
|
||||
|
||||
expect(@typeInfo(B).Struct.decls.len == 2);
|
||||
//a
|
||||
}
|
||||
|
||||
@@ -15,10 +15,12 @@ pub fn addCases(cases: *tests.StandaloneContext) void {
|
||||
cases.addBuildFile("test/standalone/static_c_lib/build.zig");
|
||||
cases.addBuildFile("test/standalone/issue_339/build.zig");
|
||||
cases.addBuildFile("test/standalone/issue_794/build.zig");
|
||||
cases.addBuildFile("test/standalone/issue_5825/build.zig");
|
||||
cases.addBuildFile("test/standalone/pkg_import/build.zig");
|
||||
cases.addBuildFile("test/standalone/use_alias/build.zig");
|
||||
cases.addBuildFile("test/standalone/brace_expansion/build.zig");
|
||||
cases.addBuildFile("test/standalone/empty_env/build.zig");
|
||||
cases.addBuildFile("test/standalone/issue_7030/build.zig");
|
||||
if (std.Target.current.os.tag != .wasi) {
|
||||
cases.addBuildFile("test/standalone/load_dynamic_library/build.zig");
|
||||
}
|
||||
|
||||
@@ -3,37 +3,40 @@ const io = std.io;
|
||||
const process = std.process;
|
||||
const fs = std.fs;
|
||||
const mem = std.mem;
|
||||
const warn = std.debug.warn;
|
||||
const allocator = std.testing.allocator;
|
||||
const warn = std.log.warn;
|
||||
|
||||
pub fn main() !void {
|
||||
var args_it = process.args();
|
||||
const exe = try unwrapArg(args_it.next(allocator).?);
|
||||
var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||
defer arena_instance.deinit();
|
||||
const arena = &arena_instance.allocator;
|
||||
|
||||
const args = try process.argsAlloc(arena);
|
||||
|
||||
const exe = args[0];
|
||||
var catted_anything = false;
|
||||
const stdout_file = io.getStdOut();
|
||||
|
||||
const cwd = fs.cwd();
|
||||
|
||||
while (args_it.next(allocator)) |arg_or_err| {
|
||||
const arg = try unwrapArg(arg_or_err);
|
||||
for (args[1..]) |arg| {
|
||||
if (mem.eql(u8, arg, "-")) {
|
||||
catted_anything = true;
|
||||
try cat_file(stdout_file, io.getStdIn());
|
||||
} else if (arg[0] == '-') {
|
||||
try stdout_file.writeFileAll(io.getStdIn(), .{});
|
||||
} else if (mem.startsWith(u8, arg, "-")) {
|
||||
return usage(exe);
|
||||
} else {
|
||||
const file = cwd.openFile(arg, .{}) catch |err| {
|
||||
warn("Unable to open file: {}\n", .{@errorName(err)});
|
||||
warn("Unable to open file: {s}\n", .{@errorName(err)});
|
||||
return err;
|
||||
};
|
||||
defer file.close();
|
||||
|
||||
catted_anything = true;
|
||||
try cat_file(stdout_file, file);
|
||||
try stdout_file.writeFileAll(file, .{});
|
||||
}
|
||||
}
|
||||
if (!catted_anything) {
|
||||
try cat_file(stdout_file, io.getStdIn());
|
||||
try stdout_file.writeFileAll(io.getStdIn(), .{});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,31 +44,3 @@ fn usage(exe: []const u8) !void {
|
||||
warn("Usage: {} [FILE]...\n", .{exe});
|
||||
return error.Invalid;
|
||||
}
|
||||
|
||||
// TODO use copy_file_range
|
||||
fn cat_file(stdout: fs.File, file: fs.File) !void {
|
||||
var buf: [1024 * 4]u8 = undefined;
|
||||
|
||||
while (true) {
|
||||
const bytes_read = file.read(buf[0..]) catch |err| {
|
||||
warn("Unable to read from stream: {}\n", .{@errorName(err)});
|
||||
return err;
|
||||
};
|
||||
|
||||
if (bytes_read == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
stdout.writeAll(buf[0..bytes_read]) catch |err| {
|
||||
warn("Unable to write to stdout: {}\n", .{@errorName(err)});
|
||||
return err;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn unwrapArg(arg: anyerror![]u8) ![]u8 {
|
||||
return arg catch |err| {
|
||||
warn("Unable to parse command line: {}\n", .{err});
|
||||
return err;
|
||||
};
|
||||
}
|
||||
|
||||
24
test/standalone/issue_5825/build.zig
Normal file
24
test/standalone/issue_5825/build.zig
Normal file
@@ -0,0 +1,24 @@
|
||||
const Builder = @import("std").build.Builder;
|
||||
|
||||
pub fn build(b: *Builder) void {
|
||||
const target = .{
|
||||
.cpu_arch = .x86_64,
|
||||
.os_tag = .windows,
|
||||
.abi = .msvc,
|
||||
};
|
||||
const mode = b.standardReleaseOptions();
|
||||
const obj = b.addObject("issue_5825", "main.zig");
|
||||
obj.setTarget(target);
|
||||
obj.setBuildMode(mode);
|
||||
|
||||
const exe = b.addExecutable("issue_5825", null);
|
||||
exe.subsystem = .Console;
|
||||
exe.linkSystemLibrary("kernel32");
|
||||
exe.linkSystemLibrary("ntdll");
|
||||
exe.setTarget(target);
|
||||
exe.setBuildMode(mode);
|
||||
exe.addObject(obj);
|
||||
|
||||
const test_step = b.step("test", "Test the program");
|
||||
test_step.dependOn(&exe.step);
|
||||
}
|
||||
5
test/standalone/issue_5825/main.zig
Normal file
5
test/standalone/issue_5825/main.zig
Normal file
@@ -0,0 +1,5 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
std.log.info("All your codebase are belong to us.", .{});
|
||||
}
|
||||
14
test/standalone/issue_7030/build.zig
Normal file
14
test/standalone/issue_7030/build.zig
Normal file
@@ -0,0 +1,14 @@
|
||||
const Builder = @import("std").build.Builder;
|
||||
|
||||
pub fn build(b: *Builder) void {
|
||||
const exe = b.addExecutable("issue_7030", "main.zig");
|
||||
exe.setTarget(.{
|
||||
.cpu_arch = .wasm32,
|
||||
.os_tag = .freestanding,
|
||||
});
|
||||
exe.install();
|
||||
b.default_step.dependOn(&exe.step);
|
||||
|
||||
const test_step = b.step("test", "Test the program");
|
||||
test_step.dependOn(&exe.step);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user