99 Commits
0.9.1 ... 0.8.1

Author SHA1 Message Date
Andrew Kelley
12828c09d6 Release 0.8.1 2021-09-06 19:41:54 -07:00
Sebastian Ullrich
c72f584218 libunwind: fix unwinding through libunwind stack frames
Fixes #9591
2021-09-03 10:19:01 -07:00
Andrew Kelley
3617615e2d CI: update Linux and macOS tarballs to LLVM 12.0.1 2021-09-03 10:18:53 -07:00
Philip Åkesson
b3a4074358 std: Use truncating cast in WIFSTOPPED for Linux, FreeBSD and DragonFly
The intermediate value can be larger than an u16, so @truncate is needed
to match the behavior of musl.
2021-09-03 10:18:28 -07:00
Andrew Kelley
46f93807aa fix merge conflicts for this branch 2021-09-01 17:01:35 -07:00
Philipp Lühmann
5356151172 fix typo 2021-08-31 13:45:04 -07:00
Andrew Kelley
f7e08ea780 re-enable all the MIPS tests
LLVM 12.0.1 fixed the regressions from LLVM 12.0.0.

Closes #8155
2021-08-31 13:44:57 -07:00
Frank Denis
a1d532752f Don't define valgrind_support on macOS (#9612)
Unfortunately, Valgrind for macOS has been broken for years,
and the Homebrew formula is only for Linux.
2021-08-31 13:44:23 -07:00
Zach Banks
2588451967 std/ArrayList: Allow ArrayList(u0) to be created
Enable creating ArrayList with zero-sized types.
This type still tracks length, but does not allocate
additional memory.
2021-08-31 13:41:05 -07:00
Meghan Denny
551971b5c3 stage1: add c_longdouble mapping for s390x 2021-08-31 13:40:01 -07:00
Takeshi Yoneda
5d08e2b5d8 Wasm,libc: fix wasm-ld failure in matching libc symbols.
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2021-08-31 13:39:15 -07:00
fn ⌃ ⌥
d38bd443ef Use -isysroot on Mojave too 2021-08-31 13:38:52 -07:00
David May
c9ab6baf06 Docs fix array/pointer/slice type coercion section (#9392)
* removed deprecated coercion: [X]T => [] const T

* Fixed tests and added desc for first test

* Improved heading
2021-08-31 13:35:24 -07:00
Alex Rønne Petersen
a45c0c5033 zig: -rdynamic now implies -fdll-export-fns unless the latter is explicitly set.
Fixes #9340.
2021-08-31 13:32:27 -07:00
Michal Ziulek
7b9612a922 Fixed compile error: 'bMenu' needs to casted. (#9426) 2021-08-31 13:31:41 -07:00
Biolunar
1cddcf4484 linux stdlib: fix definition of RW flags (#9428) 2021-08-31 13:31:27 -07:00
Frank Denis
b8a77f3d59 std.crypto: handle the top bit in 25519.field.fromBytes64() (#9435)
The only known use case for this is the hash-to-curve operation where the top bit is always cleared.

But the function is public, so let's make it work as one would expect in the general case.

Also fix the comment by the way.
2021-08-31 13:31:06 -07:00
Tau
d4e22e3eb6 Correct hasUniqueRepresentation for vectors
Closes #9333.
2021-07-21 12:30:56 -07:00
Andrew Kelley
d99f55b7cf std.ArrayList: add missing assertion in appendSliceAssumeCapacity 2021-07-21 12:30:37 -07:00
Isaac Freund
2561b1eb67 langref: remove incorrect statement on c_void
c_void is *not* simply `const c_void = opaque{};`. It has unique
semantics as any pointer type may coerce to `*c_void` which is not true
for an arbitrary `*opaque{}`.
2021-07-21 12:27:21 -07:00
Adam C
c1e444b07c FIX typo in doc comment for std.math.hypot (#9413) 2021-07-21 12:25:52 -07:00
Ryan Liptak
84154b10a2 Add inotify_rm_watch definition to c/linux.zig
Also make inotify_add_watch's pathname marked as nul-terminated
2021-07-21 12:25:10 -07:00
Ryan Liptak
ba47e09373 Add NotDir as possible error for os.inotify_add_watch
Possible when "mask contains IN_ONLYDIR and pathname is not a directory."
2021-07-21 12:25:05 -07:00
leesongun
1063bf696e Fix bigint_shl (#9305) 2021-07-21 12:24:53 -07:00
Jonathan Marler
3b8c4f07a4 clarify @bitSizeOf behavior 2021-07-21 12:24:47 -07:00
Martin Wickham
3dcbd489eb Fix libc include directories for the MSVC target 2021-07-21 12:22:09 -07:00
Malcolm Still
5582d20f04 Add waitid syscall on linux (#9335) 2021-07-21 12:22:03 -07:00
Andrew Kelley
13aedf09d6 mingw-w64: add odbc32 and dbghelp def files
related: #9124
2021-07-21 12:21:58 -07:00
Martin Wickham
cd078c518f Fix argument forwarding to LLVM on Windows 2021-07-21 12:21:48 -07:00
leesongun
ceebcfa317 Fix unexpected truncation behavior with comptime_int larger than u64 range (#9303)
Closes #9299
2021-07-06 21:30:58 -07:00
Jacob G-W
b26ab39836 remove really weird debugging statement from stage1 2021-07-06 21:30:46 -07:00
Nulo
eac9bfaa01 Link to the GPA now that it's on upstream 2021-07-06 21:30:24 -07:00
Nulo
8a83143316 CODE_OF_CONDUCT: change Freenode to Libera.chat 2021-07-06 21:30:15 -07:00
Andrew Kelley
3ef9bd5879 stage2: add the zig version to AstGen cache hash
This solves the problem of different versions of Zig having different
binary representations of ZIR code.

closes #9290
2021-07-03 15:31:29 -07:00
Veikka Tuominen
f385522ab0 stage2: fix @asyncCall parameter count
Closes #9269
2021-07-03 15:29:52 -07:00
Nameless
de028d5130 std/os/uefi: fix packed struct bitfields 2021-07-03 15:28:57 -07:00
Andrew Kelley
390a4ded98 Merge pull request #9258 from ziglang/shared-cache-locking
Shared Cache Locking
2021-07-03 15:28:29 -07:00
Andrew Kelley
b0be0c77d8 Merge pull request #9148 from marler8997/windowsChildOutput
finish ChildProcess collectOutputWindows
2021-07-03 15:25:22 -07:00
xackus
440da6bfad mark tsan as linguist-vendored 2021-07-03 15:24:28 -07:00
Jacob G-W
b7fe0db9d2 langref: make @setRuntimeSafety more correct 2021-07-03 15:24:18 -07:00
Andrew Kelley
d59fc1ac04 stage1: @shuffle type and mask params in comptime scope 2021-07-03 15:22:53 -07:00
Roman Frołow
9349c9c4b1 Docs clarification: local static variable (#8381) 2021-07-03 15:22:21 -07:00
Jacob G-W
6caa77ea52 docs: top level global assembly -> container level 2021-07-03 15:22:17 -07:00
Andrew Kelley
caddd7eb18 std.crypto.p256: fix neg function compile error
There was a typo here and the neg function referenced a non-existent
variable.
2021-07-03 15:19:50 -07:00
Andrew Kelley
2b6727c98f std.os.linux.bpf: fix incorrect usage of unexpectedErrno 2021-07-03 15:19:50 -07:00
Andrew Kelley
5ef70b8b87 mips: fix syscall_pipe
Previously the fd parameter was ignored and so the result would not get
populated. Now it passes the fd pointer to the inline assembly so that
the results can be observed.
2021-07-03 15:19:50 -07:00
Isaac Freund
e75dfbcb3f std/build: add --sysroot general option 2021-06-26 12:51:49 +02:00
Isaac Freund
16228e87d6 stage2: add --sysroot link option
This feature is necessary for cross-compiling code that dynamically
links system libraries, at least with the current feature set of lld.
2021-06-26 12:49:08 +02:00
Isaac Freund
3e4f3a1924 zig build: add --libc general option
This new option sets a default libc paths file to be used for all
LibExeObjSteps. Setting LibExeObjStep.libc_file overrides this default.

This is required to allow users to cross compile projects linking system
libraries without needing to patch the build.zig.
2021-06-26 12:41:05 +02:00
mason1920
939408289c Bring your own MAX_PATH_BYTES
Previous to #7082, users could overwrite PATH_MAX in the root file to support std.os.toPosixPath, permitting the "bring your own operating system" layer to implement the POSIX API for opening files. Unfortunately that is no longer the case.

This commit intends to fix what is arguably a regression from 0.7 in a way that doesn't break any code targeting 0.8.0, making it suitable to be included in a 0.8 patch release.
However in a future release that permits breaking changes, I am of the opinion that it would be beneficial to overwrite the value, even for "supported" operating systems. Same for all the other POSIX/BYOOS functions and values. However this is beyond the scope of this commit. Further discussion of this will be made into an issue in due time.
2021-06-21 16:18:59 -07:00
Andrew Kelley
d0575310dc Merge pull request #9168 from LemonBoy/fix-pie
std: Fix PIE startup sequence
2021-06-20 17:03:50 -07:00
LemonBoy
b72d55ea5f std: Make copy_file_range checks run at compile-time
* Avoid emitting the copy_file_range symbol at all to prevent link-time
  errors.
* Fix a bug in the check logic, the has_copy_file_range_syscall was
  set to the wrong value in case of ENOSYS
* If link_libc is true don't fall-back to the raw syscall approach,
  there's no policy about what to do in this case but let's follow what
  the other impls do.

Fixes #9146
2021-06-20 16:54:39 -07:00
pithlessly
c7dd3cc535 stage2 sema: change impl of @setCold to use zirSetCold (typo?) 2021-06-20 16:37:55 -07:00
Michael Dusan
96b77e030f macho: LC_RPATH: reserve byte for null-terminator 2021-06-20 16:36:27 -07:00
hadroncfy
cf6e2d318a HashMap.getOrPutAssumeCapacityAdapted should set key to undefined (#9138)
* std.hash_map.HashMap: getOrPutAssumeCapacityAdapted should set key to undefined

* add test for std.hash_map.HashMap.getOrPutAdapted
2021-06-20 16:26:01 -07:00
Andrew Kelley
1fe0142d1f AstGen: properly generate errdefer expressions when returning
`return` statements use a new function `nodeMayEvalToError` which does
some basic checks on the AST node to return never, always, or maybe.

Depending on this result, AstGen skips the errdefers, always includes
the errdefers, or emits a conditional branch to check whether the return
value is an error that Sema will have to evaluate.

Closes #8821
Unblocks #9047
2021-06-20 16:25:52 -07:00
LemonBoy
76102ea41f stage1: Store the specified code model in the LLVM module
This is needed for LTO builds to pick up the correct module.

Closes #9132
2021-06-20 16:25:22 -07:00
Andrew Kelley
74ca811a66 Merge pull request #9117 from greenfork/unify-compiler-error-printing
stage2: Unify compiler error printing
2021-06-17 20:28:54 -07:00
Vincent Rischmann
721ec8fa53 zig cc: improve linker args parsing
Handle linker args joined with a = like -Wl,-rpath=foo

Update existing args --major-os-version, --minor-os-version,
--major-subsystem-version and --minor-subsytem-version to work with the
new parsing.

Also handle -Wl,--script in addition to -Wl,-T
2021-06-17 20:28:37 -07:00
Andrew Kelley
dc392f49f8 stage1: fix zig0 help message
closes #9140
2021-06-17 20:28:37 -07:00
d18g
71ec89383b Fix lakemont CpuModel (#9099)
Lakemont has no x86, no MMX, no SSE and no way of handling any fp-math. In theory LLVM is able to implicitly use the soft-float emulation library calls to legalize any such operation but, given Zig's use of many non-standard features, sometimes we hit a weak spot in the X86 codegen backend.

Consider this as a work-around for this LLVM problem, fixing the problem in LLVM is not so high in my todo list as the target is pretty niche and Intel axed it in '19.

(Commit message by @LemonBoy)
2021-06-17 20:28:37 -07:00
Michael Dusan
4adbdcb587 netbsd: add more std.os.bits 2021-06-17 20:28:37 -07:00
Michael Dusan
162b92c93e netbsd: add args to limit number of PT_LOAD segs
NetBSD expects 2 PT_LOAD segments in a shared object, otherwise
ld.elf_so fails to load, emitting a general "not found" error.

Workaround issue by adding args `--no-rosegment` and `-znorelro`.

see #9109
2021-06-17 20:28:37 -07:00
Andrew Kelley
8be29674a9 fix RISC-V assembly CPU features
Previously, Zig did not properly communicate the target CPU features for
RISC-V to clang assembler, because Clang has a different way to pass CPU
features for C code and for assembly code. This commit makes Zig pass a
RISC-V -march flag in order to communicate CPU features to Clang when
compiling assembly files.
2021-06-17 20:28:37 -07:00
Björn Linse
52ead255a2 std: don't reference non-existant ComptimeStringHashMap type 2021-06-15 13:32:14 -07:00
Andrew Kelley
6f180131a5 ci: azure: update to newer msys2 release 2021-06-14 12:16:54 -07:00
Isaac Freund
4453f6a5ce std: fix auto hash of tagged union with void field 2021-06-14 12:16:36 -07:00
viri
7f6e7e3e5d std.windows: fix OVERLAPPED, add OVERLAPPED_ENTRY 2021-06-14 12:14:46 -07:00
LemonBoy
5c9eb94a2b std: Fix complex ldexp implementation
Two bugs in the implementation ported from musl made all the complex
functions relying on ldexp return incorrect results in some cases.

Spotted in #9047
2021-06-14 12:13:53 -07:00
Andrew Kelley
9c1e7de6c6 zig cc: recognize more pie flags
This is a bug fix.
2021-06-14 12:13:03 -07:00
codic12
54229fec33 c.zig: fix waitpid() definition 2021-06-11 14:50:48 -07:00
Andrew Kelley
264969a8c3 better awareness of unwind tables
* stage1 backend allows configuring the uwtables function attr
   via a flag rather than its own logic.
 * stage2 defaults to enabling uwtable attr when
   linking libunwind, or always on windows
 * stage2 makes link_eh_frame_hdr true automatically if uwtable
   attr is set to be on for zig functions
 * CLI: add -funwind-tables and -fno-unwind-tables to allow the user to
   override the defaults.
 * hook it up to `zig cc`

closes #9046
2021-06-11 10:31:48 -07:00
Veikka Tuominen
e3a74697f0 Merge pull request #8330 from kivikakk/single-limb-bigint-overflow
bigint add failures with aliasing
2021-06-11 10:31:08 -07:00
LemonBoy
a913311f3c std: Fix tanh for negative inputs
It turns out the code was not ported correctly from C and produced wrong
results for negative input values. As a bonus fix the NaN codepath by
adding yet another missing piece of code.

Spotted in #9047
2021-06-11 10:30:07 -07:00
Andrew Kelley
ec4c60c481 zig fmt 2021-06-11 10:28:42 -07:00
LemonBoy
29386f0d30 stage1: Fix handling of C ABI parameters split in multiple regs
Take into account the increased number of parameters when flattening a
structure into one or more SSE registers.

Fixes #9061
2021-06-10 10:22:08 -07:00
Frank Denis
80e1797faf aes 128-bit key expansion test - properly test the inverse round keys (#9065) 2021-06-10 10:22:03 -07:00
Jakub Konka
f677c24740 Re-enable multiple wasm32 vector tests
Fixes #5339
2021-06-10 10:21:13 -07:00
Andrew Kelley
6afdc3cc79 CLI: remove --verbose-ast and --verbose-tokenize
closes #9034

These options were listed under the
"Debug Options (Zig Compiler Development)" heading. Anything in this
section should be considered unstable and can be modified at any time
at any developer's discretion.
2021-06-10 10:20:59 -07:00
Andrew Kelley
c230258d9b native libc detection: respect spaces in CC env var
Zig has detection for when it is accidentally being called recursively
when trying to find the native libc installation. However it was not
working, resulting in a cryptic failure, because zig tried to execute
a command which had spaces in it rather than tokenizing it.

This improves the user experience of `zig cc` for systems that Zig
does not support cross-compiling for.

Closes #8960
2021-06-10 10:20:52 -07:00
Andrew Kelley
2d0dff6498 langref: link to 0.7.1 not 0.7.0 for the previous docs 2021-06-10 10:20:27 -07:00
Andrew Kelley
060cb0f277 langref: remove paragraph that mentions IRC
I want the language reference to be divorced from any particular
community. Also remove the call to action since the docs are
known to be incomplete and are not the current focus of the project.

Closes #9055
2021-06-10 10:20:16 -07:00
Filippo Casarin
05380a11a4 std.math.sqrt_int: fixed odd size integers types 2021-06-10 10:20:09 -07:00
viri
4a3ac16711 std.Progress: use *W functions on windows
Closes #534.
See: https://source.winehq.org/git/wine.git/blob/refs/heads/stable:/dlls/kernelbase/console.c#l520
2021-06-10 10:19:37 -07:00
Jakub Konka
51076f4e1d libc,macos: update and add missing libc headers 2021-06-10 10:10:24 -07:00
Matthew Borkowski
503b85a1b0 stage1: make @truncate to an integer type of different sign an error at comptime too 2021-06-08 12:27:22 -07:00
Dustin Taylor
0c25ff81a3 Limit Fixed Buffer Stream seekTo (#9023) 2021-06-08 12:27:22 -07:00
Matthew Borkowski
39c80942e7 stage1: fix render_const_value for printing const optional pointers 2021-06-08 22:24:55 +03:00
Andrew Kelley
bfc85211bb link: windows: look for more DLL import lib path names
When linking with -lfoo syntax, this indicates to Zig that the
dependency should either be provided by Zig, or it should be dynamically
provided by the system.

For windows-gnu targets, the search path was "foo.lib". Now it
additionally looks for "libfoo.dll.a".

Closes #7799
2021-06-07 22:31:32 -07:00
LemonBoy
7ca86936ca std: Add helpers to safely align pointers
Add two helpers to ensure people won't ignore some edge cases such as
pointers overflowing the address space.

Also fix #8924 to some degree, the amount of unchecked alignForward is
still scary.

Revert "tests: disable i386-linux-gnu -lc target due to CI failures"

This reverts commit 97a2f4e7ae.
2021-06-06 18:07:47 -07:00
LemonBoy
5c765b2ec4 std: Fix some BPF fn definitions
Cros-checked with bpf.h of kernel 5.12.9.
2021-06-06 18:02:52 -07:00
LemonBoy
a745a17aa9 build: Avoid using undefined variables
Closes #9013
Closes #8928
Closes #7991
2021-06-06 18:01:52 -07:00
LemonBoy
2681e1ffe0 stage1: Apply the same set of fn attributes everywhere
Make sure to propagate the target-specific attributes to internal
functions too.

Closes #8965
2021-06-06 18:01:47 -07:00
Sebastien Marie
27f6db66e3 openbsd: adjust dynamic linker path (#9010)
the dynamic linker on OpenBSD is at /usr/libexec/ld.so (and not /libexec/ld.so)
2021-06-06 18:01:40 -07:00
Michael Dusan
6d6ba1e998 test: re-enable dragonfly tests
Tests with LLVM assertions enabled are no longer failing.

closes #3563
2021-06-05 19:54:45 -07:00
Nicolas
c8ee445c86 Add zig_llvm-ar.cpp in build.zig
This was added in 0afb5b2ec6 8 days ago, but it seems it was only added in the cmake files and not build.zig
2021-06-05 19:54:33 -07:00
LemonBoy
072c3202c3 std: Better handing of POLLHUP in ChildProcess (#8988)
* std: Better handing of POLLHUP in ChildProcess

Upon hitting the EOF condition there are two main differences between
how Linux and the *BSD-derived systems behave: the former sets POLLHUP
and POLLIN and, after reading any residual data, only POLLHUP remains
set. The latter signal the EOF condition by setting both flags thus
requiring some extra checks to determine if the stream is "done".

DragonFly workaround/hack for POLLHUP is no longer required.

Closes #8969
2021-06-05 19:54:26 -07:00
LemonBoy
07852a4bc8 compiler-rt: Fix __floatunsitf signature
The function transforms an unsigned integer into a f128.

Closes #8996
2021-06-05 10:35:05 -07:00
Andrew Kelley
ae1871a028 start the 0.8.1 release branch 2021-06-04 11:30:34 -07:00
178 changed files with 8843 additions and 1196 deletions

1
.gitattributes vendored
View File

@@ -9,3 +9,4 @@ lib/libc/** linguist-vendored
lib/libcxx/** linguist-vendored
lib/libcxxabi/** linguist-vendored
lib/libunwind/** linguist-vendored
lib/tsan/** linguist-vendored

View File

@@ -26,7 +26,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
set(ZIG_VERSION_MAJOR 0)
set(ZIG_VERSION_MINOR 8)
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 "")

View File

@@ -9,7 +9,7 @@ a link. There is no concept of "official" or "unofficial", however, each
gathering place has its own moderators and rules.
This is Andrew Kelley speaking. At least for now, I'm the moderator of the
ziglang organization GitHub repositories and the #zig IRC channel on Freenode.
ziglang organization GitHub repositories and the #zig IRC channel on Libera.chat.
**This document contains the rules that govern these two spaces only**.
The rules here are strict. This space is for focused, on topic, technical work

View File

@@ -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 = 8, .patch = 0 };
const zig_version = std.builtin.Version{ .major = 0, .minor = 8, .patch = 1 };
pub fn build(b: *Builder) !void {
b.setPreferredReleaseMode(.ReleaseFast);
@@ -769,6 +769,7 @@ const zig_cpp_sources = [_][]const u8{
// These are planned to stay even when we are self-hosted.
"src/zig_llvm.cpp",
"src/zig_clang.cpp",
"src/zig_llvm-ar.cpp",
"src/zig_clang_driver.cpp",
"src/zig_clang_cc1_main.cpp",
"src/zig_clang_cc1as_main.cpp",

View File

@@ -9,7 +9,7 @@ sudo apt-get install -y cmake s3cmd tidy
ZIGDIR="$(pwd)"
ARCH="$(uname -m)"
TARGET="$ARCH-linux-musl"
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.8.0-dev.2703+c12704a33"
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.8.1-dev.94+535615117"
PREFIX="$HOME/$CACHE_BASENAME"
MCPU="baseline"
JOBS="-j$(nproc)"

View File

@@ -9,7 +9,7 @@ ZIGDIR="$(pwd)"
ARCH="x86_64"
TARGET="$ARCH-macos-gnu"
MCPU="baseline"
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.8.0-dev.2703+c12704a33"
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.8.1-dev.94+535615117"
PREFIX="$HOME/$CACHE_BASENAME"
JOBS="-j2"

View File

@@ -38,7 +38,7 @@ jobs:
timeoutInMinutes: 360
steps:
- powershell: |
(New-Object Net.WebClient).DownloadFile("https://github.com/msys2/msys2-installer/releases/download/2021-02-28/msys2-base-x86_64-20210228.sfx.exe", "sfx.exe")
(New-Object Net.WebClient).DownloadFile("https://github.com/msys2/msys2-installer/releases/download/2021-06-04/msys2-base-x86_64-20210604.sfx.exe", "sfx.exe")
.\sfx.exe -y -o\
del sfx.exe
displayName: Download/Extract/Install MSYS2

View File

@@ -193,7 +193,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> |
<a href="https://ziglang.org/documentation/0.7.1/">0.7.1</a> |
<a href="https://ziglang.org/documentation/0.8.0/">0.8.0</a> |
master
<h1>Contents</h1>
@@ -220,10 +220,6 @@
all on one page so you can search with your browser's search tool.
</p>
<p>
If you search for something specific in this documentation and do not find it,
please <a href="https://github.com/ziglang/www.ziglang.org/issues/new?title=I%20searched%20for%20___%20in%20the%20docs%20and%20didn%27t%20find%20it">file an issue</a> or <a href="https://webchat.freenode.net/?channels=%23zig">say something on IRC</a>.
</p>
<p>
The code samples in this document are compiled and tested as part of the main test suite of Zig.
</p>
<p>
@@ -262,7 +258,7 @@ pub fn main() !void {
<p>
The code sample begins by adding Zig's Standard Library to the build using the {#link|@import#} builtin function.
The {#syntax#}@import("std"){#endsyntax#} function call creates a structure to represent the Standard Library.
The code then makes a {#link|top-level declaration|Global Variables#} of a
The code then declares a
{#link|constant identifier|Assignment#}, named <code>std</code>, for easy access to
<a href="https://github.com/ziglang/zig/wiki/FAQ#where-is-the-documentation-for-the-zig-standard-library">Zig's standard library</a>.
</p>
@@ -700,7 +696,7 @@ pub fn main() void {
Because Zig source code is {#link|UTF-8 encoded|Source Encoding#}, any non-ASCII bytes appearing within a string literal
in source code carry their UTF-8 meaning into the content of the string in the Zig program;
the bytes are not modified by the compiler.
However, it is possible to embbed non-UTF-8 bytes into a string literal using <code>\xNN</code> notation.
However, it is possible to embed non-UTF-8 bytes into a string literal using <code>\xNN</code> notation.
</p>
<p>
Unicode code point literals have type {#syntax#}comptime_int{#endsyntax#}, the same as
@@ -806,7 +802,7 @@ const hello_world_in_c =
const x = 1234;
fn foo() void {
// It works at global scope as well as inside functions.
// It works at file scope as well as inside functions.
const y = 5678;
// Once assigned, an identifier cannot be changed.
@@ -876,18 +872,18 @@ test "init with undefined" {
{#syntax#}var{#endsyntax#} when declaring a variable. This causes less work for both
humans and computers to do when reading code, and creates more optimization opportunities.
</p>
{#header_open|Global Variables#}
{#header_open|Container Level Variables#}
<p>
Global variables are considered to be a top level declaration, which means that they are
order-independent and lazily analyzed. The initialization value of global variables is implicitly
{#link|comptime#}. If a global variable is {#syntax#}const{#endsyntax#} then its value is
Container level variables have static lifetime and are order-independent and lazily analyzed.
The initialization value of container level variables is implicitly
{#link|comptime#}. If a container level variable is {#syntax#}const{#endsyntax#} then its value is
{#syntax#}comptime{#endsyntax#}-known, otherwise it is runtime-known.
</p>
{#code_begin|test|global_variables#}
{#code_begin|test|container_level_variables#}
var y: i32 = add(10, x);
const x: i32 = add(12, 34);
test "global variables" {
test "container level variables" {
try expect(x == 46);
try expect(y == 56);
}
@@ -900,27 +896,51 @@ const std = @import("std");
const expect = std.testing.expect;
{#code_end#}
<p>
Global variables may be declared inside a {#link|struct#}, {#link|union#}, or {#link|enum#}:
Container level variables may be declared inside a {#link|struct#}, {#link|union#}, or {#link|enum#}:
</p>
{#code_begin|test|namespaced_global#}
{#code_begin|test|namespaced_container_level_variable#}
const std = @import("std");
const expect = std.testing.expect;
test "namespaced global variable" {
test "namespaced container level variable" {
try expect(foo() == 1235);
try expect(foo() == 1236);
}
const S = struct {
var x: i32 = 1234;
};
fn foo() i32 {
const S = struct {
var x: i32 = 1234;
};
S.x += 1;
return S.x;
}
{#code_end#}
{#header_close#}
{#header_open|Static Local Variables#}
<p>
The {#syntax#}extern{#endsyntax#} keyword can be used to link against a variable that is exported
It is also possible to have local variables with static lifetime by using containers inside functions.
</p>
{#code_begin|test|static_local_variable#}
const std = @import("std");
const expect = std.testing.expect;
test "static local variable" {
try expect(foo() == 1235);
try expect(foo() == 1236);
}
fn foo() i32 {
const S = struct {
var x: i32 = 1234;
};
S.x += 1;
return S.x;
}
{#code_end#}
<p>
The {#syntax#}extern{#endsyntax#} keyword or {#link|@extern#} builtin function can be used to link against a variable that is exported
from another object. The {#syntax#}export{#endsyntax#} keyword or {#link|@export#} builtin function
can be used to make a variable available to other objects at link time. In both cases,
the type of the variable must be C ABI compatible.
@@ -952,7 +972,7 @@ fn testTls(context: void) void {
}
{#code_end#}
<p>
For {#link|Single Threaded Builds#}, all thread local variables are treated as {#link|Global Variables#}.
For {#link|Single Threaded Builds#}, all thread local variables are treated as regular {#link|Container Level Variables#}.
</p>
<p>
Thread local variables may not be {#syntax#}const{#endsyntax#}.
@@ -2471,7 +2491,7 @@ test "dot product" {
try expect(Vec3.dot(v1, v2) == 0.0);
}
// Structs can have global declarations.
// Structs can have declarations.
// Structs can have 0 fields.
const Empty = struct {
pub const PI = 3.14;
@@ -5226,16 +5246,15 @@ test "implicit cast to comptime_int" {
}
{#code_end#}
{#header_close#}
{#header_open|Type Coercion: Arrays and Pointers#}
{#code_begin|test|coerce_arrays_and_ptrs#}
{#header_open|Type Coercion: Slices, Arrays and Pointers#}
{#code_begin|test|coerce__slices_arrays_and_ptrs#}
const std = @import("std");
const expect = std.testing.expect;
// This cast exists primarily so that string literals can be
// passed to functions that accept const slices. However
// it is probably going to be removed from the language when
// https://github.com/ziglang/zig/issues/265 is implemented.
test "[N]T to []const T" {
// You can assign constant pointers to arrays to a slice with
// const modifier on the element type. Useful in particular for
// String literals.
test "*const [N]T to []const T" {
var x1: []const u8 = "hello";
var x2: []const u8 = &[5]u8{ 'h', 'e', 'l', 'l', 111 };
try expect(std.mem.eql(u8, x1, x2));
@@ -5245,7 +5264,7 @@ test "[N]T to []const T" {
}
// Likewise, it works when the destination type is an error union.
test "[N]T to E![]const T" {
test "*const [N]T to E![]const T" {
var x1: anyerror![]const u8 = "hello";
var x2: anyerror![]const u8 = &[5]u8{ 'h', 'e', 'l', 'l', 111 };
try expect(std.mem.eql(u8, try x1, try x2));
@@ -5255,7 +5274,7 @@ test "[N]T to E![]const T" {
}
// Likewise, it works when the destination type is an optional.
test "[N]T to ?[]const T" {
test "*const [N]T to ?[]const T" {
var x1: ?[]const u8 = "hello";
var x2: ?[]const u8 = &[5]u8{ 'h', 'e', 'l', 'l', 111 };
try expect(std.mem.eql(u8, x1.?, x2.?));
@@ -5614,9 +5633,8 @@ test "turn HashMap into a set with void" {
value is deleted, as seen above.
</p>
<p>
{#syntax#}void{#endsyntax#} is distinct from {#syntax#}c_void{#endsyntax#}, which is defined like this:
{#syntax#}pub const c_void = opaque {};{#endsyntax#}.
{#syntax#}void{#endsyntax#} has a known size of 0 bytes, and {#syntax#}c_void{#endsyntax#} has an unknown, but non-zero, size.
{#syntax#}void{#endsyntax#} is distinct from {#syntax#}c_void{#endsyntax#}.
{#syntax#}void{#endsyntax#} has a known size of 0 bytes, and {#syntax#}c_void{#endsyntax#} has an unknown, but non-zero, size.
</p>
<p>
Expressions of type {#syntax#}void{#endsyntax#} are the only ones whose value can be ignored. For example:
@@ -5688,7 +5706,7 @@ test "@intToPtr for pointer to zero bit type" {
{#header_open|usingnamespace#}
<p>
{#syntax#}usingnamespace{#endsyntax#} is a top level declaration that imports all the public declarations of
{#syntax#}usingnamespace{#endsyntax#} is a declaration that imports all the public declarations of
the operand, which must be a {#link|struct#}, {#link|union#}, or {#link|enum#}, into the current scope:
</p>
{#code_begin|test|usingnamespace#}
@@ -5696,6 +5714,19 @@ usingnamespace @import("std");
test "using std namespace" {
try testing.expect(true);
}
{#code_end#}
<p>
{#syntax#}usingnamespace{#endsyntax#} can also be used in containers:
</p>
{#code_begin|test|usingnamespace_inside_struct#}
test "using namespace inside struct" {
const L = struct {
usingnamespace struct {
pub fn f() void {}
};
};
L.f();
}
{#code_end#}
<p>
@@ -6048,7 +6079,7 @@ test "fibonacci" {
</p>
<p>
In the global scope (outside of any function), all expressions are implicitly
At container level (outside of any function), all expressions are implicitly
{#syntax#}comptime{#endsyntax#} expressions. This means that we can use functions to
initialize complex static data. For example:
</p>
@@ -6466,7 +6497,7 @@ volatile (
{#header_open|Global Assembly#}
<p>
When an assembly expression occurs in a top level {#link|comptime#} block, this is
When an assembly expression occurs in a container level {#link|comptime#} block, this is
<strong>global assembly</strong>.
</p>
<p>
@@ -7048,7 +7079,8 @@ fn func(y: *i32) void {
{#header_open|@bitSizeOf#}
<pre>{#syntax#}@bitSizeOf(comptime T: type) comptime_int{#endsyntax#}</pre>
<p>
This function returns the number of bits it takes to store {#syntax#}T{#endsyntax#} in memory.
This function returns the number of bits it takes to store {#syntax#}T{#endsyntax#} in memory if the type
were a field in a packed struct/union.
The result is a target-specific compile time constant.
</p>
<p>
@@ -8118,7 +8150,7 @@ pub const FloatMode = enum {
{#header_close#}
{#header_open|@setRuntimeSafety#}
<pre>{#syntax#}@setRuntimeSafety(safety_on: bool){#endsyntax#}</pre>
<pre>{#syntax#}@setRuntimeSafety(safety_on: bool) void{#endsyntax#}</pre>
<p>
Sets whether runtime safety checks are enabled for the scope that contains the function call.
</p>
@@ -8524,7 +8556,7 @@ fn List(comptime T: type) type {
}
{#code_end#}
<p>
When {#syntax#}@This(){#endsyntax#} is used at global scope, it returns a reference to the
When {#syntax#}@This(){#endsyntax#} is used at file scope, it returns a reference to the
struct that corresponds to the current file.
</p>
{#header_close#}
@@ -8739,7 +8771,7 @@ pub fn build(b: *Builder) void {
{#header_open|Single Threaded Builds#}
<p>Zig has a compile option <code>--single-threaded</code> which has the following effects:</p>
<ul>
<li>All {#link|Thread Local Variables#} are treated as {#link|Global Variables#}.</li>
<li>All {#link|Thread Local Variables#} are treated as regular {#link|Container Level Variables#}.</li>
<li>The overhead of {#link|Async Functions#} becomes equivalent to function call overhead.</li>
<li>The {#syntax#}@import("builtin").single_threaded{#endsyntax#} becomes {#syntax#}true{#endsyntax#}
and therefore various userland APIs which read this variable become more efficient.
@@ -9523,10 +9555,7 @@ test "string literal to constant slice" {
</p>
<p>
There are many example allocators to look at for inspiration. Look at std/heap.zig and
at this
<a href="https://github.com/andrewrk/zig-general-purpose-allocator/">work-in-progress general purpose allocator</a>.
TODO: once <a href="https://github.com/ziglang/zig/issues/21">#21</a> is done, link to the docs
here.
{#syntax#}std.heap.GeneralPurposeAllocator{#endsyntax#}.
</p>
{#header_close#}
@@ -10483,6 +10512,14 @@ fn readU32Be() u32 {}
See the Zig Standard Library for more examples.
</p>
{#header_close#}
{#header_open|Doc Comment Guidance#}
<ul>
<li>Omit any information that is redundant based on the name of the thing being documented.</li>
<li>Duplicating information onto multiple similar functions is encouraged because it helps IDEs and other tools provide better help text.</li>
<li>Use the word <strong>assume</strong> to indicate invariants that cause {#link|Undefined Behavior#} when violated.</li>
<li>Use the word <strong>assert</strong> to indicate invariants that cause <em>safety-checked</em> {#link|Undefined Behavior#} when violated.</li>
</ul>
{#header_close#}
{#header_close#}
{#header_open|Source Encoding#}
<p>Zig source code is encoded in UTF-8. An invalid UTF-8 byte sequence results in a compile error.</p>

View File

@@ -0,0 +1,337 @@
/*
* Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* CommonDigest.h - common digest routines: MD2, MD4, MD5, SHA1.
*/
#ifndef _CC_COMMON_DIGEST_H_
#define _CC_COMMON_DIGEST_H_
#include <stdint.h>
#if defined(_MSC_VER)
#include <availability.h>
#else
#include <os/availability.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define CC_DIGEST_DEPRECATION_WARNING \
"This function is cryptographically broken and should not be used in security contexts. Clients should migrate to SHA256 (or stronger)."
/*
* For compatibility with legacy implementations, the *Init(), *Update(),
* and *Final() functions declared here *always* return a value of 1 (one).
* This corresponds to "success" in the similar openssl implementations.
* There are no errors of any kind which can be, or are, reported here,
* so you can safely ignore the return values of all of these functions
* if you are implementing new code.
*
* The one-shot functions (CC_MD2(), CC_SHA1(), etc.) perform digest
* calculation and place the result in the caller-supplied buffer
* indicated by the md parameter. They return the md parameter.
* Unlike the opensssl counterparts, these one-shot functions require
* a non-NULL md pointer. Passing in NULL for the md parameter
* results in a NULL return and no digest calculation.
*/
typedef uint32_t CC_LONG; /* 32 bit unsigned integer */
typedef uint64_t CC_LONG64; /* 64 bit unsigned integer */
/*** MD2 ***/
#define CC_MD2_DIGEST_LENGTH 16 /* digest length in bytes */
#define CC_MD2_BLOCK_BYTES 64 /* block size in bytes */
#define CC_MD2_BLOCK_LONG (CC_MD2_BLOCK_BYTES / sizeof(CC_LONG))
typedef struct CC_MD2state_st
{
int num;
unsigned char data[CC_MD2_DIGEST_LENGTH];
CC_LONG cksm[CC_MD2_BLOCK_LONG];
CC_LONG state[CC_MD2_BLOCK_LONG];
} CC_MD2_CTX;
extern int CC_MD2_Init(CC_MD2_CTX *c)
API_DEPRECATED(CC_DIGEST_DEPRECATION_WARNING, macos(10.4, 10.15), ios(2.0, 13.0));
extern int CC_MD2_Update(CC_MD2_CTX *c, const void *data, CC_LONG len)
API_DEPRECATED(CC_DIGEST_DEPRECATION_WARNING, macos(10.4, 10.15), ios(2.0, 13.0));
extern int CC_MD2_Final(unsigned char *md, CC_MD2_CTX *c)
API_DEPRECATED(CC_DIGEST_DEPRECATION_WARNING, macos(10.4, 10.15), ios(2.0, 13.0));
extern unsigned char *CC_MD2(const void *data, CC_LONG len, unsigned char *md)
API_DEPRECATED(CC_DIGEST_DEPRECATION_WARNING, macos(10.4, 10.15), ios(2.0, 13.0));
/*** MD4 ***/
#define CC_MD4_DIGEST_LENGTH 16 /* digest length in bytes */
#define CC_MD4_BLOCK_BYTES 64 /* block size in bytes */
#define CC_MD4_BLOCK_LONG (CC_MD4_BLOCK_BYTES / sizeof(CC_LONG))
typedef struct CC_MD4state_st
{
CC_LONG A,B,C,D;
CC_LONG Nl,Nh;
CC_LONG data[CC_MD4_BLOCK_LONG];
uint32_t num;
} CC_MD4_CTX;
extern int CC_MD4_Init(CC_MD4_CTX *c)
API_DEPRECATED(CC_DIGEST_DEPRECATION_WARNING, macos(10.4, 10.15), ios(2.0, 13.0));
extern int CC_MD4_Update(CC_MD4_CTX *c, const void *data, CC_LONG len)
API_DEPRECATED(CC_DIGEST_DEPRECATION_WARNING, macos(10.4, 10.15), ios(2.0, 13.0));
extern int CC_MD4_Final(unsigned char *md, CC_MD4_CTX *c)
API_DEPRECATED(CC_DIGEST_DEPRECATION_WARNING, macos(10.4, 10.15), ios(2.0, 13.0));
extern unsigned char *CC_MD4(const void *data, CC_LONG len, unsigned char *md)
API_DEPRECATED(CC_DIGEST_DEPRECATION_WARNING, macos(10.4, 10.15), ios(2.0, 13.0));
/*** MD5 ***/
#define CC_MD5_DIGEST_LENGTH 16 /* digest length in bytes */
#define CC_MD5_BLOCK_BYTES 64 /* block size in bytes */
#define CC_MD5_BLOCK_LONG (CC_MD5_BLOCK_BYTES / sizeof(CC_LONG))
typedef struct CC_MD5state_st
{
CC_LONG A,B,C,D;
CC_LONG Nl,Nh;
CC_LONG data[CC_MD5_BLOCK_LONG];
int num;
} CC_MD5_CTX;
extern int CC_MD5_Init(CC_MD5_CTX *c)
API_DEPRECATED(CC_DIGEST_DEPRECATION_WARNING, macos(10.4, 10.15), ios(2.0, 13.0));
extern int CC_MD5_Update(CC_MD5_CTX *c, const void *data, CC_LONG len)
API_DEPRECATED(CC_DIGEST_DEPRECATION_WARNING, macos(10.4, 10.15), ios(2.0, 13.0));
extern int CC_MD5_Final(unsigned char *md, CC_MD5_CTX *c)
API_DEPRECATED(CC_DIGEST_DEPRECATION_WARNING, macos(10.4, 10.15), ios(2.0, 13.0));
extern unsigned char *CC_MD5(const void *data, CC_LONG len, unsigned char *md)
API_DEPRECATED(CC_DIGEST_DEPRECATION_WARNING, macos(10.4, 10.15), ios(2.0, 13.0));
/*** SHA1 ***/
#define CC_SHA1_DIGEST_LENGTH 20 /* digest length in bytes */
#define CC_SHA1_BLOCK_BYTES 64 /* block size in bytes */
#define CC_SHA1_BLOCK_LONG (CC_SHA1_BLOCK_BYTES / sizeof(CC_LONG))
typedef struct CC_SHA1state_st
{
CC_LONG h0,h1,h2,h3,h4;
CC_LONG Nl,Nh;
CC_LONG data[CC_SHA1_BLOCK_LONG];
int num;
} CC_SHA1_CTX;
extern int CC_SHA1_Init(CC_SHA1_CTX *c);
extern int CC_SHA1_Update(CC_SHA1_CTX *c, const void *data, CC_LONG len);
extern int CC_SHA1_Final(unsigned char *md, CC_SHA1_CTX *c);
extern unsigned char *CC_SHA1(const void *data, CC_LONG len, unsigned char *md);
/*** SHA224 ***/
#define CC_SHA224_DIGEST_LENGTH 28 /* digest length in bytes */
#define CC_SHA224_BLOCK_BYTES 64 /* block size in bytes */
/* same context struct is used for SHA224 and SHA256 */
typedef struct CC_SHA256state_st
{ CC_LONG count[2];
CC_LONG hash[8];
CC_LONG wbuf[16];
} CC_SHA256_CTX;
extern int CC_SHA224_Init(CC_SHA256_CTX *c)
API_AVAILABLE(macos(10.4), ios(2.0));
extern int CC_SHA224_Update(CC_SHA256_CTX *c, const void *data, CC_LONG len)
API_AVAILABLE(macos(10.4), ios(2.0));
extern int CC_SHA224_Final(unsigned char *md, CC_SHA256_CTX *c)
API_AVAILABLE(macos(10.4), ios(2.0));
extern unsigned char *CC_SHA224(const void *data, CC_LONG len, unsigned char *md)
API_AVAILABLE(macos(10.4), ios(2.0));
/*** SHA256 ***/
#define CC_SHA256_DIGEST_LENGTH 32 /* digest length in bytes */
#define CC_SHA256_BLOCK_BYTES 64 /* block size in bytes */
extern int CC_SHA256_Init(CC_SHA256_CTX *c)
API_AVAILABLE(macos(10.4), ios(2.0));
extern int CC_SHA256_Update(CC_SHA256_CTX *c, const void *data, CC_LONG len)
API_AVAILABLE(macos(10.4), ios(2.0));
extern int CC_SHA256_Final(unsigned char *md, CC_SHA256_CTX *c)
API_AVAILABLE(macos(10.4), ios(2.0));
extern unsigned char *CC_SHA256(const void *data, CC_LONG len, unsigned char *md)
API_AVAILABLE(macos(10.4), ios(2.0));
/*** SHA384 ***/
#define CC_SHA384_DIGEST_LENGTH 48 /* digest length in bytes */
#define CC_SHA384_BLOCK_BYTES 128 /* block size in bytes */
/* same context struct is used for SHA384 and SHA512 */
typedef struct CC_SHA512state_st
{ CC_LONG64 count[2];
CC_LONG64 hash[8];
CC_LONG64 wbuf[16];
} CC_SHA512_CTX;
extern int CC_SHA384_Init(CC_SHA512_CTX *c)
API_AVAILABLE(macos(10.4), ios(2.0));
extern int CC_SHA384_Update(CC_SHA512_CTX *c, const void *data, CC_LONG len)
API_AVAILABLE(macos(10.4), ios(2.0));
extern int CC_SHA384_Final(unsigned char *md, CC_SHA512_CTX *c)
API_AVAILABLE(macos(10.4), ios(2.0));
extern unsigned char *CC_SHA384(const void *data, CC_LONG len, unsigned char *md)
API_AVAILABLE(macos(10.4), ios(2.0));
/*** SHA512 ***/
#define CC_SHA512_DIGEST_LENGTH 64 /* digest length in bytes */
#define CC_SHA512_BLOCK_BYTES 128 /* block size in bytes */
extern int CC_SHA512_Init(CC_SHA512_CTX *c)
API_AVAILABLE(macos(10.4), ios(2.0));
extern int CC_SHA512_Update(CC_SHA512_CTX *c, const void *data, CC_LONG len)
API_AVAILABLE(macos(10.4), ios(2.0));
extern int CC_SHA512_Final(unsigned char *md, CC_SHA512_CTX *c)
API_AVAILABLE(macos(10.4), ios(2.0));
extern unsigned char *CC_SHA512(const void *data, CC_LONG len, unsigned char *md)
API_AVAILABLE(macos(10.4), ios(2.0));
/*
* To use the above digest functions with existing code which uses
* the corresponding openssl functions, #define the symbol
* COMMON_DIGEST_FOR_OPENSSL in your client code (BEFORE including
* this file), and simply link against libSystem (or System.framework)
* instead of libcrypto.
*
* You can *NOT* mix and match functions operating on a given data
* type from the two implementations; i.e., if you do a CC_MD5_Init()
* on a CC_MD5_CTX object, do not assume that you can do an openssl-style
* MD5_Update() on that same context.
*/
#ifdef COMMON_DIGEST_FOR_OPENSSL
#define MD2_DIGEST_LENGTH CC_MD2_DIGEST_LENGTH
#define MD2_CTX CC_MD2_CTX
#define MD2_Init CC_MD2_Init
#define MD2_Update CC_MD2_Update
#define MD2_Final CC_MD2_Final
#define MD4_DIGEST_LENGTH CC_MD4_DIGEST_LENGTH
#define MD4_CTX CC_MD4_CTX
#define MD4_Init CC_MD4_Init
#define MD4_Update CC_MD4_Update
#define MD4_Final CC_MD4_Final
#define MD5_DIGEST_LENGTH CC_MD5_DIGEST_LENGTH
#define MD5_CTX CC_MD5_CTX
#define MD5_Init CC_MD5_Init
#define MD5_Update CC_MD5_Update
#define MD5_Final CC_MD5_Final
#define SHA_DIGEST_LENGTH CC_SHA1_DIGEST_LENGTH
#define SHA_CTX CC_SHA1_CTX
#define SHA1_Init CC_SHA1_Init
#define SHA1_Update CC_SHA1_Update
#define SHA1_Final CC_SHA1_Final
#define SHA224_DIGEST_LENGTH CC_SHA224_DIGEST_LENGTH
#define SHA256_CTX CC_SHA256_CTX
#define SHA224_Init CC_SHA224_Init
#define SHA224_Update CC_SHA224_Update
#define SHA224_Final CC_SHA224_Final
#define SHA256_DIGEST_LENGTH CC_SHA256_DIGEST_LENGTH
#define SHA256_Init CC_SHA256_Init
#define SHA256_Update CC_SHA256_Update
#define SHA256_Final CC_SHA256_Final
#define SHA384_DIGEST_LENGTH CC_SHA384_DIGEST_LENGTH
#define SHA512_CTX CC_SHA512_CTX
#define SHA384_Init CC_SHA384_Init
#define SHA384_Update CC_SHA384_Update
#define SHA384_Final CC_SHA384_Final
#define SHA512_DIGEST_LENGTH CC_SHA512_DIGEST_LENGTH
#define SHA512_Init CC_SHA512_Init
#define SHA512_Update CC_SHA512_Update
#define SHA512_Final CC_SHA512_Final
#endif /* COMMON_DIGEST_FOR_OPENSSL */
/*
* In a manner similar to that described above for openssl
* compatibility, these macros can be used to provide compatiblity
* with legacy implementations of MD5 using the interface defined
* in RFC 1321.
*/
#ifdef COMMON_DIGEST_FOR_RFC_1321
#define MD5_CTX CC_MD5_CTX
#define MD5Init CC_MD5_Init
#define MD5Update CC_MD5_Update
void MD5Final (unsigned char [16], MD5_CTX *)
API_DEPRECATED(CC_DIGEST_DEPRECATION_WARNING, macos(10.4, 10.15), ios(2.0, 13.0));
#endif /* COMMON_DIGEST_FOR_RFC_1321 */
#ifdef __cplusplus
}
#endif
#endif /* _CC_COMMON_DIGEST_H_ */

67
lib/libc/include/aarch64-macos-gnu/ar.h vendored Normal file
View File

@@ -0,0 +1,67 @@
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc.
* All or some portions of this file are derived from material licensed
* to the University of California by American Telephone and Telegraph
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
* the permission of UNIX System Laboratories, Inc.
*
* This code is derived from software contributed to Berkeley by
* Hugh Smith at The University of Guelph.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ar.h 8.2 (Berkeley) 1/21/94
*/
#ifndef _AR_H_
#define _AR_H_
/* Pre-4BSD archives had these magic numbers in them. */
#define OARMAG1 0177555
#define OARMAG2 0177545
#define ARMAG "!<arch>\n" /* ar "magic number" */
#define SARMAG 8 /* strlen(ARMAG); */
#define AR_EFMT1 "#1/" /* extended format #1 */
struct ar_hdr {
char ar_name[16]; /* name */
char ar_date[12]; /* modification time */
char ar_uid[6]; /* user id */
char ar_gid[6]; /* group id */
char ar_mode[8]; /* octal file permissions */
char ar_size[10]; /* size in bytes */
#define ARFMAG "`\n"
char ar_fmag[2]; /* consistency check */
};
#endif /* !_AR_H_ */

View File

@@ -0,0 +1,150 @@
/*
* Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#ifndef _MACH_O_ARCH_H_
#define _MACH_O_ARCH_H_
/*
* Copyright (c) 1997 Apple Computer, Inc.
*
* Functions that deal with information about architectures.
*
*/
#include <stdint.h>
#include <mach/machine.h>
#include <architecture/byte_order.h>
/* The NXArchInfo structs contain the architectures symbolic name
* (such as "ppc"), its CPU type and CPU subtype as defined in
* mach/machine.h, the byte order for the architecture, and a
* describing string (such as "PowerPC").
* There will both be entries for specific CPUs (such as ppc604e) as
* well as generic "family" entries (such as ppc).
*/
typedef struct {
const char *name;
cpu_type_t cputype;
cpu_subtype_t cpusubtype;
enum NXByteOrder byteorder;
const char *description;
} NXArchInfo;
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* NXGetAllArchInfos() returns a pointer to an array of all known
* NXArchInfo structures. The last NXArchInfo is marked by a NULL name.
*/
extern const NXArchInfo *NXGetAllArchInfos(void);
/* NXGetLocalArchInfo() returns the NXArchInfo for the local host, or NULL
* if none is known.
*/
extern const NXArchInfo *NXGetLocalArchInfo(void);
/* NXGetArchInfoFromName() and NXGetArchInfoFromCpuType() return the
* NXArchInfo from the architecture's name or cputype/cpusubtype
* combination. A cpusubtype of CPU_SUBTYPE_MULTIPLE can be used
* to request the most general NXArchInfo known for the given cputype.
* NULL is returned if no matching NXArchInfo can be found.
*/
extern const NXArchInfo *NXGetArchInfoFromName(const char *name);
extern const NXArchInfo *NXGetArchInfoFromCpuType(cpu_type_t cputype,
cpu_subtype_t cpusubtype);
/* The above interfaces that return pointers to NXArchInfo structs in normal
* cases returns a pointer from the array returned in NXGetAllArchInfos().
* In some cases when the cputype is CPU_TYPE_I386 or CPU_TYPE_POWERPC it will
* retun malloc(3)'ed NXArchInfo struct which contains a string in the
* description field also a malloc(3)'ed pointer. To allow programs not to
* leak memory they can call NXFreeArchInfo() on pointers returned from the
* above interfaces. Since this is a new API on older systems can use the
* code below. Going forward the above interfaces will only return pointers
* from the array returned in NXGetAllArchInfos().
*/
extern void NXFreeArchInfo(const NXArchInfo *x);
/* The code that can be used for NXFreeArchInfo() when it is not available is:
*
* static void NXFreeArchInfo(
* const NXArchInfo *x)
* {
* const NXArchInfo *p;
*
* p = NXGetAllArchInfos();
* while(p->name != NULL){
* if(x == p)
* return;
* p++;
* }
* free((char *)x->description);
* free((NXArchInfo *)x);
* }
*/
/* NXFindBestFatArch() is passed a cputype and cpusubtype and a set of
* fat_arch structs and selects the best one that matches (if any) and returns
* a pointer to that fat_arch struct (or NULL). The fat_arch structs must be
* in the host byte order and correct such that the fat_archs really points to
* enough memory for nfat_arch structs. It is possible that this routine could
* fail if new cputypes or cpusubtypes are added and an old version of this
* routine is used. But if there is an exact match between the cputype and
* cpusubtype and one of the fat_arch structs this routine will always succeed.
*/
extern struct fat_arch *NXFindBestFatArch(cpu_type_t cputype,
cpu_subtype_t cpusubtype,
struct fat_arch *fat_archs,
uint32_t nfat_archs);
/* NXFindBestFatArch_64() is passed a cputype and cpusubtype and a set of
* fat_arch_64 structs and selects the best one that matches (if any) and
* returns a pointer to that fat_arch_64 struct (or NULL). The fat_arch_64
* structs must be in the host byte order and correct such that the fat_archs64
* really points to enough memory for nfat_arch structs. It is possible that
* this routine could fail if new cputypes or cpusubtypes are added and an old
* version of this routine is used. But if there is an exact match between the
* cputype and cpusubtype and one of the fat_arch_64 structs this routine will
* always succeed.
*/
extern struct fat_arch_64 *NXFindBestFatArch_64(cpu_type_t cputype,
cpu_subtype_t cpusubtype,
struct fat_arch_64 *fat_archs64,
uint32_t nfat_archs);
/* NXCombineCpuSubtypes() returns the resulting cpusubtype when combining two
* different cpusubtypes for the specified cputype. If the two cpusubtypes
* can't be combined (the specific subtypes are mutually exclusive) -1 is
* returned indicating it is an error to combine them. This can also fail and
* return -1 if new cputypes or cpusubtypes are added and an old version of
* this routine is used. But if the cpusubtypes are the same they can always
* be combined and this routine will return the cpusubtype pass in.
*/
extern cpu_subtype_t NXCombineCpuSubtypes(cpu_type_t cputype,
cpu_subtype_t cpusubtype1,
cpu_subtype_t cpusubtype2);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _MACH_O_ARCH_H_ */

View File

@@ -0,0 +1,68 @@
/*
* Copyright (c) 2010 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#ifndef _MACHO_ARM64_RELOC_H_
#define _MACHO_ARM64_RELOC_H_
/*
* Relocation types used in the arm64 implementation.
*/
enum reloc_type_arm64
{
ARM64_RELOC_UNSIGNED, // for pointers
ARM64_RELOC_SUBTRACTOR, // must be followed by a ARM64_RELOC_UNSIGNED
ARM64_RELOC_BRANCH26, // a B/BL instruction with 26-bit displacement
ARM64_RELOC_PAGE21, // pc-rel distance to page of target
ARM64_RELOC_PAGEOFF12, // offset within page, scaled by r_length
ARM64_RELOC_GOT_LOAD_PAGE21, // pc-rel distance to page of GOT slot
ARM64_RELOC_GOT_LOAD_PAGEOFF12, // offset within page of GOT slot,
// scaled by r_length
ARM64_RELOC_POINTER_TO_GOT, // for pointers to GOT slots
ARM64_RELOC_TLVP_LOAD_PAGE21, // pc-rel distance to page of TLVP slot
ARM64_RELOC_TLVP_LOAD_PAGEOFF12, // offset within page of TLVP slot,
// scaled by r_length
ARM64_RELOC_ADDEND, // must be followed by PAGE21 or PAGEOFF12
// An arm64e authenticated pointer.
//
// Represents a pointer to a symbol (like ARM64_RELOC_UNSIGNED).
// Additionally, the resulting pointer is signed. The signature is
// specified in the target location: the addend is restricted to the lower
// 32 bits (instead of the full 64 bits for ARM64_RELOC_UNSIGNED):
//
// |63|62|61-51|50-49| 48 |47 - 32|31 - 0|
// | 1| 0| 0 | key | addr | discriminator | addend |
//
// The key is one of:
// IA: 00 IB: 01
// DA: 10 DB: 11
//
// The discriminator field is used as extra signature diversification.
//
// The addr field indicates whether the target address should be blended
// into the discriminator.
//
ARM64_RELOC_AUTHENTICATED_POINTER,
};
#endif /* #ifndef _MACHO_ARM64_RELOC_H_ */

View File

@@ -0,0 +1,532 @@
//===------------------ mach-o/compact_unwind_encoding.h ------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//
// Darwin's alternative to DWARF based unwind encodings.
//
//===----------------------------------------------------------------------===//
#ifndef __COMPACT_UNWIND_ENCODING__
#define __COMPACT_UNWIND_ENCODING__
#include <stdint.h>
//
// Compilers can emit standard DWARF FDEs in the __TEXT,__eh_frame section
// of object files. Or compilers can emit compact unwind information in
// the __LD,__compact_unwind section.
//
// When the linker creates a final linked image, it will create a
// __TEXT,__unwind_info section. This section is a small and fast way for the
// runtime to access unwind info for any given function. If the compiler
// emitted compact unwind info for the function, that compact unwind info will
// be encoded in the __TEXT,__unwind_info section. If the compiler emitted
// DWARF unwind info, the __TEXT,__unwind_info section will contain the offset
// of the FDE in the __TEXT,__eh_frame section in the final linked image.
//
// Note: Previously, the linker would transform some DWARF unwind infos into
// compact unwind info. But that is fragile and no longer done.
//
// The compact unwind endoding is a 32-bit value which encoded in an
// architecture specific way, which registers to restore from where, and how
// to unwind out of the function.
//
typedef uint32_t compact_unwind_encoding_t;
// architecture independent bits
enum {
UNWIND_IS_NOT_FUNCTION_START = 0x80000000,
UNWIND_HAS_LSDA = 0x40000000,
UNWIND_PERSONALITY_MASK = 0x30000000,
};
//
// x86
//
// 1-bit: start
// 1-bit: has lsda
// 2-bit: personality index
//
// 4-bits: 0=old, 1=ebp based, 2=stack-imm, 3=stack-ind, 4=DWARF
// ebp based:
// 15-bits (5*3-bits per reg) register permutation
// 8-bits for stack offset
// frameless:
// 8-bits stack size
// 3-bits stack adjust
// 3-bits register count
// 10-bits register permutation
//
enum {
UNWIND_X86_MODE_MASK = 0x0F000000,
UNWIND_X86_MODE_EBP_FRAME = 0x01000000,
UNWIND_X86_MODE_STACK_IMMD = 0x02000000,
UNWIND_X86_MODE_STACK_IND = 0x03000000,
UNWIND_X86_MODE_DWARF = 0x04000000,
UNWIND_X86_EBP_FRAME_REGISTERS = 0x00007FFF,
UNWIND_X86_EBP_FRAME_OFFSET = 0x00FF0000,
UNWIND_X86_FRAMELESS_STACK_SIZE = 0x00FF0000,
UNWIND_X86_FRAMELESS_STACK_ADJUST = 0x0000E000,
UNWIND_X86_FRAMELESS_STACK_REG_COUNT = 0x00001C00,
UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF,
UNWIND_X86_DWARF_SECTION_OFFSET = 0x00FFFFFF,
};
enum {
UNWIND_X86_REG_NONE = 0,
UNWIND_X86_REG_EBX = 1,
UNWIND_X86_REG_ECX = 2,
UNWIND_X86_REG_EDX = 3,
UNWIND_X86_REG_EDI = 4,
UNWIND_X86_REG_ESI = 5,
UNWIND_X86_REG_EBP = 6,
};
//
// For x86 there are four modes for the compact unwind encoding:
// UNWIND_X86_MODE_EBP_FRAME:
// EBP based frame where EBP is push on stack immediately after return address,
// then ESP is moved to EBP. Thus, to unwind ESP is restored with the current
// EPB value, then EBP is restored by popping off the stack, and the return
// is done by popping the stack once more into the pc.
// All non-volatile registers that need to be restored must have been saved
// in a small range in the stack that starts EBP-4 to EBP-1020. The offset/4
// is encoded in the UNWIND_X86_EBP_FRAME_OFFSET bits. The registers saved
// are encoded in the UNWIND_X86_EBP_FRAME_REGISTERS bits as five 3-bit entries.
// Each entry contains which register to restore.
// UNWIND_X86_MODE_STACK_IMMD:
// A "frameless" (EBP not used as frame pointer) function with a small
// constant stack size. To return, a constant (encoded in the compact
// unwind encoding) is added to the ESP. Then the return is done by
// popping the stack into the pc.
// All non-volatile registers that need to be restored must have been saved
// on the stack immediately after the return address. The stack_size/4 is
// encoded in the UNWIND_X86_FRAMELESS_STACK_SIZE (max stack size is 1024).
// The number of registers saved is encoded in UNWIND_X86_FRAMELESS_STACK_REG_COUNT.
// UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION constains which registers were
// saved and their order.
// UNWIND_X86_MODE_STACK_IND:
// A "frameless" (EBP not used as frame pointer) function large constant
// stack size. This case is like the previous, except the stack size is too
// large to encode in the compact unwind encoding. Instead it requires that
// the function contains "subl $nnnnnnnn,ESP" in its prolog. The compact
// encoding contains the offset to the nnnnnnnn value in the function in
// UNWIND_X86_FRAMELESS_STACK_SIZE.
// UNWIND_X86_MODE_DWARF:
// No compact unwind encoding is available. Instead the low 24-bits of the
// compact encoding is the offset of the DWARF FDE in the __eh_frame section.
// This mode is never used in object files. It is only generated by the
// linker in final linked images which have only DWARF unwind info for a
// function.
//
// The permutation encoding is a Lehmer code sequence encoded into a
// single variable-base number so we can encode the ordering of up to
// six registers in a 10-bit space.
//
// The following is the algorithm used to create the permutation encoding used
// with frameless stacks. It is passed the number of registers to be saved and
// an array of the register numbers saved.
//
//uint32_t permute_encode(uint32_t registerCount, const uint32_t registers[6])
//{
// uint32_t renumregs[6];
// for (int i=6-registerCount; i < 6; ++i) {
// int countless = 0;
// for (int j=6-registerCount; j < i; ++j) {
// if ( registers[j] < registers[i] )
// ++countless;
// }
// renumregs[i] = registers[i] - countless -1;
// }
// uint32_t permutationEncoding = 0;
// switch ( registerCount ) {
// case 6:
// permutationEncoding |= (120*renumregs[0] + 24*renumregs[1]
// + 6*renumregs[2] + 2*renumregs[3]
// + renumregs[4]);
// break;
// case 5:
// permutationEncoding |= (120*renumregs[1] + 24*renumregs[2]
// + 6*renumregs[3] + 2*renumregs[4]
// + renumregs[5]);
// break;
// case 4:
// permutationEncoding |= (60*renumregs[2] + 12*renumregs[3]
// + 3*renumregs[4] + renumregs[5]);
// break;
// case 3:
// permutationEncoding |= (20*renumregs[3] + 4*renumregs[4]
// + renumregs[5]);
// break;
// case 2:
// permutationEncoding |= (5*renumregs[4] + renumregs[5]);
// break;
// case 1:
// permutationEncoding |= (renumregs[5]);
// break;
// }
// return permutationEncoding;
//}
//
//
// x86_64
//
// 1-bit: start
// 1-bit: has lsda
// 2-bit: personality index
//
// 4-bits: 0=old, 1=rbp based, 2=stack-imm, 3=stack-ind, 4=DWARF
// rbp based:
// 15-bits (5*3-bits per reg) register permutation
// 8-bits for stack offset
// frameless:
// 8-bits stack size
// 3-bits stack adjust
// 3-bits register count
// 10-bits register permutation
//
enum {
UNWIND_X86_64_MODE_MASK = 0x0F000000,
UNWIND_X86_64_MODE_RBP_FRAME = 0x01000000,
UNWIND_X86_64_MODE_STACK_IMMD = 0x02000000,
UNWIND_X86_64_MODE_STACK_IND = 0x03000000,
UNWIND_X86_64_MODE_DWARF = 0x04000000,
UNWIND_X86_64_RBP_FRAME_REGISTERS = 0x00007FFF,
UNWIND_X86_64_RBP_FRAME_OFFSET = 0x00FF0000,
UNWIND_X86_64_FRAMELESS_STACK_SIZE = 0x00FF0000,
UNWIND_X86_64_FRAMELESS_STACK_ADJUST = 0x0000E000,
UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT = 0x00001C00,
UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF,
UNWIND_X86_64_DWARF_SECTION_OFFSET = 0x00FFFFFF,
};
enum {
UNWIND_X86_64_REG_NONE = 0,
UNWIND_X86_64_REG_RBX = 1,
UNWIND_X86_64_REG_R12 = 2,
UNWIND_X86_64_REG_R13 = 3,
UNWIND_X86_64_REG_R14 = 4,
UNWIND_X86_64_REG_R15 = 5,
UNWIND_X86_64_REG_RBP = 6,
};
//
// For x86_64 there are four modes for the compact unwind encoding:
// UNWIND_X86_64_MODE_RBP_FRAME:
// RBP based frame where RBP is push on stack immediately after return address,
// then RSP is moved to RBP. Thus, to unwind RSP is restored with the current
// EPB value, then RBP is restored by popping off the stack, and the return
// is done by popping the stack once more into the pc.
// All non-volatile registers that need to be restored must have been saved
// in a small range in the stack that starts RBP-8 to RBP-2040. The offset/8
// is encoded in the UNWIND_X86_64_RBP_FRAME_OFFSET bits. The registers saved
// are encoded in the UNWIND_X86_64_RBP_FRAME_REGISTERS bits as five 3-bit entries.
// Each entry contains which register to restore.
// UNWIND_X86_64_MODE_STACK_IMMD:
// A "frameless" (RBP not used as frame pointer) function with a small
// constant stack size. To return, a constant (encoded in the compact
// unwind encoding) is added to the RSP. Then the return is done by
// popping the stack into the pc.
// All non-volatile registers that need to be restored must have been saved
// on the stack immediately after the return address. The stack_size/8 is
// encoded in the UNWIND_X86_64_FRAMELESS_STACK_SIZE (max stack size is 2048).
// The number of registers saved is encoded in UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT.
// UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION constains which registers were
// saved and their order.
// UNWIND_X86_64_MODE_STACK_IND:
// A "frameless" (RBP not used as frame pointer) function large constant
// stack size. This case is like the previous, except the stack size is too
// large to encode in the compact unwind encoding. Instead it requires that
// the function contains "subq $nnnnnnnn,RSP" in its prolog. The compact
// encoding contains the offset to the nnnnnnnn value in the function in
// UNWIND_X86_64_FRAMELESS_STACK_SIZE.
// UNWIND_X86_64_MODE_DWARF:
// No compact unwind encoding is available. Instead the low 24-bits of the
// compact encoding is the offset of the DWARF FDE in the __eh_frame section.
// This mode is never used in object files. It is only generated by the
// linker in final linked images which have only DWARF unwind info for a
// function.
//
// ARM64
//
// 1-bit: start
// 1-bit: has lsda
// 2-bit: personality index
//
// 4-bits: 4=frame-based, 3=DWARF, 2=frameless
// frameless:
// 12-bits of stack size
// frame-based:
// 4-bits D reg pairs saved
// 5-bits X reg pairs saved
// DWARF:
// 24-bits offset of DWARF FDE in __eh_frame section
//
enum {
UNWIND_ARM64_MODE_MASK = 0x0F000000,
UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
UNWIND_ARM64_MODE_DWARF = 0x03000000,
UNWIND_ARM64_MODE_FRAME = 0x04000000,
UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800,
UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK = 0x00FFF000,
UNWIND_ARM64_DWARF_SECTION_OFFSET = 0x00FFFFFF,
};
// For arm64 there are three modes for the compact unwind encoding:
// UNWIND_ARM64_MODE_FRAME:
// This is a standard arm64 prolog where FP/LR are immediately pushed on the
// stack, then SP is copied to FP. If there are any non-volatile registers
// saved, then are copied into the stack frame in pairs in a contiguous
// range right below the saved FP/LR pair. Any subset of the five X pairs
// and four D pairs can be saved, but the memory layout must be in register
// number order.
// UNWIND_ARM64_MODE_FRAMELESS:
// A "frameless" leaf function, where FP/LR are not saved. The return address
// remains in LR throughout the function. If any non-volatile registers
// are saved, they must be pushed onto the stack before any stack space is
// allocated for local variables. The stack sized (including any saved
// non-volatile registers) divided by 16 is encoded in the bits
// UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK.
// UNWIND_ARM64_MODE_DWARF:
// No compact unwind encoding is available. Instead the low 24-bits of the
// compact encoding is the offset of the DWARF FDE in the __eh_frame section.
// This mode is never used in object files. It is only generated by the
// linker in final linked images which have only DWARF unwind info for a
// function.
//
#ifndef __OPEN_SOURCE__
//
// armv7k
//
// 1-bit: start
// 1-bit: has lsda
// 2-bit: personality index
//
// 4-bits: 1=frame, 2=frame+dregs, 4=dwarf
//
enum {
UNWIND_ARM_MODE_MASK = 0x0F000000,
UNWIND_ARM_MODE_FRAME = 0x01000000,
UNWIND_ARM_MODE_FRAME_D = 0x02000000,
UNWIND_ARM_MODE_DWARF = 0x04000000,
UNWIND_ARM_FRAME_STACK_ADJUST_MASK = 0x00C00000,
UNWIND_ARM_FRAME_FIRST_PUSH_R4 = 0x00000001,
UNWIND_ARM_FRAME_FIRST_PUSH_R5 = 0x00000002,
UNWIND_ARM_FRAME_FIRST_PUSH_R6 = 0x00000004,
UNWIND_ARM_FRAME_SECOND_PUSH_R8 = 0x00000008,
UNWIND_ARM_FRAME_SECOND_PUSH_R9 = 0x00000010,
UNWIND_ARM_FRAME_SECOND_PUSH_R10 = 0x00000020,
UNWIND_ARM_FRAME_SECOND_PUSH_R11 = 0x00000040,
UNWIND_ARM_FRAME_SECOND_PUSH_R12 = 0x00000080,
UNWIND_ARM_FRAME_D_REG_COUNT_MASK = 0x00000700,
UNWIND_ARM_DWARF_SECTION_OFFSET = 0x00FFFFFF,
};
// For armv7k there are three modes for the compact unwind encoding:
// UNWIND_ARM_MODE_FRAME:
// This is a standard arm prolog where lr/r7 are immediately pushed on the
// stack. As part of that first push r4, r5, or r6 can be also pushed
// and if so the FIRST_PUSH bit is set in the compact unwind. Additionally
// there can be a second push multiple which can save r8 through r12.
// If that is used, the registers saved is recorded with a SECOND_PUSH bit.
// Lastly, for var-args support, the prolog may save r1, r2, r3 to the
// stack before the frame push. If that is done the STACK_ADJUST_MASK
// records that the stack pointer must be adjust (e.g 0x00800000 means
// the stack pointer was adjusted 8 bytes down and the unwinder would
// need to add back 8 bytes to SP when unwinding through this function.
// UNWIND_ARM_MODE_FRAME_D:
// This is the same as UNWIND_ARM_MODE_FRAME, except that additionally
// some D registers were saved. The D_REG_COUNT_MASK contains which
// set if D registers were saved and where. There are currently 8 (0-7)
// possible D register save patterns supported.
// UNWIND_ARM_MODE_DWARF:
// No compact unwind encoding is available. Instead the low 24-bits of the
// compact encoding is the offset of the dwarf FDE in the __eh_frame section.
// The offset only exists in final linked images. It is zero in object files.
#endif
////////////////////////////////////////////////////////////////////////////////
//
// Relocatable Object Files: __LD,__compact_unwind
//
////////////////////////////////////////////////////////////////////////////////
//
// A compiler can generated compact unwind information for a function by adding
// a "row" to the __LD,__compact_unwind section. This section has the
// S_ATTR_DEBUG bit set, so the section will be ignored by older linkers.
// It is removed by the new linker, so never ends up in final executables.
// This section is a table, initially with one row per function (that needs
// unwind info). The table columns and some conceptual entries are:
//
// range-start pointer to start of function/range
// range-length
// compact-unwind-encoding 32-bit encoding
// personality-function or zero if no personality function
// lsda or zero if no LSDA data
//
// The length and encoding fields are 32-bits. The other are all pointer sized.
//
// In x86_64 assembly, these entry would look like:
//
// .section __LD,__compact_unwind,regular,debug
//
// #compact unwind for _foo
// .quad _foo
// .set L1,LfooEnd-_foo
// .long L1
// .long 0x01010001
// .quad 0
// .quad 0
//
// #compact unwind for _bar
// .quad _bar
// .set L2,LbarEnd-_bar
// .long L2
// .long 0x01020011
// .quad __gxx_personality
// .quad except_tab1
//
//
// Notes: There is no need for any labels in the the __compact_unwind section.
// The use of the .set directive is to force the evaluation of the
// range-length at assembly time, instead of generating relocations.
//
// To support future compiler optimizations where which non-volatile registers
// are saved changes within a function (e.g. delay saving non-volatiles until
// necessary), there can by multiple lines in the __compact_unwind table for one
// function, each with a different (non-overlapping) range and each with
// different compact unwind encodings that correspond to the non-volatiles
// saved at that range of the function.
//
// If a particular function is so wacky that there is no compact unwind way
// to encode it, then the compiler can emit traditional DWARF unwind info.
// The runtime will use which ever is available.
//
// Runtime support for compact unwind encodings are only available on 10.6
// and later. So, the compiler should not generate it when targeting pre-10.6.
////////////////////////////////////////////////////////////////////////////////
//
// Final Linked Images: __TEXT,__unwind_info
//
////////////////////////////////////////////////////////////////////////////////
//
// The __TEXT,__unwind_info section is laid out for an efficient two level lookup.
// The header of the section contains a coarse index that maps function address
// to the page (4096 byte block) containing the unwind info for that function.
//
#define UNWIND_SECTION_VERSION 1
struct unwind_info_section_header
{
uint32_t version; // UNWIND_SECTION_VERSION
uint32_t commonEncodingsArraySectionOffset;
uint32_t commonEncodingsArrayCount;
uint32_t personalityArraySectionOffset;
uint32_t personalityArrayCount;
uint32_t indexSectionOffset;
uint32_t indexCount;
// compact_unwind_encoding_t[]
// uint32_t personalities[]
// unwind_info_section_header_index_entry[]
// unwind_info_section_header_lsda_index_entry[]
};
struct unwind_info_section_header_index_entry
{
uint32_t functionOffset;
uint32_t secondLevelPagesSectionOffset; // section offset to start of regular or compress page
uint32_t lsdaIndexArraySectionOffset; // section offset to start of lsda_index array for this range
};
struct unwind_info_section_header_lsda_index_entry
{
uint32_t functionOffset;
uint32_t lsdaOffset;
};
//
// There are two kinds of second level index pages: regular and compressed.
// A compressed page can hold up to 1021 entries, but it cannot be used
// if too many different encoding types are used. The regular page holds
// 511 entries.
//
struct unwind_info_regular_second_level_entry
{
uint32_t functionOffset;
compact_unwind_encoding_t encoding;
};
#define UNWIND_SECOND_LEVEL_REGULAR 2
struct unwind_info_regular_second_level_page_header
{
uint32_t kind; // UNWIND_SECOND_LEVEL_REGULAR
uint16_t entryPageOffset;
uint16_t entryCount;
// entry array
};
#define UNWIND_SECOND_LEVEL_COMPRESSED 3
struct unwind_info_compressed_second_level_page_header
{
uint32_t kind; // UNWIND_SECOND_LEVEL_COMPRESSED
uint16_t entryPageOffset;
uint16_t entryCount;
uint16_t encodingsPageOffset;
uint16_t encodingsCount;
// 32-bit entry array
// encodings array
};
#define UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(entry) (entry & 0x00FFFFFF)
#define UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX(entry) ((entry >> 24) & 0xFF)
#endif

View File

@@ -0,0 +1,83 @@
/*
* Copyright (c) 2016 Apple, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#ifndef _MACH_O_FAT_H_
#define _MACH_O_FAT_H_
/*
* This header file describes the structures of the file format for "fat"
* architecture specific file (wrapper design). At the begining of the file
* there is one fat_header structure followed by a number of fat_arch
* structures. For each architecture in the file, specified by a pair of
* cputype and cpusubtype, the fat_header describes the file offset, file
* size and alignment in the file of the architecture specific member.
* The padded bytes in the file to place each member on it's specific alignment
* are defined to be read as zeros and can be left as "holes" if the file system
* can support them as long as they read as zeros.
*
* All structures defined here are always written and read to/from disk
* in big-endian order.
*/
/*
* <mach/machine.h> is needed here for the cpu_type_t and cpu_subtype_t types
* and contains the constants for the possible values of these types.
*/
#include <stdint.h>
#include <mach/machine.h>
#include <architecture/byte_order.h>
#define FAT_MAGIC 0xcafebabe
#define FAT_CIGAM 0xbebafeca /* NXSwapLong(FAT_MAGIC) */
struct fat_header {
uint32_t magic; /* FAT_MAGIC or FAT_MAGIC_64 */
uint32_t nfat_arch; /* number of structs that follow */
};
struct fat_arch {
cpu_type_t cputype; /* cpu specifier (int) */
cpu_subtype_t cpusubtype; /* machine specifier (int) */
uint32_t offset; /* file offset to this object file */
uint32_t size; /* size of this object file */
uint32_t align; /* alignment as a power of 2 */
};
/*
* The support for the 64-bit fat file format described here is a work in
* progress and not yet fully supported in all the Apple Developer Tools.
*
* When a slice is greater than 4mb or an offset to a slice is greater than 4mb
* then the 64-bit fat file format is used.
*/
#define FAT_MAGIC_64 0xcafebabf
#define FAT_CIGAM_64 0xbfbafeca /* NXSwapLong(FAT_MAGIC_64) */
struct fat_arch_64 {
cpu_type_t cputype; /* cpu specifier (int) */
cpu_subtype_t cpusubtype; /* machine specifier (int) */
uint64_t offset; /* file offset to this object file */
uint64_t size; /* size of this object file */
uint32_t align; /* alignment as a power of 2 */
uint32_t reserved; /* reserved */
};
#endif /* _MACH_O_FAT_H_ */

View File

@@ -0,0 +1,324 @@
/*
* Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#ifndef _MACHO_NLIST_H_
#define _MACHO_NLIST_H_
/* $NetBSD: nlist.h,v 1.5 1994/10/26 00:56:11 cgd Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc.
* All or some portions of this file are derived from material licensed
* to the University of California by American Telephone and Telegraph
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
* the permission of UNIX System Laboratories, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nlist.h 8.2 (Berkeley) 1/21/94
*/
#include <stdint.h>
/*
* Format of a symbol table entry of a Mach-O file for 32-bit architectures.
* Modified from the BSD format. The modifications from the original format
* were changing n_other (an unused field) to n_sect and the addition of the
* N_SECT type. These modifications are required to support symbols in a larger
* number of sections not just the three sections (text, data and bss) in a BSD
* file.
*/
struct nlist {
union {
#ifndef __LP64__
char *n_name; /* for use when in-core */
#endif
uint32_t n_strx; /* index into the string table */
} n_un;
uint8_t n_type; /* type flag, see below */
uint8_t n_sect; /* section number or NO_SECT */
int16_t n_desc; /* see <mach-o/stab.h> */
uint32_t n_value; /* value of this symbol (or stab offset) */
};
/*
* This is the symbol table entry structure for 64-bit architectures.
*/
struct nlist_64 {
union {
uint32_t n_strx; /* index into the string table */
} n_un;
uint8_t n_type; /* type flag, see below */
uint8_t n_sect; /* section number or NO_SECT */
uint16_t n_desc; /* see <mach-o/stab.h> */
uint64_t n_value; /* value of this symbol (or stab offset) */
};
/*
* Symbols with a index into the string table of zero (n_un.n_strx == 0) are
* defined to have a null, "", name. Therefore all string indexes to non null
* names must not have a zero string index. This is bit historical information
* that has never been well documented.
*/
/*
* The n_type field really contains four fields:
* unsigned char N_STAB:3,
* N_PEXT:1,
* N_TYPE:3,
* N_EXT:1;
* which are used via the following masks.
*/
#define N_STAB 0xe0 /* if any of these bits set, a symbolic debugging entry */
#define N_PEXT 0x10 /* private external symbol bit */
#define N_TYPE 0x0e /* mask for the type bits */
#define N_EXT 0x01 /* external symbol bit, set for external symbols */
/*
* Only symbolic debugging entries have some of the N_STAB bits set and if any
* of these bits are set then it is a symbolic debugging entry (a stab). In
* which case then the values of the n_type field (the entire field) are given
* in <mach-o/stab.h>
*/
/*
* Values for N_TYPE bits of the n_type field.
*/
#define N_UNDF 0x0 /* undefined, n_sect == NO_SECT */
#define N_ABS 0x2 /* absolute, n_sect == NO_SECT */
#define N_SECT 0xe /* defined in section number n_sect */
#define N_PBUD 0xc /* prebound undefined (defined in a dylib) */
#define N_INDR 0xa /* indirect */
/*
* If the type is N_INDR then the symbol is defined to be the same as another
* symbol. In this case the n_value field is an index into the string table
* of the other symbol's name. When the other symbol is defined then they both
* take on the defined type and value.
*/
/*
* If the type is N_SECT then the n_sect field contains an ordinal of the
* section the symbol is defined in. The sections are numbered from 1 and
* refer to sections in order they appear in the load commands for the file
* they are in. This means the same ordinal may very well refer to different
* sections in different files.
*
* The n_value field for all symbol table entries (including N_STAB's) gets
* updated by the link editor based on the value of it's n_sect field and where
* the section n_sect references gets relocated. If the value of the n_sect
* field is NO_SECT then it's n_value field is not changed by the link editor.
*/
#define NO_SECT 0 /* symbol is not in any section */
#define MAX_SECT 255 /* 1 thru 255 inclusive */
/*
* Common symbols are represented by undefined (N_UNDF) external (N_EXT) types
* who's values (n_value) are non-zero. In which case the value of the n_value
* field is the size (in bytes) of the common symbol. The n_sect field is set
* to NO_SECT. The alignment of a common symbol may be set as a power of 2
* between 2^1 and 2^15 as part of the n_desc field using the macros below. If
* the alignment is not set (a value of zero) then natural alignment based on
* the size is used.
*/
#define GET_COMM_ALIGN(n_desc) (((n_desc) >> 8) & 0x0f)
#define SET_COMM_ALIGN(n_desc,align) \
(n_desc) = (((n_desc) & 0xf0ff) | (((align) & 0x0f) << 8))
/*
* To support the lazy binding of undefined symbols in the dynamic link-editor,
* the undefined symbols in the symbol table (the nlist structures) are marked
* with the indication if the undefined reference is a lazy reference or
* non-lazy reference. If both a non-lazy reference and a lazy reference is
* made to the same symbol the non-lazy reference takes precedence. A reference
* is lazy only when all references to that symbol are made through a symbol
* pointer in a lazy symbol pointer section.
*
* The implementation of marking nlist structures in the symbol table for
* undefined symbols will be to use some of the bits of the n_desc field as a
* reference type. The mask REFERENCE_TYPE will be applied to the n_desc field
* of an nlist structure for an undefined symbol to determine the type of
* undefined reference (lazy or non-lazy).
*
* The constants for the REFERENCE FLAGS are propagated to the reference table
* in a shared library file. In that case the constant for a defined symbol,
* REFERENCE_FLAG_DEFINED, is also used.
*/
/* Reference type bits of the n_desc field of undefined symbols */
#define REFERENCE_TYPE 0x7
/* types of references */
#define REFERENCE_FLAG_UNDEFINED_NON_LAZY 0
#define REFERENCE_FLAG_UNDEFINED_LAZY 1
#define REFERENCE_FLAG_DEFINED 2
#define REFERENCE_FLAG_PRIVATE_DEFINED 3
#define REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY 4
#define REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY 5
/*
* To simplify stripping of objects that use are used with the dynamic link
* editor, the static link editor marks the symbols defined an object that are
* referenced by a dynamicly bound object (dynamic shared libraries, bundles).
* With this marking strip knows not to strip these symbols.
*/
#define REFERENCED_DYNAMICALLY 0x0010
/*
* For images created by the static link editor with the -twolevel_namespace
* option in effect the flags field of the mach header is marked with
* MH_TWOLEVEL. And the binding of the undefined references of the image are
* determined by the static link editor. Which library an undefined symbol is
* bound to is recorded by the static linker in the high 8 bits of the n_desc
* field using the SET_LIBRARY_ORDINAL macro below. The ordinal recorded
* references the libraries listed in the Mach-O's LC_LOAD_DYLIB,
* LC_LOAD_WEAK_DYLIB, LC_REEXPORT_DYLIB, LC_LOAD_UPWARD_DYLIB, and
* LC_LAZY_LOAD_DYLIB, etc. load commands in the order they appear in the
* headers. The library ordinals start from 1.
* For a dynamic library that is built as a two-level namespace image the
* undefined references from module defined in another use the same nlist struct
* an in that case SELF_LIBRARY_ORDINAL is used as the library ordinal. For
* defined symbols in all images they also must have the library ordinal set to
* SELF_LIBRARY_ORDINAL. The EXECUTABLE_ORDINAL refers to the executable
* image for references from plugins that refer to the executable that loads
* them.
*
* The DYNAMIC_LOOKUP_ORDINAL is for undefined symbols in a two-level namespace
* image that are looked up by the dynamic linker with flat namespace semantics.
* This ordinal was added as a feature in Mac OS X 10.3 by reducing the
* value of MAX_LIBRARY_ORDINAL by one. So it is legal for existing binaries
* or binaries built with older tools to have 0xfe (254) dynamic libraries. In
* this case the ordinal value 0xfe (254) must be treated as a library ordinal
* for compatibility.
*/
#define GET_LIBRARY_ORDINAL(n_desc) (((n_desc) >> 8) & 0xff)
#define SET_LIBRARY_ORDINAL(n_desc,ordinal) \
(n_desc) = (((n_desc) & 0x00ff) | (((ordinal) & 0xff) << 8))
#define SELF_LIBRARY_ORDINAL 0x0
#define MAX_LIBRARY_ORDINAL 0xfd
#define DYNAMIC_LOOKUP_ORDINAL 0xfe
#define EXECUTABLE_ORDINAL 0xff
/*
* The bit 0x0020 of the n_desc field is used for two non-overlapping purposes
* and has two different symbolic names, N_NO_DEAD_STRIP and N_DESC_DISCARDED.
*/
/*
* The N_NO_DEAD_STRIP bit of the n_desc field only ever appears in a
* relocatable .o file (MH_OBJECT filetype). And is used to indicate to the
* static link editor it is never to dead strip the symbol.
*/
#define N_NO_DEAD_STRIP 0x0020 /* symbol is not to be dead stripped */
/*
* The N_DESC_DISCARDED bit of the n_desc field never appears in linked image.
* But is used in very rare cases by the dynamic link editor to mark an in
* memory symbol as discared and longer used for linking.
*/
#define N_DESC_DISCARDED 0x0020 /* symbol is discarded */
/*
* The N_WEAK_REF bit of the n_desc field indicates to the dynamic linker that
* the undefined symbol is allowed to be missing and is to have the address of
* zero when missing.
*/
#define N_WEAK_REF 0x0040 /* symbol is weak referenced */
/*
* The N_WEAK_DEF bit of the n_desc field indicates to the static and dynamic
* linkers that the symbol definition is weak, allowing a non-weak symbol to
* also be used which causes the weak definition to be discared. Currently this
* is only supported for symbols in coalesed sections.
*/
#define N_WEAK_DEF 0x0080 /* coalesed symbol is a weak definition */
/*
* The N_REF_TO_WEAK bit of the n_desc field indicates to the dynamic linker
* that the undefined symbol should be resolved using flat namespace searching.
*/
#define N_REF_TO_WEAK 0x0080 /* reference to a weak symbol */
/*
* The N_ARM_THUMB_DEF bit of the n_desc field indicates that the symbol is
* a defintion of a Thumb function.
*/
#define N_ARM_THUMB_DEF 0x0008 /* symbol is a Thumb function (ARM) */
/*
* The N_SYMBOL_RESOLVER bit of the n_desc field indicates that the
* that the function is actually a resolver function and should
* be called to get the address of the real function to use.
* This bit is only available in .o files (MH_OBJECT filetype)
*/
#define N_SYMBOL_RESOLVER 0x0100
/*
* The N_ALT_ENTRY bit of the n_desc field indicates that the
* symbol is pinned to the previous content.
*/
#define N_ALT_ENTRY 0x0200
/*
* The N_COLD_FUNC bit of the n_desc field indicates that the symbol is used
* infrequently and the linker should order it towards the end of the section.
*/
#define N_COLD_FUNC 0x0400
#ifndef __STRICT_BSD__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*
* The function nlist(3) from the C library.
*/
extern int nlist (const char *filename, struct nlist *list);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __STRICT_BSD__ */
#endif /* _MACHO_LIST_H_ */

View File

@@ -0,0 +1,90 @@
/*
* Copyright (c) 2016 Apple, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/* ranlib.h 4.1 83/05/03 */
#ifndef _MACH_O_RANLIB_H_
#define _MACH_O_RANLIB_H_
#include <stdint.h>
#include <sys/types.h> /* off_t */
/*
* There are two known orders of table of contents for archives. The first is
* the order ranlib(1) originally produced and still produces without any
* options. This table of contents has the archive member name "__.SYMDEF"
* This order has the ranlib structures in the order the objects appear in the
* archive and the symbol names of those objects in the order of symbol table.
* The second know order is sorted by symbol name and is produced with the -s
* option to ranlib(1). This table of contents has the archive member name
* "__.SYMDEF SORTED" and many programs (notably the 1.0 version of ld(1) can't
* tell the difference between names because of the imbedded blank in the name
* and works with either table of contents). This second order is used by the
* post 1.0 link editor to produce faster linking. The original 1.0 version of
* ranlib(1) gets confused when it is run on a archive with the second type of
* table of contents because it and ar(1) which it uses use different ways to
* determined the member name (ar(1) treats all blanks in the name as
* significant and ranlib(1) only checks for the first one).
*/
#define SYMDEF "__.SYMDEF"
#define SYMDEF_SORTED "__.SYMDEF SORTED"
/*
* Structure of the __.SYMDEF table of contents for an archive.
* __.SYMDEF begins with a uint32_t giving the size in bytes of the ranlib
* structures which immediately follow, and then continues with a string
* table consisting of a uint32_t giving the number of bytes of strings which
* follow and then the strings themselves. The ran_strx fields index the
* string table whose first byte is numbered 0.
*/
struct ranlib {
union {
uint32_t ran_strx; /* string table index of */
#ifndef __LP64__
char *ran_name; /* symbol defined by */
#endif
} ran_un;
uint32_t ran_off; /* library member at this offset */
};
#define SYMDEF_64 "__.SYMDEF_64"
#define SYMDEF_64_SORTED "__.SYMDEF_64 SORTED"
/*
* The support for the 64-bit table of contents described here is a work in
* progress and not yet fully supported in all the Apple Developer Tools.
*
* When an archive offset to a library member is more than 32-bits then this is
* the structure of the __.SYMDEF_64 table of contents for an archive.
* __.SYMDEF_64 begins with a uint64_t giving the size in bytes of the ranlib
* structures which immediately follow, and then continues with a string
* table consisting of a uint64_t giving the number of bytes of strings which
* follow and then the strings themselves. The ran_strx fields index the
* string table whose first byte is numbered 0.
*/
struct ranlib_64 {
union {
uint64_t ran_strx; /* string table index of */
} ran_un;
uint64_t ran_off; /* library member at this offset */
};
#endif /* _MACH_O_RANLIB_H_ */

View File

@@ -0,0 +1,203 @@
/*
* Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/* $NetBSD: exec.h,v 1.6 1994/10/27 04:16:05 cgd Exp $ */
/*
* Copyright (c) 1993 Christopher G. Demetriou
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MACHO_RELOC_H_
#define _MACHO_RELOC_H_
#include <stdint.h>
/*
* Format of a relocation entry of a Mach-O file. Modified from the 4.3BSD
* format. The modifications from the original format were changing the value
* of the r_symbolnum field for "local" (r_extern == 0) relocation entries.
* This modification is required to support symbols in an arbitrary number of
* sections not just the three sections (text, data and bss) in a 4.3BSD file.
* Also the last 4 bits have had the r_type tag added to them.
*/
struct relocation_info {
int32_t r_address; /* offset in the section to what is being
relocated */
uint32_t r_symbolnum:24, /* symbol index if r_extern == 1 or section
ordinal if r_extern == 0 */
r_pcrel:1, /* was relocated pc relative already */
r_length:2, /* 0=byte, 1=word, 2=long, 3=quad */
r_extern:1, /* does not include value of sym referenced */
r_type:4; /* if not 0, machine specific relocation type */
};
#define R_ABS 0 /* absolute relocation type for Mach-O files */
/*
* The r_address is not really the address as it's name indicates but an offset.
* In 4.3BSD a.out objects this offset is from the start of the "segment" for
* which relocation entry is for (text or data). For Mach-O object files it is
* also an offset but from the start of the "section" for which the relocation
* entry is for. See comments in <mach-o/loader.h> about the r_address feild
* in images for used with the dynamic linker.
*
* In 4.3BSD a.out objects if r_extern is zero then r_symbolnum is an ordinal
* for the segment the symbol being relocated is in. These ordinals are the
* symbol types N_TEXT, N_DATA, N_BSS or N_ABS. In Mach-O object files these
* ordinals refer to the sections in the object file in the order their section
* structures appear in the headers of the object file they are in. The first
* section has the ordinal 1, the second 2, and so on. This means that the
* same ordinal in two different object files could refer to two different
* sections. And further could have still different ordinals when combined
* by the link-editor. The value R_ABS is used for relocation entries for
* absolute symbols which need no further relocation.
*/
/*
* For RISC machines some of the references are split across two instructions
* and the instruction does not contain the complete value of the reference.
* In these cases a second, or paired relocation entry, follows each of these
* relocation entries, using a PAIR r_type, which contains the other part of the
* reference not contained in the instruction. This other part is stored in the
* pair's r_address field. The exact number of bits of the other part of the
* reference store in the r_address field is dependent on the particular
* relocation type for the particular architecture.
*/
/*
* To make scattered loading by the link editor work correctly "local"
* relocation entries can't be used when the item to be relocated is the value
* of a symbol plus an offset (where the resulting expresion is outside the
* block the link editor is moving, a blocks are divided at symbol addresses).
* In this case. where the item is a symbol value plus offset, the link editor
* needs to know more than just the section the symbol was defined. What is
* needed is the actual value of the symbol without the offset so it can do the
* relocation correctly based on where the value of the symbol got relocated to
* not the value of the expression (with the offset added to the symbol value).
* So for the NeXT 2.0 release no "local" relocation entries are ever used when
* there is a non-zero offset added to a symbol. The "external" and "local"
* relocation entries remain unchanged.
*
* The implemention is quite messy given the compatibility with the existing
* relocation entry format. The ASSUMPTION is that a section will never be
* bigger than 2**24 - 1 (0x00ffffff or 16,777,215) bytes. This assumption
* allows the r_address (which is really an offset) to fit in 24 bits and high
* bit of the r_address field in the relocation_info structure to indicate
* it is really a scattered_relocation_info structure. Since these are only
* used in places where "local" relocation entries are used and not where
* "external" relocation entries are used the r_extern field has been removed.
*
* For scattered loading to work on a RISC machine where some of the references
* are split across two instructions the link editor needs to be assured that
* each reference has a unique 32 bit reference (that more than one reference is
* NOT sharing the same high 16 bits for example) so it move each referenced
* item independent of each other. Some compilers guarantees this but the
* compilers don't so scattered loading can be done on those that do guarantee
* this.
*/
#if defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__)
/*
* The reason for the ifdef's of __BIG_ENDIAN__ and __LITTLE_ENDIAN__ are that
* when stattered relocation entries were added the mistake of using a mask
* against a structure that is made up of bit fields was used. To make this
* design work this structure must be laid out in memory the same way so the
* mask can be applied can check the same bit each time (r_scattered).
*/
#endif /* defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__) */
#define R_SCATTERED 0x80000000 /* mask to be applied to the r_address field
of a relocation_info structure to tell that
is is really a scattered_relocation_info
stucture */
struct scattered_relocation_info {
#ifdef __BIG_ENDIAN__
uint32_t r_scattered:1, /* 1=scattered, 0=non-scattered (see above) */
r_pcrel:1, /* was relocated pc relative already */
r_length:2, /* 0=byte, 1=word, 2=long, 3=quad */
r_type:4, /* if not 0, machine specific relocation type */
r_address:24; /* offset in the section to what is being
relocated */
int32_t r_value; /* the value the item to be relocated is
refering to (without any offset added) */
#endif /* __BIG_ENDIAN__ */
#ifdef __LITTLE_ENDIAN__
uint32_t
r_address:24, /* offset in the section to what is being
relocated */
r_type:4, /* if not 0, machine specific relocation type */
r_length:2, /* 0=byte, 1=word, 2=long, 3=quad */
r_pcrel:1, /* was relocated pc relative already */
r_scattered:1; /* 1=scattered, 0=non-scattered (see above) */
int32_t r_value; /* the value the item to be relocated is
refering to (without any offset added) */
#endif /* __LITTLE_ENDIAN__ */
};
/*
* Relocation types used in a generic implementation. Relocation entries for
* normal things use the generic relocation as discribed above and their r_type
* is GENERIC_RELOC_VANILLA (a value of zero).
*
* Another type of generic relocation, GENERIC_RELOC_SECTDIFF, is to support
* the difference of two symbols defined in different sections. That is the
* expression "symbol1 - symbol2 + constant" is a relocatable expression when
* both symbols are defined in some section. For this type of relocation the
* both relocations entries are scattered relocation entries. The value of
* symbol1 is stored in the first relocation entry's r_value field and the
* value of symbol2 is stored in the pair's r_value field.
*
* A special case for a prebound lazy pointer is needed to beable to set the
* value of the lazy pointer back to its non-prebound state. This is done
* using the GENERIC_RELOC_PB_LA_PTR r_type. This is a scattered relocation
* entry where the r_value feild is the value of the lazy pointer not prebound.
*/
enum reloc_type_generic
{
GENERIC_RELOC_VANILLA, /* generic relocation as discribed above */
GENERIC_RELOC_PAIR, /* Only follows a GENERIC_RELOC_SECTDIFF */
GENERIC_RELOC_SECTDIFF,
GENERIC_RELOC_PB_LA_PTR, /* prebound lazy pointer */
GENERIC_RELOC_LOCAL_SECTDIFF,
GENERIC_RELOC_TLV /* thread local variables */
};
#endif /* _MACHO_RELOC_H_ */

View File

@@ -0,0 +1,126 @@
/*
* Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#ifndef _MACHO_STAB_H_
#define _MACHO_STAB_H_
/* $NetBSD: stab.h,v 1.4 1994/10/26 00:56:25 cgd Exp $ */
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)stab.h 5.2 (Berkeley) 4/4/91
*/
/*
* This file gives definitions supplementing <nlist.h> for permanent symbol
* table entries of Mach-O files. Modified from the BSD definitions. The
* modifications from the original definitions were changing what the values of
* what was the n_other field (an unused field) which is now the n_sect field.
* These modifications are required to support symbols in an arbitrary number of
* sections not just the three sections (text, data and bss) in a BSD file.
* The values of the defined constants have NOT been changed.
*
* These must have one of the N_STAB bits on. The n_value fields are subject
* to relocation according to the value of their n_sect field. So for types
* that refer to things in sections the n_sect field must be filled in with the
* proper section ordinal. For types that are not to have their n_value field
* relocatated the n_sect field must be NO_SECT.
*/
/*
* Symbolic debugger symbols. The comments give the conventional use for
*
* .stabs "n_name", n_type, n_sect, n_desc, n_value
*
* where n_type is the defined constant and not listed in the comment. Other
* fields not listed are zero. n_sect is the section ordinal the entry is
* refering to.
*/
#define N_GSYM 0x20 /* global symbol: name,,NO_SECT,type,0 */
#define N_FNAME 0x22 /* procedure name (f77 kludge): name,,NO_SECT,0,0 */
#define N_FUN 0x24 /* procedure: name,,n_sect,linenumber,address */
#define N_STSYM 0x26 /* static symbol: name,,n_sect,type,address */
#define N_LCSYM 0x28 /* .lcomm symbol: name,,n_sect,type,address */
#define N_BNSYM 0x2e /* begin nsect sym: 0,,n_sect,0,address */
#define N_AST 0x32 /* AST file path: name,,NO_SECT,0,0 */
#define N_OPT 0x3c /* emitted with gcc2_compiled and in gcc source */
#define N_RSYM 0x40 /* register sym: name,,NO_SECT,type,register */
#define N_SLINE 0x44 /* src line: 0,,n_sect,linenumber,address */
#define N_ENSYM 0x4e /* end nsect sym: 0,,n_sect,0,address */
#define N_SSYM 0x60 /* structure elt: name,,NO_SECT,type,struct_offset */
#define N_SO 0x64 /* source file name: name,,n_sect,0,address */
#define N_OSO 0x66 /* object file name: name,,(see below),0,st_mtime */
/* historically N_OSO set n_sect to 0. The N_OSO
* n_sect may instead hold the low byte of the
* cpusubtype value from the Mach-O header. */
#define N_LSYM 0x80 /* local sym: name,,NO_SECT,type,offset */
#define N_BINCL 0x82 /* include file beginning: name,,NO_SECT,0,sum */
#define N_SOL 0x84 /* #included file name: name,,n_sect,0,address */
#define N_PARAMS 0x86 /* compiler parameters: name,,NO_SECT,0,0 */
#define N_VERSION 0x88 /* compiler version: name,,NO_SECT,0,0 */
#define N_OLEVEL 0x8A /* compiler -O level: name,,NO_SECT,0,0 */
#define N_PSYM 0xa0 /* parameter: name,,NO_SECT,type,offset */
#define N_EINCL 0xa2 /* include file end: name,,NO_SECT,0,0 */
#define N_ENTRY 0xa4 /* alternate entry: name,,n_sect,linenumber,address */
#define N_LBRAC 0xc0 /* left bracket: 0,,NO_SECT,nesting level,address */
#define N_EXCL 0xc2 /* deleted include file: name,,NO_SECT,0,sum */
#define N_RBRAC 0xe0 /* right bracket: 0,,NO_SECT,nesting level,address */
#define N_BCOMM 0xe2 /* begin common: name,,NO_SECT,0,0 */
#define N_ECOMM 0xe4 /* end common: name,,n_sect,0,0 */
#define N_ECOML 0xe8 /* end common (local name): 0,,n_sect,0,address */
#define N_LENG 0xfe /* second stab entry with length information */
/*
* for the berkeley pascal compiler, pc(1):
*/
#define N_PC 0x30 /* global pascal symbol: name,,NO_SECT,subtype,line */
#endif /* _MACHO_STAB_H_ */

View File

@@ -0,0 +1,185 @@
/*
* Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Relocations for x86_64 are a bit different than for other architectures in
* Mach-O: Scattered relocations are not used. Almost all relocations produced
* by the compiler are external relocations. An external relocation has the
* r_extern bit set to 1 and the r_symbolnum field contains the symbol table
* index of the target label.
*
* When the assembler is generating relocations, if the target label is a local
* label (begins with 'L'), then the previous non-local label in the same
* section is used as the target of the external relocation. An addend is used
* with the distance from that non-local label to the target label. Only when
* there is no previous non-local label in the section is an internal
* relocation used.
*
* The addend (i.e. the 4 in _foo+4) is encoded in the instruction (Mach-O does
* not have RELA relocations). For PC-relative relocations, the addend is
* stored directly in the instruction. This is different from other Mach-O
* architectures, which encode the addend minus the current section offset.
*
* The relocation types are:
*
* X86_64_RELOC_UNSIGNED // for absolute addresses
* X86_64_RELOC_SIGNED // for signed 32-bit displacement
* X86_64_RELOC_BRANCH // a CALL/JMP instruction with 32-bit displacement
* X86_64_RELOC_GOT_LOAD // a MOVQ load of a GOT entry
* X86_64_RELOC_GOT // other GOT references
* X86_64_RELOC_SUBTRACTOR // must be followed by a X86_64_RELOC_UNSIGNED
*
* The following are sample assembly instructions, followed by the relocation
* and section content they generate in an object file:
*
* call _foo
* r_type=X86_64_RELOC_BRANCH, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
* E8 00 00 00 00
*
* call _foo+4
* r_type=X86_64_RELOC_BRANCH, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
* E8 04 00 00 00
*
* movq _foo@GOTPCREL(%rip), %rax
* r_type=X86_64_RELOC_GOT_LOAD, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
* 48 8B 05 00 00 00 00
*
* pushq _foo@GOTPCREL(%rip)
* r_type=X86_64_RELOC_GOT, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
* FF 35 00 00 00 00
*
* movl _foo(%rip), %eax
* r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
* 8B 05 00 00 00 00
*
* movl _foo+4(%rip), %eax
* r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
* 8B 05 04 00 00 00
*
* movb $0x12, _foo(%rip)
* r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
* C6 05 FF FF FF FF 12
*
* movl $0x12345678, _foo(%rip)
* r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
* C7 05 FC FF FF FF 78 56 34 12
*
* .quad _foo
* r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
* 00 00 00 00 00 00 00 00
*
* .quad _foo+4
* r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
* 04 00 00 00 00 00 00 00
*
* .quad _foo - _bar
* r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_bar
* r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
* 00 00 00 00 00 00 00 00
*
* .quad _foo - _bar + 4
* r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_bar
* r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
* 04 00 00 00 00 00 00 00
*
* .long _foo - _bar
* r_type=X86_64_RELOC_SUBTRACTOR, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_bar
* r_type=X86_64_RELOC_UNSIGNED, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_foo
* 00 00 00 00
*
* lea L1(%rip), %rax
* r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_prev
* 48 8d 05 12 00 00 00
* // assumes _prev is the first non-local label 0x12 bytes before L1
*
* lea L0(%rip), %rax
* r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=0, r_pcrel=1, r_symbolnum=3
* 48 8d 05 56 00 00 00
* // assumes L0 is in third section and there is no previous non-local label.
* // The rip-relative-offset of 0x00000056 is L0-address_of_next_instruction.
* // address_of_next_instruction is the address of the relocation + 4.
*
* add $6,L0(%rip)
* r_type=X86_64_RELOC_SIGNED_1, r_length=2, r_extern=0, r_pcrel=1, r_symbolnum=3
* 83 05 18 00 00 00 06
* // assumes L0 is in third section and there is no previous non-local label.
* // The rip-relative-offset of 0x00000018 is L0-address_of_next_instruction.
* // address_of_next_instruction is the address of the relocation + 4 + 1.
* // The +1 comes from SIGNED_1. This is used because the relocation is not
* // at the end of the instruction.
*
* .quad L1
* r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev
* 12 00 00 00 00 00 00 00
* // assumes _prev is the first non-local label 0x12 bytes before L1
*
* .quad L0
* r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=0, r_pcrel=0, r_symbolnum=3
* 56 00 00 00 00 00 00 00
* // assumes L0 is in third section, has an address of 0x00000056 in .o
* // file, and there is no previous non-local label
*
* .quad _foo - .
* r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev
* r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
* EE FF FF FF FF FF FF FF
* // assumes _prev is the first non-local label 0x12 bytes before this
* // .quad
*
* .quad _foo - L1
* r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev
* r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
* EE FF FF FF FF FF FF FF
* // assumes _prev is the first non-local label 0x12 bytes before L1
*
* .quad L1 - _prev
* // No relocations. This is an assembly time constant.
* 12 00 00 00 00 00 00 00
* // assumes _prev is the first non-local label 0x12 bytes before L1
*
*
*
* In final linked images, there are only two valid relocation kinds:
*
* r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_pcrel=0, r_extern=1, r_symbolnum=sym_index
* This tells dyld to add the address of a symbol to a pointer sized (8-byte)
* piece of data (i.e on disk the 8-byte piece of data contains the addend). The
* r_symbolnum contains the index into the symbol table of the target symbol.
*
* r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_pcrel=0, r_extern=0, r_symbolnum=0
* This tells dyld to adjust the pointer sized (8-byte) piece of data by the amount
* the containing image was loaded from its base address (e.g. slide).
*
*/
enum reloc_type_x86_64
{
X86_64_RELOC_UNSIGNED, // for absolute addresses
X86_64_RELOC_SIGNED, // for signed 32-bit displacement
X86_64_RELOC_BRANCH, // a CALL/JMP instruction with 32-bit displacement
X86_64_RELOC_GOT_LOAD, // a MOVQ load of a GOT entry
X86_64_RELOC_GOT, // other GOT references
X86_64_RELOC_SUBTRACTOR, // must be followed by a X86_64_RELOC_UNSIGNED
X86_64_RELOC_SIGNED_1, // for signed 32-bit displacement with a -1 addend
X86_64_RELOC_SIGNED_2, // for signed 32-bit displacement with a -2 addend
X86_64_RELOC_SIGNED_4, // for signed 32-bit displacement with a -4 addend
X86_64_RELOC_TLV, // for thread local variables
};

View File

@@ -327,6 +327,14 @@
/* Denied by security policy
*/
#define KERN_MISSING_KC 54
/* The KC on which the function is operating is missing
*/
#define KERN_INVALID_KC 55
/* The KC on which the function is operating is invalid
*/
#define KERN_RETURN_MAX 0x100
/* Maximum return value allowable
*/

View File

@@ -102,6 +102,11 @@ extern kern_return_t _kernelrpc_mach_vm_deallocate_trap(
mach_vm_size_t size
);
extern kern_return_t task_dyld_process_info_notify_get(
mach_port_name_array_t names_addr,
natural_t *names_count_addr
);
extern kern_return_t _kernelrpc_mach_vm_protect_trap(
mach_port_name_t target,
mach_vm_address_t address,

View File

@@ -146,6 +146,7 @@ typedef mach_port_t arcade_register_t;
typedef mach_port_t ipc_eventlink_t;
typedef mach_port_t eventlink_port_pair_t[2];
typedef mach_port_t suid_cred_t;
typedef mach_port_t task_id_token_t;
/*
@@ -168,6 +169,8 @@ typedef mach_port_t io_master_t;
typedef mach_port_t UNDServerRef;
typedef mach_port_t mach_eventlink_t;
typedef ipc_info_port_t exception_handler_info_t;
/*
* Mig doesn't translate the components of an array.
* For example, Mig won't use the thread_t translations
@@ -246,25 +249,26 @@ typedef uint32_t suid_cred_uid_t;
#define MACH_EVENTLINK_NULL ((mach_eventlink_t) 0)
#define IPC_EVENTLINK_NULL ((ipc_eventlink_t) 0)
#define SUID_CRED_NULL ((suid_cred_t) 0)
#define TASK_ID_TOKEN_NULL ((task_id_token_t) 0)
/* capability strictly _DECREASING_.
* not ordered the other way around because we want TASK_FLAVOR_CONTROL
* to be closest to the itk_lock. see task.h.
*/
typedef unsigned int mach_task_flavor_t;
#define TASK_FLAVOR_CONTROL 0 /* a task_t */
#define TASK_FLAVOR_CONTROL 0 /* a task_t */
#define TASK_FLAVOR_READ 1 /* a task_read_t */
#define TASK_FLAVOR_INSPECT 2 /* a task_inspect_t */
#define TASK_FLAVOR_NAME 3 /* a task_name_t */
/* capability strictly _DECREASING_ */
typedef unsigned int mach_thread_flavor_t;
#define THREAD_FLAVOR_CONTROL 0 /* a thread_t */
#define THREAD_FLAVOR_CONTROL 0 /* a thread_t */
#define THREAD_FLAVOR_READ 1 /* a thread_read_t */
#define THREAD_FLAVOR_INSPECT 2 /* a thread_inspect_t */
/* DEPRECATED */
typedef natural_t ledger_item_t;
typedef natural_t ledger_item_t;
#define LEDGER_ITEM_INFINITY ((ledger_item_t) (~0))
typedef int64_t ledger_amount_t;

View File

@@ -376,9 +376,7 @@ typedef integer_t cpu_threadtype_t;
#define CPUFAMILY_INTEL_SKYLAKE 0x37fc219f
#define CPUFAMILY_INTEL_KABYLAKE 0x0f817246
#define CPUFAMILY_INTEL_ICELAKE 0x38435547
#if !defined(RC_HIDE_XNU_COMETLAKE)
#define CPUFAMILY_INTEL_COMETLAKE 0x1cf8a03e
#endif /* not RC_HIDE_XNU_COMETLAKE */
#define CPUFAMILY_ARM_9 0xe73283ae
#define CPUFAMILY_ARM_11 0x8ff620d8
#define CPUFAMILY_ARM_XSCALE 0x53b005f5

View File

@@ -211,7 +211,6 @@ typedef mach_port_type_t *mach_port_type_array_t;
#define MACH_PORT_TYPE_LABELH MACH_PORT_TYPE(MACH_PORT_RIGHT_LABELH) /* obsolete */
/* Convenient combinations. */
#define MACH_PORT_TYPE_SEND_RECEIVE \
@@ -388,9 +387,16 @@ enum mach_port_guard_exception_codes {
kGUARD_EXC_SEND_INVALID_RIGHT = 1u << 18,
kGUARD_EXC_RCV_INVALID_NAME = 1u << 19,
kGUARD_EXC_RCV_GUARDED_DESC = 1u << 20, /* should never be fatal; for development only */
kGUARD_EXC_MOD_REFS_NON_FATAL = 1u << 21,
kGUARD_EXC_IMMOVABLE_NON_FATAL = 1u << 22,
};
#define MAX_FATAL_kGUARD_EXC_CODE (1u << 6)
#define MAX_FATAL_kGUARD_EXC_CODE (1u << 7)
/*
* Mach port guard flags.
*/
#define MPG_FLAGS_NONE (0x00ull)
/*
* These flags are used as bits in the subcode of kGUARD_EXC_STRICT_REPLY exceptions.
@@ -402,6 +408,16 @@ enum mach_port_guard_exception_codes {
#define MPG_FLAGS_STRICT_REPLY_MISMATCHED_PERSONA (0x10ull << 56)
#define MPG_FLAGS_STRICT_REPLY_MASK (0xffull << 56)
/*
* These flags are used as bits in the subcode of kGUARD_EXC_MOD_REFS exceptions.
*/
#define MPG_FLAGS_MOD_REFS_PINNED_DEALLOC (0x01ull << 56)
/*
* These flags are used as bits in the subcode of kGUARD_EXC_IMMOVABLE exceptions.
*/
#define MPG_FLAGS_IMMOVABLE_PINNED (0x01ull << 56)
/*
* Flags for mach_port_guard_with_flags. These flags extend
* the attributes associated with a guarded port.

View File

@@ -49,7 +49,7 @@ typedef function_table_entry *function_table_t;
#endif /* AUTOTEST */
#ifndef task_MSG_COUNT
#define task_MSG_COUNT 55
#define task_MSG_COUNT 61
#endif /* task_MSG_COUNT */
#include <mach/std_types.h>
@@ -175,7 +175,7 @@ __WATCHOS_PROHIBITED
__TVOS_PROHIBITED
kern_return_t task_suspend
(
task_t target_task
task_read_t target_task
);
/* Routine task_resume */
@@ -188,7 +188,7 @@ __WATCHOS_PROHIBITED
__TVOS_PROHIBITED
kern_return_t task_resume
(
task_t target_task
task_read_t target_task
);
/* Routine task_get_special_port */
@@ -305,7 +305,7 @@ kern_return_t task_swap_exception_ports
thread_state_flavor_t new_flavor,
exception_mask_array_t masks,
mach_msg_type_number_t *masksCnt,
exception_handler_array_t old_handlerss,
exception_handler_array_t old_handlers,
exception_behavior_array_t old_behaviors,
exception_flavor_array_t old_flavors
);
@@ -606,7 +606,7 @@ __WATCHOS_PROHIBITED
__TVOS_PROHIBITED
kern_return_t task_suspend2
(
task_t target_task,
task_read_t target_task,
task_suspension_token_t *suspend_token
);
@@ -687,7 +687,7 @@ extern
#endif /* mig_external */
kern_return_t task_generate_corpse
(
task_t task,
task_read_t task,
mach_port_t *corpse_task_port
);
@@ -848,6 +848,72 @@ kern_return_t task_create_suid_cred
suid_cred_t *delegation
);
/* Routine task_dyld_process_info_notify_register */
#ifdef mig_external
mig_external
#else
extern
#endif /* mig_external */
kern_return_t task_dyld_process_info_notify_register
(
task_read_t target_task,
mach_port_t notify
);
/* Routine task_create_identity_token */
#ifdef mig_external
mig_external
#else
extern
#endif /* mig_external */
kern_return_t task_create_identity_token
(
task_t task,
task_id_token_t *token
);
/* Routine task_identity_token_get_task_port */
#ifdef mig_external
mig_external
#else
extern
#endif /* mig_external */
kern_return_t task_identity_token_get_task_port
(
task_id_token_t token,
task_flavor_t flavor,
mach_port_t *task_port
);
/* Routine task_dyld_process_info_notify_deregister */
#ifdef mig_external
mig_external
#else
extern
#endif /* mig_external */
kern_return_t task_dyld_process_info_notify_deregister
(
task_read_t target_task,
mach_port_name_t notify
);
/* Routine task_get_exception_ports_info */
#ifdef mig_external
mig_external
#else
extern
#endif /* mig_external */
kern_return_t task_get_exception_ports_info
(
mach_port_t port,
exception_mask_t exception_mask,
exception_mask_array_t masks,
mach_msg_type_number_t *masksCnt,
exception_handler_info_array_t old_handlers_info,
exception_behavior_array_t old_behaviors,
exception_flavor_array_t old_flavors
);
__END_DECLS
/********************** Caution **************************/
@@ -1586,6 +1652,66 @@ __END_DECLS
#ifdef __MigPackStructs
#pragma pack(pop)
#endif
#ifdef __MigPackStructs
#pragma pack(push, 4)
#endif
typedef struct {
mach_msg_header_t Head;
/* start of the kernel processed data */
mach_msg_body_t msgh_body;
mach_msg_port_descriptor_t notify;
/* end of the kernel processed data */
} __Request__task_dyld_process_info_notify_register_t __attribute__((unused));
#ifdef __MigPackStructs
#pragma pack(pop)
#endif
#ifdef __MigPackStructs
#pragma pack(push, 4)
#endif
typedef struct {
mach_msg_header_t Head;
} __Request__task_create_identity_token_t __attribute__((unused));
#ifdef __MigPackStructs
#pragma pack(pop)
#endif
#ifdef __MigPackStructs
#pragma pack(push, 4)
#endif
typedef struct {
mach_msg_header_t Head;
NDR_record_t NDR;
task_flavor_t flavor;
} __Request__task_identity_token_get_task_port_t __attribute__((unused));
#ifdef __MigPackStructs
#pragma pack(pop)
#endif
#ifdef __MigPackStructs
#pragma pack(push, 4)
#endif
typedef struct {
mach_msg_header_t Head;
NDR_record_t NDR;
mach_port_name_t notify;
} __Request__task_dyld_process_info_notify_deregister_t __attribute__((unused));
#ifdef __MigPackStructs
#pragma pack(pop)
#endif
#ifdef __MigPackStructs
#pragma pack(push, 4)
#endif
typedef struct {
mach_msg_header_t Head;
NDR_record_t NDR;
exception_mask_t exception_mask;
} __Request__task_get_exception_ports_info_t __attribute__((unused));
#ifdef __MigPackStructs
#pragma pack(pop)
#endif
#endif /* !__Request__task_subsystem__defined */
/* union of all requests */
@@ -1648,6 +1774,11 @@ union __RequestUnion__task_subsystem {
__Request__task_get_exc_guard_behavior_t Request_task_get_exc_guard_behavior;
__Request__task_set_exc_guard_behavior_t Request_task_set_exc_guard_behavior;
__Request__task_create_suid_cred_t Request_task_create_suid_cred;
__Request__task_dyld_process_info_notify_register_t Request_task_dyld_process_info_notify_register;
__Request__task_create_identity_token_t Request_task_create_identity_token;
__Request__task_identity_token_get_task_port_t Request_task_identity_token_get_task_port;
__Request__task_dyld_process_info_notify_deregister_t Request_task_dyld_process_info_notify_deregister;
__Request__task_get_exception_ports_info_t Request_task_get_exception_ports_info;
};
#endif /* !__RequestUnion__task_subsystem__defined */
/* typedefs for all replies */
@@ -1867,7 +1998,7 @@ union __RequestUnion__task_subsystem {
mach_msg_header_t Head;
/* start of the kernel processed data */
mach_msg_body_t msgh_body;
mach_msg_port_descriptor_t old_handlerss[32];
mach_msg_port_descriptor_t old_handlers[32];
/* end of the kernel processed data */
NDR_record_t NDR;
mach_msg_type_number_t masksCnt;
@@ -2392,6 +2523,75 @@ union __RequestUnion__task_subsystem {
#ifdef __MigPackStructs
#pragma pack(pop)
#endif
#ifdef __MigPackStructs
#pragma pack(push, 4)
#endif
typedef struct {
mach_msg_header_t Head;
NDR_record_t NDR;
kern_return_t RetCode;
} __Reply__task_dyld_process_info_notify_register_t __attribute__((unused));
#ifdef __MigPackStructs
#pragma pack(pop)
#endif
#ifdef __MigPackStructs
#pragma pack(push, 4)
#endif
typedef struct {
mach_msg_header_t Head;
/* start of the kernel processed data */
mach_msg_body_t msgh_body;
mach_msg_port_descriptor_t token;
/* end of the kernel processed data */
} __Reply__task_create_identity_token_t __attribute__((unused));
#ifdef __MigPackStructs
#pragma pack(pop)
#endif
#ifdef __MigPackStructs
#pragma pack(push, 4)
#endif
typedef struct {
mach_msg_header_t Head;
/* start of the kernel processed data */
mach_msg_body_t msgh_body;
mach_msg_port_descriptor_t task_port;
/* end of the kernel processed data */
} __Reply__task_identity_token_get_task_port_t __attribute__((unused));
#ifdef __MigPackStructs
#pragma pack(pop)
#endif
#ifdef __MigPackStructs
#pragma pack(push, 4)
#endif
typedef struct {
mach_msg_header_t Head;
NDR_record_t NDR;
kern_return_t RetCode;
} __Reply__task_dyld_process_info_notify_deregister_t __attribute__((unused));
#ifdef __MigPackStructs
#pragma pack(pop)
#endif
#ifdef __MigPackStructs
#pragma pack(push, 4)
#endif
typedef struct {
mach_msg_header_t Head;
NDR_record_t NDR;
kern_return_t RetCode;
mach_msg_type_number_t masksCnt;
exception_mask_t masks[32];
exception_handler_info_t old_handlers_info[32];
exception_behavior_t old_behaviors[32];
thread_state_flavor_t old_flavors[32];
} __Reply__task_get_exception_ports_info_t __attribute__((unused));
#ifdef __MigPackStructs
#pragma pack(pop)
#endif
#endif /* !__Reply__task_subsystem__defined */
/* union of all replies */
@@ -2454,6 +2654,11 @@ union __ReplyUnion__task_subsystem {
__Reply__task_get_exc_guard_behavior_t Reply_task_get_exc_guard_behavior;
__Reply__task_set_exc_guard_behavior_t Reply_task_set_exc_guard_behavior;
__Reply__task_create_suid_cred_t Reply_task_create_suid_cred;
__Reply__task_dyld_process_info_notify_register_t Reply_task_dyld_process_info_notify_register;
__Reply__task_create_identity_token_t Reply_task_create_identity_token;
__Reply__task_identity_token_get_task_port_t Reply_task_identity_token_get_task_port;
__Reply__task_dyld_process_info_notify_deregister_t Reply_task_dyld_process_info_notify_deregister;
__Reply__task_get_exception_ports_info_t Reply_task_get_exception_ports_info;
};
#endif /* !__RequestUnion__task_subsystem__defined */
@@ -2513,7 +2718,12 @@ union __ReplyUnion__task_subsystem {
{ "task_inspect", 3451 },\
{ "task_get_exc_guard_behavior", 3452 },\
{ "task_set_exc_guard_behavior", 3453 },\
{ "task_create_suid_cred", 3454 }
{ "task_create_suid_cred", 3454 },\
{ "task_dyld_process_info_notify_register", 3456 },\
{ "task_create_identity_token", 3457 },\
{ "task_identity_token_get_task_port", 3458 },\
{ "task_dyld_process_info_notify_deregister", 3459 },\
{ "task_get_exception_ports_info", 3460 }
#endif
#ifdef __AfterMigUserHeader

View File

@@ -81,7 +81,9 @@ typedef int task_special_port_t;
#define TASK_READ_PORT 6 /* The read port for task. */
/*
* Evolving and likely to change.
*/
#define TASK_SEATBELT_PORT 7 /* Seatbelt compiler/DEM port for task. */

View File

@@ -49,7 +49,7 @@ typedef function_table_entry *function_table_t;
#endif /* AUTOTEST */
#ifndef thread_act_MSG_COUNT
#define thread_act_MSG_COUNT 29
#define thread_act_MSG_COUNT 31
#endif /* thread_act_MSG_COUNT */
#include <mach/std_types.h>
@@ -149,7 +149,7 @@ extern
__WATCHOS_PROHIBITED
kern_return_t thread_suspend
(
thread_act_t target_act
thread_read_t target_act
);
/* Routine thread_resume */
@@ -161,7 +161,7 @@ extern
__WATCHOS_PROHIBITED
kern_return_t thread_resume
(
thread_act_t target_act
thread_read_t target_act
);
/* Routine thread_abort */
@@ -484,6 +484,23 @@ kern_return_t thread_convert_thread_state
mach_msg_type_number_t *out_stateCnt
);
/* Routine thread_get_exception_ports_info */
#ifdef mig_external
mig_external
#else
extern
#endif /* mig_external */
kern_return_t thread_get_exception_ports_info
(
mach_port_t port,
exception_mask_t exception_mask,
exception_mask_array_t masks,
mach_msg_type_number_t *masksCnt,
exception_handler_info_array_t old_handlers_info,
exception_behavior_array_t old_behaviors,
exception_flavor_array_t old_flavors
);
__END_DECLS
/********************** Caution **************************/
@@ -884,6 +901,18 @@ __END_DECLS
#ifdef __MigPackStructs
#pragma pack(pop)
#endif
#ifdef __MigPackStructs
#pragma pack(push, 4)
#endif
typedef struct {
mach_msg_header_t Head;
NDR_record_t NDR;
exception_mask_t exception_mask;
} __Request__thread_get_exception_ports_info_t __attribute__((unused));
#ifdef __MigPackStructs
#pragma pack(pop)
#endif
#endif /* !__Request__thread_act_subsystem__defined */
/* union of all requests */
@@ -920,6 +949,7 @@ union __RequestUnion__thread_act_subsystem {
__Request__thread_set_mach_voucher_t Request_thread_set_mach_voucher;
__Request__thread_swap_mach_voucher_t Request_thread_swap_mach_voucher;
__Request__thread_convert_thread_state_t Request_thread_convert_thread_state;
__Request__thread_get_exception_ports_info_t Request_thread_get_exception_ports_info;
};
#endif /* !__RequestUnion__thread_act_subsystem__defined */
/* typedefs for all replies */
@@ -1307,6 +1337,23 @@ union __RequestUnion__thread_act_subsystem {
#ifdef __MigPackStructs
#pragma pack(pop)
#endif
#ifdef __MigPackStructs
#pragma pack(push, 4)
#endif
typedef struct {
mach_msg_header_t Head;
NDR_record_t NDR;
kern_return_t RetCode;
mach_msg_type_number_t masksCnt;
exception_mask_t masks[32];
exception_handler_info_t old_handlers_info[32];
exception_behavior_t old_behaviors[32];
thread_state_flavor_t old_flavors[32];
} __Reply__thread_get_exception_ports_info_t __attribute__((unused));
#ifdef __MigPackStructs
#pragma pack(pop)
#endif
#endif /* !__Reply__thread_act_subsystem__defined */
/* union of all replies */
@@ -1343,6 +1390,7 @@ union __ReplyUnion__thread_act_subsystem {
__Reply__thread_set_mach_voucher_t Reply_thread_set_mach_voucher;
__Reply__thread_swap_mach_voucher_t Reply_thread_swap_mach_voucher;
__Reply__thread_convert_thread_state_t Reply_thread_convert_thread_state;
__Reply__thread_get_exception_ports_info_t Reply_thread_get_exception_ports_info;
};
#endif /* !__RequestUnion__thread_act_subsystem__defined */
@@ -1376,7 +1424,8 @@ union __ReplyUnion__thread_act_subsystem {
{ "thread_get_mach_voucher", 3625 },\
{ "thread_set_mach_voucher", 3626 },\
{ "thread_swap_mach_voucher", 3627 },\
{ "thread_convert_thread_state", 3628 }
{ "thread_convert_thread_state", 3628 },\
{ "thread_get_exception_ports_info", 3630 }
#endif
#ifdef __AfterMigUserHeader

View File

@@ -73,6 +73,7 @@
#define THREAD_READ_PORT 3 /* The read port for thread. */
#define THREAD_MAX_SPECIAL_PORT THREAD_READ_PORT
/*
* Definitions for ease of use
*/

View File

@@ -272,6 +272,7 @@ typedef struct vm_purgeable_info *vm_purgeable_info_t;
#define VM_FLAGS_NO_CACHE 0x0010
#define VM_FLAGS_RESILIENT_CODESIGN 0x0020
#define VM_FLAGS_RESILIENT_MEDIA 0x0040
#define VM_FLAGS_PERMANENT 0x0080
#define VM_FLAGS_OVERWRITE 0x4000 /* delete any existing mappings first */
/*
* VM_FLAGS_SUPERPAGE_MASK
@@ -295,6 +296,7 @@ typedef struct vm_purgeable_info *vm_purgeable_info_t;
VM_FLAGS_4GB_CHUNK | \
VM_FLAGS_RANDOM_ADDR | \
VM_FLAGS_NO_CACHE | \
VM_FLAGS_PERMANENT | \
VM_FLAGS_OVERWRITE | \
VM_FLAGS_SUPERPAGE_MASK | \
VM_FLAGS_ALIAS_MASK)

View File

@@ -127,7 +127,8 @@ struct rt_metrics {
#define RTF_PROXY 0x8000000 /* proxying, no interface scope */
#define RTF_ROUTER 0x10000000 /* host is a router */
#define RTF_DEAD 0x20000000 /* Route entry is being freed */
/* 0x40000000 and up unassigned */
#define RTF_GLOBAL 0x40000000 /* route to destination of the global internet */
/* 0x80000000 unassigned */
#define RTPRF_OURS RTF_PROTO3 /* set on routes we manage */
#define RTF_BITS \
@@ -135,7 +136,7 @@ struct rt_metrics {
"\10DELCLONE\11CLONING\12XRESOLVE\13LLINFO\14STATIC\15BLACKHOLE" \
"\16NOIFREF\17PROTO2\20PROTO1\21PRCLONING\22WASCLONED\23PROTO3" \
"\25PINNED\26LOCAL\27BROADCAST\30MULTICAST\31IFSCOPE\32CONDEMNED" \
"\33IFREF\34PROXY\35ROUTER"
"\33IFREF\34PROXY\35ROUTER\37GLOBAL"
#define IS_DIRECT_HOSTROUTE(rt) \
(((rt)->rt_flags & (RTF_HOST | RTF_GATEWAY)) == RTF_HOST)

View File

@@ -283,4 +283,22 @@
# endif
#endif
/* OBJC_COLD: very rarely called, e.g. on error path */
#if !defined(OBJC_COLD)
# if __OBJC__ && __has_attribute(cold)
# define OBJC_COLD __attribute__((cold))
# else
# define OBJC_COLD
# endif
#endif
/* OBJC_NORETURN: does not return normally, but may throw */
#if !defined(OBJC_NORETURN)
# if __OBJC__ && __has_attribute(noreturn)
# define OBJC_NORETURN __attribute__((noreturn))
# else
# define OBJC_NORETURN
# endif
#endif
#endif

View File

@@ -557,11 +557,11 @@ __API_AVAILABLE(macos(10.4), ios(2.0))
void pthread_yield_np(void);
__API_AVAILABLE(macos(11.0))
__API_UNAVAILABLE(ios, tvos, watchos)
__API_UNAVAILABLE(ios, tvos, watchos, driverkit)
void pthread_jit_write_protect_np(int enabled);
__API_AVAILABLE(macos(11.0))
__API_UNAVAILABLE(ios, tvos, watchos)
__API_UNAVAILABLE(ios, tvos, watchos, driverkit)
int pthread_jit_write_protect_supported_np(void);
/*!

View File

@@ -15,7 +15,7 @@
*
* <pre>
* @textblock
* simd_float4 vector = *(packed_simd_float4 *)&array[i];
* simd_float4 vector = *(simd_packed_float4 *)&array[i];
* // do something with vector ...
* @/textblock
* </pre>

View File

@@ -335,6 +335,12 @@
#define __DARWIN_ALIAS_STARTING_IPHONE___IPHONE_14_3(x)
#endif
#if defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 140500
#define __DARWIN_ALIAS_STARTING_IPHONE___IPHONE_14_5(x) x
#else
#define __DARWIN_ALIAS_STARTING_IPHONE___IPHONE_14_5(x)
#endif
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1000
#define __DARWIN_ALIAS_STARTING_MAC___MAC_10_0(x) x
#else
@@ -543,4 +549,10 @@
#define __DARWIN_ALIAS_STARTING_MAC___MAC_11_1(x) x
#else
#define __DARWIN_ALIAS_STARTING_MAC___MAC_11_1(x)
#endif
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 110300
#define __DARWIN_ALIAS_STARTING_MAC___MAC_11_3(x) x
#else
#define __DARWIN_ALIAS_STARTING_MAC___MAC_11_3(x)
#endif

View File

@@ -80,6 +80,8 @@
#include <mach/boolean.h>
#include <Availability.h>
struct session;
struct pgrp;

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 1999, 2000-2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. The rights granted to you under the License
* may not be used to create, or enable the creation or redistribution of,
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
*
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
#ifndef __SYS_RANDOM_H__
#define __SYS_RANDOM_H__
#include <sys/appleapiopts.h>
#include <sys/cdefs.h>
__BEGIN_DECLS
__OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0)
int getentropy(void* buffer, size_t size);
__END_DECLS
#endif /* __SYS_RANDOM_H__ */

View File

@@ -457,6 +457,8 @@ struct proc_rlimit_control_wakeupmon {
#define IOPOL_TYPE_VFS_STATFS_NO_DATA_VOLUME 4
#define IOPOL_TYPE_VFS_TRIGGER_RESOLVE 5
#define IOPOL_TYPE_VFS_IGNORE_CONTENT_PROTECTION 6
#define IOPOL_TYPE_VFS_IGNORE_PERMISSIONS 7
#define IOPOL_TYPE_VFS_SKIP_MTIME_UPDATE 8
/* scope */
#define IOPOL_SCOPE_PROCESS 0
@@ -492,6 +494,12 @@ struct proc_rlimit_control_wakeupmon {
#define IOPOL_VFS_CONTENT_PROTECTION_DEFAULT 0
#define IOPOL_VFS_CONTENT_PROTECTION_IGNORE 1
#define IOPOL_VFS_IGNORE_PERMISSIONS_OFF 0
#define IOPOL_VFS_IGNORE_PERMISSIONS_ON 1
#define IOPOL_VFS_SKIP_MTIME_UPDATE_OFF 0
#define IOPOL_VFS_SKIP_MTIME_UPDATE_ON 1
#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */

View File

@@ -81,10 +81,10 @@
#include <sys/appleapiopts.h>
#include <sys/time.h>
#include <sys/ucred.h>
#include <sys/proc.h>
#include <sys/vm.h>
/*
* Definitions for sysctl call. The sysctl call uses a hierarchical name
* for objects that can be examined or modified. The name is expressed as
@@ -135,25 +135,26 @@ struct ctlname {
int ctl_type; /* type of name */
};
#define CTLTYPE 0xf /* Mask for the type */
#define CTLTYPE_NODE 1 /* name is a node */
#define CTLTYPE_INT 2 /* name describes an integer */
#define CTLTYPE_STRING 3 /* name describes a string */
#define CTLTYPE_QUAD 4 /* name describes a 64-bit number */
#define CTLTYPE_OPAQUE 5 /* name describes a structure */
#define CTLTYPE_STRUCT CTLTYPE_OPAQUE /* name describes a structure */
#define CTLTYPE 0xf /* Mask for the type */
#define CTLTYPE_NODE 1 /* name is a node */
#define CTLTYPE_INT 2 /* name describes an integer */
#define CTLTYPE_STRING 3 /* name describes a string */
#define CTLTYPE_QUAD 4 /* name describes a 64-bit number */
#define CTLTYPE_OPAQUE 5 /* name describes a structure */
#define CTLTYPE_STRUCT CTLTYPE_OPAQUE /* name describes a structure */
#define CTLFLAG_RD 0x80000000 /* Allow reads of variable */
#define CTLFLAG_WR 0x40000000 /* Allow writes to the variable */
#define CTLFLAG_RW (CTLFLAG_RD|CTLFLAG_WR)
#define CTLFLAG_NOLOCK 0x20000000 /* XXX Don't Lock */
#define CTLFLAG_ANYBODY 0x10000000 /* All users can set this var */
#define CTLFLAG_SECURE 0x08000000 /* Permit set only if securelevel<=0 */
#define CTLFLAG_MASKED 0x04000000 /* deprecated variable, do not display */
#define CTLFLAG_NOAUTO 0x02000000 /* do not auto-register */
#define CTLFLAG_KERN 0x01000000 /* valid inside the kernel */
#define CTLFLAG_LOCKED 0x00800000 /* node will handle locking itself */
#define CTLFLAG_OID2 0x00400000 /* struct sysctl_oid has version info */
#define CTLFLAG_RD 0x80000000 /* Allow reads of variable */
#define CTLFLAG_WR 0x40000000 /* Allow writes to the variable */
#define CTLFLAG_RW (CTLFLAG_RD|CTLFLAG_WR)
#define CTLFLAG_NOLOCK 0x20000000 /* XXX Don't Lock */
#define CTLFLAG_ANYBODY 0x10000000 /* All users can set this var */
#define CTLFLAG_SECURE 0x08000000 /* Permit set only if securelevel<=0 */
#define CTLFLAG_MASKED 0x04000000 /* deprecated variable, do not display */
#define CTLFLAG_NOAUTO 0x02000000 /* do not auto-register */
#define CTLFLAG_KERN 0x01000000 /* valid inside the kernel */
#define CTLFLAG_LOCKED 0x00800000 /* node will handle locking itself */
#define CTLFLAG_OID2 0x00400000 /* struct sysctl_oid has version info */
#define CTLFLAG_EXPERIMENT 0x00100000 /* Allows writing w/ the trial experiment entitlement. */
/*
* USE THIS instead of a hardwired number from the categories below
@@ -168,8 +169,8 @@ struct ctlname {
* in I/O-Kit. In this case, you have to call sysctl_register_oid()
* manually - just like in a KEXT.
*/
#define OID_AUTO (-1)
#define OID_AUTO_START 100 /* conventional */
#define OID_AUTO (-1)
#define OID_AUTO_START 100 /* conventional */
#define SYSCTL_DEF_ENABLED

View File

@@ -181,6 +181,7 @@
#include <mach/port.h>
#include <mach/thread_status.h>
#include <mach/machine/vm_types.h>
#include <mach_debug/ipc_info.h>
/*
* Exported types
*/
@@ -196,6 +197,7 @@ typedef exception_mask_t *exception_mask_array_t;
typedef exception_behavior_t *exception_behavior_array_t;
typedef thread_state_flavor_t *exception_flavor_array_t;
typedef mach_port_t *exception_port_array_t;
typedef ipc_info_port_t *exception_port_info_array_t;
typedef mach_exception_data_type_t mach_exception_code_t;
typedef mach_exception_data_type_t mach_exception_subcode_t;

View File

@@ -108,9 +108,10 @@
#define HOST_SYSPOLICYD_PORT (22 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_FILECOORDINATIOND_PORT (23 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_FAIRPLAYD_PORT (24 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_IOCOMPRESSIONSTATS_PORT (25 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_MAX_SPECIAL_PORT HOST_FAIRPLAYD_PORT
/* MAX = last since rdar://35861175 */
#define HOST_MAX_SPECIAL_PORT HOST_IOCOMPRESSIONSTATS_PORT
/* MAX = last since rdar://59872249 */
/* obsolete name */
#define HOST_CHUD_PORT HOST_LAUNCHCTL_PORT
@@ -274,6 +275,13 @@
#define host_set_fairplayd_port(host, port) \
(host_set_special_port((host), HOST_FAIRPLAYD_PORT, (port)))
#define host_get_iocompressionstats_port(host, port) \
(host_get_special_port((host), \
HOST_LOCAL_NODE, HOST_IOCOMPRESSIONSTATS_PORT, (port)))
#define host_set_iocompressionstats_port(host, port) \
(host_set_special_port((host), HOST_IOCOMPRESSIONSTATS_PORT, (port)))
/* HOST_RESOURCE_NOTIFY_PORT doesn't #defines these conveniences.
* All lookups go through send_resource_violation()
*/

View File

@@ -64,6 +64,10 @@
#include <sys/cdefs.h>
#ifndef KERNEL
#include <Availability.h>
#endif
/*
* Kernel-related ports; how a task/thread controls itself
*/
@@ -71,6 +75,8 @@
__BEGIN_DECLS
extern mach_port_t mach_host_self(void);
extern mach_port_t mach_thread_self(void);
__API_AVAILABLE(macos(11.3), ios(14.5), tvos(14.5), watchos(7.3))
extern boolean_t mach_task_is_self(task_name_t task);
extern kern_return_t host_page_size(host_t, vm_size_t *);
extern mach_port_t mach_task_self_;

View File

@@ -79,6 +79,7 @@
#include <sys/cdefs.h>
#define VM_64_BIT_DATA_OBJECTS
typedef unsigned long long memory_object_offset_t;
@@ -95,6 +96,11 @@ typedef unsigned long long vm_object_id_t;
typedef mach_port_t memory_object_t;
/*
* vestigial, maintained for source compatibility,
* no MIG interface will accept or return non NULL
* objects for those.
*/
typedef mach_port_t memory_object_control_t;

View File

@@ -49,7 +49,7 @@ typedef function_table_entry *function_table_t;
#endif /* AUTOTEST */
#ifndef vm_map_MSG_COUNT
#define vm_map_MSG_COUNT 32
#define vm_map_MSG_COUNT 33
#endif /* vm_map_MSG_COUNT */
#include <mach/std_types.h>
@@ -493,6 +493,27 @@ kern_return_t vm_map_exec_lockdown
vm_map_t target_task
);
/* Routine vm_remap_new */
#ifdef mig_external
mig_external
#else
extern
#endif /* mig_external */
kern_return_t vm_remap_new
(
vm_map_t target_task,
vm_address_t *target_address,
vm_size_t size,
vm_address_t mask,
int flags,
vm_map_read_t src_task,
vm_address_t src_address,
boolean_t copy,
vm_prot_t *cur_protection,
vm_prot_t *max_protection,
vm_inherit_t inheritance
);
__END_DECLS
/********************** Caution **************************/
@@ -924,6 +945,30 @@ __END_DECLS
#ifdef __MigPackStructs
#pragma pack(pop)
#endif
#ifdef __MigPackStructs
#pragma pack(push, 4)
#endif
typedef struct {
mach_msg_header_t Head;
/* start of the kernel processed data */
mach_msg_body_t msgh_body;
mach_msg_port_descriptor_t src_task;
/* end of the kernel processed data */
NDR_record_t NDR;
vm_address_t target_address;
vm_size_t size;
vm_address_t mask;
int flags;
vm_address_t src_address;
boolean_t copy;
vm_prot_t cur_protection;
vm_prot_t max_protection;
vm_inherit_t inheritance;
} __Request__vm_remap_new_t __attribute__((unused));
#ifdef __MigPackStructs
#pragma pack(pop)
#endif
#endif /* !__Request__vm_map_subsystem__defined */
/* union of all requests */
@@ -959,6 +1004,7 @@ union __RequestUnion__vm_map_subsystem {
__Request__vm_map_64_t Request_vm_map_64;
__Request__vm_purgable_control_t Request_vm_purgable_control;
__Request__vm_map_exec_lockdown_t Request_vm_map_exec_lockdown;
__Request__vm_remap_new_t Request_vm_remap_new;
};
#endif /* !__RequestUnion__vm_map_subsystem__defined */
/* typedefs for all replies */
@@ -1363,6 +1409,21 @@ union __RequestUnion__vm_map_subsystem {
#ifdef __MigPackStructs
#pragma pack(pop)
#endif
#ifdef __MigPackStructs
#pragma pack(push, 4)
#endif
typedef struct {
mach_msg_header_t Head;
NDR_record_t NDR;
kern_return_t RetCode;
vm_address_t target_address;
vm_prot_t cur_protection;
vm_prot_t max_protection;
} __Reply__vm_remap_new_t __attribute__((unused));
#ifdef __MigPackStructs
#pragma pack(pop)
#endif
#endif /* !__Reply__vm_map_subsystem__defined */
/* union of all replies */
@@ -1398,6 +1459,7 @@ union __ReplyUnion__vm_map_subsystem {
__Reply__vm_map_64_t Reply_vm_map_64;
__Reply__vm_purgable_control_t Reply_vm_purgable_control;
__Reply__vm_map_exec_lockdown_t Reply_vm_map_exec_lockdown;
__Reply__vm_remap_new_t Reply_vm_remap_new;
};
#endif /* !__RequestUnion__vm_map_subsystem__defined */
@@ -1430,7 +1492,8 @@ union __ReplyUnion__vm_map_subsystem {
{ "mach_make_memory_entry_64", 3825 },\
{ "vm_map_64", 3826 },\
{ "vm_purgable_control", 3830 },\
{ "vm_map_exec_lockdown", 3831 }
{ "vm_map_exec_lockdown", 3831 },\
{ "vm_remap_new", 3832 }
#endif
#ifdef __AfterMigUserHeader

View File

@@ -113,4 +113,11 @@ typedef struct ipc_info_tree_name {
typedef ipc_info_tree_name_t *ipc_info_tree_name_array_t;
typedef struct ipc_info_port {
natural_t iip_port_object; /* port object identifier */
natural_t iip_receiver_object; /* receiver task identifier (if any) */
} ipc_info_port_t;
typedef ipc_info_port_t *exception_handler_info_array_t;
#endif /* _MACH_DEBUG_IPC_INFO_H_ */

View File

@@ -190,9 +190,9 @@ int clock_settime(clockid_t __clock_id, const struct timespec *__tp);
#endif /* __DARWIN_C_LEVEL */
#endif /* _DARWIN_FEATURE_CLOCK_GETTIME */
#if (__DARWIN_C_LEVEL >= __DARWIN_C_FULL) && \
((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \
(defined(__cplusplus) && __cplusplus >= 201703L))
#if (__DARWIN_C_LEVEL >= __DARWIN_C_FULL) || \
(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \
(defined(__cplusplus) && __cplusplus >= 201703L)
/* ISO/IEC 9899:201x 7.27.2.5 The timespec_get function */
#define TIME_UTC 1 /* time elapsed since epoch */
__API_AVAILABLE(macosx(10.15), ios(13.0), tvos(13.0), watchos(6.0))

View File

@@ -0,0 +1,204 @@
/*
* Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. The rights granted to you under the License
* may not be used to create, or enable the creation or redistribution of,
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
*
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/*
* @OSF_COPYRIGHT@
*/
/*
* Mach Operating System
* Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
/*
*/
#ifndef _MACH_EXCEPTION_TYPES_H_
#define _MACH_EXCEPTION_TYPES_H_
#include <mach/machine/exception.h>
/*
* Machine-independent exception definitions.
*/
#define EXC_BAD_ACCESS 1 /* Could not access memory */
/* Code contains kern_return_t describing error. */
/* Subcode contains bad memory address. */
#define EXC_BAD_INSTRUCTION 2 /* Instruction failed */
/* Illegal or undefined instruction or operand */
#define EXC_ARITHMETIC 3 /* Arithmetic exception */
/* Exact nature of exception is in code field */
#define EXC_EMULATION 4 /* Emulation instruction */
/* Emulation support instruction encountered */
/* Details in code and subcode fields */
#define EXC_SOFTWARE 5 /* Software generated exception */
/* Exact exception is in code field. */
/* Codes 0 - 0xFFFF reserved to hardware */
/* Codes 0x10000 - 0x1FFFF reserved for OS emulation (Unix) */
#define EXC_BREAKPOINT 6 /* Trace, breakpoint, etc. */
/* Details in code field. */
#define EXC_SYSCALL 7 /* System calls. */
#define EXC_MACH_SYSCALL 8 /* Mach system calls. */
#define EXC_RPC_ALERT 9 /* RPC alert */
#define EXC_CRASH 10 /* Abnormal process exit */
#define EXC_RESOURCE 11 /* Hit resource consumption limit */
/* Exact resource is in code field. */
#define EXC_GUARD 12 /* Violated guarded resource protections */
#define EXC_CORPSE_NOTIFY 13 /* Abnormal process exited to corpse state */
#define EXC_CORPSE_VARIANT_BIT 0x100 /* bit set for EXC_*_CORPSE variants of EXC_* */
/*
* Machine-independent exception behaviors
*/
# define EXCEPTION_DEFAULT 1
/* Send a catch_exception_raise message including the identity.
*/
# define EXCEPTION_STATE 2
/* Send a catch_exception_raise_state message including the
* thread state.
*/
# define EXCEPTION_STATE_IDENTITY 3
/* Send a catch_exception_raise_state_identity message including
* the thread identity and state.
*/
#define MACH_EXCEPTION_ERRORS 0x40000000
/* include additional exception specific errors, not used yet. */
#define MACH_EXCEPTION_CODES 0x80000000
/* Send 64-bit code and subcode in the exception header */
#define MACH_EXCEPTION_MASK (MACH_EXCEPTION_CODES | MACH_EXCEPTION_ERRORS)
/*
* Masks for exception definitions, above
* bit zero is unused, therefore 1 word = 31 exception types
*/
#define EXC_MASK_BAD_ACCESS (1 << EXC_BAD_ACCESS)
#define EXC_MASK_BAD_INSTRUCTION (1 << EXC_BAD_INSTRUCTION)
#define EXC_MASK_ARITHMETIC (1 << EXC_ARITHMETIC)
#define EXC_MASK_EMULATION (1 << EXC_EMULATION)
#define EXC_MASK_SOFTWARE (1 << EXC_SOFTWARE)
#define EXC_MASK_BREAKPOINT (1 << EXC_BREAKPOINT)
#define EXC_MASK_SYSCALL (1 << EXC_SYSCALL)
#define EXC_MASK_MACH_SYSCALL (1 << EXC_MACH_SYSCALL)
#define EXC_MASK_RPC_ALERT (1 << EXC_RPC_ALERT)
#define EXC_MASK_CRASH (1 << EXC_CRASH)
#define EXC_MASK_RESOURCE (1 << EXC_RESOURCE)
#define EXC_MASK_GUARD (1 << EXC_GUARD)
#define EXC_MASK_CORPSE_NOTIFY (1 << EXC_CORPSE_NOTIFY)
#define EXC_MASK_ALL (EXC_MASK_BAD_ACCESS | \
EXC_MASK_BAD_INSTRUCTION | \
EXC_MASK_ARITHMETIC | \
EXC_MASK_EMULATION | \
EXC_MASK_SOFTWARE | \
EXC_MASK_BREAKPOINT | \
EXC_MASK_SYSCALL | \
EXC_MASK_MACH_SYSCALL | \
EXC_MASK_RPC_ALERT | \
EXC_MASK_RESOURCE | \
EXC_MASK_GUARD | \
EXC_MASK_MACHINE)
#define FIRST_EXCEPTION 1 /* ZERO is illegal */
/*
* Machine independent codes for EXC_SOFTWARE
* Codes 0x10000 - 0x1FFFF reserved for OS emulation (Unix)
* 0x10000 - 0x10002 in use for unix signals
* 0x20000 - 0x2FFFF reserved for MACF
*/
#define EXC_SOFT_SIGNAL 0x10003 /* Unix signal exceptions */
#define EXC_MACF_MIN 0x20000 /* MACF exceptions */
#define EXC_MACF_MAX 0x2FFFF
#ifndef ASSEMBLER
#include <mach/port.h>
#include <mach/thread_status.h>
#include <mach/machine/vm_types.h>
/*
* Exported types
*/
typedef int exception_type_t;
typedef integer_t exception_data_type_t;
typedef int64_t mach_exception_data_type_t;
typedef int exception_behavior_t;
typedef exception_data_type_t *exception_data_t;
typedef mach_exception_data_type_t *mach_exception_data_t;
typedef unsigned int exception_mask_t;
typedef exception_mask_t *exception_mask_array_t;
typedef exception_behavior_t *exception_behavior_array_t;
typedef thread_state_flavor_t *exception_flavor_array_t;
typedef mach_port_t *exception_port_array_t;
typedef mach_exception_data_type_t mach_exception_code_t;
typedef mach_exception_data_type_t mach_exception_subcode_t;
#endif /* ASSEMBLER */
#endif /* _MACH_EXCEPTION_TYPES_H_ */

View File

@@ -0,0 +1,281 @@
/*
* Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. The rights granted to you under the License
* may not be used to create, or enable the creation or redistribution of,
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
*
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/*
* @OSF_COPYRIGHT@
*/
/*
* Mach Operating System
* Copyright (c) 1991 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
/*
*/
/*
* File: mach/host_special_ports.h
*
* Defines codes for access to host-wide special ports.
*/
#ifndef _MACH_HOST_SPECIAL_PORTS_H_
#define _MACH_HOST_SPECIAL_PORTS_H_
/*
* Cannot be set or gotten from user space
*/
#define HOST_SECURITY_PORT 0
#define HOST_MIN_SPECIAL_PORT HOST_SECURITY_PORT
/*
* Always provided by kernel (cannot be set from user-space).
*/
#define HOST_PORT 1
#define HOST_PRIV_PORT 2
#define HOST_IO_MASTER_PORT 3
#define HOST_MAX_SPECIAL_KERNEL_PORT 7 /* room to grow */
#define HOST_LAST_SPECIAL_KERNEL_PORT HOST_IO_MASTER_PORT
/*
* Not provided by kernel
*/
#define HOST_DYNAMIC_PAGER_PORT (1 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_AUDIT_CONTROL_PORT (2 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_USER_NOTIFICATION_PORT (3 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_AUTOMOUNTD_PORT (4 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_LOCKD_PORT (5 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_KTRACE_BACKGROUND_PORT (6 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_SEATBELT_PORT (7 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_KEXTD_PORT (8 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_LAUNCHCTL_PORT (9 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_UNFREED_PORT (10 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_AMFID_PORT (11 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_GSSD_PORT (12 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_TELEMETRY_PORT (13 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_ATM_NOTIFICATION_PORT (14 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_COALITION_PORT (15 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_SYSDIAGNOSE_PORT (16 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_XPC_EXCEPTION_PORT (17 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_CONTAINERD_PORT (18 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_NODE_PORT (19 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_RESOURCE_NOTIFY_PORT (20 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_CLOSURED_PORT (21 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_SYSPOLICYD_PORT (22 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_FILECOORDINATIOND_PORT (23 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_FAIRPLAYD_PORT (24 + HOST_MAX_SPECIAL_KERNEL_PORT)
#define HOST_MAX_SPECIAL_PORT HOST_FAIRPLAYD_PORT
/* MAX = last since rdar://35861175 */
/* obsolete name */
#define HOST_CHUD_PORT HOST_LAUNCHCTL_PORT
/*
* Special node identifier to always represent the local node.
*/
#define HOST_LOCAL_NODE -1
/*
* Definitions for ease of use.
*
* In the get call, the host parameter can be any host, but will generally
* be the local node host port. In the set call, the host must the per-node
* host port for the node being affected.
*/
#define host_get_host_port(host, port) \
(host_get_special_port((host), \
HOST_LOCAL_NODE, HOST_PORT, (port)))
#define host_set_host_port(host, port) (KERN_INVALID_ARGUMENT)
#define host_get_host_priv_port(host, port) \
(host_get_special_port((host), \
HOST_LOCAL_NODE, HOST_PRIV_PORT, (port)))
#define host_set_host_priv_port(host, port) (KERN_INVALID_ARGUMENT)
#define host_get_io_master_port(host, port) \
(host_get_special_port((host), \
HOST_LOCAL_NODE, HOST_IO_MASTER_PORT, (port)))
#define host_set_io_master_port(host, port) (KERN_INVALID_ARGUMENT)
/*
* User-settable special ports.
*/
#define host_get_dynamic_pager_port(host, port) \
(host_get_special_port((host), \
HOST_LOCAL_NODE, HOST_DYNAMIC_PAGER_PORT, (port)))
#define host_set_dynamic_pager_port(host, port) \
(host_set_special_port((host), HOST_DYNAMIC_PAGER_PORT, (port)))
#define host_get_audit_control_port(host, port) \
(host_get_special_port((host), \
HOST_LOCAL_NODE, HOST_AUDIT_CONTROL_PORT, (port)))
#define host_set_audit_control_port(host, port) \
(host_set_special_port((host), HOST_AUDIT_CONTROL_PORT, (port)))
#define host_get_user_notification_port(host, port) \
(host_get_special_port((host), \
HOST_LOCAL_NODE, HOST_USER_NOTIFICATION_PORT, (port)))
#define host_set_user_notification_port(host, port) \
(host_set_special_port((host), HOST_USER_NOTIFICATION_PORT, (port)))
#define host_get_automountd_port(host, port) \
(host_get_special_port((host), \
HOST_LOCAL_NODE, HOST_AUTOMOUNTD_PORT, (port)))
#define host_set_automountd_port(host, port) \
(host_set_special_port((host), HOST_AUTOMOUNTD_PORT, (port)))
#define host_get_lockd_port(host, port) \
(host_get_special_port((host), \
HOST_LOCAL_NODE, HOST_LOCKD_PORT, (port)))
#define host_set_lockd_port(host, port) \
(host_set_special_port((host), HOST_LOCKD_PORT, (port)))
#define host_get_ktrace_background_port(host, port) \
(host_get_special_port((host), \
HOST_LOCAL_NODE, HOST_KTRACE_BACKGROUND_PORT, (port)))
#define host_set_ktrace_background_port(host, port) \
(host_set_special_port((host), HOST_KTRACE_BACKGROUND_PORT, (port)))
#define host_get_kextd_port(host, port) \
(host_get_special_port((host), \
HOST_LOCAL_NODE, HOST_KEXTD_PORT, (port)))
#define host_set_kextd_port(host, port) \
(host_set_special_port((host), HOST_KEXTD_PORT, (port)))
#define host_get_launchctl_port(host, port) \
(host_get_special_port((host), HOST_LOCAL_NODE, HOST_LAUNCHCTL_PORT, \
(port)))
#define host_set_launchctl_port(host, port) \
(host_set_special_port((host), HOST_LAUNCHCTL_PORT, (port)))
#define host_get_chud_port(host, port) host_get_launchctl_port(host, port)
#define host_set_chud_port(host, port) host_set_launchctl_port(host, port)
#define host_get_unfreed_port(host, port) \
(host_get_special_port((host), \
HOST_LOCAL_NODE, HOST_UNFREED_PORT, (port)))
#define host_set_unfreed_port(host, port) \
(host_set_special_port((host), HOST_UNFREED_PORT, (port)))
#define host_get_amfid_port(host, port) \
(host_get_special_port((host), \
HOST_LOCAL_NODE, HOST_AMFID_PORT, (port)))
#define host_set_amfid_port(host, port) \
(host_set_special_port((host), HOST_AMFID_PORT, (port)))
#define host_get_gssd_port(host, port) \
(host_get_special_port((host), \
HOST_LOCAL_NODE, HOST_GSSD_PORT, (port)))
#define host_set_gssd_port(host, port) \
(host_set_special_port((host), HOST_GSSD_PORT, (port)))
#define host_get_telemetry_port(host, port) \
(host_get_special_port((host), \
HOST_LOCAL_NODE, HOST_TELEMETRY_PORT, (port)))
#define host_set_telemetry_port(host, port) \
(host_set_special_port((host), HOST_TELEMETRY_PORT, (port)))
#define host_get_atm_notification_port(host, port) \
(host_get_special_port((host), \
HOST_LOCAL_NODE, HOST_ATM_NOTIFICATION_PORT, (port)))
#define host_set_atm_notification_port(host, port) \
(host_set_special_port((host), HOST_ATM_NOTIFICATION_PORT, (port)))
#define host_get_coalition_port(host, port) \
(host_get_special_port((host), \
HOST_LOCAL_NODE, HOST_COALITION_PORT, (port)))
#define host_set_coalition_port(host, port) \
(host_set_special_port((host), HOST_COALITION_PORT, (port)))
#define host_get_sysdiagnose_port(host, port) \
(host_get_special_port((host), \
HOST_LOCAL_NODE, HOST_SYSDIAGNOSE_PORT, (port)))
#define host_set_sysdiagnose_port(host, port) \
(host_set_special_port((host), HOST_SYSDIAGNOSE_PORT, (port)))
#define host_get_container_port(host, port) \
(host_get_special_port((host), \
HOST_LOCAL_NODE, HOST_CONTAINERD_PORT, (port)))
#define host_set_container_port(host, port) \
(host_set_special_port((host), HOST_CONTAINERD_PORT, (port)))
#define host_get_node_port(host, port) \
(host_get_special_port((host), \
HOST_LOCAL_NODE, HOST_NODE_PORT, (port)))
#define host_set_node_port(host, port) \
(host_set_special_port((host), HOST_NODE_PORT, (port)))
#define host_get_closured_port(host, port) \
(host_get_special_port((host), \
HOST_LOCAL_NODE, HOST_CLOSURED_PORT, (port)))
#define host_set_closured_port(host, port) \
(host_set_special_port((host), HOST_CLOSURED_PORT, (port)))
#define host_get_syspolicyd_port(host, port) \
(host_get_special_port((host), \
HOST_LOCAL_NODE, HOST_SYSPOLICYD_PORT, (port)))
#define host_set_syspolicyd_port(host, port) \
(host_set_special_port((host), HOST_SYSPOLICYD_PORT, (port)))
#define host_get_filecoordinationd_port(host, port) \
(host_get_special_port((host), \
HOST_LOCAL_NODE, HOST_FILECOORDINATIOND_PORT, (port)))
#define host_set_filecoordinationd_port(host, port) \
(host_set_special_port((host), HOST_FILECOORDINATIOND_PORT, (port)))
#define host_get_fairplayd_port(host, port) \
(host_get_special_port((host), \
HOST_LOCAL_NODE, HOST_FAIRPLAYD_PORT, (port)))
#define host_set_fairplayd_port(host, port) \
(host_set_special_port((host), HOST_FAIRPLAYD_PORT, (port)))
/* HOST_RESOURCE_NOTIFY_PORT doesn't #defines these conveniences.
* All lookups go through send_resource_violation()
*/
#endif /* _MACH_HOST_SPECIAL_PORTS_H_ */

View File

@@ -0,0 +1,110 @@
/*
* Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. The rights granted to you under the License
* may not be used to create, or enable the creation or redistribution of,
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
*
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/*
* Mach Operating System
* Copyright (c) 1991,1990,1989,1988,1987,1986 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
/*
* Items provided by the Mach environment initialization.
*/
#ifndef _MACH_INIT_
#define _MACH_INIT_ 1
#include <mach/mach_types.h>
#include <mach/vm_page_size.h>
#include <stdarg.h>
#include <sys/cdefs.h>
/*
* Kernel-related ports; how a task/thread controls itself
*/
__BEGIN_DECLS
extern mach_port_t mach_host_self(void);
extern mach_port_t mach_thread_self(void);
extern kern_return_t host_page_size(host_t, vm_size_t *);
extern mach_port_t mach_task_self_;
#define mach_task_self() mach_task_self_
#define current_task() mach_task_self()
__END_DECLS
#include <mach/mach_traps.h>
__BEGIN_DECLS
/*
* Other important ports in the Mach user environment
*/
extern mach_port_t bootstrap_port;
/*
* Where these ports occur in the "mach_ports_register"
* collection... only servers or the runtime library need know.
*/
#define NAME_SERVER_SLOT 0
#define ENVIRONMENT_SLOT 1
#define SERVICE_SLOT 2
#define MACH_PORTS_SLOTS_USED 3
/*
* fprintf_stderr uses vprintf_stderr_func to produce
* error messages, this can be overridden by a user
* application to point to a user-specified output function
*/
extern int (*vprintf_stderr_func)(const char *format, va_list ap);
__END_DECLS
#endif /* _MACH_INIT_ */

View File

@@ -0,0 +1,299 @@
/*
* Copyright (c) 2000-2016 Apple Computer, Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. The rights granted to you under the License
* may not be used to create, or enable the creation or redistribution of,
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
*
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/*
* @OSF_COPYRIGHT@
*/
/*
* Mach Operating System
* Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
/*
*/
/*
* File: memory_object.h
* Author: Michael Wayne Young
*
* External memory management interface definition.
*/
#ifndef _MACH_MEMORY_OBJECT_TYPES_H_
#define _MACH_MEMORY_OBJECT_TYPES_H_
/*
* User-visible types used in the external memory
* management interface:
*/
#include <mach/port.h>
#include <mach/message.h>
#include <mach/vm_prot.h>
#include <mach/vm_sync.h>
#include <mach/vm_types.h>
#include <mach/machine/vm_types.h>
#include <sys/cdefs.h>
#define VM_64_BIT_DATA_OBJECTS
typedef unsigned long long memory_object_offset_t;
typedef unsigned long long memory_object_size_t;
typedef natural_t memory_object_cluster_size_t;
typedef natural_t * memory_object_fault_info_t;
typedef unsigned long long vm_object_id_t;
/*
* Temporary until real EMMI version gets re-implemented
*/
typedef mach_port_t memory_object_t;
typedef mach_port_t memory_object_control_t;
typedef memory_object_t *memory_object_array_t;
/* A memory object ... */
/* Used by the kernel to retrieve */
/* or store data */
typedef mach_port_t memory_object_name_t;
/* Used to describe the memory ... */
/* object in vm_regions() calls */
typedef mach_port_t memory_object_default_t;
/* Registered with the host ... */
/* for creating new internal objects */
#define MEMORY_OBJECT_NULL ((memory_object_t) 0)
#define MEMORY_OBJECT_CONTROL_NULL ((memory_object_control_t) 0)
#define MEMORY_OBJECT_NAME_NULL ((memory_object_name_t) 0)
#define MEMORY_OBJECT_DEFAULT_NULL ((memory_object_default_t) 0)
typedef int memory_object_copy_strategy_t;
/* How memory manager handles copy: */
#define MEMORY_OBJECT_COPY_NONE 0
/* ... No special support */
#define MEMORY_OBJECT_COPY_CALL 1
/* ... Make call on memory manager */
#define MEMORY_OBJECT_COPY_DELAY 2
/* ... Memory manager doesn't
* change data externally.
*/
#define MEMORY_OBJECT_COPY_TEMPORARY 3
/* ... Memory manager doesn't
* change data externally, and
* doesn't need to see changes.
*/
#define MEMORY_OBJECT_COPY_SYMMETRIC 4
/* ... Memory manager doesn't
* change data externally,
* doesn't need to see changes,
* and object will not be
* multiply mapped.
*
* XXX
* Not yet safe for non-kernel use.
*/
#define MEMORY_OBJECT_COPY_INVALID 5
/* ... An invalid copy strategy,
* for external objects which
* have not been initialized.
* Allows copy_strategy to be
* examined without also
* examining pager_ready and
* internal.
*/
typedef int memory_object_return_t;
/* Which pages to return to manager
* this time (lock_request) */
#define MEMORY_OBJECT_RETURN_NONE 0
/* ... don't return any. */
#define MEMORY_OBJECT_RETURN_DIRTY 1
/* ... only dirty pages. */
#define MEMORY_OBJECT_RETURN_ALL 2
/* ... dirty and precious pages. */
#define MEMORY_OBJECT_RETURN_ANYTHING 3
/* ... any resident page. */
/*
* Data lock request flags
*/
#define MEMORY_OBJECT_DATA_FLUSH 0x1
#define MEMORY_OBJECT_DATA_NO_CHANGE 0x2
#define MEMORY_OBJECT_DATA_PURGE 0x4
#define MEMORY_OBJECT_COPY_SYNC 0x8
#define MEMORY_OBJECT_DATA_SYNC 0x10
#define MEMORY_OBJECT_IO_SYNC 0x20
#define MEMORY_OBJECT_DATA_FLUSH_ALL 0x40
/*
* Types for the memory object flavor interfaces
*/
#define MEMORY_OBJECT_INFO_MAX (1024)
typedef int *memory_object_info_t;
typedef int memory_object_flavor_t;
typedef int memory_object_info_data_t[MEMORY_OBJECT_INFO_MAX];
#define MEMORY_OBJECT_PERFORMANCE_INFO 11
#define MEMORY_OBJECT_ATTRIBUTE_INFO 14
#define MEMORY_OBJECT_BEHAVIOR_INFO 15
struct memory_object_perf_info {
memory_object_cluster_size_t cluster_size;
boolean_t may_cache;
};
struct memory_object_attr_info {
memory_object_copy_strategy_t copy_strategy;
memory_object_cluster_size_t cluster_size;
boolean_t may_cache_object;
boolean_t temporary;
};
struct memory_object_behave_info {
memory_object_copy_strategy_t copy_strategy;
boolean_t temporary;
boolean_t invalidate;
boolean_t silent_overwrite;
boolean_t advisory_pageout;
};
typedef struct memory_object_behave_info *memory_object_behave_info_t;
typedef struct memory_object_behave_info memory_object_behave_info_data_t;
typedef struct memory_object_perf_info *memory_object_perf_info_t;
typedef struct memory_object_perf_info memory_object_perf_info_data_t;
typedef struct memory_object_attr_info *memory_object_attr_info_t;
typedef struct memory_object_attr_info memory_object_attr_info_data_t;
#define MEMORY_OBJECT_BEHAVE_INFO_COUNT ((mach_msg_type_number_t) \
(sizeof(memory_object_behave_info_data_t)/sizeof(int)))
#define MEMORY_OBJECT_PERF_INFO_COUNT ((mach_msg_type_number_t) \
(sizeof(memory_object_perf_info_data_t)/sizeof(int)))
#define MEMORY_OBJECT_ATTR_INFO_COUNT ((mach_msg_type_number_t) \
(sizeof(memory_object_attr_info_data_t)/sizeof(int)))
#define invalid_memory_object_flavor(f) \
(f != MEMORY_OBJECT_ATTRIBUTE_INFO && \
f != MEMORY_OBJECT_PERFORMANCE_INFO && \
f != OLD_MEMORY_OBJECT_BEHAVIOR_INFO && \
f != MEMORY_OBJECT_BEHAVIOR_INFO && \
f != OLD_MEMORY_OBJECT_ATTRIBUTE_INFO)
/*
* Used to support options on memory_object_release_name call
*/
#define MEMORY_OBJECT_TERMINATE_IDLE 0x1
#define MEMORY_OBJECT_RESPECT_CACHE 0x2
#define MEMORY_OBJECT_RELEASE_NO_OP 0x4
/* named entry processor mapping options */
/* enumerated */
#define MAP_MEM_NOOP 0
#define MAP_MEM_COPYBACK 1
#define MAP_MEM_IO 2
#define MAP_MEM_WTHRU 3
#define MAP_MEM_WCOMB 4 /* Write combining mode */
/* aka store gather */
#define MAP_MEM_INNERWBACK 5
#define MAP_MEM_POSTED 6
#define MAP_MEM_RT 7
#define MAP_MEM_POSTED_REORDERED 8
#define MAP_MEM_POSTED_COMBINED_REORDERED 9
#define GET_MAP_MEM(flags) \
((((unsigned int)(flags)) >> 24) & 0xFF)
#define SET_MAP_MEM(caching, flags) \
((flags) = ((((unsigned int)(caching)) << 24) \
& 0xFF000000) | ((flags) & 0xFFFFFF));
/* leave room for vm_prot bits (0xFF ?) */
#define MAP_MEM_LEDGER_TAGGED 0x002000 /* object owned by a specific task and ledger */
#define MAP_MEM_PURGABLE_KERNEL_ONLY 0x004000 /* volatility controlled by kernel */
#define MAP_MEM_GRAB_SECLUDED 0x008000 /* can grab secluded pages */
#define MAP_MEM_ONLY 0x010000 /* change processor caching */
#define MAP_MEM_NAMED_CREATE 0x020000 /* create extant object */
#define MAP_MEM_PURGABLE 0x040000 /* create a purgable VM object */
#define MAP_MEM_NAMED_REUSE 0x080000 /* reuse provided entry if identical */
#define MAP_MEM_USE_DATA_ADDR 0x100000 /* preserve address of data, rather than base of page */
#define MAP_MEM_VM_COPY 0x200000 /* make a copy of a VM range */
#define MAP_MEM_VM_SHARE 0x400000 /* extract a VM range for remap */
#define MAP_MEM_4K_DATA_ADDR 0x800000 /* preserve 4K aligned address of data */
#define MAP_MEM_FLAGS_MASK 0x00FFFF00
#define MAP_MEM_FLAGS_USER ( \
MAP_MEM_PURGABLE_KERNEL_ONLY | \
MAP_MEM_GRAB_SECLUDED | \
MAP_MEM_ONLY | \
MAP_MEM_NAMED_CREATE | \
MAP_MEM_PURGABLE | \
MAP_MEM_NAMED_REUSE | \
MAP_MEM_USE_DATA_ADDR | \
MAP_MEM_VM_COPY | \
MAP_MEM_VM_SHARE | \
MAP_MEM_LEDGER_TAGGED | \
MAP_MEM_4K_DATA_ADDR)
#define MAP_MEM_FLAGS_ALL ( \
MAP_MEM_FLAGS_USER)
#endif /* _MACH_MEMORY_OBJECT_TYPES_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,116 @@
/*
* Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. The rights granted to you under the License
* may not be used to create, or enable the creation or redistribution of,
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
*
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/*
* @OSF_COPYRIGHT@
*/
/*
* Mach Operating System
* Copyright (c) 1991,1990 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
/*
*/
/*
* File: mach_debug/ipc_info.h
* Author: Rich Draves
* Date: March, 1990
*
* Definitions for the IPC debugging interface.
*/
#ifndef _MACH_DEBUG_IPC_INFO_H_
#define _MACH_DEBUG_IPC_INFO_H_
#include <mach/boolean.h>
#include <mach/port.h>
#include <mach/machine/vm_types.h>
/*
* Remember to update the mig type definitions
* in mach_debug_types.defs when adding/removing fields.
*/
typedef struct ipc_info_space {
natural_t iis_genno_mask; /* generation number mask */
natural_t iis_table_size; /* size of table */
natural_t iis_table_next; /* next possible size of table */
natural_t iis_tree_size; /* size of tree (UNUSED) */
natural_t iis_tree_small; /* # of small entries in tree (UNUSED) */
natural_t iis_tree_hash; /* # of hashed entries in tree (UNUSED) */
} ipc_info_space_t;
typedef struct ipc_info_space_basic {
natural_t iisb_genno_mask; /* generation number mask */
natural_t iisb_table_size; /* size of table */
natural_t iisb_table_next; /* next possible size of table */
natural_t iisb_table_inuse; /* number of entries in use */
natural_t iisb_reserved[2]; /* future expansion */
} ipc_info_space_basic_t;
typedef struct ipc_info_name {
mach_port_name_t iin_name; /* port name, including gen number */
/*boolean_t*/ integer_t iin_collision; /* collision at this entry? */
mach_port_type_t iin_type; /* straight port type */
mach_port_urefs_t iin_urefs; /* user-references */
natural_t iin_object; /* object pointer/identifier */
natural_t iin_next; /* marequest/next in free list */
natural_t iin_hash; /* hash index */
} ipc_info_name_t;
typedef ipc_info_name_t *ipc_info_name_array_t;
/* UNUSED */
typedef struct ipc_info_tree_name {
ipc_info_name_t iitn_name;
mach_port_name_t iitn_lchild; /* name of left child */
mach_port_name_t iitn_rchild; /* name of right child */
} ipc_info_tree_name_t;
typedef ipc_info_tree_name_t *ipc_info_tree_name_array_t;
#endif /* _MACH_DEBUG_IPC_INFO_H_ */

208
lib/libc/include/x86_64-macos-gnu/time.h vendored Normal file
View File

@@ -0,0 +1,208 @@
/*
* Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc.
* All or some portions of this file are derived from material licensed
* to the University of California by American Telephone and Telegraph
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
* the permission of UNIX System Laboratories, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)time.h 8.3 (Berkeley) 1/21/94
*/
#ifndef _TIME_H_
#define _TIME_H_
#include <_types.h>
#include <sys/cdefs.h>
#include <Availability.h>
#include <sys/_types/_clock_t.h>
#include <sys/_types/_null.h>
#include <sys/_types/_size_t.h>
#include <sys/_types/_time_t.h>
#include <sys/_types/_timespec.h>
struct tm {
int tm_sec; /* seconds after the minute [0-60] */
int tm_min; /* minutes after the hour [0-59] */
int tm_hour; /* hours since midnight [0-23] */
int tm_mday; /* day of the month [1-31] */
int tm_mon; /* months since January [0-11] */
int tm_year; /* years since 1900 */
int tm_wday; /* days since Sunday [0-6] */
int tm_yday; /* days since January 1 [0-365] */
int tm_isdst; /* Daylight Savings Time flag */
long tm_gmtoff; /* offset from UTC in seconds */
char *tm_zone; /* timezone abbreviation */
};
#if __DARWIN_UNIX03
#define CLOCKS_PER_SEC 1000000 /* [XSI] */
#else /* !__DARWIN_UNIX03 */
#include <machine/_limits.h> /* Include file containing CLK_TCK. */
#define CLOCKS_PER_SEC (__DARWIN_CLK_TCK)
#endif /* __DARWIN_UNIX03 */
#ifndef _ANSI_SOURCE
extern char *tzname[];
#endif
extern int getdate_err;
#if __DARWIN_UNIX03
extern long timezone __DARWIN_ALIAS(timezone);
#endif /* __DARWIN_UNIX03 */
extern int daylight;
__BEGIN_DECLS
char *asctime(const struct tm *);
clock_t clock(void) __DARWIN_ALIAS(clock);
char *ctime(const time_t *);
double difftime(time_t, time_t);
struct tm *getdate(const char *);
struct tm *gmtime(const time_t *);
struct tm *localtime(const time_t *);
time_t mktime(struct tm *) __DARWIN_ALIAS(mktime);
size_t strftime(char * __restrict, size_t, const char * __restrict, const struct tm * __restrict) __DARWIN_ALIAS(strftime);
char *strptime(const char * __restrict, const char * __restrict, struct tm * __restrict) __DARWIN_ALIAS(strptime);
time_t time(time_t *);
#ifndef _ANSI_SOURCE
void tzset(void);
#endif /* not ANSI */
/* [TSF] Thread safe functions */
char *asctime_r(const struct tm * __restrict, char * __restrict);
char *ctime_r(const time_t *, char *);
struct tm *gmtime_r(const time_t * __restrict, struct tm * __restrict);
struct tm *localtime_r(const time_t * __restrict, struct tm * __restrict);
#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE))
time_t posix2time(time_t);
#if !__DARWIN_UNIX03
char *timezone(int, int);
#endif /* !__DARWIN_UNIX03 */
void tzsetwall(void);
time_t time2posix(time_t);
time_t timelocal(struct tm * const);
time_t timegm(struct tm * const);
#endif /* neither ANSI nor POSIX */
#if !defined(_ANSI_SOURCE)
int nanosleep(const struct timespec *__rqtp, struct timespec *__rmtp) __DARWIN_ALIAS_C(nanosleep);
#endif
#if !defined(_DARWIN_FEATURE_CLOCK_GETTIME) || _DARWIN_FEATURE_CLOCK_GETTIME != 0
#if __DARWIN_C_LEVEL >= 199309L
#if __has_feature(enumerator_attributes)
#define __CLOCK_AVAILABILITY __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0)
#else
#define __CLOCK_AVAILABILITY
#endif
typedef enum {
_CLOCK_REALTIME __CLOCK_AVAILABILITY = 0,
#define CLOCK_REALTIME _CLOCK_REALTIME
_CLOCK_MONOTONIC __CLOCK_AVAILABILITY = 6,
#define CLOCK_MONOTONIC _CLOCK_MONOTONIC
#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
_CLOCK_MONOTONIC_RAW __CLOCK_AVAILABILITY = 4,
#define CLOCK_MONOTONIC_RAW _CLOCK_MONOTONIC_RAW
_CLOCK_MONOTONIC_RAW_APPROX __CLOCK_AVAILABILITY = 5,
#define CLOCK_MONOTONIC_RAW_APPROX _CLOCK_MONOTONIC_RAW_APPROX
_CLOCK_UPTIME_RAW __CLOCK_AVAILABILITY = 8,
#define CLOCK_UPTIME_RAW _CLOCK_UPTIME_RAW
_CLOCK_UPTIME_RAW_APPROX __CLOCK_AVAILABILITY = 9,
#define CLOCK_UPTIME_RAW_APPROX _CLOCK_UPTIME_RAW_APPROX
#endif
_CLOCK_PROCESS_CPUTIME_ID __CLOCK_AVAILABILITY = 12,
#define CLOCK_PROCESS_CPUTIME_ID _CLOCK_PROCESS_CPUTIME_ID
_CLOCK_THREAD_CPUTIME_ID __CLOCK_AVAILABILITY = 16
#define CLOCK_THREAD_CPUTIME_ID _CLOCK_THREAD_CPUTIME_ID
} clockid_t;
__CLOCK_AVAILABILITY
int clock_getres(clockid_t __clock_id, struct timespec *__res);
__CLOCK_AVAILABILITY
int clock_gettime(clockid_t __clock_id, struct timespec *__tp);
#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
__CLOCK_AVAILABILITY
__uint64_t clock_gettime_nsec_np(clockid_t __clock_id);
#endif
__OSX_AVAILABLE(10.12) __IOS_PROHIBITED
__TVOS_PROHIBITED __WATCHOS_PROHIBITED
int clock_settime(clockid_t __clock_id, const struct timespec *__tp);
#undef __CLOCK_AVAILABILITY
#endif /* __DARWIN_C_LEVEL */
#endif /* _DARWIN_FEATURE_CLOCK_GETTIME */
#if (__DARWIN_C_LEVEL >= __DARWIN_C_FULL) && \
((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \
(defined(__cplusplus) && __cplusplus >= 201703L))
/* ISO/IEC 9899:201x 7.27.2.5 The timespec_get function */
#define TIME_UTC 1 /* time elapsed since epoch */
__API_AVAILABLE(macosx(10.15), ios(13.0), tvos(13.0), watchos(6.0))
int timespec_get(struct timespec *ts, int base);
#endif
__END_DECLS
#ifdef _USE_EXTENDED_LOCALES_
#include <xlocale/_time.h>
#endif /* _USE_EXTENDED_LOCALES_ */
#endif /* !_TIME_H_ */

238
lib/libc/mingw/lib-common/dbghelp.def vendored Normal file
View File

@@ -0,0 +1,238 @@
;
; Definition file of dbghelp.dll
; Automatic generated by gendef
; written by Kai Tietz 2008-2014
;
LIBRARY "dbghelp.dll"
EXPORTS
SymGetOmapBlockBase
DbgHelpCreateUserDump
DbgHelpCreateUserDumpW
EnumDirTree
EnumDirTreeW
EnumerateLoadedModules
EnumerateLoadedModules64
EnumerateLoadedModulesEx
EnumerateLoadedModulesExW
EnumerateLoadedModulesW64
ExtensionApiVersion
FindDebugInfoFile
FindDebugInfoFileEx
FindDebugInfoFileExW
FindExecutableImage
FindExecutableImageEx
FindExecutableImageExW
FindFileInPath
FindFileInSearchPath
GetSymLoadError
GetTimestampForLoadedLibrary
ImageDirectoryEntryToData
ImageDirectoryEntryToDataEx
ImageNtHeader
ImageRvaToSection
ImageRvaToVa
ImagehlpApiVersion
ImagehlpApiVersionEx
MakeSureDirectoryPathExists
MapDebugInformation
MiniDumpReadDumpStream
MiniDumpWriteDump
RangeMapAddPeImageSections
RangeMapCreate
RangeMapFree
RangeMapRead
RangeMapRemove
RangeMapWrite
RemoveInvalidModuleList
ReportSymbolLoadSummary
SearchTreeForFile
SearchTreeForFileW
SetCheckUserInterruptShared
SetSymLoadError
StackWalk
StackWalk64
StackWalkEx
SymAddSourceStream
SymAddSourceStreamA
SymAddSourceStreamW
SymAddSymbol
SymAddSymbolW
SymAddrIncludeInlineTrace
SymCleanup
SymCompareInlineTrace
SymDeleteSymbol
SymDeleteSymbolW
SymEnumLines
SymEnumLinesW
SymEnumProcesses
SymEnumSourceFileTokens
SymEnumSourceFiles
SymEnumSourceFilesW
SymEnumSourceLines
SymEnumSourceLinesW
SymEnumSym
SymEnumSymbols
SymEnumSymbolsEx
SymEnumSymbolsExW
SymEnumSymbolsForAddr
SymEnumSymbolsForAddrW
SymEnumSymbolsW
SymEnumTypes
SymEnumTypesByName
SymEnumTypesByNameW
SymEnumTypesW
SymEnumerateModules
SymEnumerateModules64
SymEnumerateModulesW64
SymEnumerateSymbols
SymEnumerateSymbols64
SymEnumerateSymbolsW
SymEnumerateSymbolsW64
SymFindDebugInfoFile
SymFindDebugInfoFileW
SymFindExecutableImage
SymFindExecutableImageW
SymFindFileInPath
SymFindFileInPathW
SymFromAddr
SymFromAddrW
SymFromIndex
SymFromIndexW
SymFromInlineContext
SymFromInlineContextW
SymFromName
SymFromNameW
SymFromToken
SymFromTokenW
SymFunctionTableAccess
SymFunctionTableAccess64
SymFunctionTableAccess64AccessRoutines
SymGetFileLineOffsets64
SymGetHomeDirectory
SymGetHomeDirectoryW
SymGetLineFromAddr
SymGetLineFromAddr64
SymGetLineFromAddrW64
SymGetLineFromInlineContext
SymGetLineFromInlineContextW
SymGetLineFromName
SymGetLineFromName64
SymGetLineFromNameW64
SymGetLineNext
SymGetLineNext64
SymGetLineNextW64
SymGetLinePrev
SymGetLinePrev64
SymGetLinePrevW64
SymGetModuleBase
SymGetModuleBase64
SymGetModuleInfo
SymGetModuleInfo64
SymGetModuleInfoW
SymGetModuleInfoW64
SymGetOmaps
SymGetOptions
SymGetScope
SymGetScopeW
SymGetSearchPath
SymGetSearchPathW
SymGetSourceFile
SymGetSourceFileFromToken
SymGetSourceFileFromTokenW
SymGetSourceFileToken
SymGetSourceFileTokenW
SymGetSourceFileW
SymGetSourceVarFromToken
SymGetSourceVarFromTokenW
SymGetSymFromAddr
SymGetSymFromAddr64
SymGetSymFromName
SymGetSymFromName64
SymGetSymNext
SymGetSymNext64
SymGetSymPrev
SymGetSymPrev64
SymGetSymbolFile
SymGetSymbolFileW
SymGetTypeFromName
SymGetTypeFromNameW
SymGetTypeInfo
SymGetTypeInfoEx
SymGetUnwindInfo
SymInitialize
SymInitializeW
SymLoadModule
SymLoadModule64
SymLoadModuleEx
SymLoadModuleExW
SymMatchFileName
SymMatchFileNameW
SymMatchString
SymMatchStringA
SymMatchStringW
SymNext
SymNextW
SymPrev
SymPrevW
SymQueryInlineTrace
SymRefreshModuleList
SymRegisterCallback
SymRegisterCallback64
SymRegisterCallbackW64
SymRegisterFunctionEntryCallback
SymRegisterFunctionEntryCallback64
SymSearch
SymSearchW
SymSetContext
SymSetHomeDirectory
SymSetHomeDirectoryW
SymSetOptions
SymSetParentWindow
SymSetScopeFromAddr
SymSetScopeFromIndex
SymSetScopeFromInlineContext
SymSetSearchPath
SymSetSearchPathW
SymSrvDeltaName
SymSrvDeltaNameW
SymSrvGetFileIndexInfo
SymSrvGetFileIndexInfoW
SymSrvGetFileIndexString
SymSrvGetFileIndexStringW
SymSrvGetFileIndexes
SymSrvGetFileIndexesW
SymSrvGetSupplement
SymSrvGetSupplementW
SymSrvIsStore
SymSrvIsStoreW
SymSrvStoreFile
SymSrvStoreFileW
SymSrvStoreSupplement
SymSrvStoreSupplementW
SymUnDName
SymUnDName64
SymUnloadModule
SymUnloadModule64
UnDecorateSymbolName
UnDecorateSymbolNameW
UnmapDebugInformation
WinDbgExtensionDllInit
block
chksym
dbghelp
dh
fptr
homedir
inlinedbg
itoldyouso
lmi
lminfo
omap
optdbgdump
optdbgdumpaddr
srcfiles
stack_force_ebp
stackdbg
sym
symsrv
vc7fpo

192
lib/libc/mingw/lib-common/odbc32.def vendored Normal file
View File

@@ -0,0 +1,192 @@
;
; Exports of file ODBC32.dll
;
; Autogenerated by gen_exportdef
; Written by Kai Tietz, 2007
;
LIBRARY ODBC32.dll
EXPORTS
SQLAllocConnect
SQLAllocEnv
SQLAllocStmt
SQLBindCol
SQLCancel
SQLColAttributes
SQLConnect
SQLDescribeCol
SQLDisconnect
SQLError
SQLExecDirect
SQLExecute
SQLFetch
SQLFreeConnect
SQLFreeEnv
SQLFreeStmt
SQLGetCursorName
SQLNumResultCols
SQLPrepare
SQLRowCount
SQLSetCursorName
SQLSetParam
SQLTransact
SQLAllocHandle
SQLBindParam
SQLCloseCursor
SQLColAttribute
SQLCopyDesc
SQLEndTran
SQLFetchScroll
SQLFreeHandle
SQLGetConnectAttr
SQLGetDescField
SQLGetDescRec
SQLGetDiagField
SQLGetDiagRec
SQLGetEnvAttr
SQLGetStmtAttr
SQLSetConnectAttr
SQLColumns
SQLDriverConnect
SQLGetConnectOption
SQLGetData
SQLGetFunctions
SQLGetInfo
SQLGetStmtOption
SQLGetTypeInfo
SQLParamData
SQLPutData
SQLSetConnectOption
SQLSetStmtOption
SQLSpecialColumns
SQLStatistics
SQLTables
SQLBrowseConnect
SQLColumnPrivileges
SQLDataSources
SQLDescribeParam
SQLExtendedFetch
SQLForeignKeys
SQLMoreResults
SQLNativeSql
SQLNumParams
SQLParamOptions
SQLPrimaryKeys
SQLProcedureColumns
SQLProcedures
SQLSetPos
SQLSetScrollOptions
SQLTablePrivileges
SQLDrivers
SQLBindParameter
SQLSetDescField
SQLSetDescRec
SQLSetEnvAttr
SQLSetStmtAttr
SQLAllocHandleStd
SQLBulkOperations
CloseODBCPerfData
CollectODBCPerfData
CursorLibLockDbc
CursorLibLockDesc
CursorLibLockStmt
ODBCGetTryWaitValue
CursorLibTransact
ODBCSetTryWaitValue
DllBidEntryPoint
GetODBCSharedData
LockHandle
MpHeapAlloc
MpHeapCompact
MpHeapCreate
MpHeapDestroy
MpHeapFree
MpHeapReAlloc
MpHeapSize
MpHeapValidate
ODBCInternalConnectW
OpenODBCPerfData
PostComponentError
PostODBCComponentError
PostODBCError
SQLCancelHandle
SQLCompleteAsync
SearchStatusCode
VFreeErrors
VRetrieveDriverErrorsRowCol
SQLColAttributesW
SQLConnectW
SQLDescribeColW
ValidateErrorQueue
SQLErrorW
SQLExecDirectW
g_hHeapMalloc DATA
SQLGetCursorNameW
SQLPrepareW
SQLSetCursorNameW
SQLColAttributeW
SQLGetConnectAttrW
SQLGetDescFieldW
SQLGetDescRecW
SQLGetDiagFieldW
SQLGetDiagRecW
SQLGetStmtAttrW
SQLSetConnectAttrW
SQLColumnsW
SQLDriverConnectW
SQLGetConnectOptionW
SQLGetInfoW
SQLGetTypeInfoW
SQLSetConnectOptionW
SQLSpecialColumnsW
SQLStatisticsW
SQLTablesW
SQLBrowseConnectW
SQLColumnPrivilegesW
SQLDataSourcesW
SQLForeignKeysW
SQLNativeSqlW
SQLPrimaryKeysW
SQLProcedureColumnsW
SQLProceduresW
SQLTablePrivilegesW
SQLDriversW
SQLSetDescFieldW
SQLSetStmtAttrW
SQLColAttributesA
SQLConnectA
SQLDescribeColA
SQLErrorA
SQLExecDirectA
SQLGetCursorNameA
SQLPrepareA
SQLSetCursorNameA
SQLColAttributeA
SQLGetConnectAttrA
SQLGetDescFieldA
SQLGetDescRecA
SQLGetDiagFieldA
SQLGetDiagRecA
SQLGetStmtAttrA
SQLSetConnectAttrA
SQLColumnsA
SQLDriverConnectA
SQLGetConnectOptionA
SQLGetInfoA
SQLGetTypeInfoA
SQLSetConnectOptionA
SQLSpecialColumnsA
SQLStatisticsA
SQLTablesA
SQLBrowseConnectA
SQLColumnPrivilegesA
SQLDataSourcesA
SQLForeignKeysA
SQLNativeSqlA
SQLPrimaryKeysA
SQLProcedureColumnsA
SQLProceduresA
SQLTablePrivilegesA
SQLDriversA
SQLSetDescFieldA
SQLSetStmtAttrA
ODBCQualifyFileDSNW

212
lib/libc/mingw/lib32/dbghelp.def vendored Normal file
View File

@@ -0,0 +1,212 @@
;
; Definition file of dbghelp.dll
; Automatic generated by gendef
; written by Kai Tietz 2008
;
LIBRARY "dbghelp.dll"
EXPORTS
SymGetOmapBlockBase@16
DbgHelpCreateUserDump@12
DbgHelpCreateUserDumpW@12
EnumDirTree@24
EnumDirTreeW@24
EnumerateLoadedModules64@12
EnumerateLoadedModules@12
EnumerateLoadedModulesEx@12
EnumerateLoadedModulesExW@12
EnumerateLoadedModulesW64@12
ExtensionApiVersion@0
FindDebugInfoFile@12
FindDebugInfoFileEx@20
FindDebugInfoFileExW@20
FindExecutableImage@12
FindExecutableImageEx@20
FindExecutableImageExW@20
FindFileInPath@32
FindFileInSearchPath@28
GetTimestampForLoadedLibrary@4
ImageDirectoryEntryToData@16
ImageDirectoryEntryToDataEx@20
ImageNtHeader@4
ImageRvaToSection@12
ImageRvaToVa@16
ImagehlpApiVersion@0
ImagehlpApiVersionEx@4
MakeSureDirectoryPathExists@4
MapDebugInformation@16
MiniDumpReadDumpStream@20
MiniDumpWriteDump@28
SearchTreeForFile@12
SearchTreeForFileW@12
StackWalk64@36
StackWalk@36
SymAddSourceStream@24
SymAddSourceStreamA@24
SymAddSourceStreamW@24
SymAddSymbol@32
SymAddSymbolW@32
SymCleanup@4
SymDeleteSymbol@28
SymDeleteSymbolW@28
SymEnumLines@28
SymEnumLinesW@28
SymEnumProcesses@8
SymEnumSourceFileTokens@16
SymEnumSourceFiles@24
SymEnumSourceFilesW@24
SymEnumSourceLines@36
SymEnumSourceLinesW@36
SymEnumSym@20
SymEnumSymbols@24
SymEnumSymbolsForAddr@20
SymEnumSymbolsForAddrW@20
SymEnumSymbolsW@24
SymEnumTypes@20
SymEnumTypesByName@24
SymEnumTypesByNameW@24
SymEnumTypesW@20
SymEnumerateModules64@12
SymEnumerateModules@12
SymEnumerateModulesW64@12
SymEnumerateSymbols64@20
SymEnumerateSymbols@16
SymEnumerateSymbolsW64@20
SymEnumerateSymbolsW@16
SymFindDebugInfoFile@20
SymFindDebugInfoFileW@20
SymFindExecutableImage@20
SymFindExecutableImageW@20
SymFindFileInPath@40
SymFindFileInPathW@40
SymFromAddr@20
SymFromAddrW@20
SymFromIndex@20
SymFromIndexW@20
SymFromName@12
SymFromNameW@12
SymFromToken@20
SymFromTokenW@20
SymFunctionTableAccess64@12
SymFunctionTableAccess@8
SymGetFileLineOffsets64@20
SymGetHomeDirectory@12
SymGetHomeDirectoryW@12
SymGetLineFromAddr64@20
SymGetLineFromAddr@16
SymGetLineFromAddrW64@20
SymGetLineFromName64@24
SymGetLineFromName@24
SymGetLineFromNameW64@24
SymGetLineNext64@8
SymGetLineNext@8
SymGetLineNextW64@8
SymGetLinePrev64@8
SymGetLinePrev@8
SymGetLinePrevW64@8
SymGetModuleBase64@12
SymGetModuleBase@8
SymGetModuleInfo64@16
SymGetModuleInfo@12
SymGetModuleInfoW64@16
SymGetModuleInfoW@12
SymGetOmaps@28
SymGetOptions@0
SymGetScope@20
SymGetScopeW@20
SymGetSearchPath@12
SymGetSearchPathW@12
SymGetSourceFile@28
SymGetSourceFileFromToken@20
SymGetSourceFileFromTokenW@20
SymGetSourceFileToken@24
SymGetSourceFileTokenW@24
SymGetSourceFileW@28
SymGetSourceVarFromToken@24
SymGetSourceVarFromTokenW@24
SymGetSymFromAddr64@20
SymGetSymFromAddr@16
SymGetSymFromName64@12
SymGetSymFromName@12
SymGetSymNext64@8
SymGetSymNext@8
SymGetSymPrev64@8
SymGetSymPrev@8
SymGetSymbolFile@32
SymGetSymbolFileW@32
SymGetTypeFromName@20
SymGetTypeFromNameW@20
SymGetTypeInfo@24
SymGetTypeInfoEx@16
SymGetUnwindInfo@20
SymInitialize@12
SymInitializeW@12
SymLoadModule64@28
SymLoadModule@24
SymLoadModuleEx@36
SymLoadModuleExW@36
SymMatchFileName@16
SymMatchFileNameW@16
SymMatchString@12
SymMatchStringA@12
SymMatchStringW@12
SymNext@8
SymNextW@8
SymPrev@8
SymPrevW@8
SymRefreshModuleList@4
SymRegisterCallback64@16
SymRegisterCallback@12
SymRegisterCallbackW64@16
SymRegisterFunctionEntryCallback64@16
SymRegisterFunctionEntryCallback@12
SymSearch@44
SymSearchW@44
SymSetContext@12
SymSetHomeDirectory@8
SymSetHomeDirectoryW@8
SymSetOptions@4
SymSetParentWindow@4
SymSetScopeFromAddr@12
SymSetScopeFromIndex@16
SymSetSearchPath@8
SymSetSearchPathW@8
SymSrvDeltaName@20
SymSrvDeltaNameW@20
SymSrvGetFileIndexInfo@12
SymSrvGetFileIndexInfoW@12
SymSrvGetFileIndexString@24
SymSrvGetFileIndexStringW@24
SymSrvGetFileIndexes@20
SymSrvGetFileIndexesW@20
SymSrvGetSupplement@16
SymSrvGetSupplementW@16
SymSrvIsStore@8
SymSrvIsStoreW@8
SymSrvStoreFile@16
SymSrvStoreFileW@16
SymSrvStoreSupplement@20
SymSrvStoreSupplementW@20
SymUnDName64@12
SymUnDName@12
SymUnloadModule64@12
SymUnloadModule@8
UnDecorateSymbolName@16
UnDecorateSymbolNameW@16
UnmapDebugInformation@4
WinDbgExtensionDllInit@12
block@24
chksym@24
dbghelp@8
dh@24
fptr@24
homedir@24
itoldyouso@24
lmi@24
lminfo@24
omap@24
srcfiles@24
stack_force_ebp@24
stackdbg@24
sym@24
symsrv@24
vc7fpo@24

185
lib/libc/mingw/lib32/odbc32.def vendored Normal file
View File

@@ -0,0 +1,185 @@
LIBRARY ODBC32.dll
EXPORTS
CloseODBCPerfData@0
CollectODBCPerfData@16
CursorLibLockDbc@8
CursorLibLockDesc@8
CursorLibLockStmt@8
CursorLibTransact@12
LockHandle@12
MpHeapAlloc
MpHeapCompact
MpHeapCreate
MpHeapDestroy
MpHeapFree
MpHeapReAlloc
MpHeapSize
MpHeapValidate
ODBCGetTryWaitValue@0
ODBCInternalConnectW@36
ODBCQualifyFileDSNW@4
ODBCSetTryWaitValue@4
ODBCSharedPerfMon
ODBCSharedTraceFlag
ODBCSharedVSFlag
OpenODBCPerfData@4
PostComponentError@4
PostODBCComponentError@4
PostODBCError@16
SQLAllocConnect@8
SQLAllocEnv@4
SQLAllocHandle@12
SQLAllocHandleStd@12
SQLAllocStmt@8
SQLBindCol@24
SQLBindParam@32
SQLBindParameter@40
SQLBrowseConnect@24
SQLBrowseConnectA@24
SQLBrowseConnectW@24
SQLBulkOperations@8
SQLCancel@4
SQLCloseCursor@4
SQLColAttribute@28
SQLColAttributeA@28
SQLColAttributeW@28
SQLColAttributes@28
SQLColAttributesA@28
SQLColAttributesW@28
SQLColumnPrivileges@36
SQLColumnPrivilegesA@36
SQLColumnPrivilegesW@36
SQLColumns@36
SQLColumnsA@36
SQLColumnsW@36
SQLConnect@28
SQLConnectA@28
SQLConnectW@28
SQLCopyDesc@8
SQLDataSources@32
SQLDataSourcesA@32
SQLDataSourcesW@32
SQLDescribeCol@36
SQLDescribeColA@36
SQLDescribeColW@36
SQLDescribeParam@24
SQLDisconnect@4
SQLDriverConnect@32
SQLDriverConnectA@32
SQLDriverConnectW@32
SQLDrivers@32
SQLDriversA@32
SQLDriversW@32
SQLEndTran@12
SQLError@32
SQLErrorA@32
SQLErrorW@32
SQLExecDirect@12
SQLExecDirectA@12
SQLExecDirectW@12
SQLExecute@4
SQLExtendedFetch@20
SQLFetch@4
SQLFetchScroll@12
SQLForeignKeys@52
SQLForeignKeysA@52
SQLForeignKeysW@52
SQLFreeConnect@4
SQLFreeEnv@4
SQLFreeHandle@8
SQLFreeStmt@8
SQLGetConnectAttr@20
SQLGetConnectAttrA@20
SQLGetConnectAttrW@20
SQLGetConnectOption@12
SQLGetConnectOptionA@12
SQLGetConnectOptionW@12
SQLGetCursorName@16
SQLGetCursorNameA@16
SQLGetCursorNameW@16
SQLGetData@24
SQLGetDescField@24
SQLGetDescFieldA@24
SQLGetDescFieldW@24
SQLGetDescRec@44
SQLGetDescRecA@44
SQLGetDescRecW@44
SQLGetDiagField@28
SQLGetDiagFieldA@28
SQLGetDiagFieldW@28
SQLGetDiagRec@32
SQLGetDiagRecA@32
SQLGetDiagRecW@32
SQLGetEnvAttr@20
SQLGetFunctions@12
SQLGetInfo@20
SQLGetInfoA@20
SQLGetInfoW@20
SQLGetStmtAttr@20
SQLGetStmtAttrA@20
SQLGetStmtAttrW@20
SQLGetStmtOption@12
SQLGetTypeInfo@8
SQLGetTypeInfoA@8
SQLGetTypeInfoW@8
SQLMoreResults@4
SQLNativeSql@24
SQLNativeSqlA@24
SQLNativeSqlW@24
SQLNumParams@8
SQLNumResultCols@8
SQLParamData@8
SQLParamOptions@12
SQLPrepare@12
SQLPrepareA@12
SQLPrepareW@12
SQLPrimaryKeys@28
SQLPrimaryKeysA@28
SQLPrimaryKeysW@28
SQLProcedureColumns@36
SQLProcedureColumnsA@36
SQLProcedureColumnsW@36
SQLProcedures@28
SQLProceduresA@28
SQLProceduresW@28
SQLPutData@12
SQLRowCount@8
SQLSetConnectAttr@16
SQLSetConnectAttrA@16
SQLSetConnectAttrW@16
SQLSetConnectOption@12
SQLSetConnectOptionA@12
SQLSetConnectOptionW@12
SQLSetCursorName@12
SQLSetCursorNameA@12
SQLSetCursorNameW@12
SQLSetDescField@20
SQLSetDescFieldA@20
SQLSetDescFieldW@20
SQLSetDescRec@40
SQLSetEnvAttr@16
SQLSetParam@32
SQLSetPos@16
SQLSetScrollOptions@16
SQLSetStmtAttr@16
SQLSetStmtAttrA@16
SQLSetStmtAttrW@16
SQLSetStmtOption@12
SQLSpecialColumns@40
SQLSpecialColumnsA@40
SQLSpecialColumnsW@40
SQLStatistics@36
SQLStatisticsA@36
SQLStatisticsW@36
SQLTablePrivileges@28
SQLTablePrivilegesA@28
SQLTablePrivilegesW@28
SQLTables@36
SQLTablesA@36
SQLTablesW@36
SQLTransact@12
SearchStatusCode@8
VFreeErrors@4
VRetrieveDriverErrorsRowCol@24
ValidateErrorQueue@8
g_hHeapMalloc

10
lib/libc/mingw/lib64/odbc32gt.def vendored Normal file
View File

@@ -0,0 +1,10 @@
;
; Exports of file ODBC32GT.dll
;
; Autogenerated by gen_exportdef
; Written by Kai Tietz, 2007
;
LIBRARY ODBC32GT.dll
EXPORTS
Dispatch
Dispatch2

View File

@@ -234,7 +234,7 @@ fn refreshWithHeldLock(self: *Progress) void {
self.terminal = null;
break :winapi;
}
if (windows.kernel32.FillConsoleOutputCharacterA(
if (windows.kernel32.FillConsoleOutputCharacterW(
file.handle,
' ',
fill_chars,

View File

@@ -124,7 +124,7 @@ pub fn ArrayHashMap(
/// Create an ArrayHashMap instance which will use a specified allocator.
pub fn init(allocator: *Allocator) Self {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call initContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call initContext instead.");
return initContext(allocator, undefined);
}
pub fn initContext(allocator: *Allocator, ctx: Context) Self {
@@ -518,7 +518,7 @@ pub fn ArrayHashMapUnmanaged(
/// the promoted map should no longer be used.
pub fn promote(self: Self, allocator: *Allocator) Managed {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call promoteContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call promoteContext instead.");
return self.promoteContext(allocator, undefined);
}
pub fn promoteContext(self: Self, allocator: *Allocator, ctx: Context) Managed {
@@ -618,7 +618,7 @@ pub fn ArrayHashMapUnmanaged(
/// the value (but not the key).
pub fn getOrPut(self: *Self, allocator: *Allocator, key: K) !GetOrPutResult {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call getOrPutContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutContext instead.");
return self.getOrPutContext(allocator, key, undefined);
}
pub fn getOrPutContext(self: *Self, allocator: *Allocator, key: K, ctx: Context) !GetOrPutResult {
@@ -630,7 +630,7 @@ pub fn ArrayHashMapUnmanaged(
}
pub fn getOrPutAdapted(self: *Self, allocator: *Allocator, key: anytype, key_ctx: anytype) !GetOrPutResult {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call getOrPutContextAdapted instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutContextAdapted instead.");
return self.getOrPutContextAdapted(allocator, key, key_ctx, undefined);
}
pub fn getOrPutContextAdapted(self: *Self, allocator: *Allocator, key: anytype, key_ctx: anytype, ctx: Context) !GetOrPutResult {
@@ -658,7 +658,7 @@ pub fn ArrayHashMapUnmanaged(
/// is enough capacity to store it.
pub fn getOrPutAssumeCapacity(self: *Self, key: K) GetOrPutResult {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call getOrPutAssumeCapacityContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutAssumeCapacityContext instead.");
return self.getOrPutAssumeCapacityContext(key, undefined);
}
pub fn getOrPutAssumeCapacityContext(self: *Self, key: K, ctx: Context) GetOrPutResult {
@@ -716,7 +716,7 @@ pub fn ArrayHashMapUnmanaged(
pub fn getOrPutValue(self: *Self, allocator: *Allocator, key: K, value: V) !GetOrPutResult {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call getOrPutValueContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutValueContext instead.");
return self.getOrPutValueContext(allocator, key, value, undefined);
}
pub fn getOrPutValueContext(self: *Self, allocator: *Allocator, key: K, value: V, ctx: Context) !GetOrPutResult {
@@ -735,7 +735,7 @@ pub fn ArrayHashMapUnmanaged(
/// `expected_count` will not cause an allocation, and therefore cannot fail.
pub fn ensureTotalCapacity(self: *Self, allocator: *Allocator, new_capacity: usize) !void {
if (@sizeOf(ByIndexContext) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call ensureTotalCapacityContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call ensureTotalCapacityContext instead.");
return self.ensureTotalCapacityContext(allocator, new_capacity, undefined);
}
pub fn ensureTotalCapacityContext(self: *Self, allocator: *Allocator, new_capacity: usize, ctx: Context) !void {
@@ -769,7 +769,7 @@ pub fn ArrayHashMapUnmanaged(
additional_capacity: usize,
) !void {
if (@sizeOf(ByIndexContext) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call ensureTotalCapacityContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call ensureTotalCapacityContext instead.");
return self.ensureUnusedCapacityContext(allocator, additional_capacity, undefined);
}
pub fn ensureUnusedCapacityContext(
@@ -794,7 +794,7 @@ pub fn ArrayHashMapUnmanaged(
/// existing data, see `getOrPut`.
pub fn put(self: *Self, allocator: *Allocator, key: K, value: V) !void {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call putContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call putContext instead.");
return self.putContext(allocator, key, value, undefined);
}
pub fn putContext(self: *Self, allocator: *Allocator, key: K, value: V, ctx: Context) !void {
@@ -806,7 +806,7 @@ pub fn ArrayHashMapUnmanaged(
/// entry with the same key is already present
pub fn putNoClobber(self: *Self, allocator: *Allocator, key: K, value: V) !void {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call putNoClobberContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call putNoClobberContext instead.");
return self.putNoClobberContext(allocator, key, value, undefined);
}
pub fn putNoClobberContext(self: *Self, allocator: *Allocator, key: K, value: V, ctx: Context) !void {
@@ -820,7 +820,7 @@ pub fn ArrayHashMapUnmanaged(
/// existing data, see `getOrPutAssumeCapacity`.
pub fn putAssumeCapacity(self: *Self, key: K, value: V) void {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call putAssumeCapacityContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call putAssumeCapacityContext instead.");
return self.putAssumeCapacityContext(key, value, undefined);
}
pub fn putAssumeCapacityContext(self: *Self, key: K, value: V, ctx: Context) void {
@@ -833,7 +833,7 @@ pub fn ArrayHashMapUnmanaged(
/// To detect if a put would clobber existing data, see `getOrPutAssumeCapacity`.
pub fn putAssumeCapacityNoClobber(self: *Self, key: K, value: V) void {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call putAssumeCapacityNoClobberContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call putAssumeCapacityNoClobberContext instead.");
return self.putAssumeCapacityNoClobberContext(key, value, undefined);
}
pub fn putAssumeCapacityNoClobberContext(self: *Self, key: K, value: V, ctx: Context) void {
@@ -845,7 +845,7 @@ pub fn ArrayHashMapUnmanaged(
/// Inserts a new `Entry` into the hash map, returning the previous one, if any.
pub fn fetchPut(self: *Self, allocator: *Allocator, key: K, value: V) !?KV {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call fetchPutContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call fetchPutContext instead.");
return self.fetchPutContext(allocator, key, value, undefined);
}
pub fn fetchPutContext(self: *Self, allocator: *Allocator, key: K, value: V, ctx: Context) !?KV {
@@ -865,7 +865,7 @@ pub fn ArrayHashMapUnmanaged(
/// If insertion happens, asserts there is enough capacity without allocating.
pub fn fetchPutAssumeCapacity(self: *Self, key: K, value: V) ?KV {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call fetchPutAssumeCapacityContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call fetchPutAssumeCapacityContext instead.");
return self.fetchPutAssumeCapacityContext(key, value, undefined);
}
pub fn fetchPutAssumeCapacityContext(self: *Self, key: K, value: V, ctx: Context) ?KV {
@@ -884,7 +884,7 @@ pub fn ArrayHashMapUnmanaged(
/// Finds pointers to the key and value storage associated with a key.
pub fn getEntry(self: Self, key: K) ?Entry {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call getEntryContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getEntryContext instead.");
return self.getEntryContext(key, undefined);
}
pub fn getEntryContext(self: Self, key: K, ctx: Context) ?Entry {
@@ -903,7 +903,7 @@ pub fn ArrayHashMapUnmanaged(
/// Finds the index in the `entries` array where a key is stored
pub fn getIndex(self: Self, key: K) ?usize {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call getIndexContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getIndexContext instead.");
return self.getIndexContext(key, undefined);
}
pub fn getIndexContext(self: Self, key: K, ctx: Context) ?usize {
@@ -938,7 +938,7 @@ pub fn ArrayHashMapUnmanaged(
/// Find the value associated with a key
pub fn get(self: Self, key: K) ?V {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call getContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getContext instead.");
return self.getContext(key, undefined);
}
pub fn getContext(self: Self, key: K, ctx: Context) ?V {
@@ -952,7 +952,7 @@ pub fn ArrayHashMapUnmanaged(
/// Find a pointer to the value associated with a key
pub fn getPtr(self: Self, key: K) ?*V {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call getPtrContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getPtrContext instead.");
return self.getPtrContext(key, undefined);
}
pub fn getPtrContext(self: Self, key: K, ctx: Context) ?*V {
@@ -967,7 +967,7 @@ pub fn ArrayHashMapUnmanaged(
/// Check whether a key is stored in the map
pub fn contains(self: Self, key: K) bool {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call containsContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call containsContext instead.");
return self.containsContext(key, undefined);
}
pub fn containsContext(self: Self, key: K, ctx: Context) bool {
@@ -983,7 +983,7 @@ pub fn ArrayHashMapUnmanaged(
/// element.
pub fn fetchSwapRemove(self: *Self, key: K) ?KV {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call fetchSwapRemoveContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call fetchSwapRemoveContext instead.");
return self.fetchSwapRemoveContext(key, undefined);
}
pub fn fetchSwapRemoveContext(self: *Self, key: K, ctx: Context) ?KV {
@@ -991,7 +991,7 @@ pub fn ArrayHashMapUnmanaged(
}
pub fn fetchSwapRemoveAdapted(self: *Self, key: anytype, ctx: anytype) ?KV {
if (@sizeOf(ByIndexContext) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call fetchSwapRemoveContextAdapted instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call fetchSwapRemoveContextAdapted instead.");
return self.fetchSwapRemoveContextAdapted(key, ctx, undefined);
}
pub fn fetchSwapRemoveContextAdapted(self: *Self, key: anytype, key_ctx: anytype, ctx: Context) ?KV {
@@ -1004,7 +1004,7 @@ pub fn ArrayHashMapUnmanaged(
/// thereby maintaining the current ordering.
pub fn fetchOrderedRemove(self: *Self, key: K) ?KV {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call fetchOrderedRemoveContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call fetchOrderedRemoveContext instead.");
return self.fetchOrderedRemoveContext(key, undefined);
}
pub fn fetchOrderedRemoveContext(self: *Self, key: K, ctx: Context) ?KV {
@@ -1012,7 +1012,7 @@ pub fn ArrayHashMapUnmanaged(
}
pub fn fetchOrderedRemoveAdapted(self: *Self, key: anytype, ctx: anytype) ?KV {
if (@sizeOf(ByIndexContext) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call fetchOrderedRemoveContextAdapted instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call fetchOrderedRemoveContextAdapted instead.");
return self.fetchOrderedRemoveContextAdapted(key, ctx, undefined);
}
pub fn fetchOrderedRemoveContextAdapted(self: *Self, key: anytype, key_ctx: anytype, ctx: Context) ?KV {
@@ -1025,7 +1025,7 @@ pub fn ArrayHashMapUnmanaged(
/// was removed, false otherwise.
pub fn swapRemove(self: *Self, key: K) bool {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call swapRemoveContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call swapRemoveContext instead.");
return self.swapRemoveContext(key, undefined);
}
pub fn swapRemoveContext(self: *Self, key: K, ctx: Context) bool {
@@ -1033,7 +1033,7 @@ pub fn ArrayHashMapUnmanaged(
}
pub fn swapRemoveAdapted(self: *Self, key: anytype, ctx: anytype) bool {
if (@sizeOf(ByIndexContext) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call swapRemoveContextAdapted instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call swapRemoveContextAdapted instead.");
return self.swapRemoveContextAdapted(key, ctx, undefined);
}
pub fn swapRemoveContextAdapted(self: *Self, key: anytype, key_ctx: anytype, ctx: Context) bool {
@@ -1046,7 +1046,7 @@ pub fn ArrayHashMapUnmanaged(
/// current ordering. Returns true if an entry was removed, false otherwise.
pub fn orderedRemove(self: *Self, key: K) bool {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call orderedRemoveContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call orderedRemoveContext instead.");
return self.orderedRemoveContext(key, undefined);
}
pub fn orderedRemoveContext(self: *Self, key: K, ctx: Context) bool {
@@ -1054,7 +1054,7 @@ pub fn ArrayHashMapUnmanaged(
}
pub fn orderedRemoveAdapted(self: *Self, key: anytype, ctx: anytype) bool {
if (@sizeOf(ByIndexContext) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call orderedRemoveContextAdapted instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call orderedRemoveContextAdapted instead.");
return self.orderedRemoveContextAdapted(key, ctx, undefined);
}
pub fn orderedRemoveContextAdapted(self: *Self, key: anytype, key_ctx: anytype, ctx: Context) bool {
@@ -1066,7 +1066,7 @@ pub fn ArrayHashMapUnmanaged(
/// by swapping it with the last element.
pub fn swapRemoveAt(self: *Self, index: usize) void {
if (@sizeOf(ByIndexContext) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call swapRemoveAtContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call swapRemoveAtContext instead.");
return self.swapRemoveAtContext(index, undefined);
}
pub fn swapRemoveAtContext(self: *Self, index: usize, ctx: Context) void {
@@ -1079,7 +1079,7 @@ pub fn ArrayHashMapUnmanaged(
/// current ordering.
pub fn orderedRemoveAt(self: *Self, index: usize) void {
if (@sizeOf(ByIndexContext) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call orderedRemoveAtContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call orderedRemoveAtContext instead.");
return self.orderedRemoveAtContext(index, undefined);
}
pub fn orderedRemoveAtContext(self: *Self, index: usize, ctx: Context) void {
@@ -1090,7 +1090,7 @@ pub fn ArrayHashMapUnmanaged(
/// The copy uses the same context and allocator as this instance.
pub fn clone(self: Self, allocator: *Allocator) !Self {
if (@sizeOf(ByIndexContext) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call cloneContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call cloneContext instead.");
return self.cloneContext(allocator, undefined);
}
pub fn cloneContext(self: Self, allocator: *Allocator, ctx: Context) !Self {
@@ -1110,7 +1110,7 @@ pub fn ArrayHashMapUnmanaged(
/// can call `reIndex` to update the indexes to account for these new entries.
pub fn reIndex(self: *Self, allocator: *Allocator) !void {
if (@sizeOf(ByIndexContext) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call reIndexContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call reIndexContext instead.");
return self.reIndexContext(allocator, undefined);
}
pub fn reIndexContext(self: *Self, allocator: *Allocator, ctx: Context) !void {
@@ -1128,7 +1128,7 @@ pub fn ArrayHashMapUnmanaged(
/// index entries. Keeps capacity the same.
pub fn shrinkRetainingCapacity(self: *Self, new_len: usize) void {
if (@sizeOf(ByIndexContext) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call shrinkRetainingCapacityContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call shrinkRetainingCapacityContext instead.");
return self.shrinkRetainingCapacityContext(new_len, undefined);
}
pub fn shrinkRetainingCapacityContext(self: *Self, new_len: usize, ctx: Context) void {
@@ -1147,7 +1147,7 @@ pub fn ArrayHashMapUnmanaged(
/// index entries. Reduces allocated capacity.
pub fn shrinkAndFree(self: *Self, allocator: *Allocator, new_len: usize) void {
if (@sizeOf(ByIndexContext) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call shrinkAndFreeContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call shrinkAndFreeContext instead.");
return self.shrinkAndFreeContext(allocator, new_len, undefined);
}
pub fn shrinkAndFreeContext(self: *Self, allocator: *Allocator, new_len: usize, ctx: Context) void {
@@ -1165,13 +1165,13 @@ pub fn ArrayHashMapUnmanaged(
/// Removes the last inserted `Entry` in the hash map and returns it.
pub fn pop(self: *Self) KV {
if (@sizeOf(ByIndexContext) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call popContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call popContext instead.");
return self.popContext(undefined);
}
pub fn popContext(self: *Self, ctx: Context) KV {
const item = self.entries.get(self.entries.len-1);
const item = self.entries.get(self.entries.len - 1);
if (self.index_header) |header|
self.removeFromIndexByIndex(self.entries.len-1, if (store_hash) {} else ctx, header);
self.removeFromIndexByIndex(self.entries.len - 1, if (store_hash) {} else ctx, header);
self.entries.len -= 1;
return .{
.key = item.key,
@@ -1276,7 +1276,7 @@ pub fn ArrayHashMapUnmanaged(
}
fn removeFromArrayAndUpdateIndex(self: *Self, entry_index: usize, ctx: ByIndexContext, header: *IndexHeader, comptime I: type, indexes: []Index(I), comptime removal_type: RemovalType) void {
const last_index = self.entries.len-1; // overflow => remove from empty map
const last_index = self.entries.len - 1; // overflow => remove from empty map
switch (removal_type) {
.swap => {
if (last_index != entry_index) {
@@ -1358,8 +1358,7 @@ pub fn ArrayHashMapUnmanaged(
fn getSlotByIndex(self: *Self, entry_index: usize, ctx: ByIndexContext, header: *IndexHeader, comptime I: type, indexes: []Index(I)) usize {
const slice = self.entries.slice();
const h = if (store_hash) slice.items(.hash)[entry_index]
else checkedHash(ctx, slice.items(.key)[entry_index]);
const h = if (store_hash) slice.items(.hash)[entry_index] else checkedHash(ctx, slice.items(.key)[entry_index]);
const start_index = safeTruncate(usize, h);
const end_index = start_index +% indexes.len;
@@ -1569,30 +1568,30 @@ pub fn ArrayHashMapUnmanaged(
}
}
fn checkedHash(ctx: anytype, key: anytype) callconv(.Inline) u32 {
inline fn checkedHash(ctx: anytype, key: anytype) u32 {
comptime std.hash_map.verifyContext(@TypeOf(ctx), @TypeOf(key), K, u32);
// If you get a compile error on the next line, it means that
const hash = ctx.hash(key); // your generic hash function doesn't accept your key
if (@TypeOf(hash) != u32) {
@compileError("Context "++@typeName(@TypeOf(ctx))++" has a generic hash function that returns the wrong type!\n"++
@typeName(u32)++" was expected, but found "++@typeName(@TypeOf(hash)));
@compileError("Context " ++ @typeName(@TypeOf(ctx)) ++ " has a generic hash function that returns the wrong type!\n" ++
@typeName(u32) ++ " was expected, but found " ++ @typeName(@TypeOf(hash)));
}
return hash;
}
fn checkedEql(ctx: anytype, a: anytype, b: K) callconv(.Inline) bool {
inline fn checkedEql(ctx: anytype, a: anytype, b: K) bool {
comptime std.hash_map.verifyContext(@TypeOf(ctx), @TypeOf(a), K, u32);
// If you get a compile error on the next line, it means that
const eql = ctx.eql(a, b); // your generic eql function doesn't accept (self, adapt key, K)
if (@TypeOf(eql) != bool) {
@compileError("Context "++@typeName(@TypeOf(ctx))++" has a generic eql function that returns the wrong type!\n"++
@typeName(bool)++" was expected, but found "++@typeName(@TypeOf(eql)));
@compileError("Context " ++ @typeName(@TypeOf(ctx)) ++ " has a generic eql function that returns the wrong type!\n" ++
@typeName(bool) ++ " was expected, but found " ++ @typeName(@TypeOf(eql)));
}
return eql;
}
fn dumpState(self: Self, comptime keyFmt: []const u8, comptime valueFmt: []const u8) void {
if (@sizeOf(ByIndexContext) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call dumpStateContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call dumpStateContext instead.");
self.dumpStateContext(keyFmt, valueFmt, undefined);
}
fn dumpStateContext(self: Self, comptime keyFmt: []const u8, comptime valueFmt: []const u8, ctx: Context) void {
@@ -1600,21 +1599,20 @@ pub fn ArrayHashMapUnmanaged(
p("{s}:\n", .{@typeName(Self)});
const slice = self.entries.slice();
const hash_status = if (store_hash) "stored" else "computed";
p(" len={} capacity={} hashes {s}\n", .{slice.len, slice.capacity, hash_status});
p(" len={} capacity={} hashes {s}\n", .{ slice.len, slice.capacity, hash_status });
var i: usize = 0;
const mask: u32 = if (self.index_header) |header| header.mask() else ~@as(u32, 0);
while (i < slice.len) : (i += 1) {
const hash = if (store_hash) slice.items(.hash)[i]
else checkedHash(ctx, slice.items(.key)[i]);
const hash = if (store_hash) slice.items(.hash)[i] else checkedHash(ctx, slice.items(.key)[i]);
if (store_hash) {
p(
" [{}]: key="++keyFmt++" value="++valueFmt++" hash=0x{x} slot=[0x{x}]\n",
.{i, slice.items(.key)[i], slice.items(.value)[i], hash, hash & mask},
" [{}]: key=" ++ keyFmt ++ " value=" ++ valueFmt ++ " hash=0x{x} slot=[0x{x}]\n",
.{ i, slice.items(.key)[i], slice.items(.value)[i], hash, hash & mask },
);
} else {
p(
" [{}]: key="++keyFmt++" value="++valueFmt++" slot=[0x{x}]\n",
.{i, slice.items(.key)[i], slice.items(.value)[i], hash & mask},
" [{}]: key=" ++ keyFmt ++ " value=" ++ valueFmt ++ " slot=[0x{x}]\n",
.{ i, slice.items(.key)[i], slice.items(.value)[i], hash & mask },
);
}
}
@@ -1629,7 +1627,7 @@ pub fn ArrayHashMapUnmanaged(
}
fn dumpIndex(self: Self, header: *IndexHeader, comptime I: type) void {
const p = std.debug.print;
p(" index len=0x{x} type={}\n", .{header.length(), header.capacityIndexType()});
p(" index len=0x{x} type={}\n", .{ header.length(), header.capacityIndexType() });
const indexes = header.indexes(I);
if (indexes.len == 0) return;
var is_empty = false;
@@ -1641,7 +1639,7 @@ pub fn ArrayHashMapUnmanaged(
is_empty = false;
p(" ...\n", .{});
}
p(" [0x{x}]: [{}] +{}\n", .{i, idx.entry_index, idx.distance_from_start_index});
p(" [0x{x}]: [{}] +{}\n", .{ i, idx.entry_index, idx.distance_from_start_index });
}
}
if (is_empty) {
@@ -1730,7 +1728,7 @@ const max_capacity = (1 << max_bit_index) - 1;
const index_capacities = blk: {
var caps: [max_bit_index + 1]u32 = undefined;
for (caps[0..max_bit_index]) |*item, i| {
item.* = (1<<i) * 3 / 5;
item.* = (1 << i) * 3 / 5;
}
caps[max_bit_index] = max_capacity;
break :blk caps;

View File

@@ -65,16 +65,23 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
pub fn initCapacity(allocator: *Allocator, num: usize) !Self {
var self = Self.init(allocator);
const new_memory = try self.allocator.allocAdvanced(T, alignment, num, .at_least);
self.items.ptr = new_memory.ptr;
self.capacity = new_memory.len;
if (@sizeOf(T) > 0) {
const new_memory = try self.allocator.allocAdvanced(T, alignment, num, .at_least);
self.items.ptr = new_memory.ptr;
self.capacity = new_memory.len;
} else {
// If `T` is a zero-sized type, then we do not need to allocate memory.
self.capacity = std.math.maxInt(usize);
}
return self;
}
/// Release all allocated memory.
pub fn deinit(self: Self) void {
self.allocator.free(self.allocatedSlice());
if (@sizeOf(T) > 0) {
self.allocator.free(self.allocatedSlice());
}
}
pub const span = @compileError("deprecated: use `items` field directly");
@@ -227,10 +234,11 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
/// Append the slice of items to the list, asserting the capacity is already
/// enough to store the new items. **Does not** invalidate pointers.
pub fn appendSliceAssumeCapacity(self: *Self, items: []const T) void {
const oldlen = self.items.len;
const newlen = self.items.len + items.len;
self.items.len = newlen;
mem.copy(T, self.items[oldlen..], items);
const old_len = self.items.len;
const new_len = old_len + items.len;
assert(new_len <= self.capacity);
self.items.len = new_len;
mem.copy(T, self.items[old_len..], items);
}
pub usingnamespace if (T != u8) struct {} else struct {
@@ -278,13 +286,17 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
pub fn shrinkAndFree(self: *Self, new_len: usize) void {
assert(new_len <= self.items.len);
self.items = self.allocator.realloc(self.allocatedSlice(), new_len) catch |e| switch (e) {
error.OutOfMemory => { // no problem, capacity is still correct then.
self.items.len = new_len;
return;
},
};
self.capacity = new_len;
if (@sizeOf(T) > 0) {
self.items = self.allocator.realloc(self.allocatedSlice(), new_len) catch |e| switch (e) {
error.OutOfMemory => { // no problem, capacity is still correct then.
self.items.len = new_len;
return;
},
};
self.capacity = new_len;
} else {
self.items.len = new_len;
}
}
/// Reduce length to `new_len`.
@@ -312,18 +324,22 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
/// Modify the array so that it can hold at least `new_capacity` items.
/// Invalidates pointers if additional memory is needed.
pub fn ensureTotalCapacity(self: *Self, new_capacity: usize) !void {
var better_capacity = self.capacity;
if (better_capacity >= new_capacity) return;
if (@sizeOf(T) > 0) {
var better_capacity = self.capacity;
if (better_capacity >= new_capacity) return;
while (true) {
better_capacity += better_capacity / 2 + 8;
if (better_capacity >= new_capacity) break;
while (true) {
better_capacity += better_capacity / 2 + 8;
if (better_capacity >= new_capacity) break;
}
// TODO This can be optimized to avoid needlessly copying undefined memory.
const new_memory = try self.allocator.reallocAtLeast(self.allocatedSlice(), better_capacity);
self.items.ptr = new_memory.ptr;
self.capacity = new_memory.len;
} else {
self.capacity = std.math.maxInt(usize);
}
// TODO This can be optimized to avoid needlessly copying undefined memory.
const new_memory = try self.allocator.reallocAtLeast(self.allocatedSlice(), better_capacity);
self.items.ptr = new_memory.ptr;
self.capacity = new_memory.len;
}
/// Modify the array so that it can hold at least `additional_count` **more** items.
@@ -570,11 +586,11 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
/// Append the slice of items to the list, asserting the capacity is enough
/// to store the new items.
pub fn appendSliceAssumeCapacity(self: *Self, items: []const T) void {
const oldlen = self.items.len;
const newlen = self.items.len + items.len;
self.items.len = newlen;
mem.copy(T, self.items[oldlen..], items);
const old_len = self.items.len;
const new_len = old_len + items.len;
assert(new_len <= self.capacity);
self.items.len = new_len;
mem.copy(T, self.items[old_len..], items);
}
/// Append a value to the list `n` times.
@@ -1298,3 +1314,23 @@ test "ArrayListAligned/ArrayListAlignedUnmanaged accepts unaligned slices" {
try testing.expectEqualSlices(u8, list.items, &.{ 0, 8, 9, 6, 7, 2, 3 });
}
}
test "std.ArrayList(u0)" {
// An ArrayList on zero-sized types should not need to allocate
const a = &testing.FailingAllocator.init(testing.allocator, 0).allocator;
var list = ArrayList(u0).init(a);
defer list.deinit();
try list.append(0);
try list.append(0);
try list.append(0);
try testing.expectEqual(list.items.len, 3);
var count: usize = 0;
for (list.items) |x| {
try testing.expectEqual(x, 0);
count += 1;
}
try testing.expectEqual(count, 3);
}

View File

@@ -57,7 +57,9 @@ pub const Builder = struct {
exe_dir: []const u8,
h_dir: []const u8,
install_path: []const u8,
sysroot: ?[]const u8 = null,
search_prefixes: ArrayList([]const u8),
libc_file: ?[]const u8 = null,
installed_files: ArrayList(InstalledFile),
build_root: []const u8,
cache_root: []const u8,
@@ -1336,8 +1338,8 @@ pub const LibExeObjStep = struct {
version: ?Version,
build_mode: builtin.Mode,
kind: Kind,
major_only_filename: []const u8,
name_only_filename: []const u8,
major_only_filename: ?[]const u8,
name_only_filename: ?[]const u8,
strip: bool,
lib_paths: ArrayList([]const u8),
rpaths: ArrayList([]const u8),
@@ -1529,8 +1531,8 @@ pub const LibExeObjStep = struct {
.out_h_filename = builder.fmt("{s}.h", .{name}),
.out_lib_filename = undefined,
.out_pdb_filename = builder.fmt("{s}.pdb", .{name}),
.major_only_filename = undefined,
.name_only_filename = undefined,
.major_only_filename = null,
.name_only_filename = null,
.packages = ArrayList(Pkg).init(builder.allocator),
.include_dirs = ArrayList(IncludeDir).init(builder.allocator),
.link_objects = ArrayList(LinkObject).init(builder.allocator),
@@ -2377,6 +2379,9 @@ pub const LibExeObjStep = struct {
if (self.libc_file) |libc_file| {
try zig_args.append("--libc");
try zig_args.append(builder.pathFromRoot(libc_file));
} else if (builder.libc_file) |libc_file| {
try zig_args.append("--libc");
try zig_args.append(libc_file);
}
switch (self.build_mode) {
@@ -2597,6 +2602,10 @@ pub const LibExeObjStep = struct {
}
}
if (builder.sysroot) |sysroot| {
try zig_args.appendSlice(&[_][]const u8{ "--sysroot", sysroot });
}
for (builder.search_prefixes.items) |search_prefix| {
try zig_args.append("-L");
try zig_args.append(try fs.path.join(builder.allocator, &[_][]const u8{
@@ -2703,7 +2712,7 @@ pub const LibExeObjStep = struct {
}
if (self.kind == Kind.Lib and self.is_dynamic and self.version != null and self.target.wantSharedLibSymLinks()) {
try doAtomicSymLinks(builder.allocator, self.getOutputPath(), self.major_only_filename, self.name_only_filename);
try doAtomicSymLinks(builder.allocator, self.getOutputPath(), self.major_only_filename.?, self.name_only_filename.?);
}
}
};
@@ -2746,9 +2755,11 @@ pub const InstallArtifactStep = struct {
builder.pushInstalledFile(self.dest_dir, artifact.out_filename);
if (self.artifact.isDynamicLibrary()) {
if (self.artifact.version != null) {
builder.pushInstalledFile(.Lib, artifact.major_only_filename);
builder.pushInstalledFile(.Lib, artifact.name_only_filename);
if (artifact.major_only_filename) |name| {
builder.pushInstalledFile(.Lib, name);
}
if (artifact.name_only_filename) |name| {
builder.pushInstalledFile(.Lib, name);
}
if (self.artifact.target.isWindows()) {
builder.pushInstalledFile(.Lib, artifact.out_lib_filename);
@@ -2770,7 +2781,7 @@ pub const InstallArtifactStep = struct {
const full_dest_path = builder.getInstallPath(self.dest_dir, self.artifact.out_filename);
try builder.updateFile(self.artifact.getOutputPath(), full_dest_path);
if (self.artifact.isDynamicLibrary() and self.artifact.version != null and self.artifact.target.wantSharedLibSymLinks()) {
try doAtomicSymLinks(builder.allocator, full_dest_path, self.artifact.major_only_filename, self.artifact.name_only_filename);
try doAtomicSymLinks(builder.allocator, full_dest_path, self.artifact.major_only_filename.?, self.artifact.name_only_filename.?);
}
if (self.pdb_dir) |pdb_dir| {
const full_pdb_path = builder.getInstallPath(pdb_dir, self.artifact.out_pdb_filename);

View File

@@ -103,7 +103,7 @@ pub extern "c" fn linkat(oldfd: fd_t, oldpath: [*:0]const u8, newfd: fd_t, newpa
pub extern "c" fn unlink(path: [*:0]const u8) c_int;
pub extern "c" fn unlinkat(dirfd: fd_t, path: [*:0]const u8, flags: c_uint) c_int;
pub extern "c" fn getcwd(buf: [*]u8, size: usize) ?[*]u8;
pub extern "c" fn waitpid(pid: c_int, stat_loc: *c_uint, options: c_uint) c_int;
pub extern "c" fn waitpid(pid: pid_t, stat_loc: ?*c_int, options: c_int) pid_t;
pub extern "c" fn fork() c_int;
pub extern "c" fn access(path: [*:0]const u8, mode: c_uint) c_int;
pub extern "c" fn faccessat(dirfd: fd_t, path: [*:0]const u8, mode: c_uint, flags: c_uint) c_int;
@@ -192,6 +192,7 @@ pub usingnamespace switch (builtin.os.tag) {
pub const sigaction = __sigaction14;
pub const sigaltstack = __sigaltstack14;
pub const sigprocmask = __sigprocmask14;
pub const socket = __socket30;
pub const stat = __stat50;
},
.macos, .ios, .watchos, .tvos => struct {

View File

@@ -94,7 +94,8 @@ pub extern "c" fn epoll_pwait(
sigmask: *const sigset_t,
) c_int;
pub extern "c" fn inotify_init1(flags: c_uint) c_int;
pub extern "c" fn inotify_add_watch(fd: fd_t, pathname: [*]const u8, mask: u32) c_int;
pub extern "c" fn inotify_add_watch(fd: fd_t, pathname: [*:0]const u8, mask: u32) c_int;
pub extern "c" fn inotify_rm_watch(fd: fd_t, wd: c_int) c_int;
/// See std.elf for constants for this
pub extern "c" fn getauxval(__type: c_ulong) c_ulong;

View File

@@ -13,6 +13,7 @@ const process = std.process;
const File = std.fs.File;
const windows = os.windows;
const mem = std.mem;
const math = std.math;
const debug = std.debug;
const BufMap = std.BufMap;
const builtin = std.builtin;
@@ -203,16 +204,18 @@ pub const ChildProcess = struct {
// of space an ArrayList will allocate grows exponentially.
const bump_amt = 512;
// TODO https://github.com/ziglang/zig/issues/8724
// parent process does not receive POLLHUP events
const dragonfly_workaround = builtin.os.tag == .dragonfly;
const err_mask = os.POLLERR | os.POLLNVAL | os.POLLHUP;
while (dead_fds < poll_fds.len) {
const events = try os.poll(&poll_fds, std.math.maxInt(i32));
if (events == 0) continue;
var remove_stdout = false;
var remove_stderr = false;
// Try reading whatever is available before checking the error
// conditions.
// It's still possible to read after a POLLHUP is received, always
// check if there's some data waiting to be read first.
if (poll_fds[0].revents & os.POLLIN != 0) {
// stdout is ready.
const new_capacity = std.math.min(stdout.items.len + bump_amt, max_output_bytes);
@@ -222,9 +225,12 @@ pub const ChildProcess = struct {
const nread = try os.read(poll_fds[0].fd, buf);
stdout.items.len += nread;
// insert POLLHUP event because dragonfly fails to do so
if (dragonfly_workaround and nread == 0) poll_fds[0].revents |= os.POLLHUP;
// Remove the fd when the EOF condition is met.
remove_stdout = nread == 0;
} else {
remove_stdout = poll_fds[0].revents & err_mask != 0;
}
if (poll_fds[1].revents & os.POLLIN != 0) {
// stderr is ready.
const new_capacity = std.math.min(stderr.items.len + bump_amt, max_output_bytes);
@@ -234,22 +240,97 @@ pub const ChildProcess = struct {
const nread = try os.read(poll_fds[1].fd, buf);
stderr.items.len += nread;
// insert POLLHUP event because dragonfly fails to do so
if (dragonfly_workaround and nread == 0) poll_fds[1].revents |= os.POLLHUP;
// Remove the fd when the EOF condition is met.
remove_stderr = nread == 0;
} else {
remove_stderr = poll_fds[1].revents & err_mask != 0;
}
// Exclude the fds that signaled an error.
if (poll_fds[0].revents & (os.POLLERR | os.POLLNVAL | os.POLLHUP) != 0) {
if (remove_stdout) {
poll_fds[0].fd = -1;
dead_fds += 1;
}
if (poll_fds[1].revents & (os.POLLERR | os.POLLNVAL | os.POLLHUP) != 0) {
if (remove_stderr) {
poll_fds[1].fd = -1;
dead_fds += 1;
}
}
}
fn collectOutputWindows(child: *const ChildProcess, outs: [2]*std.ArrayList(u8), max_output_bytes: usize) !void {
const bump_amt = 512;
const handles = [_]windows.HANDLE{
child.stdout.?.handle,
child.stderr.?.handle,
};
var overlapped = [_]windows.OVERLAPPED{
mem.zeroes(windows.OVERLAPPED),
mem.zeroes(windows.OVERLAPPED),
};
var wait_objects: [2]windows.HANDLE = undefined;
var wait_object_count: u2 = 0;
// we need to cancel all pending IO before returning so our OVERLAPPED values don't go out of scope
defer for (wait_objects[0..wait_object_count]) |o| {
_ = windows.kernel32.CancelIo(o);
};
// Windows Async IO requires an initial call to ReadFile before waiting on the handle
for ([_]u1{ 0, 1 }) |i| {
try outs[i].ensureCapacity(bump_amt);
const buf = outs[i].unusedCapacitySlice();
_ = windows.kernel32.ReadFile(handles[i], buf.ptr, math.cast(u32, buf.len) catch maxInt(u32), null, &overlapped[i]);
wait_objects[wait_object_count] = handles[i];
wait_object_count += 1;
}
while (true) {
const status = windows.kernel32.WaitForMultipleObjects(wait_object_count, &wait_objects, 0, windows.INFINITE);
if (status == windows.WAIT_FAILED) {
switch (windows.kernel32.GetLastError()) {
else => |err| return windows.unexpectedError(err),
}
}
if (status < windows.WAIT_OBJECT_0 or status > windows.WAIT_OBJECT_0 + wait_object_count - 1)
unreachable;
const wait_idx = status - windows.WAIT_OBJECT_0;
// this extra `i` index is needed to map the wait handle back to the stdout or stderr
// values since the wait_idx can change which handle it corresponds with
const i: u1 = if (wait_objects[wait_idx] == handles[0]) 0 else 1;
// remove completed event from the wait list
wait_object_count -= 1;
if (wait_idx == 0)
wait_objects[0] = wait_objects[1];
var read_bytes: u32 = undefined;
if (windows.kernel32.GetOverlappedResult(handles[i], &overlapped[i], &read_bytes, 0) == 0) {
switch (windows.kernel32.GetLastError()) {
.BROKEN_PIPE => {
if (wait_object_count == 0)
break;
continue;
},
else => |err| return windows.unexpectedError(err),
}
}
outs[i].items.len += read_bytes;
const new_capacity = std.math.min(outs[i].items.len + bump_amt, max_output_bytes);
try outs[i].ensureCapacity(new_capacity);
const buf = outs[i].unusedCapacitySlice();
if (buf.len == 0) return if (i == 0) error.StdoutStreamTooLong else error.StderrStreamTooLong;
_ = windows.kernel32.ReadFile(handles[i], buf.ptr, math.cast(u32, buf.len) catch maxInt(u32), null, &overlapped[i]);
wait_objects[wait_object_count] = handles[i];
wait_object_count += 1;
}
}
/// Spawns a child process, waits for it, collecting stdout and stderr, and then returns.
/// If it succeeds, the caller owns result.stdout and result.stderr memory.
pub fn exec(args: struct {
@@ -294,8 +375,16 @@ pub const ChildProcess = struct {
var stdout = std.ArrayList(u8).init(args.allocator);
var stderr = std.ArrayList(u8).init(args.allocator);
errdefer {
stdout.deinit();
stderr.deinit();
}
try collectOutputPosix(child, &stdout, &stderr, args.max_output_bytes);
if (builtin.os.tag == .windows) {
try collectOutputWindows(child, [_]*std.ArrayList(u8){ &stdout, &stderr }, args.max_output_bytes);
} else {
try collectOutputPosix(child, &stdout, &stderr, args.max_output_bytes);
}
return ExecResult{
.term = try child.wait(),
@@ -633,7 +722,7 @@ pub const ChildProcess = struct {
var g_hChildStd_OUT_Wr: ?windows.HANDLE = null;
switch (self.stdout_behavior) {
StdIo.Pipe => {
try windowsMakePipeOut(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr);
try windowsMakeAsyncPipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr);
},
StdIo.Ignore => {
g_hChildStd_OUT_Wr = nul_handle;
@@ -653,7 +742,7 @@ pub const ChildProcess = struct {
var g_hChildStd_ERR_Wr: ?windows.HANDLE = null;
switch (self.stderr_behavior) {
StdIo.Pipe => {
try windowsMakePipeOut(&g_hChildStd_ERR_Rd, &g_hChildStd_ERR_Wr, &saAttr);
try windowsMakeAsyncPipe(&g_hChildStd_ERR_Rd, &g_hChildStd_ERR_Wr, &saAttr);
},
StdIo.Ignore => {
g_hChildStd_ERR_Wr = nul_handle;
@@ -896,14 +985,64 @@ fn windowsMakePipeIn(rd: *?windows.HANDLE, wr: *?windows.HANDLE, sattr: *const w
wr.* = wr_h;
}
fn windowsMakePipeOut(rd: *?windows.HANDLE, wr: *?windows.HANDLE, sattr: *const windows.SECURITY_ATTRIBUTES) !void {
var rd_h: windows.HANDLE = undefined;
var wr_h: windows.HANDLE = undefined;
try windows.CreatePipe(&rd_h, &wr_h, sattr);
errdefer windowsDestroyPipe(rd_h, wr_h);
try windows.SetHandleInformation(rd_h, windows.HANDLE_FLAG_INHERIT, 0);
rd.* = rd_h;
wr.* = wr_h;
var pipe_name_counter = std.atomic.Atomic(u32).init(1);
fn windowsMakeAsyncPipe(rd: *?windows.HANDLE, wr: *?windows.HANDLE, sattr: *const windows.SECURITY_ATTRIBUTES) !void {
var tmp_bufw: [128]u16 = undefined;
// We must make a named pipe on windows because anonymous pipes do not support async IO
const pipe_path = blk: {
var tmp_buf: [128]u8 = undefined;
// Forge a random path for the pipe.
const pipe_path = std.fmt.bufPrintZ(
&tmp_buf,
"\\\\.\\pipe\\zig-childprocess-{d}-{d}",
.{ windows.kernel32.GetCurrentProcessId(), pipe_name_counter.fetchAdd(1, .Monotonic) },
) catch unreachable;
const len = std.unicode.utf8ToUtf16Le(&tmp_bufw, pipe_path) catch unreachable;
tmp_bufw[len] = 0;
break :blk tmp_bufw[0..len :0];
};
// Create the read handle that can be used with overlapped IO ops.
const read_handle = windows.kernel32.CreateNamedPipeW(
pipe_path.ptr,
windows.PIPE_ACCESS_INBOUND | windows.FILE_FLAG_OVERLAPPED,
windows.PIPE_TYPE_BYTE,
1,
4096,
4096,
0,
sattr,
);
if (read_handle == windows.INVALID_HANDLE_VALUE) {
switch (windows.kernel32.GetLastError()) {
else => |err| return windows.unexpectedError(err),
}
}
errdefer os.close(read_handle);
var sattr_copy = sattr.*;
const write_handle = windows.kernel32.CreateFileW(
pipe_path.ptr,
windows.GENERIC_WRITE,
0,
&sattr_copy,
windows.OPEN_EXISTING,
windows.FILE_ATTRIBUTE_NORMAL,
null,
);
if (write_handle == windows.INVALID_HANDLE_VALUE) {
switch (windows.kernel32.GetLastError()) {
else => |err| return windows.unexpectedError(err),
}
}
errdefer os.close(write_handle);
try windows.SetHandleInformation(read_handle, windows.HANDLE_FLAG_INHERIT, 0);
rd.* = read_handle;
wr.* = write_handle;
}
fn destroyPipe(pipe: [2]os.fd_t) void {

View File

@@ -6,7 +6,7 @@
const std = @import("std.zig");
const mem = std.mem;
/// Like ComptimeStringHashMap but optimized for small sets of disparate string keys.
/// Comptime string map optimized for small sets of disparate string keys.
/// Works by separating the keys by length at comptime and only checking strings of
/// equal length at runtime.
///

View File

@@ -93,7 +93,7 @@ pub const Fe = struct {
return s;
}
/// Map a 64-bit big endian string into a field element
/// Map a 64 bytes big endian string into a field element
pub fn fromBytes64(s: [64]u8) Fe {
var fl: [32]u8 = undefined;
var gl: [32]u8 = undefined;
@@ -106,7 +106,7 @@ pub const Fe = struct {
gl[31] &= 0x7f;
var fe_f = fromBytes(fl);
const fe_g = fromBytes(gl);
fe_f.limbs[0] += (s[32] >> 7) * 19;
fe_f.limbs[0] += (s[32] >> 7) * 19 + @as(u10, s[0] >> 7) * 722;
i = 0;
while (i < 5) : (i += 1) {
fe_f.limbs[i] += 38 * fe_g.limbs[i];

View File

@@ -115,7 +115,7 @@ test "expand 128-bit key" {
"2b7e151628aed2a6abf7158809cf4f3c", "a0fafe1788542cb123a339392a6c7605", "f2c295f27a96b9435935807a7359f67f", "3d80477d4716fe3e1e237e446d7a883b", "ef44a541a8525b7fb671253bdb0bad00", "d4d1c6f87c839d87caf2b8bc11f915bc", "6d88a37a110b3efddbf98641ca0093fd", "4e54f70e5f5fc9f384a64fb24ea6dc4f", "ead27321b58dbad2312bf5607f8d292f", "ac7766f319fadc2128d12941575c006e", "d014f9a8c9ee2589e13f0cc8b6630ca6",
};
const exp_dec = [_]*const [32:0]u8{
"2b7e151628aed2a6abf7158809cf4f3c", "a0fafe1788542cb123a339392a6c7605", "f2c295f27a96b9435935807a7359f67f", "3d80477d4716fe3e1e237e446d7a883b", "ef44a541a8525b7fb671253bdb0bad00", "d4d1c6f87c839d87caf2b8bc11f915bc", "6d88a37a110b3efddbf98641ca0093fd", "4e54f70e5f5fc9f384a64fb24ea6dc4f", "ead27321b58dbad2312bf5607f8d292f", "ac7766f319fadc2128d12941575c006e", "d014f9a8c9ee2589e13f0cc8b6630ca6",
"d014f9a8c9ee2589e13f0cc8b6630ca6", "0c7b5a631319eafeb0398890664cfbb4", "df7d925a1f62b09da320626ed6757324", "12c07647c01f22c7bc42d2f37555114a", "6efcd876d2df54807c5df034c917c3b9", "6ea30afcbc238cf6ae82a4b4b54a338d", "90884413d280860a12a128421bc89739", "7c1f13f74208c219c021ae480969bf7b", "cc7505eb3e17d1ee82296c51c9481133", "2b3708a7f262d405bc3ebdbf4b617d62", "2b7e151628aed2a6abf7158809cf4f3c",
};
const enc = Aes128.initEnc(key);
const dec = Aes128.initDec(key);
@@ -125,7 +125,7 @@ test "expand 128-bit key" {
_ = try std.fmt.hexToBytes(&exp, exp_enc[i]);
try testing.expectEqualSlices(u8, &exp, &round_key.toBytes());
}
for (enc.key_schedule.round_keys) |round_key, i| {
for (dec.key_schedule.round_keys) |round_key, i| {
_ = try std.fmt.hexToBytes(&exp, exp_dec[i]);
try testing.expectEqualSlices(u8, &exp, &round_key.toBytes());
}

View File

@@ -63,7 +63,7 @@ pub fn add(a: CompressedScalar, b: CompressedScalar, endian: builtin.Endian) Non
/// Return -s (mod L)
pub fn neg(s: CompressedScalar, endian: builtin.Endian) NonCanonicalError!CompressedScalar {
return (try Scalar.fromBytes(a, endian)).neg().toBytes(endian);
return (try Scalar.fromBytes(s, endian)).neg().toBytes(endian);
}
/// Return (a-b) (mod L)

View File

@@ -19,7 +19,7 @@ const max = std.math.max;
pub const DynLib = switch (builtin.os.tag) {
.linux => if (builtin.link_libc) DlDynlib else ElfDynLib,
.windows => WindowsDynLib,
.macos, .tvos, .watchos, .ios, .freebsd, .openbsd, .dragonfly => DlDynlib,
.macos, .tvos, .watchos, .ios, .freebsd, .netbsd, .openbsd, .dragonfly => DlDynlib,
else => void,
};

View File

@@ -54,8 +54,12 @@ pub const Loop = struct {
.windows => windows.OVERLAPPED{
.Internal = 0,
.InternalHigh = 0,
.Offset = 0,
.OffsetHigh = 0,
.DUMMYUNIONNAME = .{
.DUMMYSTRUCTNAME = .{
.Offset = 0,
.OffsetHigh = 0,
},
},
.hEvent = null,
},
else => {},

View File

@@ -2392,10 +2392,6 @@ test "vector" {
// https://github.com/ziglang/zig/issues/4486
return error.SkipZigTest;
}
if (builtin.target.cpu.arch == .wasm32) {
// https://github.com/ziglang/zig/issues/5339
return error.SkipZigTest;
}
const vbool: std.meta.Vector(4, bool) = [_]bool{ true, false, true, false };
const vi64: std.meta.Vector(4, i64) = [_]i64{ -2, -1, 0, 1 };

View File

@@ -3,6 +3,7 @@
// 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 root = @import("root");
const builtin = std.builtin;
const std = @import("std.zig");
const os = std.os;
@@ -47,7 +48,10 @@ pub const MAX_PATH_BYTES = switch (builtin.os.tag) {
.windows => os.windows.PATH_MAX_WIDE * 3 + 1,
// TODO work out what a reasonable value we should use here
.wasi => 4096,
else => @compileError("Unsupported OS"),
else => if (@hasDecl(root, "os") and @hasDecl(root.os, "PATH_MAX"))
root.os.PATH_MAX
else
@compileError("PATH_MAX not implemented for " ++ @tagName(builtin.os.tag)),
};
pub const base64_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".*;
@@ -879,24 +883,39 @@ pub const Dir = struct {
/// [WTF-16](https://simonsapin.github.io/wtf-8/#potentially-ill-formed-utf-16) encoded.
pub fn openFileW(self: Dir, sub_path_w: []const u16, flags: File.OpenFlags) File.OpenError!File {
const w = os.windows;
return @as(File, .{
.handle = try os.windows.OpenFile(sub_path_w, .{
const file: File = .{
.handle = try w.OpenFile(sub_path_w, .{
.dir = self.fd,
.access_mask = w.SYNCHRONIZE |
(if (flags.read) @as(u32, w.GENERIC_READ) else 0) |
(if (flags.write) @as(u32, w.GENERIC_WRITE) else 0),
.share_access = switch (flags.lock) {
.None => w.FILE_SHARE_WRITE | w.FILE_SHARE_READ | w.FILE_SHARE_DELETE,
.Shared => w.FILE_SHARE_READ | w.FILE_SHARE_DELETE,
.Exclusive => w.FILE_SHARE_DELETE,
},
.share_access_nonblocking = flags.lock_nonblocking,
.creation = w.FILE_OPEN,
.io_mode = flags.intended_io_mode,
}),
.capable_io_mode = std.io.default_mode,
.intended_io_mode = flags.intended_io_mode,
});
};
var io: w.IO_STATUS_BLOCK = undefined;
const range_off: w.LARGE_INTEGER = 0;
const range_len: w.LARGE_INTEGER = 1;
const exclusive = switch (flags.lock) {
.None => return file,
.Shared => false,
.Exclusive => true,
};
try w.LockFile(
file.handle,
null,
null,
null,
&io,
&range_off,
&range_len,
null,
@boolToInt(flags.lock_nonblocking),
@boolToInt(exclusive),
);
return file;
}
/// Creates, opens, or overwrites a file with write access.
@@ -1015,16 +1034,10 @@ pub const Dir = struct {
pub fn createFileW(self: Dir, sub_path_w: []const u16, flags: File.CreateFlags) File.OpenError!File {
const w = os.windows;
const read_flag = if (flags.read) @as(u32, w.GENERIC_READ) else 0;
return @as(File, .{
const file: File = .{
.handle = try os.windows.OpenFile(sub_path_w, .{
.dir = self.fd,
.access_mask = w.SYNCHRONIZE | w.GENERIC_WRITE | read_flag,
.share_access = switch (flags.lock) {
.None => w.FILE_SHARE_WRITE | w.FILE_SHARE_READ | w.FILE_SHARE_DELETE,
.Shared => w.FILE_SHARE_READ | w.FILE_SHARE_DELETE,
.Exclusive => w.FILE_SHARE_DELETE,
},
.share_access_nonblocking = flags.lock_nonblocking,
.creation = if (flags.exclusive)
@as(u32, w.FILE_CREATE)
else if (flags.truncate)
@@ -1035,7 +1048,28 @@ pub const Dir = struct {
}),
.capable_io_mode = std.io.default_mode,
.intended_io_mode = flags.intended_io_mode,
});
};
var io: w.IO_STATUS_BLOCK = undefined;
const range_off: w.LARGE_INTEGER = 0;
const range_len: w.LARGE_INTEGER = 1;
const exclusive = switch (flags.lock) {
.None => return file,
.Shared => false,
.Exclusive => true,
};
try w.LockFile(
file.handle,
null,
null,
null,
&io,
&range_off,
&range_len,
null,
@boolToInt(flags.lock_nonblocking),
@boolToInt(exclusive),
);
return file;
}
pub const openRead = @compileError("deprecated in favor of openFile");

View File

@@ -74,17 +74,28 @@ pub const File = struct {
read: bool = true,
write: bool = false,
/// Open the file with a lock to prevent other processes from accessing it at the
/// same time. An exclusive lock will prevent other processes from acquiring a lock.
/// A shared lock will prevent other processes from acquiring a exclusive lock, but
/// doesn't prevent other process from getting their own shared locks.
/// Open the file with an advisory lock to coordinate with other processes
/// accessing it at the same time. An exclusive lock will prevent other
/// processes from acquiring a lock. A shared lock will prevent other
/// processes from acquiring a exclusive lock, but does not prevent
/// other process from getting their own shared locks.
///
/// Note that the lock is only advisory on Linux, except in very specific cirsumstances[1].
/// The lock is advisory, except on Linux in very specific cirsumstances[1].
/// This means that a process that does not respect the locking API can still get access
/// to the file, despite the lock.
///
/// Windows' file locks are mandatory, and any process attempting to access the file will
/// receive an error.
/// On these operating systems, the lock is acquired atomically with
/// opening the file:
/// * Darwin
/// * DragonFlyBSD
/// * FreeBSD
/// * Haiku
/// * NetBSD
/// * OpenBSD
/// On these operating systems, the lock is acquired via a separate syscall
/// after opening the file:
/// * Linux
/// * Windows
///
/// [1]: https://www.kernel.org/doc/Documentation/filesystems/mandatory-locking.txt
lock: Lock = .None,
@@ -120,17 +131,28 @@ pub const File = struct {
/// `error.PathAlreadyExists` to be returned.
exclusive: bool = false,
/// Open the file with a lock to prevent other processes from accessing it at the
/// same time. An exclusive lock will prevent other processes from acquiring a lock.
/// A shared lock will prevent other processes from acquiring a exclusive lock, but
/// doesn't prevent other process from getting their own shared locks.
/// Open the file with an advisory lock to coordinate with other processes
/// accessing it at the same time. An exclusive lock will prevent other
/// processes from acquiring a lock. A shared lock will prevent other
/// processes from acquiring a exclusive lock, but does not prevent
/// other process from getting their own shared locks.
///
/// Note that the lock is only advisory on Linux, except in very specific cirsumstances[1].
/// The lock is advisory, except on Linux in very specific cirsumstances[1].
/// This means that a process that does not respect the locking API can still get access
/// to the file, despite the lock.
///
/// Windows's file locks are mandatory, and any process attempting to access the file will
/// receive an error.
/// On these operating systems, the lock is acquired atomically with
/// opening the file:
/// * Darwin
/// * DragonFlyBSD
/// * FreeBSD
/// * Haiku
/// * NetBSD
/// * OpenBSD
/// On these operating systems, the lock is acquired via a separate syscall
/// after opening the file:
/// * Linux
/// * Windows
///
/// [1]: https://www.kernel.org/doc/Documentation/filesystems/mandatory-locking.txt
lock: Lock = .None,
@@ -829,4 +851,165 @@ pub const File = struct {
pub fn seekableStream(file: File) SeekableStream {
return .{ .context = file };
}
const range_off: windows.LARGE_INTEGER = 0;
const range_len: windows.LARGE_INTEGER = 1;
pub const LockError = error{
SystemResources,
} || os.UnexpectedError;
/// Blocks when an incompatible lock is held by another process.
/// A process may hold only one type of lock (shared or exclusive) on
/// a file. When a process terminates in any way, the lock is released.
///
/// Assumes the file is unlocked.
///
/// TODO: integrate with async I/O
pub fn lock(file: File, l: Lock) LockError!void {
if (is_windows) {
var io_status_block: windows.IO_STATUS_BLOCK = undefined;
const exclusive = switch (l) {
.None => return,
.Shared => false,
.Exclusive => true,
};
return windows.LockFile(
file.handle,
null,
null,
null,
&io_status_block,
&range_off,
&range_len,
null,
windows.FALSE, // non-blocking=false
@boolToInt(exclusive),
) catch |err| switch (err) {
error.WouldBlock => unreachable, // non-blocking=false
else => |e| return e,
};
} else {
return os.flock(file.handle, switch (l) {
.None => os.LOCK_UN,
.Shared => os.LOCK_SH,
.Exclusive => os.LOCK_EX,
}) catch |err| switch (err) {
error.WouldBlock => unreachable, // non-blocking=false
else => |e| return e,
};
}
}
/// Assumes the file is locked.
pub fn unlock(file: File) void {
if (is_windows) {
var io_status_block: windows.IO_STATUS_BLOCK = undefined;
return windows.UnlockFile(
file.handle,
&io_status_block,
&range_off,
&range_len,
null,
) catch |err| switch (err) {
error.RangeNotLocked => unreachable, // Function assumes unlocked.
error.Unexpected => unreachable, // Resource deallocation must succeed.
};
} else {
return os.flock(file.handle, os.LOCK_UN) catch |err| switch (err) {
error.WouldBlock => unreachable, // unlocking can't block
error.SystemResources => unreachable, // We are deallocating resources.
error.Unexpected => unreachable, // Resource deallocation must succeed.
};
}
}
/// Attempts to obtain a lock, returning `true` if the lock is
/// obtained, and `false` if there was an existing incompatible lock held.
/// A process may hold only one type of lock (shared or exclusive) on
/// a file. When a process terminates in any way, the lock is released.
///
/// Assumes the file is unlocked.
///
/// TODO: integrate with async I/O
pub fn tryLock(file: File, l: Lock) LockError!bool {
if (is_windows) {
var io_status_block: windows.IO_STATUS_BLOCK = undefined;
const exclusive = switch (l) {
.None => return,
.Shared => false,
.Exclusive => true,
};
windows.LockFile(
file.handle,
null,
null,
null,
&io_status_block,
&range_off,
&range_len,
null,
windows.TRUE, // non-blocking=true
@boolToInt(exclusive),
) catch |err| switch (err) {
error.WouldBlock => return false,
else => |e| return e,
};
} else {
os.flock(file.handle, switch (l) {
.None => os.LOCK_UN,
.Shared => os.LOCK_SH | os.LOCK_NB,
.Exclusive => os.LOCK_EX | os.LOCK_NB,
}) catch |err| switch (err) {
error.WouldBlock => return false,
else => |e| return e,
};
}
return true;
}
/// Assumes the file is already locked in exclusive mode.
/// Atomically modifies the lock to be in shared mode, without releasing it.
///
/// TODO: integrate with async I/O
pub fn downgradeLock(file: File) LockError!void {
if (is_windows) {
// On Windows it works like a semaphore + exclusivity flag. To implement this
// function, we first obtain another lock in shared mode. This changes the
// exclusivity flag, but increments the semaphore to 2. So we follow up with
// an NtUnlockFile which decrements the semaphore but does not modify the
// exclusivity flag.
var io_status_block: windows.IO_STATUS_BLOCK = undefined;
windows.LockFile(
file.handle,
null,
null,
null,
&io_status_block,
&range_off,
&range_len,
null,
windows.TRUE, // non-blocking=true
windows.FALSE, // exclusive=false
) catch |err| switch (err) {
error.WouldBlock => unreachable, // File was not locked in exclusive mode.
else => |e| return e,
};
return windows.UnlockFile(
file.handle,
&io_status_block,
&range_off,
&range_len,
null,
) catch |err| switch (err) {
error.RangeNotLocked => unreachable, // File was not locked.
error.Unexpected => unreachable, // Resource deallocation must succeed.
};
} else {
return os.flock(file.handle, os.LOCK_SH | os.LOCK_NB) catch |err| switch (err) {
error.WouldBlock => unreachable, // File was not locked in exclusive mode.
else => |e| return e,
};
}
}
};

View File

@@ -278,7 +278,7 @@ test "directory operations on files" {
try testing.expectError(error.NotDir, tmp_dir.dir.deleteDir(test_file_name));
switch (builtin.os.tag) {
.wasi, .freebsd, .openbsd, .dragonfly => {},
.wasi, .freebsd, .netbsd, .openbsd, .dragonfly => {},
else => {
const absolute_path = try tmp_dir.dir.realpathAlloc(testing.allocator, test_file_name);
defer testing.allocator.free(absolute_path);
@@ -308,17 +308,22 @@ test "file operations on directories" {
try testing.expectError(error.IsDir, tmp_dir.dir.createFile(test_dir_name, .{}));
try testing.expectError(error.IsDir, tmp_dir.dir.deleteFile(test_dir_name));
// Currently, WASI will return error.Unexpected (via ENOTCAPABLE) when attempting fd_read on a directory handle.
// TODO: Re-enable on WASI once https://github.com/bytecodealliance/wasmtime/issues/1935 is resolved.
if (builtin.os.tag != .wasi) {
try testing.expectError(error.IsDir, tmp_dir.dir.readFileAlloc(testing.allocator, test_dir_name, std.math.maxInt(usize)));
switch (builtin.os.tag) {
// NetBSD does not error when reading a directory.
.netbsd => {},
// Currently, WASI will return error.Unexpected (via ENOTCAPABLE) when attempting fd_read on a directory handle.
// TODO: Re-enable on WASI once https://github.com/bytecodealliance/wasmtime/issues/1935 is resolved.
.wasi => {},
else => {
try testing.expectError(error.IsDir, tmp_dir.dir.readFileAlloc(testing.allocator, test_dir_name, std.math.maxInt(usize)));
},
}
// Note: The `.write = true` is necessary to ensure the error occurs on all platforms.
// TODO: Add a read-only test as well, see https://github.com/ziglang/zig/issues/5732
try testing.expectError(error.IsDir, tmp_dir.dir.openFile(test_dir_name, .{ .write = true }));
switch (builtin.os.tag) {
.wasi, .freebsd, .openbsd, .dragonfly => {},
.wasi, .freebsd, .netbsd, .openbsd, .dragonfly => {},
else => {
const absolute_path = try tmp_dir.dir.realpathAlloc(testing.allocator, test_dir_name);
defer testing.allocator.free(absolute_path);

View File

@@ -437,8 +437,12 @@ pub fn Watch(comptime V: type) type {
.overlapped = windows.OVERLAPPED{
.Internal = 0,
.InternalHigh = 0,
.Offset = 0,
.OffsetHigh = 0,
.DUMMYUNIONNAME = .{
.DUMMYSTRUCTNAME = .{
.Offset = 0,
.OffsetHigh = 0,
},
},
.hEvent = null,
},
},

View File

@@ -122,12 +122,9 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void {
.Array => hashArray(hasher, key, strat),
.Vector => |info| {
if (std.meta.bitCount(info.child) % 8 == 0) {
// If there's no unused bits in the child type, we can just hash
// this as an array of bytes.
if (comptime meta.trait.hasUniqueRepresentation(Key)) {
hasher.update(mem.asBytes(&key));
} else {
// Otherwise, hash every element.
comptime var i = 0;
inline while (i < info.len) : (i += 1) {
hash(hasher, key[i], strat);
@@ -146,10 +143,12 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void {
.Union => |info| {
if (info.tag_type) |tag_type| {
const tag = meta.activeTag(key);
const s = hash(hasher, tag, strat);
hash(hasher, tag, strat);
inline for (info.fields) |field| {
if (@field(tag_type, field.name) == tag) {
hash(hasher, @field(key, field.name), strat);
if (field.field_type != void) {
hash(hasher, @field(key, field.name), strat);
}
// TODO use a labelled break when it does not crash the compiler. cf #2908
// break :blk;
return;
@@ -385,17 +384,23 @@ test "testHash union" {
A: u32,
B: bool,
C: u32,
D: void,
};
const a = Foo{ .A = 18 };
var b = Foo{ .B = true };
const c = Foo{ .C = 18 };
const d: Foo = .D;
try testing.expect(testHash(a) == testHash(a));
try testing.expect(testHash(a) != testHash(b));
try testing.expect(testHash(a) != testHash(c));
try testing.expect(testHash(a) != testHash(d));
b = Foo{ .A = 18 };
try testing.expect(testHash(a) == testHash(b));
b = .D;
try testing.expect(testHash(d) == testHash(b));
}
test "testHash vector" {

View File

@@ -116,20 +116,20 @@ pub fn verifyContext(comptime RawContext: type, comptime PseudoKey: type, compti
switch (@typeInfo(Context)) {
.Struct, .Union, .Enum => {},
// Special-case .Opaque for a better error message
.Opaque => @compileError("Hash context must be a type with hash and eql member functions. Cannot use "++@typeName(Context)++" because it is opaque. Use a pointer instead."),
.Opaque => @compileError("Hash context must be a type with hash and eql member functions. Cannot use " ++ @typeName(Context) ++ " because it is opaque. Use a pointer instead."),
.Pointer => |ptr| {
if (ptr.size != .One) {
@compileError("Hash context must be a type with hash and eql member functions. Cannot use "++@typeName(Context)++" because it is not a single pointer.");
@compileError("Hash context must be a type with hash and eql member functions. Cannot use " ++ @typeName(Context) ++ " because it is not a single pointer.");
}
Context = ptr.child;
allow_const_ptr = true;
allow_mutable_ptr = !ptr.is_const;
switch (@typeInfo(Context)) {
.Struct, .Union, .Enum, .Opaque => {},
else => @compileError("Hash context must be a type with hash and eql member functions. Cannot use "++@typeName(Context)),
else => @compileError("Hash context must be a type with hash and eql member functions. Cannot use " ++ @typeName(Context)),
}
},
else => @compileError("Hash context must be a type with hash and eql member functions. Cannot use "++@typeName(Context)),
else => @compileError("Hash context must be a type with hash and eql member functions. Cannot use " ++ @typeName(Context)),
}
// Keep track of multiple errors so we can report them all.
@@ -140,12 +140,12 @@ pub fn verifyContext(comptime RawContext: type, comptime PseudoKey: type, compti
const lazy = struct {
const prefix = "\n ";
const deep_prefix = prefix ++ " ";
const hash_signature = "fn (self, "++@typeName(PseudoKey)++") "++@typeName(Hash);
const eql_signature = "fn (self, "++@typeName(PseudoKey)++", "++@typeName(Key)++") bool";
const hash_signature = "fn (self, " ++ @typeName(PseudoKey) ++ ") " ++ @typeName(Hash);
const eql_signature = "fn (self, " ++ @typeName(PseudoKey) ++ ", " ++ @typeName(Key) ++ ") bool";
const err_invalid_hash_signature = prefix ++ @typeName(Context) ++ ".hash must be " ++ hash_signature ++
deep_prefix ++ "but is actually " ++ @typeName(@TypeOf(Context.hash));
deep_prefix ++ "but is actually " ++ @typeName(@TypeOf(Context.hash));
const err_invalid_eql_signature = prefix ++ @typeName(Context) ++ ".eql must be " ++ eql_signature ++
deep_prefix ++ "but is actually " ++ @typeName(@TypeOf(Context.eql));
deep_prefix ++ "but is actually " ++ @typeName(@TypeOf(Context.eql));
};
// Verify Context.hash(self, PseudoKey) => Hash
@@ -167,7 +167,7 @@ pub fn verifyContext(comptime RawContext: type, comptime PseudoKey: type, compti
errors = errors ++ lazy.err_invalid_hash_signature;
emitted_signature = true;
}
errors = errors ++ lazy.deep_prefix ++ "First parameter must be "++@typeName(Context)++", but is "++@typeName(Self);
errors = errors ++ lazy.deep_prefix ++ "First parameter must be " ++ @typeName(Context) ++ ", but is " ++ @typeName(Self);
errors = errors ++ lazy.deep_prefix ++ "Note: Cannot be a pointer because it is passed by value.";
}
} else if (Self == *Context) {
@@ -177,10 +177,10 @@ pub fn verifyContext(comptime RawContext: type, comptime PseudoKey: type, compti
emitted_signature = true;
}
if (!allow_const_ptr) {
errors = errors ++ lazy.deep_prefix ++ "First parameter must be "++@typeName(Context)++", but is "++@typeName(Self);
errors = errors ++ lazy.deep_prefix ++ "First parameter must be " ++ @typeName(Context) ++ ", but is " ++ @typeName(Self);
errors = errors ++ lazy.deep_prefix ++ "Note: Cannot be a pointer because it is passed by value.";
} else {
errors = errors ++ lazy.deep_prefix ++ "First parameter must be "++@typeName(Context)++" or "++@typeName(*const Context)++", but is "++@typeName(Self);
errors = errors ++ lazy.deep_prefix ++ "First parameter must be " ++ @typeName(Context) ++ " or " ++ @typeName(*const Context) ++ ", but is " ++ @typeName(Self);
errors = errors ++ lazy.deep_prefix ++ "Note: Cannot be non-const because it is passed by const pointer.";
}
}
@@ -189,14 +189,14 @@ pub fn verifyContext(comptime RawContext: type, comptime PseudoKey: type, compti
errors = errors ++ lazy.err_invalid_hash_signature;
emitted_signature = true;
}
errors = errors ++ lazy.deep_prefix ++ "First parameter must be "++@typeName(Context);
errors = errors ++ lazy.deep_prefix ++ "First parameter must be " ++ @typeName(Context);
if (allow_const_ptr) {
errors = errors++" or "++@typeName(*const Context);
errors = errors ++ " or " ++ @typeName(*const Context);
if (allow_mutable_ptr) {
errors = errors++" or "++@typeName(*Context);
errors = errors ++ " or " ++ @typeName(*Context);
}
}
errors = errors++", but is "++@typeName(Self);
errors = errors ++ ", but is " ++ @typeName(Self);
}
}
if (func.args[1].arg_type != null and func.args[1].arg_type.? != PseudoKey) {
@@ -204,14 +204,14 @@ pub fn verifyContext(comptime RawContext: type, comptime PseudoKey: type, compti
errors = errors ++ lazy.err_invalid_hash_signature;
emitted_signature = true;
}
errors = errors ++ lazy.deep_prefix ++ "Second parameter must be "++@typeName(PseudoKey)++", but is "++@typeName(func.args[1].arg_type.?);
errors = errors ++ lazy.deep_prefix ++ "Second parameter must be " ++ @typeName(PseudoKey) ++ ", but is " ++ @typeName(func.args[1].arg_type.?);
}
if (func.return_type != null and func.return_type.? != Hash) {
if (!emitted_signature) {
errors = errors ++ lazy.err_invalid_hash_signature;
emitted_signature = true;
}
errors = errors ++ lazy.deep_prefix ++ "Return type must be "++@typeName(Hash)++", but was "++@typeName(func.return_type.?);
errors = errors ++ lazy.deep_prefix ++ "Return type must be " ++ @typeName(Hash) ++ ", but was " ++ @typeName(func.return_type.?);
}
// If any of these are generic (null), we cannot verify them.
// The call sites check the return type, but cannot check the
@@ -243,7 +243,7 @@ pub fn verifyContext(comptime RawContext: type, comptime PseudoKey: type, compti
errors = errors ++ lazy.err_invalid_eql_signature;
emitted_signature = true;
}
errors = errors ++ lazy.deep_prefix ++ "First parameter must be "++@typeName(Context)++", but is "++@typeName(Self);
errors = errors ++ lazy.deep_prefix ++ "First parameter must be " ++ @typeName(Context) ++ ", but is " ++ @typeName(Self);
errors = errors ++ lazy.deep_prefix ++ "Note: Cannot be a pointer because it is passed by value.";
}
} else if (Self == *Context) {
@@ -253,10 +253,10 @@ pub fn verifyContext(comptime RawContext: type, comptime PseudoKey: type, compti
emitted_signature = true;
}
if (!allow_const_ptr) {
errors = errors ++ lazy.deep_prefix ++ "First parameter must be "++@typeName(Context)++", but is "++@typeName(Self);
errors = errors ++ lazy.deep_prefix ++ "First parameter must be " ++ @typeName(Context) ++ ", but is " ++ @typeName(Self);
errors = errors ++ lazy.deep_prefix ++ "Note: Cannot be a pointer because it is passed by value.";
} else {
errors = errors ++ lazy.deep_prefix ++ "First parameter must be "++@typeName(Context)++" or "++@typeName(*const Context)++", but is "++@typeName(Self);
errors = errors ++ lazy.deep_prefix ++ "First parameter must be " ++ @typeName(Context) ++ " or " ++ @typeName(*const Context) ++ ", but is " ++ @typeName(Self);
errors = errors ++ lazy.deep_prefix ++ "Note: Cannot be non-const because it is passed by const pointer.";
}
}
@@ -265,14 +265,14 @@ pub fn verifyContext(comptime RawContext: type, comptime PseudoKey: type, compti
errors = errors ++ lazy.err_invalid_eql_signature;
emitted_signature = true;
}
errors = errors ++ lazy.deep_prefix ++ "First parameter must be "++@typeName(Context);
errors = errors ++ lazy.deep_prefix ++ "First parameter must be " ++ @typeName(Context);
if (allow_const_ptr) {
errors = errors++" or "++@typeName(*const Context);
errors = errors ++ " or " ++ @typeName(*const Context);
if (allow_mutable_ptr) {
errors = errors++" or "++@typeName(*Context);
errors = errors ++ " or " ++ @typeName(*Context);
}
}
errors = errors++", but is "++@typeName(Self);
errors = errors ++ ", but is " ++ @typeName(Self);
}
}
if (func.args[1].arg_type.? != PseudoKey) {
@@ -280,21 +280,21 @@ pub fn verifyContext(comptime RawContext: type, comptime PseudoKey: type, compti
errors = errors ++ lazy.err_invalid_eql_signature;
emitted_signature = true;
}
errors = errors ++ lazy.deep_prefix ++ "Second parameter must be "++@typeName(PseudoKey)++", but is "++@typeName(func.args[1].arg_type.?);
errors = errors ++ lazy.deep_prefix ++ "Second parameter must be " ++ @typeName(PseudoKey) ++ ", but is " ++ @typeName(func.args[1].arg_type.?);
}
if (func.args[2].arg_type.? != Key) {
if (!emitted_signature) {
errors = errors ++ lazy.err_invalid_eql_signature;
emitted_signature = true;
}
errors = errors ++ lazy.deep_prefix ++ "Third parameter must be "++@typeName(Key)++", but is "++@typeName(func.args[2].arg_type.?);
errors = errors ++ lazy.deep_prefix ++ "Third parameter must be " ++ @typeName(Key) ++ ", but is " ++ @typeName(func.args[2].arg_type.?);
}
if (func.return_type.? != bool) {
if (!emitted_signature) {
errors = errors ++ lazy.err_invalid_eql_signature;
emitted_signature = true;
}
errors = errors ++ lazy.deep_prefix ++ "Return type must be bool, but was "++@typeName(func.return_type.?);
errors = errors ++ lazy.deep_prefix ++ "Return type must be bool, but was " ++ @typeName(func.return_type.?);
}
// If any of these are generic (null), we cannot verify them.
// The call sites check the return type, but cannot check the
@@ -309,7 +309,7 @@ pub fn verifyContext(comptime RawContext: type, comptime PseudoKey: type, compti
if (errors.len != 0) {
// errors begins with a newline (from lazy.prefix)
@compileError("Problems found with hash context type "++@typeName(Context)++":"++errors);
@compileError("Problems found with hash context type " ++ @typeName(Context) ++ ":" ++ errors);
}
}
}
@@ -790,7 +790,7 @@ pub fn HashMapUnmanaged(
pub fn promote(self: Self, allocator: *Allocator) Managed {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call promoteContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call promoteContext instead.");
return promoteContext(self, allocator, undefined);
}
@@ -819,7 +819,7 @@ pub fn HashMapUnmanaged(
pub fn ensureCapacity(self: *Self, allocator: *Allocator, new_size: Size) !void {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call ensureCapacityContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call ensureCapacityContext instead.");
return ensureCapacityContext(self, allocator, new_size, undefined);
}
pub fn ensureCapacityContext(self: *Self, allocator: *Allocator, new_size: Size, ctx: Context) !void {
@@ -902,7 +902,7 @@ pub fn HashMapUnmanaged(
/// Insert an entry in the map. Assumes it is not already present.
pub fn putNoClobber(self: *Self, allocator: *Allocator, key: K, value: V) !void {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call putNoClobberContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call putNoClobberContext instead.");
return self.putNoClobberContext(allocator, key, value, undefined);
}
pub fn putNoClobberContext(self: *Self, allocator: *Allocator, key: K, value: V, ctx: Context) !void {
@@ -917,7 +917,7 @@ pub fn HashMapUnmanaged(
/// existing data, see `getOrPutAssumeCapacity`.
pub fn putAssumeCapacity(self: *Self, key: K, value: V) void {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call putAssumeCapacityContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call putAssumeCapacityContext instead.");
return self.putAssumeCapacityContext(key, value, undefined);
}
pub fn putAssumeCapacityContext(self: *Self, key: K, value: V, ctx: Context) void {
@@ -929,7 +929,7 @@ pub fn HashMapUnmanaged(
/// and that no allocation is needed.
pub fn putAssumeCapacityNoClobber(self: *Self, key: K, value: V) void {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call putAssumeCapacityNoClobberContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call putAssumeCapacityNoClobberContext instead.");
return self.putAssumeCapacityNoClobberContext(key, value, undefined);
}
pub fn putAssumeCapacityNoClobberContext(self: *Self, key: K, value: V, ctx: Context) void {
@@ -961,7 +961,7 @@ pub fn HashMapUnmanaged(
/// Inserts a new `Entry` into the hash map, returning the previous one, if any.
pub fn fetchPut(self: *Self, allocator: *Allocator, key: K, value: V) !?KV {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call fetchPutContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call fetchPutContext instead.");
return self.fetchPutContext(allocator, key, value, undefined);
}
pub fn fetchPutContext(self: *Self, allocator: *Allocator, key: K, value: V, ctx: Context) !?KV {
@@ -981,7 +981,7 @@ pub fn HashMapUnmanaged(
/// If insertion happens, asserts there is enough capacity without allocating.
pub fn fetchPutAssumeCapacity(self: *Self, key: K, value: V) ?KV {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call fetchPutAssumeCapacityContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call fetchPutAssumeCapacityContext instead.");
return self.fetchPutAssumeCapacityContext(key, value, undefined);
}
pub fn fetchPutAssumeCapacityContext(self: *Self, key: K, value: V, ctx: Context) ?KV {
@@ -1001,7 +1001,7 @@ pub fn HashMapUnmanaged(
/// the hash map, and then returned from this function.
pub fn fetchRemove(self: *Self, key: K) ?KV {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call fetchRemoveContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call fetchRemoveContext instead.");
return self.fetchRemoveContext(key, undefined);
}
pub fn fetchRemoveContext(self: *Self, key: K, ctx: Context) ?KV {
@@ -1033,7 +1033,7 @@ pub fn HashMapUnmanaged(
/// fuse the basic blocks after the branch to the basic blocks
/// from this function. To encourage that, this function is
/// marked as inline.
fn getIndex(self: Self, key: anytype, ctx: anytype) callconv(.Inline) ?usize {
inline fn getIndex(self: Self, key: anytype, ctx: anytype) ?usize {
comptime verifyContext(@TypeOf(ctx), @TypeOf(key), K, Hash);
if (self.size == 0) {
@@ -1046,7 +1046,7 @@ pub fn HashMapUnmanaged(
// verifyContext can't verify the return type of generic hash functions,
// so we need to double-check it here.
if (@TypeOf(hash) != Hash) {
@compileError("Context "++@typeName(@TypeOf(ctx))++" has a generic hash function that returns the wrong type! "++@typeName(Hash)++" was expected, but found "++@typeName(@TypeOf(hash)));
@compileError("Context " ++ @typeName(@TypeOf(ctx)) ++ " has a generic hash function that returns the wrong type! " ++ @typeName(Hash) ++ " was expected, but found " ++ @typeName(@TypeOf(hash)));
}
const mask = self.capacity() - 1;
const fingerprint = Metadata.takeFingerprint(hash);
@@ -1062,7 +1062,7 @@ pub fn HashMapUnmanaged(
// verifyContext can't verify the return type of generic eql functions,
// so we need to double-check it here.
if (@TypeOf(eql) != bool) {
@compileError("Context "++@typeName(@TypeOf(ctx))++" has a generic eql function that returns the wrong type! bool was expected, but found "++@typeName(@TypeOf(eql)));
@compileError("Context " ++ @typeName(@TypeOf(ctx)) ++ " has a generic eql function that returns the wrong type! bool was expected, but found " ++ @typeName(@TypeOf(eql)));
}
if (eql) {
return idx;
@@ -1078,7 +1078,7 @@ pub fn HashMapUnmanaged(
pub fn getEntry(self: Self, key: K) ?Entry {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call getEntryContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getEntryContext instead.");
return self.getEntryContext(key, undefined);
}
pub fn getEntryContext(self: Self, key: K, ctx: Context) ?Entry {
@@ -1097,7 +1097,7 @@ pub fn HashMapUnmanaged(
/// Insert an entry if the associated key is not already present, otherwise update preexisting value.
pub fn put(self: *Self, allocator: *Allocator, key: K, value: V) !void {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call putContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call putContext instead.");
return self.putContext(allocator, key, value, undefined);
}
pub fn putContext(self: *Self, allocator: *Allocator, key: K, value: V, ctx: Context) !void {
@@ -1108,7 +1108,7 @@ pub fn HashMapUnmanaged(
/// Get an optional pointer to the value associated with key, if present.
pub fn getPtr(self: Self, key: K) ?*V {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call getPtrContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getPtrContext instead.");
return self.getPtrContext(key, undefined);
}
pub fn getPtrContext(self: Self, key: K, ctx: Context) ?*V {
@@ -1124,7 +1124,7 @@ pub fn HashMapUnmanaged(
/// Get a copy of the value associated with key, if present.
pub fn get(self: Self, key: K) ?V {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call getContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getContext instead.");
return self.getContext(key, undefined);
}
pub fn getContext(self: Self, key: K, ctx: Context) ?V {
@@ -1139,7 +1139,7 @@ pub fn HashMapUnmanaged(
pub fn getOrPut(self: *Self, allocator: *Allocator, key: K) !GetOrPutResult {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call getOrPutContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutContext instead.");
return self.getOrPutContext(allocator, key, undefined);
}
pub fn getOrPutContext(self: *Self, allocator: *Allocator, key: K, ctx: Context) !GetOrPutResult {
@@ -1151,7 +1151,7 @@ pub fn HashMapUnmanaged(
}
pub fn getOrPutAdapted(self: *Self, allocator: *Allocator, key: anytype, key_ctx: anytype) !GetOrPutResult {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call getOrPutContextAdapted instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutContextAdapted instead.");
return self.getOrPutContextAdapted(allocator, key, key_ctx, undefined);
}
pub fn getOrPutContextAdapted(self: *Self, allocator: *Allocator, key: anytype, key_ctx: anytype, ctx: Context) !GetOrPutResult {
@@ -1171,7 +1171,7 @@ pub fn HashMapUnmanaged(
pub fn getOrPutAssumeCapacity(self: *Self, key: K) GetOrPutResult {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call getOrPutAssumeCapacityContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutAssumeCapacityContext instead.");
return self.getOrPutAssumeCapacityContext(key, undefined);
}
pub fn getOrPutAssumeCapacityContext(self: *Self, key: K, ctx: Context) GetOrPutResult {
@@ -1190,7 +1190,7 @@ pub fn HashMapUnmanaged(
// verifyContext can't verify the return type of generic hash functions,
// so we need to double-check it here.
if (@TypeOf(hash) != Hash) {
@compileError("Context "++@typeName(@TypeOf(ctx))++" has a generic hash function that returns the wrong type! "++@typeName(Hash)++" was expected, but found "++@typeName(@TypeOf(hash)));
@compileError("Context " ++ @typeName(@TypeOf(ctx)) ++ " has a generic hash function that returns the wrong type! " ++ @typeName(Hash) ++ " was expected, but found " ++ @typeName(@TypeOf(hash)));
}
const mask = self.capacity() - 1;
const fingerprint = Metadata.takeFingerprint(hash);
@@ -1207,7 +1207,7 @@ pub fn HashMapUnmanaged(
// verifyContext can't verify the return type of generic eql functions,
// so we need to double-check it here.
if (@TypeOf(eql) != bool) {
@compileError("Context "++@typeName(@TypeOf(ctx))++" has a generic eql function that returns the wrong type! bool was expected, but found "++@typeName(@TypeOf(eql)));
@compileError("Context " ++ @typeName(@TypeOf(ctx)) ++ " has a generic eql function that returns the wrong type! bool was expected, but found " ++ @typeName(@TypeOf(eql)));
}
if (eql) {
return GetOrPutResult{
@@ -1236,7 +1236,7 @@ pub fn HashMapUnmanaged(
metadata[0].fill(fingerprint);
const new_key = &self.keys()[idx];
const new_value = &self.values()[idx];
new_key.* = key;
new_key.* = undefined;
new_value.* = undefined;
self.size += 1;
@@ -1249,7 +1249,7 @@ pub fn HashMapUnmanaged(
pub fn getOrPutValue(self: *Self, allocator: *Allocator, key: K, value: V) !Entry {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call getOrPutValueContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutValueContext instead.");
return self.getOrPutValueContext(allocator, key, value, undefined);
}
pub fn getOrPutValueContext(self: *Self, allocator: *Allocator, key: K, value: V, ctx: Context) !Entry {
@@ -1264,7 +1264,7 @@ pub fn HashMapUnmanaged(
/// Return true if there is a value associated with key in the map.
pub fn contains(self: *const Self, key: K) bool {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call containsContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call containsContext instead.");
return self.containsContext(key, undefined);
}
pub fn containsContext(self: *const Self, key: K, ctx: Context) bool {
@@ -1279,7 +1279,7 @@ pub fn HashMapUnmanaged(
/// function returns false.
pub fn remove(self: *Self, key: K) bool {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call removeContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call removeContext instead.");
return self.removeContext(key, undefined);
}
pub fn removeContext(self: *Self, key: K, ctx: Context) bool {
@@ -1317,7 +1317,7 @@ pub fn HashMapUnmanaged(
pub fn clone(self: Self, allocator: *Allocator) !Self {
if (@sizeOf(Context) != 0)
@compileError("Cannot infer context "++@typeName(Context)++", call cloneContext instead.");
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call cloneContext instead.");
return self.cloneContext(allocator, @as(Context, undefined));
}
pub fn cloneContext(self: Self, allocator: *Allocator, new_ctx: anytype) !HashMapUnmanaged(K, V, @TypeOf(new_ctx), max_load_percentage) {
@@ -1884,6 +1884,52 @@ test "std.hash_map clone" {
}
}
test "std.hash_map getOrPutAdapted" {
const AdaptedContext = struct {
fn eql(self: @This(), adapted_key: []const u8, test_key: u64) bool {
return std.fmt.parseInt(u64, adapted_key, 10) catch unreachable == test_key;
}
fn hash(self: @This(), adapted_key: []const u8) u64 {
const key = std.fmt.parseInt(u64, adapted_key, 10) catch unreachable;
return (AutoContext(u64){}).hash(key);
}
};
var map = AutoHashMap(u64, u64).init(testing.allocator);
defer map.deinit();
const keys = [_][]const u8{
"1231",
"4564",
"7894",
"1132",
"65235",
"95462",
"0112305",
"00658",
"0",
"2",
};
var real_keys: [keys.len]u64 = undefined;
inline for (keys) |key_str, i| {
const result = try map.getOrPutAdapted(key_str, AdaptedContext{});
try testing.expect(!result.found_existing);
real_keys[i] = std.fmt.parseInt(u64, key_str, 10) catch unreachable;
result.key_ptr.* = real_keys[i];
result.value_ptr.* = i * 2;
}
try testing.expectEqual(map.count(), keys.len);
inline for (keys) |key_str, i| {
const result = try map.getOrPutAdapted(key_str, AdaptedContext{});
try testing.expect(result.found_existing);
try testing.expectEqual(real_keys[i], result.key_ptr.*);
try testing.expectEqual(@as(u64, i) * 2, result.value_ptr.*);
}
}
test "compile everything" {
std.testing.refAllDecls(AutoHashMap(i32, i32));
std.testing.refAllDecls(StringHashMap([]const u8));

View File

@@ -247,7 +247,7 @@ const PageAllocator = struct {
) catch return error.OutOfMemory;
// If the allocation is sufficiently aligned, use it.
if (@ptrToInt(addr) & (alignment - 1) == 0) {
if (mem.isAligned(@ptrToInt(addr), alignment)) {
return @ptrCast([*]u8, addr)[0..alignPageAllocLen(aligned_len, n, len_align)];
}
@@ -300,13 +300,13 @@ const PageAllocator = struct {
) catch return error.OutOfMemory;
assert(mem.isAligned(@ptrToInt(slice.ptr), mem.page_size));
const aligned_addr = mem.alignForward(@ptrToInt(slice.ptr), alignment);
const result_ptr = @alignCast(mem.page_size, @intToPtr([*]u8, aligned_addr));
const result_ptr = mem.alignPointer(slice.ptr, alignment) orelse
return error.OutOfMemory;
// Unmap the extra bytes that were only requested in order to guarantee
// that the range of memory we were provided had a proper alignment in
// it somewhere. The extra bytes could be at the beginning, or end, or both.
const drop_len = aligned_addr - @ptrToInt(slice.ptr);
const drop_len = @ptrToInt(result_ptr) - @ptrToInt(slice.ptr);
if (drop_len != 0) {
os.munmap(slice[0..drop_len]);
}
@@ -372,7 +372,7 @@ const PageAllocator = struct {
return alignPageAllocLen(new_size_aligned, new_size, len_align);
if (new_size_aligned < buf_aligned_len) {
const ptr = @intToPtr([*]align(mem.page_size) u8, @ptrToInt(buf_unaligned.ptr) + new_size_aligned);
const ptr = @alignCast(mem.page_size, buf_unaligned.ptr + new_size_aligned);
// TODO: if the next_mmap_addr_hint is within the unmapped range, update it
os.munmap(ptr[0 .. buf_aligned_len - new_size_aligned]);
if (new_size_aligned == 0)
@@ -692,8 +692,9 @@ pub const FixedBufferAllocator = struct {
fn alloc(allocator: *Allocator, n: usize, ptr_align: u29, len_align: u29, ra: usize) ![]u8 {
const self = @fieldParentPtr(FixedBufferAllocator, "allocator", allocator);
const aligned_addr = mem.alignForward(@ptrToInt(self.buffer.ptr) + self.end_index, ptr_align);
const adjusted_index = aligned_addr - @ptrToInt(self.buffer.ptr);
const adjust_off = mem.alignPointerOffset(self.buffer.ptr + self.end_index, ptr_align) orelse
return error.OutOfMemory;
const adjusted_index = self.end_index + adjust_off;
const new_end_index = adjusted_index + n;
if (new_end_index > self.buffer.len) {
return error.OutOfMemory;
@@ -765,9 +766,9 @@ pub const ThreadSafeFixedBufferAllocator = blk: {
const self = @fieldParentPtr(ThreadSafeFixedBufferAllocator, "allocator", allocator);
var end_index = @atomicLoad(usize, &self.end_index, builtin.AtomicOrder.SeqCst);
while (true) {
const addr = @ptrToInt(self.buffer.ptr) + end_index;
const adjusted_addr = mem.alignForward(addr, ptr_align);
const adjusted_index = end_index + (adjusted_addr - addr);
const adjust_off = mem.alignPointerOffset(self.buffer.ptr + end_index, ptr_align) orelse
return error.OutOfMemory;
const adjusted_index = end_index + adjust_off;
const new_end_index = adjusted_index + n;
if (new_end_index > self.buffer.len) {
return error.OutOfMemory;

View File

@@ -81,7 +81,7 @@ pub fn FixedBufferStream(comptime Buffer: type) type {
}
pub fn seekTo(self: *Self, pos: u64) SeekError!void {
self.pos = if (std.math.cast(usize, pos)) |x| x else |_| self.buffer.len;
self.pos = if (std.math.cast(usize, pos)) |x| std.math.min(self.buffer.len, x) else |_| self.buffer.len;
}
pub fn seekBy(self: *Self, amt: i64) SeekError!void {
@@ -155,6 +155,9 @@ test "FixedBufferStream output 2" {
try testing.expectError(error.NoSpaceLeft, fbs.writer().writeAll("Hello world!"));
try testing.expect(mem.eql(u8, fbs.getWritten(), "Hello worl"));
try fbs.seekTo((try fbs.getEndPos()) + 1);
try testing.expectError(error.NoSpaceLeft, fbs.writer().writeAll("H"));
}
test "FixedBufferStream input" {
@@ -163,14 +166,18 @@ test "FixedBufferStream input" {
var dest: [4]u8 = undefined;
var read = try fbs.reader().read(dest[0..4]);
var read = try fbs.reader().read(&dest);
try testing.expect(read == 4);
try testing.expect(mem.eql(u8, dest[0..4], bytes[0..4]));
read = try fbs.reader().read(dest[0..4]);
read = try fbs.reader().read(&dest);
try testing.expect(read == 3);
try testing.expect(mem.eql(u8, dest[0..3], bytes[4..7]));
read = try fbs.reader().read(dest[0..4]);
read = try fbs.reader().read(&dest);
try testing.expect(read == 0);
try fbs.seekTo((try fbs.getEndPos()) + 1);
read = try fbs.reader().read(&dest);
try testing.expect(read == 0);
}

View File

@@ -1087,14 +1087,14 @@ fn testCeilPowerOfTwo() !void {
pub fn log2_int(comptime T: type, x: T) Log2Int(T) {
if (@typeInfo(T) != .Int or @typeInfo(T).Int.signedness != .unsigned)
@compileError("log2_int requires an unsigned integer, found "++@typeName(T));
@compileError("log2_int requires an unsigned integer, found " ++ @typeName(T));
assert(x != 0);
return @intCast(Log2Int(T), @typeInfo(T).Int.bits - 1 - @clz(T, x));
}
pub fn log2_int_ceil(comptime T: type, x: T) Log2IntCeil(T) {
if (@typeInfo(T) != .Int or @typeInfo(T).Int.signedness != .unsigned)
@compileError("log2_int_ceil requires an unsigned integer, found "++@typeName(T));
@compileError("log2_int_ceil requires an unsigned integer, found " ++ @typeName(T));
assert(x != 0);
if (x == 1) return 0;
const log2_val: Log2IntCeil(T) = log2_int(T, x - 1);

View File

@@ -316,7 +316,9 @@ pub const Mutable = struct {
}
if (a.limbs.len == 1 and b.limbs.len == 1 and a.positive == b.positive) {
if (!@addWithOverflow(Limb, a.limbs[0], b.limbs[0], &r.limbs[0])) {
var o: Limb = undefined;
if (!@addWithOverflow(Limb, a.limbs[0], b.limbs[0], &o)) {
r.limbs[0] = o;
r.len = 1;
r.positive = a.positive;
return;
@@ -333,10 +335,10 @@ pub const Mutable = struct {
}
} else {
if (a.limbs.len >= b.limbs.len) {
lladd(r.limbs[0..], a.limbs[0..a.limbs.len], b.limbs[0..b.limbs.len]);
lladd(r.limbs[0..], a.limbs, b.limbs);
r.normalize(a.limbs.len + 1);
} else {
lladd(r.limbs[0..], b.limbs[0..b.limbs.len], a.limbs[0..a.limbs.len]);
lladd(r.limbs[0..], b.limbs, a.limbs);
r.normalize(b.limbs.len + 1);
}
@@ -1683,12 +1685,14 @@ pub const Managed = struct {
/// r = a + scalar
///
/// r and a may be aliases.
/// r and a may be aliases. If r aliases a, then caller must call
/// `r.ensureAddScalarCapacity` prior to calling `add`.
/// scalar is a primitive integer type.
///
/// Returns an error if memory could not be allocated.
pub fn addScalar(r: *Managed, a: Const, scalar: anytype) Allocator.Error!void {
try r.ensureCapacity(math.max(a.limbs.len, calcLimbLen(scalar)) + 1);
assert((r.limbs.ptr != a.limbs.ptr) or r.limbs.len >= math.max(a.limbs.len, calcLimbLen(scalar)) + 1);
try r.ensureAddScalarCapacity(a, scalar);
var m = r.toMutable();
m.addScalar(a, scalar);
r.setMetadata(m.positive, m.len);
@@ -1696,11 +1700,13 @@ pub const Managed = struct {
/// r = a + b
///
/// r, a and b may be aliases.
/// r, a and b may be aliases. If r aliases a or b, then caller must call
/// `r.ensureAddCapacity` prior to calling `add`.
///
/// Returns an error if memory could not be allocated.
pub fn add(r: *Managed, a: Const, b: Const) Allocator.Error!void {
try r.ensureCapacity(math.max(a.limbs.len, b.limbs.len) + 1);
assert((r.limbs.ptr != a.limbs.ptr and r.limbs.ptr != b.limbs.ptr) or r.limbs.len >= math.max(a.limbs.len, b.limbs.len) + 1);
try r.ensureAddCapacity(a, b);
var m = r.toMutable();
m.add(a, b);
r.setMetadata(m.positive, m.len);
@@ -1746,6 +1752,14 @@ pub const Managed = struct {
rma.setMetadata(m.positive, m.len);
}
pub fn ensureAddScalarCapacity(r: *Managed, a: Const, scalar: anytype) !void {
try r.ensureCapacity(math.max(a.limbs.len, calcLimbLen(scalar)) + 1);
}
pub fn ensureAddCapacity(r: *Managed, a: Const, b: Const) !void {
try r.ensureCapacity(math.max(a.limbs.len, b.limbs.len) + 1);
}
pub fn ensureMulCapacity(rma: *Managed, a: Const, b: Const) !void {
try rma.ensureCapacity(a.limbs.len + b.limbs.len + 1);
}

View File

@@ -538,6 +538,17 @@ test "big.int add sign" {
try testing.expect((try a.to(i32)) == -3);
}
test "big.int add scalar" {
var a = try Managed.initSet(testing.allocator, 50);
defer a.deinit();
var b = try Managed.init(testing.allocator);
defer b.deinit();
try b.addScalar(a.toConst(), 5);
try testing.expect((try b.to(u32)) == 55);
}
test "big.int sub single-single" {
var a = try Managed.initSet(testing.allocator, 50);
defer a.deinit();
@@ -1562,3 +1573,31 @@ test "big.int pow" {
try testing.expectEqual(@as(i32, 1), try a.to(i32));
}
}
test "big.int regression test for 1 limb overflow with alias" {
// Note these happen to be two consecutive Fibonacci sequence numbers, the
// first two whose sum exceeds 2**64.
var a = try Managed.initSet(testing.allocator, 7540113804746346429);
defer a.deinit();
var b = try Managed.initSet(testing.allocator, 12200160415121876738);
defer b.deinit();
try a.ensureAddCapacity(a.toConst(), b.toConst());
try a.add(a.toConst(), b.toConst());
try testing.expect(a.toConst().orderAgainstScalar(19740274219868223167) == .eq);
}
test "big.int regression test for realloc with alias" {
// Note these happen to be two consecutive Fibonacci sequence numbers, the
// second of which is the first such number to exceed 2**192.
var a = try Managed.initSet(testing.allocator, 5611500259351924431073312796924978741056961814867751431689);
defer a.deinit();
var b = try Managed.initSet(testing.allocator, 9079598147510263717870894449029933369491131786514446266146);
defer b.deinit();
try a.ensureAddCapacity(a.toConst(), b.toConst());
try a.add(a.toConst(), b.toConst());
try testing.expect(a.toConst().orderAgainstScalar(14691098406862188148944207245954912110548093601382197697835) == .eq);
}

View File

@@ -124,20 +124,42 @@ fn exp64(z: Complex(f64)) Complex(f64) {
}
}
const epsilon = 0.0001;
test "complex.cexp32" {
const a = Complex(f32).init(5, 3);
const c = exp(a);
const tolerance_f32 = math.sqrt(math.epsilon(f32));
try testing.expect(math.approxEqAbs(f32, c.re, -146.927917, epsilon));
try testing.expect(math.approxEqAbs(f32, c.im, 20.944065, epsilon));
{
const a = Complex(f32).init(5, 3);
const c = exp(a);
try testing.expectApproxEqRel(@as(f32, -1.46927917e+02), c.re, tolerance_f32);
try testing.expectApproxEqRel(@as(f32, 2.0944065e+01), c.im, tolerance_f32);
}
{
const a = Complex(f32).init(88.8, 0x1p-149);
const c = exp(a);
try testing.expectApproxEqAbs(math.inf(f32), c.re, tolerance_f32);
try testing.expectApproxEqAbs(@as(f32, 5.15088629e-07), c.im, tolerance_f32);
}
}
test "complex.cexp64" {
const a = Complex(f64).init(5, 3);
const c = exp(a);
const tolerance_f64 = math.sqrt(math.epsilon(f64));
try testing.expect(math.approxEqAbs(f64, c.re, -146.927917, epsilon));
try testing.expect(math.approxEqAbs(f64, c.im, 20.944065, epsilon));
{
const a = Complex(f64).init(5, 3);
const c = exp(a);
try testing.expectApproxEqRel(@as(f64, -1.469279139083189e+02), c.re, tolerance_f64);
try testing.expectApproxEqRel(@as(f64, 2.094406620874596e+01), c.im, tolerance_f64);
}
{
const a = Complex(f64).init(709.8, 0x1p-1074);
const c = exp(a);
try testing.expectApproxEqAbs(math.inf(f64), c.re, tolerance_f64);
try testing.expectApproxEqAbs(@as(f64, 9.036659362159884e-16), c.im, tolerance_f64);
}
}

View File

@@ -13,6 +13,7 @@ const std = @import("../../std.zig");
const debug = std.debug;
const math = std.math;
const cmath = math.complex;
const testing = std.testing;
const Complex = cmath.Complex;
/// Returns exp(z) scaled to avoid overflow.
@@ -48,7 +49,10 @@ fn ldexp_cexp32(z: Complex(f32), expt: i32) Complex(f32) {
const half_expt2 = exptf - half_expt1;
const scale2 = @bitCast(f32, (0x7f + half_expt2) << 23);
return Complex(f32).init(math.cos(z.im) * exp_x * scale1 * scale2, math.sin(z.im) * exp_x * scale1 * scale2);
return Complex(f32).init(
math.cos(z.im) * exp_x * scale1 * scale2,
math.sin(z.im) * exp_x * scale1 * scale2,
);
}
fn frexp_exp64(x: f64, expt: *i32) f64 {
@@ -57,7 +61,7 @@ fn frexp_exp64(x: f64, expt: *i32) f64 {
const exp_x = math.exp(x - kln2);
const fx = @bitCast(u64, x);
const fx = @bitCast(u64, exp_x);
const hx = @intCast(u32, fx >> 32);
const lx = @truncate(u32, fx);
@@ -73,10 +77,10 @@ fn ldexp_cexp64(z: Complex(f64), expt: i32) Complex(f64) {
const exptf = @as(i64, expt + ex_expt);
const half_expt1 = @divTrunc(exptf, 2);
const scale1 = @bitCast(f64, (0x3ff + half_expt1) << 20);
const scale1 = @bitCast(f64, (0x3ff + half_expt1) << (20 + 32));
const half_expt2 = exptf - half_expt1;
const scale2 = @bitCast(f64, (0x3ff + half_expt2) << 20);
const scale2 = @bitCast(f64, (0x3ff + half_expt2) << (20 + 32));
return Complex(f64).init(
math.cos(z.im) * exp_x * scale1 * scale2,

View File

@@ -14,7 +14,7 @@ const math = std.math;
const expect = std.testing.expect;
const maxInt = std.math.maxInt;
/// Returns sqrt(x * x + y * y), avoiding unncessary overflow and underflow.
/// Returns sqrt(x * x + y * y), avoiding unnecessary overflow and underflow.
///
/// Special Cases:
/// - hypot(+-inf, y) = +inf

View File

@@ -39,55 +39,50 @@ pub fn sqrt(x: anytype) Sqrt(@TypeOf(x)) {
}
fn sqrt_int(comptime T: type, value: T) Sqrt(T) {
switch (T) {
u0 => return 0,
u1 => return value,
else => {},
}
if (@typeInfo(T).Int.bits <= 2) {
return if (value == 0) 0 else 1; // shortcut for small number of bits to simplify general case
} else {
var op = value;
var res: T = 0;
var one: T = 1 << ((@typeInfo(T).Int.bits - 1) & -2); // highest power of four that fits into T
var op = value;
var res: T = 0;
var one: T = 1 << (@typeInfo(T).Int.bits - 2);
// "one" starts at the highest power of four <= than the argument.
while (one > op) {
one >>= 2;
}
while (one != 0) {
if (op >= res + one) {
op -= res + one;
res += 2 * one;
// "one" starts at the highest power of four <= than the argument.
while (one > op) {
one >>= 2;
}
res >>= 1;
one >>= 2;
}
const ResultType = Sqrt(T);
return @intCast(ResultType, res);
while (one != 0) {
var c = op >= res + one;
if (c) op -= res + one;
res >>= 1;
if (c) res += one;
one >>= 2;
}
return @intCast(Sqrt(T), res);
}
}
test "math.sqrt_int" {
try expect(sqrt_int(u0, 0) == 0);
try expect(sqrt_int(u1, 1) == 1);
try expect(sqrt_int(u32, 3) == 1);
try expect(sqrt_int(u32, 4) == 2);
try expect(sqrt_int(u32, 5) == 2);
try expect(sqrt_int(u32, 8) == 2);
try expect(sqrt_int(u32, 9) == 3);
try expect(sqrt_int(u32, 10) == 3);
try expect(sqrt_int(u0, 0) == 0);
try expect(sqrt_int(u1, 1) == 1);
try expect(sqrt_int(u2, 3) == 1);
try expect(sqrt_int(u3, 4) == 2);
try expect(sqrt_int(u4, 8) == 2);
try expect(sqrt_int(u4, 9) == 3);
}
/// Returns the return type `sqrt` will return given an operand of type `T`.
pub fn Sqrt(comptime T: type) type {
return switch (@typeInfo(T)) {
.Int => |int| {
return switch (int.bits) {
0 => u0,
1 => u1,
else => std.meta.Int(.unsigned, int.bits / 2),
};
},
.Int => |int| std.meta.Int(.unsigned, (int.bits + 1) / 2),
else => T,
};
}

View File

@@ -37,89 +37,75 @@ fn tanh32(x: f32) f32 {
const u = @bitCast(u32, x);
const ux = u & 0x7FFFFFFF;
const ax = @bitCast(f32, ux);
const sign = (u >> 31) != 0;
var t: f32 = undefined;
if (x == 0.0 or math.isNan(x)) {
return x;
}
// |x| < log(3) / 2 ~= 0.5493 or nan
if (ux > 0x3F0C9F54) {
// |x| > 10
if (ux > 0x41200000) {
t = 1.0;
t = 1.0 + 0 / x;
} else {
t = math.expm1(2 * x);
t = math.expm1(2 * ax);
t = 1 - 2 / (t + 2);
}
}
// |x| > log(5 / 3) / 2 ~= 0.2554
else if (ux > 0x3E82C578) {
t = math.expm1(2 * x);
t = math.expm1(2 * ax);
t = t / (t + 2);
}
// |x| >= 0x1.0p-126
else if (ux >= 0x00800000) {
t = math.expm1(-2 * x);
t = math.expm1(-2 * ax);
t = -t / (t + 2);
}
// |x| is subnormal
else {
math.doNotOptimizeAway(x * x);
t = x;
math.doNotOptimizeAway(ax * ax);
t = ax;
}
if (u >> 31 != 0) {
return -t;
} else {
return t;
}
return if (sign) -t else t;
}
fn tanh64(x: f64) f64 {
const u = @bitCast(u64, x);
const w = @intCast(u32, u >> 32);
const ax = @bitCast(f64, u & (maxInt(u64) >> 1));
const ux = u & 0x7FFFFFFFFFFFFFFF;
const w = @intCast(u32, ux >> 32);
const ax = @bitCast(f64, ux);
const sign = (u >> 63) != 0;
var t: f64 = undefined;
// TODO: Shouldn't need these checks.
if (x == 0.0 or math.isNan(x)) {
return x;
}
// |x| < log(3) / 2 ~= 0.5493 or nan
if (w > 0x3FE193EA) {
// |x| > 20 or nan
if (w > 0x40340000) {
t = 1.0;
t = 1.0 - 0 / ax;
} else {
t = math.expm1(2 * x);
t = math.expm1(2 * ax);
t = 1 - 2 / (t + 2);
}
}
// |x| > log(5 / 3) / 2 ~= 0.2554
else if (w > 0x3FD058AE) {
t = math.expm1(2 * x);
t = math.expm1(2 * ax);
t = t / (t + 2);
}
// |x| >= 0x1.0p-1022
else if (w >= 0x00100000) {
t = math.expm1(-2 * x);
t = math.expm1(-2 * ax);
t = -t / (t + 2);
}
// |x| is subnormal
else {
math.doNotOptimizeAway(@floatCast(f32, x));
t = x;
math.doNotOptimizeAway(@floatCast(f32, ax));
t = ax;
}
if (u >> 63 != 0) {
return -t;
} else {
return t;
}
return if (sign) -t else t;
}
test "math.tanh" {
@@ -135,6 +121,9 @@ test "math.tanh32" {
try expect(math.approxEqAbs(f32, tanh32(0.8923), 0.712528, epsilon));
try expect(math.approxEqAbs(f32, tanh32(1.5), 0.905148, epsilon));
try expect(math.approxEqAbs(f32, tanh32(37.45), 1.0, epsilon));
try expect(math.approxEqAbs(f32, tanh32(-0.8923), -0.712528, epsilon));
try expect(math.approxEqAbs(f32, tanh32(-1.5), -0.905148, epsilon));
try expect(math.approxEqAbs(f32, tanh32(-37.45), -1.0, epsilon));
}
test "math.tanh64" {
@@ -145,6 +134,9 @@ test "math.tanh64" {
try expect(math.approxEqAbs(f64, tanh64(0.8923), 0.712528, epsilon));
try expect(math.approxEqAbs(f64, tanh64(1.5), 0.905148, epsilon));
try expect(math.approxEqAbs(f64, tanh64(37.45), 1.0, epsilon));
try expect(math.approxEqAbs(f64, tanh64(-0.8923), -0.712528, epsilon));
try expect(math.approxEqAbs(f64, tanh64(-1.5), -0.905148, epsilon));
try expect(math.approxEqAbs(f64, tanh64(-37.45), -1.0, epsilon));
}
test "math.tanh32.special" {

View File

@@ -2323,6 +2323,70 @@ pub fn nativeToBig(comptime T: type, x: T) T {
};
}
/// Returns the number of elements that, if added to the given pointer, align it
/// to a multiple of the given quantity, or `null` if one of the following
/// conditions is met:
/// - The aligned pointer would not fit the address space,
/// - The delta required to align the pointer is not a multiple of the pointee's
/// type.
pub fn alignPointerOffset(ptr: anytype, align_to: u29) ?usize {
assert(align_to != 0 and @popCount(u29, align_to) == 1);
const T = @TypeOf(ptr);
const info = @typeInfo(T);
if (info != .Pointer or info.Pointer.size != .Many)
@compileError("expected many item pointer, got " ++ @typeName(T));
// Do nothing if the pointer is already well-aligned.
if (align_to <= info.Pointer.alignment)
return 0;
// Calculate the aligned base address with an eye out for overflow.
const addr = @ptrToInt(ptr);
var new_addr: usize = undefined;
if (@addWithOverflow(usize, addr, align_to - 1, &new_addr)) return null;
new_addr &= ~@as(usize, align_to - 1);
// The delta is expressed in terms of bytes, turn it into a number of child
// type elements.
const delta = new_addr - addr;
const pointee_size = @sizeOf(info.Pointer.child);
if (delta % pointee_size != 0) return null;
return delta / pointee_size;
}
/// Aligns a given pointer value to a specified alignment factor.
/// Returns an aligned pointer or null if one of the following conditions is
/// met:
/// - The aligned pointer would not fit the address space,
/// - The delta required to align the pointer is not a multiple of the pointee's
/// type.
pub fn alignPointer(ptr: anytype, align_to: u29) ?@TypeOf(ptr) {
const adjust_off = alignPointerOffset(ptr, align_to) orelse return null;
const T = @TypeOf(ptr);
// Avoid the use of intToPtr to avoid losing the pointer provenance info.
return @alignCast(@typeInfo(T).Pointer.alignment, ptr + adjust_off);
}
test "alignPointer" {
const S = struct {
fn checkAlign(comptime T: type, base: usize, align_to: u29, expected: usize) !void {
var ptr = @intToPtr(T, base);
var aligned = alignPointer(ptr, align_to);
try testing.expectEqual(expected, @ptrToInt(aligned));
}
};
try S.checkAlign([*]u8, 0x123, 0x200, 0x200);
try S.checkAlign([*]align(4) u8, 0x10, 2, 0x10);
try S.checkAlign([*]u32, 0x10, 2, 0x10);
try S.checkAlign([*]u32, 0x4, 16, 0x10);
// Misaligned.
try S.checkAlign([*]align(1) u32, 0x3, 2, 0);
// Overflow.
try S.checkAlign([*]u32, math.maxInt(usize) - 3, 8, 0);
}
fn CopyPtrAttrs(comptime source: type, comptime size: std.builtin.TypeInfo.Pointer.Size, comptime child: type) type {
const info = @typeInfo(source).Pointer;
return @Type(.{

View File

@@ -582,7 +582,7 @@ pub fn hasUniqueRepresentation(comptime T: type) bool {
return @sizeOf(T) == sum_size;
},
.Vector => |info| return comptime hasUniqueRepresentation(info.child),
.Vector => |info| return comptime hasUniqueRepresentation(info.child) and @sizeOf(T) == @sizeOf(info.child) * info.len,
}
}
@@ -653,4 +653,7 @@ test "std.meta.trait.hasUniqueRepresentation" {
try testing.expect(!hasUniqueRepresentation([]u8));
try testing.expect(!hasUniqueRepresentation([]const u8));
try testing.expect(hasUniqueRepresentation(@Vector(4, u16)));
try testing.expect(!hasUniqueRepresentation(@Vector(3, u16)));
}

View File

@@ -46,8 +46,7 @@ pub fn MultiArrayList(comptime S: type) type {
return &[_]F{};
}
const byte_ptr = self.ptrs[@enumToInt(field)];
const casted_ptr: [*]F = if (@sizeOf([*]F) == 0) undefined
else @ptrCast([*]F, @alignCast(@alignOf(F), byte_ptr));
const casted_ptr: [*]F = if (@sizeOf([*]F) == 0) undefined else @ptrCast([*]F, @alignCast(@alignOf(F), byte_ptr));
return casted_ptr[0..self.len];
}
@@ -197,7 +196,7 @@ pub fn MultiArrayList(comptime S: type) type {
try self.ensureCapacity(gpa, self.len + 1);
self.insertAssumeCapacity(index, elem);
}
/// Inserts an item into an ordered list which has room for it.
/// Shifts all elements after and including the specified index
/// back by one and sets the given index to the specified element.
@@ -209,9 +208,9 @@ pub fn MultiArrayList(comptime S: type) type {
const slices = self.slice();
inline for (fields) |field_info, field_index| {
const field_slice = slices.items(@intToEnum(Field, field_index));
var i: usize = self.len-1;
var i: usize = self.len - 1;
while (i > index) : (i -= 1) {
field_slice[i] = field_slice[i-1];
field_slice[i] = field_slice[i - 1];
}
field_slice[index] = @field(elem, field_info.name);
}
@@ -224,8 +223,8 @@ pub fn MultiArrayList(comptime S: type) type {
const slices = self.slice();
inline for (fields) |field_info, i| {
const field_slice = slices.items(@intToEnum(Field, i));
field_slice[index] = field_slice[self.len-1];
field_slice[self.len-1] = undefined;
field_slice[index] = field_slice[self.len - 1];
field_slice[self.len - 1] = undefined;
}
self.len -= 1;
}
@@ -237,8 +236,8 @@ pub fn MultiArrayList(comptime S: type) type {
inline for (fields) |field_info, field_index| {
const field_slice = slices.items(@intToEnum(Field, field_index));
var i = index;
while (i < self.len-1) : (i += 1) {
field_slice[i] = field_slice[i+1];
while (i < self.len - 1) : (i += 1) {
field_slice[i] = field_slice[i + 1];
}
field_slice[i] = undefined;
}

View File

@@ -3435,10 +3435,10 @@ pub const WaitPidResult = struct {
};
pub fn waitpid(pid: pid_t, flags: u32) WaitPidResult {
const Status = if (builtin.link_libc) c_uint else u32;
const Status = if (builtin.link_libc) c_int else u32;
var status: Status = undefined;
while (true) {
const rc = system.waitpid(pid, &status, flags);
const rc = system.waitpid(pid, &status, if (builtin.link_libc) @intCast(c_int, flags) else flags);
switch (errno(rc)) {
0 => return .{
.pid = @intCast(pid_t, rc),
@@ -3652,6 +3652,7 @@ pub const INotifyAddWatchError = error{
FileNotFound,
SystemResources,
UserResourceLimitReached,
NotDir,
} || UnexpectedError;
/// add a watch to an initialized inotify instance
@@ -3675,6 +3676,7 @@ pub fn inotify_add_watchZ(inotify_fd: i32, pathname: [*:0]const u8, mask: u32) I
ENOENT => return error.FileNotFound,
ENOMEM => return error.SystemResources,
ENOSPC => return error.UserResourceLimitReached,
ENOTDIR => return error.NotDir,
else => |err| return unexpectedErrno(err),
}
}
@@ -5532,10 +5534,7 @@ pub const CopyFileRangeError = error{
FileBusy,
} || PReadError || PWriteError || UnexpectedError;
var has_copy_file_range_syscall = init: {
const kernel_has_syscall = std.Target.current.os.isAtLeast(.linux, .{ .major = 4, .minor = 5 }) orelse true;
break :init std.atomic.Atomic(bool).init(kernel_has_syscall);
};
var has_copy_file_range_syscall = std.atomic.Atomic(bool).init(true);
/// Transfer data between file descriptors at specified offsets.
/// Returns the number of bytes written, which can less than requested.
@@ -5563,18 +5562,17 @@ var has_copy_file_range_syscall = init: {
///
/// Maximum offsets on Linux are `math.maxInt(i64)`.
pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len: usize, flags: u32) CopyFileRangeError!usize {
const use_c = std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 }).ok;
if (std.Target.current.os.tag == .linux and
(use_c or has_copy_file_range_syscall.load(.Monotonic)))
{
const sys = if (use_c) std.c else linux;
const call_cfr = comptime if (builtin.link_libc)
std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 }).ok
else
std.Target.current.os.isAtLeast(.linux, .{ .major = 4, .minor = 5 }) orelse true;
if (call_cfr and has_copy_file_range_syscall.load(.Monotonic)) {
var off_in_copy = @bitCast(i64, off_in);
var off_out_copy = @bitCast(i64, off_out);
const rc = sys.copy_file_range(fd_in, &off_in_copy, fd_out, &off_out_copy, len, flags);
switch (sys.getErrno(rc)) {
const rc = system.copy_file_range(fd_in, &off_in_copy, fd_out, &off_out_copy, len, flags);
switch (system.getErrno(rc)) {
0 => return @intCast(usize, rc),
EBADF => return error.FilesOpenedWithWrongFlags,
EFBIG => return error.FileTooBig,
@@ -5591,7 +5589,7 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len
EXDEV => {},
// syscall added in Linux 4.5, use fallback
ENOSYS => {
has_copy_file_range_syscall.store(true, .Monotonic);
has_copy_file_range_syscall.store(false, .Monotonic);
},
else => |err| return unexpectedErrno(err),
}
@@ -6121,7 +6119,7 @@ pub fn getrlimit(resource: rlimit_resource) GetrlimitError!rlimit {
}
}
pub const SetrlimitError = error{PermissionDenied, LimitTooBig} || UnexpectedError;
pub const SetrlimitError = error{ PermissionDenied, LimitTooBig } || UnexpectedError;
pub fn setrlimit(resource: rlimit_resource, limits: rlimit) SetrlimitError!void {
const setrlimit_sym = if (builtin.os.tag == .linux and builtin.link_libc)

View File

@@ -345,7 +345,7 @@ pub fn WIFEXITED(s: u32) bool {
return WTERMSIG(s) == 0;
}
pub fn WIFSTOPPED(s: u32) bool {
return @intCast(u16, (((s & 0xffff) *% 0x10001) >> 8)) > 0x7f00;
return @truncate(u16, (((s & 0xffff) *% 0x10001) >> 8)) > 0x7f00;
}
pub fn WIFSIGNALED(s: u32) bool {
return (s & 0xffff) -% 1 < 0xff;

View File

@@ -742,7 +742,7 @@ pub fn WIFEXITED(s: u32) bool {
return WTERMSIG(s) == 0;
}
pub fn WIFSTOPPED(s: u32) bool {
return @intCast(u16, (((s & 0xffff) *% 0x10001) >> 8)) > 0x7f00;
return @truncate(u16, (((s & 0xffff) *% 0x10001) >> 8)) > 0x7f00;
}
pub fn WIFSIGNALED(s: u32) bool {
return (s & 0xffff) -% 1 < 0xff;

View File

@@ -203,6 +203,15 @@ pub const WEXITED = 4;
pub const WCONTINUED = 8;
pub const WNOWAIT = 0x1000000;
// waitid id types
pub const P = enum(c_uint) {
ALL = 0,
PID = 1,
PGID = 2,
PIDFD = 3,
_,
};
pub usingnamespace if (is_mips)
struct {
pub const SA_NOCLDSTOP = 1;
@@ -329,19 +338,19 @@ pub const O_RDWR = 0o2;
pub const kernel_rwf = u32;
/// high priority request, poll if possible
pub const RWF_HIPRI = kernel_rwf(0x00000001);
pub const RWF_HIPRI: kernel_rwf = 0x00000001;
/// per-IO O_DSYNC
pub const RWF_DSYNC = kernel_rwf(0x00000002);
pub const RWF_DSYNC: kernel_rwf = 0x00000002;
/// per-IO O_SYNC
pub const RWF_SYNC = kernel_rwf(0x00000004);
pub const RWF_SYNC: kernel_rwf = 0x00000004;
/// per-IO, return -EAGAIN if operation would block
pub const RWF_NOWAIT = kernel_rwf(0x00000008);
pub const RWF_NOWAIT: kernel_rwf = 0x00000008;
/// per-IO O_APPEND
pub const RWF_APPEND = kernel_rwf(0x00000010);
pub const RWF_APPEND: kernel_rwf = 0x00000010;
pub const SEEK_SET = 0;
pub const SEEK_CUR = 1;
@@ -1052,7 +1061,7 @@ pub fn WIFEXITED(s: u32) bool {
return WTERMSIG(s) == 0;
}
pub fn WIFSTOPPED(s: u32) bool {
return @intCast(u16, ((s & 0xffff) *% 0x10001) >> 8) > 0x7f00;
return @truncate(u16, ((s & 0xffff) *% 0x10001) >> 8) > 0x7f00;
}
pub fn WIFSIGNALED(s: u32) bool {
return (s & 0xffff) -% 1 < 0xff;

View File

@@ -34,6 +34,17 @@ pub const Kevent = extern struct {
udata: usize,
};
pub const RTLD_LAZY = 1;
pub const RTLD_NOW = 2;
pub const RTLD_GLOBAL = 0x100;
pub const RTLD_LOCAL = 0x200;
pub const RTLD_NODELETE = 0x01000;
pub const RTLD_NOLOAD = 0x02000;
pub const RTLD_NEXT = @intToPtr(*c_void, @bitCast(usize, @as(isize, -1)));
pub const RTLD_DEFAULT = @intToPtr(*c_void, @bitCast(usize, @as(isize, -2)));
pub const RTLD_SELF = @intToPtr(*c_void, @bitCast(usize, @as(isize, -3)));
pub const dl_phdr_info = extern struct {
dlpi_addr: usize,
dlpi_name: ?[*:0]const u8,
@@ -212,6 +223,121 @@ pub const dirent = extern struct {
}
};
pub const SOCK_STREAM = 1;
pub const SOCK_DGRAM = 2;
pub const SOCK_RAW = 3;
pub const SOCK_RDM = 4;
pub const SOCK_SEQPACKET = 5;
pub const SOCK_CONN_DGRAM = 6;
pub const SOCK_DCCP = SOCK_CONN_DGRAM;
pub const SOCK_CLOEXEC = 0x10000000;
pub const SOCK_NONBLOCK = 0x20000000;
pub const SOCK_NOSIGPIPE = 0x40000000;
pub const SOCK_FLAGS_MASK = 0xf0000000;
pub const SO_DEBUG = 0x0001;
pub const SO_ACCEPTCONN = 0x0002;
pub const SO_REUSEADDR = 0x0004;
pub const SO_KEEPALIVE = 0x0008;
pub const SO_DONTROUTE = 0x0010;
pub const SO_BROADCAST = 0x0020;
pub const SO_USELOOPBACK = 0x0040;
pub const SO_LINGER = 0x0080;
pub const SO_OOBINLINE = 0x0100;
pub const SO_REUSEPORT = 0x0200;
pub const SO_NOSIGPIPE = 0x0800;
pub const SO_ACCEPTFILTER = 0x1000;
pub const SO_TIMESTAMP = 0x2000;
pub const SO_RERROR = 0x4000;
pub const SO_SNDBUF = 0x1001;
pub const SO_RCVBUF = 0x1002;
pub const SO_SNDLOWAT = 0x1003;
pub const SO_RCVLOWAT = 0x1004;
pub const SO_ERROR = 0x1007;
pub const SO_TYPE = 0x1008;
pub const SO_OVERFLOWED = 0x1009;
pub const SO_NOHEADER = 0x100a;
pub const SO_SNDTIMEO = 0x100b;
pub const SO_RCVTIMEO = 0x100c;
pub const SOL_SOCKET = 0xffff;
pub const PF_UNSPEC = AF_UNSPEC;
pub const PF_LOCAL = AF_LOCAL;
pub const PF_UNIX = PF_LOCAL;
pub const PF_INET = AF_INET;
pub const PF_IMPLINK = AF_IMPLINK;
pub const PF_PUP = AF_PUP;
pub const PF_CHAOS = AF_CHAOS;
pub const PF_NS = AF_NS;
pub const PF_ISO = AF_ISO;
pub const PF_OSI = AF_ISO;
pub const PF_ECMA = AF_ECMA;
pub const PF_DATAKIT = AF_DATAKIT;
pub const PF_CCITT = AF_CCITT;
pub const PF_SNA = AF_SNA;
pub const PF_DECnet = AF_DECnet;
pub const PF_DLI = AF_DLI;
pub const PF_LAT = AF_LAT;
pub const PF_HYLINK = AF_HYLINK;
pub const PF_APPLETALK = AF_APPLETALK;
pub const PF_OROUTE = AF_OROUTE;
pub const PF_LINK = AF_LINK;
pub const PF_COIP = AF_COIP;
pub const PF_CNT = AF_CNT;
pub const PF_INET6 = AF_INET6;
pub const PF_IPX = AF_IPX;
pub const PF_ISDN = AF_ISDN;
pub const PF_E164 = AF_E164;
pub const PF_NATM = AF_NATM;
pub const PF_ARP = AF_ARP;
pub const PF_BLUETOOTH = AF_BLUETOOTH;
pub const PF_MPLS = AF_MPLS;
pub const PF_ROUTE = AF_ROUTE;
pub const PF_CAN = AF_CAN;
pub const PF_ETHER = AF_ETHER;
pub const PF_MAX = AF_MAX;
pub const AF_UNSPEC = 0;
pub const AF_LOCAL = 1;
pub const AF_UNIX = AF_LOCAL;
pub const AF_INET = 2;
pub const AF_IMPLINK = 3;
pub const AF_PUP = 4;
pub const AF_CHAOS = 5;
pub const AF_NS = 6;
pub const AF_ISO = 7;
pub const AF_OSI = AF_ISO;
pub const AF_ECMA = 8;
pub const AF_DATAKIT = 9;
pub const AF_CCITT = 10;
pub const AF_SNA = 11;
pub const AF_DECnet = 12;
pub const AF_DLI = 13;
pub const AF_LAT = 14;
pub const AF_HYLINK = 15;
pub const AF_APPLETALK = 16;
pub const AF_OROUTE = 17;
pub const AF_LINK = 18;
pub const AF_COIP = 20;
pub const AF_CNT = 21;
pub const AF_IPX = 23;
pub const AF_INET6 = 24;
pub const AF_ISDN = 26;
pub const AF_E164 = AF_ISDN;
pub const AF_NATM = 27;
pub const AF_ARP = 28;
pub const AF_BLUETOOTH = 31;
pub const AF_IEEE80211 = 32;
pub const AF_MPLS = 33;
pub const AF_ROUTE = 34;
pub const AF_CAN = 35;
pub const AF_ETHER = 36;
pub const AF_MAX = 37;
pub const in_port_t = u16;
pub const sa_family_t = u8;
@@ -471,48 +597,6 @@ pub const SIG_BLOCK = 1;
pub const SIG_UNBLOCK = 2;
pub const SIG_SETMASK = 3;
pub const SOCK_STREAM = 1;
pub const SOCK_DGRAM = 2;
pub const SOCK_RAW = 3;
pub const SOCK_RDM = 4;
pub const SOCK_SEQPACKET = 5;
pub const SOCK_CLOEXEC = 0x10000000;
pub const SOCK_NONBLOCK = 0x20000000;
pub const PF_UNSPEC = 0;
pub const PF_LOCAL = 1;
pub const PF_UNIX = PF_LOCAL;
pub const PF_FILE = PF_LOCAL;
pub const PF_INET = 2;
pub const PF_APPLETALK = 16;
pub const PF_INET6 = 24;
pub const PF_DECnet = 12;
pub const PF_KEY = 29;
pub const PF_ROUTE = 34;
pub const PF_SNA = 11;
pub const PF_MPLS = 33;
pub const PF_CAN = 35;
pub const PF_BLUETOOTH = 31;
pub const PF_ISDN = 26;
pub const PF_MAX = 37;
pub const AF_UNSPEC = PF_UNSPEC;
pub const AF_LOCAL = PF_LOCAL;
pub const AF_UNIX = AF_LOCAL;
pub const AF_FILE = AF_LOCAL;
pub const AF_INET = PF_INET;
pub const AF_APPLETALK = PF_APPLETALK;
pub const AF_INET6 = PF_INET6;
pub const AF_KEY = PF_KEY;
pub const AF_ROUTE = PF_ROUTE;
pub const AF_SNA = PF_SNA;
pub const AF_MPLS = PF_MPLS;
pub const AF_CAN = PF_CAN;
pub const AF_BLUETOOTH = PF_BLUETOOTH;
pub const AF_ISDN = PF_ISDN;
pub const AF_MAX = PF_MAX;
pub const DT_UNKNOWN = 0;
pub const DT_FIFO = 1;
pub const DT_CHR = 2;

View File

@@ -34,6 +34,7 @@ pub usingnamespace switch (native_arch) {
};
pub usingnamespace @import("bits.zig");
pub const tls = @import("linux/tls.zig");
pub const pie = @import("linux/start_pie.zig");
pub const BPF = @import("linux/bpf.zig");
pub usingnamespace @import("linux/io_uring.zig");
@@ -704,6 +705,10 @@ pub fn waitpid(pid: pid_t, status: *u32, flags: u32) usize {
return syscall4(.wait4, @bitCast(usize, @as(isize, pid)), @ptrToInt(status), flags, 0);
}
pub fn waitid(id_type: P, id: i32, infop: *siginfo_t, flags: u32) usize {
return syscall5(.waitid, @enumToInt(id_type), @bitCast(usize, @as(isize, id)), @ptrToInt(infop), flags, 0);
}
pub fn fcntl(fd: fd_t, cmd: i32, arg: usize) usize {
return syscall3(.fcntl, @bitCast(usize, @as(isize, fd)), @bitCast(usize, @as(isize, cmd)), arg);
}

View File

@@ -1513,7 +1513,7 @@ pub fn map_create(map_type: MapType, key_size: u32, value_size: u32, max_entries
EINVAL => error.MapTypeOrAttrInvalid,
ENOMEM => error.SystemResources,
EPERM => error.AccessDenied,
else => |err| unexpectedErrno(rc),
else => |err| unexpectedErrno(err),
};
}
@@ -1539,7 +1539,7 @@ pub fn map_lookup_elem(fd: fd_t, key: []const u8, value: []u8) !void {
EINVAL => return error.FieldInAttrNeedsZeroing,
ENOENT => return error.NotFound,
EPERM => return error.AccessDenied,
else => |err| return unexpectedErrno(rc),
else => |err| return unexpectedErrno(err),
}
}

View File

@@ -148,10 +148,10 @@ pub const ringbuf_reserve = @intToPtr(fn (ringbuf: ?*c_void, size: u64, flags: u
pub const ringbuf_submit = @intToPtr(fn (data: ?*c_void, flags: u64) void, 132);
pub const ringbuf_discard = @intToPtr(fn (data: ?*c_void, flags: u64) void, 133);
pub const ringbuf_query = @intToPtr(fn (ringbuf: ?*c_void, flags: u64) u64, 134);
pub const csum_level = @intToPtr(fn (skb: *kern.SkBuff, level: u64) c_long, 134);
pub const skc_to_tcp6_sock = @intToPtr(fn (sk: ?*c_void) ?*kern.Tcp6Sock, 135);
pub const skc_to_tcp_sock = @intToPtr(fn (sk: ?*c_void) ?*kern.TcpSock, 136);
pub const skc_to_tcp_timewait_sock = @intToPtr(fn (sk: ?*c_void) ?*kern.TcpTimewaitSock, 137);
pub const skc_to_tcp_request_sock = @intToPtr(fn (sk: ?*c_void) ?*kern.TcpRequestSock, 138);
pub const skc_to_udp6_sock = @intToPtr(fn (sk: ?*c_void) ?*kern.Udp6Sock, 139);
pub const get_task_stack = @intToPtr(fn (task: ?*c_void, buf: ?*c_void, size: u32, flags: u64) c_long, 140);
pub const csum_level = @intToPtr(fn (skb: *kern.SkBuff, level: u64) c_long, 135);
pub const skc_to_tcp6_sock = @intToPtr(fn (sk: ?*c_void) ?*kern.Tcp6Sock, 136);
pub const skc_to_tcp_sock = @intToPtr(fn (sk: ?*c_void) ?*kern.TcpSock, 137);
pub const skc_to_tcp_timewait_sock = @intToPtr(fn (sk: ?*c_void) ?*kern.TcpTimewaitSock, 138);
pub const skc_to_tcp_request_sock = @intToPtr(fn (sk: ?*c_void) ?*kern.TcpRequestSock, 139);
pub const skc_to_udp6_sock = @intToPtr(fn (sk: ?*c_void) ?*kern.Udp6Sock, 140);
pub const get_task_stack = @intToPtr(fn (task: ?*c_void, buf: ?*c_void, size: u32, flags: u64) c_long, 141);

View File

@@ -31,7 +31,8 @@ pub fn syscall_pipe(fd: *[2]i32) usize {
\\ sw $3, 4($4)
\\ 2:
: [ret] "={$2}" (-> usize)
: [number] "{$2}" (@enumToInt(SYS.pipe))
: [number] "{$2}" (@enumToInt(SYS.pipe)),
[fd] "{$4}" (fd)
: "memory", "cc", "$7"
);
}

View File

@@ -8,33 +8,35 @@ const R_386_RELATIVE = 8;
const R_ARM_RELATIVE = 23;
const R_AARCH64_RELATIVE = 1027;
const R_RISCV_RELATIVE = 3;
const R_SPARC_RELATIVE = 22;
const ARCH_RELATIVE_RELOC = switch (builtin.cpu.arch) {
const R_RELATIVE = switch (builtin.cpu.arch) {
.i386 => R_386_RELATIVE,
.x86_64 => R_AMD64_RELATIVE,
.arm => R_ARM_RELATIVE,
.aarch64 => R_AARCH64_RELATIVE,
.riscv64 => R_RISCV_RELATIVE,
else => @compileError("unsupported architecture"),
else => @compileError("Missing R_RELATIVE definition for this target"),
};
// Just a convoluted (but necessary) way to obtain the address of the _DYNAMIC[]
// vector as PC-relative so that we can use it before any relocation is applied
// Obtain a pointer to the _DYNAMIC array.
// We have to compute its address as a PC-relative quantity not to require a
// relocation that, at this point, is not yet applied.
fn getDynamicSymbol() [*]elf.Dyn {
const addr = switch (builtin.cpu.arch) {
return switch (builtin.cpu.arch) {
.i386 => asm volatile (
\\ .weak _DYNAMIC
\\ .hidden _DYNAMIC
\\ call 1f
\\ 1: pop %[ret]
\\ lea _DYNAMIC-1b(%[ret]), %[ret]
: [ret] "=r" (-> usize)
: [ret] "=r" (-> [*]elf.Dyn)
),
.x86_64 => asm volatile (
\\ .weak _DYNAMIC
\\ .hidden _DYNAMIC
\\ lea _DYNAMIC(%%rip), %[ret]
: [ret] "=r" (-> usize)
: [ret] "=r" (-> [*]elf.Dyn)
),
// Work around the limited offset range of `ldr`
.arm => asm volatile (
@@ -45,7 +47,7 @@ fn getDynamicSymbol() [*]elf.Dyn {
\\ b 2f
\\ 1: .word _DYNAMIC-1b
\\ 2:
: [ret] "=r" (-> usize)
: [ret] "=r" (-> [*]elf.Dyn)
),
// A simple `adr` is not enough as it has a limited offset range
.aarch64 => asm volatile (
@@ -53,61 +55,39 @@ fn getDynamicSymbol() [*]elf.Dyn {
\\ .hidden _DYNAMIC
\\ adrp %[ret], _DYNAMIC
\\ add %[ret], %[ret], #:lo12:_DYNAMIC
: [ret] "=r" (-> usize)
: [ret] "=r" (-> [*]elf.Dyn)
),
.riscv64 => asm volatile (
\\ .weak _DYNAMIC
\\ .hidden _DYNAMIC
\\ lla %[ret], _DYNAMIC
: [ret] "=r" (-> usize)
: [ret] "=r" (-> [*]elf.Dyn)
),
else => @compileError("???"),
else => {
@compileError("PIE startup is not yet supported for this target!");
},
};
return @intToPtr([*]elf.Dyn, addr);
}
pub fn apply_relocations() void {
pub fn relocate(phdrs: []elf.Phdr) void {
@setRuntimeSafety(false);
const dynv = getDynamicSymbol();
const auxv = std.os.linux.elf_aux_maybe.?;
var at_phent: usize = undefined;
var at_phnum: usize = undefined;
var at_phdr: usize = undefined;
var at_hwcap: usize = undefined;
{
var i: usize = 0;
while (auxv[i].a_type != std.elf.AT_NULL) : (i += 1) {
switch (auxv[i].a_type) {
elf.AT_PHENT => at_phent = auxv[i].a_un.a_val,
elf.AT_PHNUM => at_phnum = auxv[i].a_un.a_val,
elf.AT_PHDR => at_phdr = auxv[i].a_un.a_val,
else => continue,
}
}
}
// Sanity check
assert(at_phent == @sizeOf(elf.Phdr));
// Search the TLS section
const phdrs = (@intToPtr([*]elf.Phdr, at_phdr))[0..at_phnum];
const base_addr = blk: {
// Recover the delta applied by the loader by comparing the effective and
// the theoretical load addresses for the `_DYNAMIC` symbol.
const base_addr = base: {
for (phdrs) |*phdr| {
if (phdr.p_type == elf.PT_DYNAMIC) {
break :blk @ptrToInt(&dynv[0]) - phdr.p_vaddr;
}
if (phdr.p_type != elf.PT_DYNAMIC) continue;
break :base @ptrToInt(dynv) - phdr.p_vaddr;
}
unreachable;
// This is not supposed to happen for well-formed binaries.
std.os.abort();
};
var rel_addr: usize = 0;
var rela_addr: usize = 0;
var rel_size: usize = 0;
var rela_size: usize = 0;
{
var i: usize = 0;
while (dynv[i].d_tag != elf.DT_NULL) : (i += 1) {
@@ -121,18 +101,18 @@ pub fn apply_relocations() void {
}
}
// Perform the relocations
// Apply the relocations.
if (rel_addr != 0) {
const rel = std.mem.bytesAsSlice(elf.Rel, @intToPtr([*]u8, rel_addr)[0..rel_size]);
for (rel) |r| {
if (r.r_type() != ARCH_RELATIVE_RELOC) continue;
if (r.r_type() != R_RELATIVE) continue;
@intToPtr(*usize, base_addr + r.r_offset).* += base_addr;
}
}
if (rela_addr != 0) {
const rela = std.mem.bytesAsSlice(elf.Rela, @intToPtr([*]u8, rela_addr)[0..rela_size]);
for (rela) |r| {
if (r.r_type() != ARCH_RELATIVE_RELOC) continue;
if (r.r_type() != R_RELATIVE) continue;
@intToPtr(*usize, base_addr + r.r_offset).* += base_addr + @bitCast(usize, r.r_addend);
}
}

Some files were not shown because too many files have changed in this diff Show More