Compare commits
95 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d44a6222d | ||
|
|
be097cdba8 | ||
|
|
9f6b9850ac | ||
|
|
f9af406341 | ||
|
|
8bf14231b2 | ||
|
|
d2398cf009 | ||
|
|
0d006afb23 | ||
|
|
bf6af1963c | ||
|
|
45d4e2f816 | ||
|
|
46c3d9c571 | ||
|
|
c4458e1b45 | ||
|
|
fbde43524f | ||
|
|
8e10c80c5f | ||
|
|
a8bd36c3d2 | ||
|
|
2e95bb0e29 | ||
|
|
3c40cf1693 | ||
|
|
5cfc22bd36 | ||
|
|
a418c59546 | ||
|
|
a0cd4c0f32 | ||
|
|
d107ef8697 | ||
|
|
cee0f082df | ||
|
|
23d148e5c7 | ||
|
|
eace6906ce | ||
|
|
ac3ac255a2 | ||
|
|
69f46cab55 | ||
|
|
452c35656e | ||
|
|
a24f4d8da4 | ||
|
|
5762b6d218 | ||
|
|
8b5e4af78e | ||
|
|
aad6ef1fc3 | ||
|
|
b54f6186ac | ||
|
|
e2f36c292e | ||
|
|
e9d916571a | ||
|
|
021c1190af | ||
|
|
45cd1114f7 | ||
|
|
d7feeaaa2c | ||
|
|
2b29424efd | ||
|
|
8f89056dc2 | ||
|
|
e8c4fec1b2 | ||
|
|
ac3d9759ed | ||
|
|
922d33e5b9 | ||
|
|
936294e32a | ||
|
|
7e61bdbaa4 | ||
|
|
340bb8198f | ||
|
|
e37c55bae0 | ||
|
|
93545fe74f | ||
|
|
8ed432fe3c | ||
|
|
148b963a60 | ||
|
|
b713ce0249 | ||
|
|
4d5a598599 | ||
|
|
aa8112c847 | ||
|
|
3d52a322ab | ||
|
|
af844d865f | ||
|
|
252fb642d5 | ||
|
|
dcbab17b62 | ||
|
|
881e507ac5 | ||
|
|
18fabd99cc | ||
|
|
afd1f7ed47 | ||
|
|
2ac7aefe2f | ||
|
|
bb9399cc5d | ||
|
|
bc90a2a083 | ||
|
|
1e6de105c8 | ||
|
|
385b7e4808 | ||
|
|
57d7ad9172 | ||
|
|
e67e15a29a | ||
|
|
06ae13fe35 | ||
|
|
dafbc6eb25 | ||
|
|
6f49233ac6 | ||
|
|
bb8eef8d24 | ||
|
|
511990c83b | ||
|
|
9fa55ae777 | ||
|
|
53e41682ba | ||
|
|
3542dcad33 | ||
|
|
9b97edb012 | ||
|
|
1c61038255 | ||
|
|
73cbc13a97 | ||
|
|
adf7c654d4 | ||
|
|
2304dbaba4 | ||
|
|
675590cd44 | ||
|
|
4d38f456ea | ||
|
|
8771ef897a | ||
|
|
1676729c66 | ||
|
|
eee395287f | ||
|
|
419499b252 | ||
|
|
47e3deeeaa | ||
|
|
c4b4192d20 | ||
|
|
64a2b14f26 | ||
|
|
9a0010b186 | ||
|
|
b86aadfa38 | ||
|
|
4d9377923d | ||
|
|
cfc00e743e | ||
|
|
f5cb3fc688 | ||
|
|
acdb859644 | ||
|
|
20f073dcdd | ||
|
|
69e2b712bc |
@@ -26,7 +26,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
|
|||||||
|
|
||||||
set(ZIG_VERSION_MAJOR 0)
|
set(ZIG_VERSION_MAJOR 0)
|
||||||
set(ZIG_VERSION_MINOR 9)
|
set(ZIG_VERSION_MINOR 9)
|
||||||
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.")
|
set(ZIG_VERSION "" CACHE STRING "Override Zig version string. Default is to find out with git.")
|
||||||
|
|
||||||
if("${ZIG_VERSION}" STREQUAL "")
|
if("${ZIG_VERSION}" STREQUAL "")
|
||||||
@@ -787,7 +787,7 @@ else()
|
|||||||
set(ZIG1_RELEASE_ARG -OReleaseFast --strip)
|
set(ZIG1_RELEASE_ARG -OReleaseFast --strip)
|
||||||
endif()
|
endif()
|
||||||
if(ZIG_SINGLE_THREADED)
|
if(ZIG_SINGLE_THREADED)
|
||||||
set(ZIG1_SINGLE_THREADED_ARG "--single-threaded")
|
set(ZIG1_SINGLE_THREADED_ARG "-fsingle-threaded")
|
||||||
else()
|
else()
|
||||||
set(ZIG1_SINGLE_THREADED_ARG "")
|
set(ZIG1_SINGLE_THREADED_ARG "")
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
One of the best ways you can contribute to Zig is to start using it for a
|
One of the best ways you can contribute to Zig is to start using it for a
|
||||||
personal project. Here are some great examples:
|
personal project. Here are some great examples:
|
||||||
|
|
||||||
* [Oxid](https://github.com/dbandstra/oxid) - arcade style game
|
|
||||||
* [TM35-Metronome](https://github.com/TM35-Metronome) - tools for modifying and randomizing Pokémon games
|
* [TM35-Metronome](https://github.com/TM35-Metronome) - tools for modifying and randomizing Pokémon games
|
||||||
* [River](https://github.com/ifreund/river/) - a dynamic tiling wayland compositor
|
* [River](https://github.com/ifreund/river/) - a dynamic tiling wayland compositor
|
||||||
|
|
||||||
|
|||||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
|||||||
The MIT License (Expat)
|
The MIT License (Expat)
|
||||||
|
|
||||||
Copyright (c) 2015-2021, Zig contributors
|
Copyright (c) 2015-2022, Zig contributors
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||

|

|
||||||
|
|
||||||
A general-purpose programming language and toolchain for maintaining
|
A general-purpose programming language and toolchain for maintaining
|
||||||
**robust**, **optimal**, and **reusable** software.
|
**robust**, **optimal**, and **reusable** software.
|
||||||
|
|||||||
@@ -10,13 +10,13 @@ const fs = std.fs;
|
|||||||
const InstallDirectoryOptions = std.build.InstallDirectoryOptions;
|
const InstallDirectoryOptions = std.build.InstallDirectoryOptions;
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
|
|
||||||
const zig_version = std.builtin.Version{ .major = 0, .minor = 9, .patch = 0 };
|
const zig_version = std.builtin.Version{ .major = 0, .minor = 9, .patch = 1 };
|
||||||
|
|
||||||
pub fn build(b: *Builder) !void {
|
pub fn build(b: *Builder) !void {
|
||||||
b.setPreferredReleaseMode(.ReleaseFast);
|
b.setPreferredReleaseMode(.ReleaseFast);
|
||||||
const mode = b.standardReleaseOptions();
|
const mode = b.standardReleaseOptions();
|
||||||
const target = b.standardTargetOptions(.{});
|
const target = b.standardTargetOptions(.{});
|
||||||
const single_threaded = b.option(bool, "single-threaded", "Build artifacts that run in single threaded mode") orelse false;
|
const single_threaded = b.option(bool, "single-threaded", "Build artifacts that run in single threaded mode");
|
||||||
const use_zig_libcxx = b.option(bool, "use-zig-libcxx", "If libc++ is needed, use zig's bundled version, don't try to integrate with the system") orelse false;
|
const use_zig_libcxx = b.option(bool, "use-zig-libcxx", "If libc++ is needed, use zig's bundled version, don't try to integrate with the system") orelse false;
|
||||||
|
|
||||||
var docgen_exe = b.addExecutable("docgen", "doc/docgen.zig");
|
var docgen_exe = b.addExecutable("docgen", "doc/docgen.zig");
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ jobs:
|
|||||||
timeoutInMinutes: 360
|
timeoutInMinutes: 360
|
||||||
steps:
|
steps:
|
||||||
- powershell: |
|
- powershell: |
|
||||||
(New-Object Net.WebClient).DownloadFile("https://github.com/msys2/msys2-installer/releases/download/2021-07-25/msys2-base-x86_64-20210725.sfx.exe", "sfx.exe")
|
(New-Object Net.WebClient).DownloadFile("https://github.com/msys2/msys2-installer/releases/download/2022-01-28/msys2-base-x86_64-20220128.sfx.exe", "sfx.exe")
|
||||||
.\sfx.exe -y -o\
|
.\sfx.exe -y -o\
|
||||||
displayName: Download/Extract/Install MSYS2
|
displayName: Download/Extract/Install MSYS2
|
||||||
- script: |
|
- script: |
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ else()
|
|||||||
FIND_AND_ADD_LLD_LIB(lldELF)
|
FIND_AND_ADD_LLD_LIB(lldELF)
|
||||||
FIND_AND_ADD_LLD_LIB(lldCOFF)
|
FIND_AND_ADD_LLD_LIB(lldCOFF)
|
||||||
FIND_AND_ADD_LLD_LIB(lldWasm)
|
FIND_AND_ADD_LLD_LIB(lldWasm)
|
||||||
|
FIND_AND_ADD_LLD_LIB(lldMachO)
|
||||||
FIND_AND_ADD_LLD_LIB(lldReaderWriter)
|
FIND_AND_ADD_LLD_LIB(lldReaderWriter)
|
||||||
FIND_AND_ADD_LLD_LIB(lldCore)
|
FIND_AND_ADD_LLD_LIB(lldCore)
|
||||||
FIND_AND_ADD_LLD_LIB(lldYAML)
|
FIND_AND_ADD_LLD_LIB(lldYAML)
|
||||||
|
|||||||
@@ -1290,13 +1290,39 @@ test "expectError demo" {
|
|||||||
A variable is a unit of {#link|Memory#} storage.
|
A variable is a unit of {#link|Memory#} storage.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Variables are never allowed to shadow identifiers from an outer scope.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
It is generally preferable to use {#syntax#}const{#endsyntax#} rather than
|
It is generally preferable to use {#syntax#}const{#endsyntax#} rather than
|
||||||
{#syntax#}var{#endsyntax#} when declaring a variable. This causes less work for both
|
{#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.
|
humans and computers to do when reading code, and creates more optimization opportunities.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
{#header_open|Identifiers#}
|
||||||
|
<p>
|
||||||
|
Variable identifiers are never allowed to shadow identifiers from an outer scope.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Identifiers must start with an alphabetic character or underscore and may be followed
|
||||||
|
by any number of alphanumeric characters or underscores.
|
||||||
|
They must not overlap with any keywords. See {#link|Keyword Reference#}.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
If a name that does not fit these requirements is needed, such as for linking with external libraries, the {#syntax#}@""{#endsyntax#} syntax may be used.
|
||||||
|
</p>
|
||||||
|
{#code_begin|syntax#}
|
||||||
|
const @"identifier with spaces in it" = 0xff;
|
||||||
|
const @"1SmallStep4Man" = 112358;
|
||||||
|
|
||||||
|
const c = @import("std").c;
|
||||||
|
pub extern "c" fn @"error"() anyopaque;
|
||||||
|
pub extern "c" fn @"fstat$INODE64"(fd: c.fd_t, buf: *c.Stat) c_int;
|
||||||
|
|
||||||
|
const Color = enum {
|
||||||
|
red,
|
||||||
|
@"really red",
|
||||||
|
};
|
||||||
|
const color: Color = .@"really red";
|
||||||
|
{#code_end#}
|
||||||
|
{#header_close#}
|
||||||
|
|
||||||
{#header_open|Container Level Variables#}
|
{#header_open|Container Level Variables#}
|
||||||
<p>
|
<p>
|
||||||
Container level variables have static lifetime and are order-independent and lazily analyzed.
|
Container level variables have static lifetime and are order-independent and lazily analyzed.
|
||||||
@@ -1481,7 +1507,7 @@ fn divide(a: i32, b: i32) i32 {
|
|||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Operators such as {#syntax#}+{#endsyntax#} and {#syntax#}-{#endsyntax#} cause undefined behavior on
|
Operators such as {#syntax#}+{#endsyntax#} and {#syntax#}-{#endsyntax#} cause undefined behavior on
|
||||||
integer overflow. Alternative operators are provided for wrapping and saturating arithmetic on all targets.
|
integer overflow. Alternative operators are provided for wrapping and saturating arithmetic on all targets.
|
||||||
{#syntax#}+%{#endsyntax#} and {#syntax#}-%{#endsyntax#} perform wrapping arithmetic
|
{#syntax#}+%{#endsyntax#} and {#syntax#}-%{#endsyntax#} perform wrapping arithmetic
|
||||||
while {#syntax#}+|{#endsyntax#} and {#syntax#}-|{#endsyntax#} perform saturating arithmetic.
|
while {#syntax#}+|{#endsyntax#} and {#syntax#}-|{#endsyntax#} perform saturating arithmetic.
|
||||||
</p>
|
</p>
|
||||||
@@ -2048,7 +2074,7 @@ unwrapped == 1234{#endsyntax#}</pre>
|
|||||||
without evaluating {#syntax#}b{#endsyntax#}. Otherwise, returns {#syntax#}b{#endsyntax#}.
|
without evaluating {#syntax#}b{#endsyntax#}. Otherwise, returns {#syntax#}b{#endsyntax#}.
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<pre>{#syntax#}false or true == true{#endsyntax#}</pre>
|
<pre>{#syntax#}(false or true) == true{#endsyntax#}</pre>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -2488,32 +2514,32 @@ test "null terminated array" {
|
|||||||
or using the shorthand function {#syntax#}std.meta.Vector{#endsyntax#}.
|
or using the shorthand function {#syntax#}std.meta.Vector{#endsyntax#}.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Vectors support the same builtin operators as their underlying base types. These operations are performed
|
Vectors support the same builtin operators as their underlying base types. These operations are performed
|
||||||
element-wise, and return a vector of the same length as the input vectors. This includes:
|
element-wise, and return a vector of the same length as the input vectors. This includes:
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Arithmetic ({#syntax#}+{#endsyntax#}, {#syntax#}-{#endsyntax#}, {#syntax#}/{#endsyntax#}, {#syntax#}*{#endsyntax#},
|
<li>Arithmetic ({#syntax#}+{#endsyntax#}, {#syntax#}-{#endsyntax#}, {#syntax#}/{#endsyntax#}, {#syntax#}*{#endsyntax#},
|
||||||
{#syntax#}@divFloor{#endsyntax#}, {#syntax#}@sqrt{#endsyntax#}, {#syntax#}@ceil{#endsyntax#},
|
{#syntax#}@divFloor{#endsyntax#}, {#syntax#}@sqrt{#endsyntax#}, {#syntax#}@ceil{#endsyntax#},
|
||||||
{#syntax#}@log{#endsyntax#}, etc.)</li>
|
{#syntax#}@log{#endsyntax#}, etc.)</li>
|
||||||
<li>Bitwise operators ({#syntax#}>>{#endsyntax#}, {#syntax#}<<{#endsyntax#}, {#syntax#}&{#endsyntax#},
|
<li>Bitwise operators ({#syntax#}>>{#endsyntax#}, {#syntax#}<<{#endsyntax#}, {#syntax#}&{#endsyntax#},
|
||||||
{#syntax#}|{#endsyntax#}, {#syntax#}~{#endsyntax#}, etc.)</li>
|
{#syntax#}|{#endsyntax#}, {#syntax#}~{#endsyntax#}, etc.)</li>
|
||||||
<li>Comparison operators ({#syntax#}<{#endsyntax#}, {#syntax#}>{#endsyntax#}, {#syntax#}=={#endsyntax#}, etc.)</li>
|
<li>Comparison operators ({#syntax#}<{#endsyntax#}, {#syntax#}>{#endsyntax#}, {#syntax#}=={#endsyntax#}, etc.)</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>
|
<p>
|
||||||
It is prohibited to use a math operator on a mixture of scalars (individual numbers) and vectors.
|
It is prohibited to use a math operator on a mixture of scalars (individual numbers) and vectors.
|
||||||
Zig provides the {#link|@splat#} builtin to easily convert from scalars to vectors, and it supports {#link|@reduce#}
|
Zig provides the {#link|@splat#} builtin to easily convert from scalars to vectors, and it supports {#link|@reduce#}
|
||||||
and array indexing syntax to convert from vectors to scalars. Vectors also support assignment to and from
|
and array indexing syntax to convert from vectors to scalars. Vectors also support assignment to and from
|
||||||
fixed-length arrays with comptime known length.
|
fixed-length arrays with comptime known length.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
For rearranging elements within and between vectors, Zig provides the {#link|@shuffle#} and {#link|@select#} functions.
|
For rearranging elements within and between vectors, Zig provides the {#link|@shuffle#} and {#link|@select#} functions.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Operations on vectors shorter than the target machine's native SIMD size will typically compile to single SIMD
|
Operations on vectors shorter than the target machine's native SIMD size will typically compile to single SIMD
|
||||||
instructions, while vectors longer than the target machine's native SIMD size will compile to multiple SIMD
|
instructions, while vectors longer than the target machine's native SIMD size will compile to multiple SIMD
|
||||||
instructions. If a given operation doesn't have SIMD support on the target architecture, the compiler will default
|
instructions. If a given operation doesn't have SIMD support on the target architecture, the compiler will default
|
||||||
to operating on each vector element one at a time. Zig supports any comptime-known vector length up to 2^32-1,
|
to operating on each vector element one at a time. Zig supports any comptime-known vector length up to 2^32-1,
|
||||||
although small powers of two (2-64) are most typical. Note that excessively long vector lengths (e.g. 2^20) may
|
although small powers of two (2-64) are most typical. Note that excessively long vector lengths (e.g. 2^20) may
|
||||||
result in compiler crashes on current versions of Zig.
|
result in compiler crashes on current versions of Zig.
|
||||||
</p>
|
</p>
|
||||||
{#code_begin|test|vector_example#}
|
{#code_begin|test|vector_example#}
|
||||||
@@ -2563,7 +2589,7 @@ test "Conversion between vectors, arrays, and slices" {
|
|||||||
TODO consider suggesting std.MultiArrayList
|
TODO consider suggesting std.MultiArrayList
|
||||||
</p>
|
</p>
|
||||||
{#see_also|@splat|@shuffle|@select|@reduce#}
|
{#see_also|@splat|@shuffle|@select|@reduce#}
|
||||||
|
|
||||||
{#header_close#}
|
{#header_close#}
|
||||||
|
|
||||||
{#header_open|Pointers#}
|
{#header_open|Pointers#}
|
||||||
@@ -2582,7 +2608,7 @@ test "Conversion between vectors, arrays, and slices" {
|
|||||||
<li>Supports slice syntax: {#syntax#}ptr[start..end]{#endsyntax#}</li>
|
<li>Supports slice syntax: {#syntax#}ptr[start..end]{#endsyntax#}</li>
|
||||||
<li>Supports pointer arithmetic: {#syntax#}ptr + x{#endsyntax#}, {#syntax#}ptr - x{#endsyntax#}</li>
|
<li>Supports pointer arithmetic: {#syntax#}ptr + x{#endsyntax#}, {#syntax#}ptr - x{#endsyntax#}</li>
|
||||||
<li>{#syntax#}T{#endsyntax#} must have a known size, which means that it cannot be
|
<li>{#syntax#}T{#endsyntax#} must have a known size, which means that it cannot be
|
||||||
{#syntax#}c_void{#endsyntax#} or any other {#link|opaque type|opaque#}.</li>
|
{#syntax#}anyopaque{#endsyntax#} or any other {#link|opaque type|opaque#}.</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -2981,8 +3007,8 @@ test "null terminated slice" {
|
|||||||
}
|
}
|
||||||
{#code_end#}
|
{#code_end#}
|
||||||
<p>
|
<p>
|
||||||
Sentinel-terminated slices can also be created using a variation of the slice syntax
|
Sentinel-terminated slices can also be created using a variation of the slice syntax
|
||||||
{#syntax#}data[start..end :x]{#endsyntax#}, where {#syntax#}data{#endsyntax#} is a many-item pointer,
|
{#syntax#}data[start..end :x]{#endsyntax#}, where {#syntax#}data{#endsyntax#} is a many-item pointer,
|
||||||
array or slice and {#syntax#}x{#endsyntax#} is the sentinel value.
|
array or slice and {#syntax#}x{#endsyntax#} is the sentinel value.
|
||||||
</p>
|
</p>
|
||||||
{#code_begin|test|null_terminated_slicing#}
|
{#code_begin|test|null_terminated_slicing#}
|
||||||
@@ -2999,7 +3025,7 @@ test "null terminated slicing" {
|
|||||||
}
|
}
|
||||||
{#code_end#}
|
{#code_end#}
|
||||||
<p>
|
<p>
|
||||||
Sentinel-terminated slicing asserts that the element in the sentinel position of the backing data is
|
Sentinel-terminated slicing asserts that the element in the sentinel position of the backing data is
|
||||||
actually the sentinel value. If this is not the case, safety-protected {#link|Undefined Behavior#} results.
|
actually the sentinel value. If this is not the case, safety-protected {#link|Undefined Behavior#} results.
|
||||||
</p>
|
</p>
|
||||||
{#code_begin|test_safety|sentinel mismatch#}
|
{#code_begin|test_safety|sentinel mismatch#}
|
||||||
@@ -3008,10 +3034,10 @@ const expect = std.testing.expect;
|
|||||||
|
|
||||||
test "sentinel mismatch" {
|
test "sentinel mismatch" {
|
||||||
var array = [_]u8{ 3, 2, 1, 0 };
|
var array = [_]u8{ 3, 2, 1, 0 };
|
||||||
|
|
||||||
// Creating a sentinel-terminated slice from the array with a length of 2
|
// Creating a sentinel-terminated slice from the array with a length of 2
|
||||||
// will result in the value `1` occupying the sentinel element position.
|
// will result in the value `1` occupying the sentinel element position.
|
||||||
// This does not match the indicated sentinel value of `0` and will lead
|
// This does not match the indicated sentinel value of `0` and will lead
|
||||||
// to a runtime panic.
|
// to a runtime panic.
|
||||||
var runtime_length: usize = 2;
|
var runtime_length: usize = 2;
|
||||||
const slice = array[0..runtime_length :0];
|
const slice = array[0..runtime_length :0];
|
||||||
@@ -3159,7 +3185,12 @@ test "linked list" {
|
|||||||
.last = &node,
|
.last = &node,
|
||||||
.len = 1,
|
.len = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// When using a pointer to a struct, fields can be accessed directly,
|
||||||
|
// without explicitly dereferencing the pointer.
|
||||||
|
// So you can do
|
||||||
try expect(list2.first.?.data == 1234);
|
try expect(list2.first.?.data == 1234);
|
||||||
|
// instead of try expect(list2.first.?.*.data == 1234);
|
||||||
}
|
}
|
||||||
{#code_end#}
|
{#code_end#}
|
||||||
|
|
||||||
@@ -3486,7 +3517,7 @@ fn dump(args: anytype) !void {
|
|||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
The fields are implicitly named using numbers starting from 0. Because their names are integers,
|
The fields are implicitly named using numbers starting from 0. Because their names are integers,
|
||||||
the {#syntax#}@"0"{#endsyntax#} syntax must be used to access them. Names inside {#syntax#}@""{#endsyntax#} are always recognised as identifiers.
|
the {#syntax#}@"0"{#endsyntax#} syntax must be used to access them. Names inside {#syntax#}@""{#endsyntax#} are always recognised as {#link|identifiers|Identifiers#}.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Like arrays, tuples have a .len field, can be indexed and work with the ++ and ** operators. They can also be iterated over with {#link|inline for#}.
|
Like arrays, tuples have a .len field, can be indexed and work with the ++ and ** operators. They can also be iterated over with {#link|inline for#}.
|
||||||
@@ -3975,7 +4006,7 @@ test "labeled break from labeled block expression" {
|
|||||||
{#see_also|Labeled while|Labeled for#}
|
{#see_also|Labeled while|Labeled for#}
|
||||||
|
|
||||||
{#header_open|Shadowing#}
|
{#header_open|Shadowing#}
|
||||||
<p>Identifiers are never allowed to "hide" other identifiers by using the same name:</p>
|
<p>{#link|Identifiers#} are never allowed to "hide" other identifiers by using the same name:</p>
|
||||||
{#code_begin|test_err|local shadows declaration#}
|
{#code_begin|test_err|local shadows declaration#}
|
||||||
const pi = 3.14;
|
const pi = 3.14;
|
||||||
|
|
||||||
@@ -3987,8 +4018,8 @@ test "inside test block" {
|
|||||||
}
|
}
|
||||||
{#code_end#}
|
{#code_end#}
|
||||||
<p>
|
<p>
|
||||||
Because of this, when you read Zig code you can always rely on an identifier to consistently mean
|
Because of this, when you read Zig code you can always rely on an identifier to consistently mean
|
||||||
the same thing within the scope it is defined. Note that you can, however, use the same name if
|
the same thing within the scope it is defined. Note that you can, however, use the same name if
|
||||||
the scopes are separate:
|
the scopes are separate:
|
||||||
</p>
|
</p>
|
||||||
{#code_begin|test|test_scopes#}
|
{#code_begin|test|test_scopes#}
|
||||||
@@ -4026,7 +4057,7 @@ test "switch simple" {
|
|||||||
1, 2, 3 => 0,
|
1, 2, 3 => 0,
|
||||||
|
|
||||||
// Ranges can be specified using the ... syntax. These are inclusive
|
// Ranges can be specified using the ... syntax. These are inclusive
|
||||||
// both ends.
|
// of both ends.
|
||||||
5...100 => 1,
|
5...100 => 1,
|
||||||
|
|
||||||
// Branches can be arbitrarily complex.
|
// Branches can be arbitrarily complex.
|
||||||
@@ -4798,7 +4829,7 @@ test "errdefer unwinding" {
|
|||||||
</p>
|
</p>
|
||||||
{#header_open|Basics#}
|
{#header_open|Basics#}
|
||||||
{#code_begin|test|test_unreachable#}
|
{#code_begin|test|test_unreachable#}
|
||||||
// unreachable is used to assert that control flow will never happen upon a
|
// unreachable is used to assert that control flow will never reach a
|
||||||
// particular location:
|
// particular location:
|
||||||
test "basic math" {
|
test "basic math" {
|
||||||
const x = 1;
|
const x = 1;
|
||||||
@@ -6269,8 +6300,8 @@ test "turn HashMap into a set with void" {
|
|||||||
value is deleted, as seen above.
|
value is deleted, as seen above.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
{#syntax#}void{#endsyntax#} is distinct from {#syntax#}c_void{#endsyntax#}.
|
{#syntax#}void{#endsyntax#} is distinct from {#syntax#}anyopaque{#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#} has a known size of 0 bytes, and {#syntax#}anyopaque{#endsyntax#} has an unknown, but non-zero, size.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Expressions of type {#syntax#}void{#endsyntax#} are the only ones whose value can be ignored. For example:
|
Expressions of type {#syntax#}void{#endsyntax#} are the only ones whose value can be ignored. For example:
|
||||||
@@ -6766,8 +6797,7 @@ test "variable values" {
|
|||||||
generic data structure.
|
generic data structure.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Here is an example of a generic {#syntax#}List{#endsyntax#} data structure, that we will instantiate with
|
Here is an example of a generic {#syntax#}List{#endsyntax#} data structure.
|
||||||
the type {#syntax#}i32{#endsyntax#}. In Zig we refer to the type as {#syntax#}List(i32){#endsyntax#}.
|
|
||||||
</p>
|
</p>
|
||||||
{#code_begin|syntax#}
|
{#code_begin|syntax#}
|
||||||
fn List(comptime T: type) type {
|
fn List(comptime T: type) type {
|
||||||
@@ -6776,27 +6806,46 @@ fn List(comptime T: type) type {
|
|||||||
len: usize,
|
len: usize,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
{#code_end#}
|
|
||||||
<p>
|
// The generic List data structure can be instantiated by passing in a type:
|
||||||
That's it. It's a function that returns an anonymous {#syntax#}struct{#endsyntax#}. For the purposes of error messages
|
var buffer: [10]i32 = undefined;
|
||||||
and debugging, Zig infers the name {#syntax#}"List(i32)"{#endsyntax#} from the function name and parameters invoked when creating
|
var list = List(i32){
|
||||||
the anonymous struct.
|
.items = &buffer,
|
||||||
</p>
|
.len = 0,
|
||||||
<p>
|
|
||||||
To keep the language small and uniform, all aggregate types in Zig are anonymous. To give a type
|
|
||||||
a name, we assign it to a constant:
|
|
||||||
</p>
|
|
||||||
{#code_begin|syntax#}
|
|
||||||
const Node = struct {
|
|
||||||
next: *Node,
|
|
||||||
name: []u8,
|
|
||||||
};
|
};
|
||||||
{#code_end#}
|
{#code_end#}
|
||||||
<p>
|
<p>
|
||||||
This works because all top level declarations are order-independent, and as long as there isn't
|
That's it. It's a function that returns an anonymous {#syntax#}struct{#endsyntax#}.
|
||||||
an actual infinite regression, values can refer to themselves, directly or indirectly. In this case,
|
To keep the language small and uniform, all aggregate types in Zig are anonymous.
|
||||||
{#syntax#}Node{#endsyntax#} refers to itself as a pointer, which is not actually an infinite regression, so
|
For the purposes of error messages and debugging, Zig infers the name
|
||||||
it works fine.
|
{#syntax#}"List(i32)"{#endsyntax#} from the function name and parameters invoked when creating
|
||||||
|
the anonymous struct.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
To explicitly give a type a name, we assign it to a constant.
|
||||||
|
</p>
|
||||||
|
{#code_begin|syntax#}
|
||||||
|
const Node = struct {
|
||||||
|
next: ?*Node,
|
||||||
|
name: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
var node_a = Node{
|
||||||
|
.next = null,
|
||||||
|
.name = &"Node A",
|
||||||
|
};
|
||||||
|
|
||||||
|
var node_b = Node{
|
||||||
|
.next = &node_a,
|
||||||
|
.name = &"Node B",
|
||||||
|
};
|
||||||
|
{#code_end#}
|
||||||
|
<p>
|
||||||
|
In this example, the {#syntax#}Node{#endsyntax#} struct refers to itself.
|
||||||
|
This works because all top level declarations are order-independent.
|
||||||
|
As long as the compiler can determine the size of the struct, it is free to refer to itself.
|
||||||
|
In this case, {#syntax#}Node{#endsyntax#} refers to itself as a pointer, which has a
|
||||||
|
well-defined size at compile time, so it works fine.
|
||||||
</p>
|
</p>
|
||||||
{#header_close#}
|
{#header_close#}
|
||||||
{#header_open|Case Study: print in Zig#}
|
{#header_open|Case Study: print in Zig#}
|
||||||
@@ -7209,10 +7258,10 @@ test "global assembly" {
|
|||||||
provided explicitly by the caller, and it can be suspended and resumed any number of times.
|
provided explicitly by the caller, and it can be suspended and resumed any number of times.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
The code following the {#syntax#}async{#endsyntax#} callsite runs immediately after the async
|
The code following the {#syntax#}async{#endsyntax#} callsite runs immediately after the async
|
||||||
function first suspends. When the return value of the async function is needed,
|
function first suspends. When the return value of the async function is needed,
|
||||||
the calling code can {#syntax#}await{#endsyntax#} on the async function frame.
|
the calling code can {#syntax#}await{#endsyntax#} on the async function frame.
|
||||||
This will suspend the calling code until the async function completes, at which point
|
This will suspend the calling code until the async function completes, at which point
|
||||||
execution resumes just after the {#syntax#}await{#endsyntax#} callsite.
|
execution resumes just after the {#syntax#}await{#endsyntax#} callsite.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
@@ -7322,8 +7371,8 @@ fn testResumeFromSuspend(my_result: *i32) void {
|
|||||||
in standard code.
|
in standard code.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
However, it is possible to have an {#syntax#}async{#endsyntax#} call
|
However, it is possible to have an {#syntax#}async{#endsyntax#} call
|
||||||
without a matching {#syntax#}await{#endsyntax#}. Upon completion of the async function,
|
without a matching {#syntax#}await{#endsyntax#}. Upon completion of the async function,
|
||||||
execution would continue at the most recent {#syntax#}async{#endsyntax#} callsite or {#syntax#}resume{#endsyntax#} callsite,
|
execution would continue at the most recent {#syntax#}async{#endsyntax#} callsite or {#syntax#}resume{#endsyntax#} callsite,
|
||||||
and the return value of the async function would be lost.
|
and the return value of the async function would be lost.
|
||||||
</p>
|
</p>
|
||||||
@@ -7360,8 +7409,8 @@ fn func() void {
|
|||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
{#syntax#}await{#endsyntax#} is a suspend point, and takes as an operand anything that
|
{#syntax#}await{#endsyntax#} is a suspend point, and takes as an operand anything that
|
||||||
coerces to {#syntax#}anyframe->T{#endsyntax#}. Calling {#syntax#}await{#endsyntax#} on
|
coerces to {#syntax#}anyframe->T{#endsyntax#}. Calling {#syntax#}await{#endsyntax#} on
|
||||||
the frame of an async function will cause execution to continue at the
|
the frame of an async function will cause execution to continue at the
|
||||||
{#syntax#}await{#endsyntax#} callsite once the target function completes.
|
{#syntax#}await{#endsyntax#} callsite once the target function completes.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
@@ -8286,8 +8335,8 @@ fn internalName() callconv(.C) void {}
|
|||||||
{#code_begin|obj#}
|
{#code_begin|obj#}
|
||||||
export fn foo() void {}
|
export fn foo() void {}
|
||||||
{#code_end#}
|
{#code_end#}
|
||||||
<p>Note that even when using {#syntax#}export{#endsyntax#}, {#syntax#}@"foo"{#endsyntax#} syntax can
|
<p>Note that even when using {#syntax#}export{#endsyntax#}, the {#syntax#}@"foo"{#endsyntax#} syntax for
|
||||||
be used to choose any string for the symbol name:</p>
|
{#link|identifiers|Identifiers#} can be used to choose any string for the symbol name:</p>
|
||||||
{#code_begin|obj#}
|
{#code_begin|obj#}
|
||||||
export fn @"A function name that is a complete sentence."() void {}
|
export fn @"A function name that is a complete sentence."() void {}
|
||||||
{#code_end#}
|
{#code_end#}
|
||||||
@@ -8518,6 +8567,9 @@ test "@hasDecl" {
|
|||||||
<li>{#syntax#}@import("builtin"){#endsyntax#} - Target-specific information
|
<li>{#syntax#}@import("builtin"){#endsyntax#} - Target-specific information
|
||||||
The command <code>zig build-exe --show-builtin</code> outputs the source to stdout for reference.
|
The command <code>zig build-exe --show-builtin</code> outputs the source to stdout for reference.
|
||||||
</li>
|
</li>
|
||||||
|
<li>{#syntax#}@import("root"){#endsyntax#} - Points to the root source file
|
||||||
|
This is usually `src/main.zig` but it depends on what file is chosen to be built.
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
{#see_also|Compile Variables|@embedFile#}
|
{#see_also|Compile Variables|@embedFile#}
|
||||||
{#header_close#}
|
{#header_close#}
|
||||||
@@ -8529,6 +8581,16 @@ test "@hasDecl" {
|
|||||||
Attempting to convert a number which is out of range of the destination type results in
|
Attempting to convert a number which is out of range of the destination type results in
|
||||||
safety-protected {#link|Undefined Behavior#}.
|
safety-protected {#link|Undefined Behavior#}.
|
||||||
</p>
|
</p>
|
||||||
|
{#code_begin|test_err|cast truncated bits#}
|
||||||
|
test "integer cast panic" {
|
||||||
|
var a: u16 = 0xabcd;
|
||||||
|
var b: u8 = @intCast(u8, a);
|
||||||
|
_ = b;
|
||||||
|
}
|
||||||
|
{#code_end#}
|
||||||
|
<p>
|
||||||
|
To truncate the significant bits of a number out of range of the destination type, use {#link|@truncate#}.
|
||||||
|
</p>
|
||||||
<p>
|
<p>
|
||||||
If {#syntax#}T{#endsyntax#} is {#syntax#}comptime_int{#endsyntax#},
|
If {#syntax#}T{#endsyntax#} is {#syntax#}comptime_int{#endsyntax#},
|
||||||
then this is semantically equivalent to {#link|Type Coercion#}.
|
then this is semantically equivalent to {#link|Type Coercion#}.
|
||||||
@@ -8573,7 +8635,9 @@ test "@hasDecl" {
|
|||||||
{#header_open|@intToPtr#}
|
{#header_open|@intToPtr#}
|
||||||
<pre>{#syntax#}@intToPtr(comptime DestType: type, address: usize) DestType{#endsyntax#}</pre>
|
<pre>{#syntax#}@intToPtr(comptime DestType: type, address: usize) DestType{#endsyntax#}</pre>
|
||||||
<p>
|
<p>
|
||||||
Converts an integer to a {#link|pointer|Pointers#}. To convert the other way, use {#link|@ptrToInt#}.
|
Converts an integer to a {#link|pointer|Pointers#}. To convert the other way, use {#link|@ptrToInt#}. Casting an address of 0 to a destination type
|
||||||
|
which in not {#link|optional|Optional Pointers#} and does not have the {#syntax#}allowzero{#endsyntax#} attribute will result in a
|
||||||
|
{#link|Pointer Cast Invalid Null#} panic when runtime safety checks are enabled.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
If the destination pointer type does not allow address zero and {#syntax#}address{#endsyntax#}
|
If the destination pointer type does not allow address zero and {#syntax#}address{#endsyntax#}
|
||||||
@@ -8687,7 +8751,8 @@ test "@wasmMemoryGrow" {
|
|||||||
<pre>{#syntax#}@mod(numerator: T, denominator: T) T{#endsyntax#}</pre>
|
<pre>{#syntax#}@mod(numerator: T, denominator: T) T{#endsyntax#}</pre>
|
||||||
<p>
|
<p>
|
||||||
Modulus division. For unsigned integers this is the same as
|
Modulus division. For unsigned integers this is the same as
|
||||||
{#syntax#}numerator % denominator{#endsyntax#}. Caller guarantees {#syntax#}denominator > 0{#endsyntax#}.
|
{#syntax#}numerator % denominator{#endsyntax#}. Caller guarantees {#syntax#}denominator > 0{#endsyntax#}, otherwise the
|
||||||
|
operation will result in a {#link|Remainder Division by Zero#} when runtime safety checks are enabled.
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>{#syntax#}@mod(-5, 3) == 1{#endsyntax#}</li>
|
<li>{#syntax#}@mod(-5, 3) == 1{#endsyntax#}</li>
|
||||||
@@ -8705,7 +8770,7 @@ test "@wasmMemoryGrow" {
|
|||||||
If no overflow or underflow occurs, returns {#syntax#}false{#endsyntax#}.
|
If no overflow or underflow occurs, returns {#syntax#}false{#endsyntax#}.
|
||||||
</p>
|
</p>
|
||||||
{#header_close#}
|
{#header_close#}
|
||||||
|
|
||||||
{#header_open|@panic#}
|
{#header_open|@panic#}
|
||||||
<pre>{#syntax#}@panic(message: []const u8) noreturn{#endsyntax#}</pre>
|
<pre>{#syntax#}@panic(message: []const u8) noreturn{#endsyntax#}</pre>
|
||||||
<p>
|
<p>
|
||||||
@@ -8812,7 +8877,8 @@ pub const PrefetchOptions = struct {
|
|||||||
<pre>{#syntax#}@rem(numerator: T, denominator: T) T{#endsyntax#}</pre>
|
<pre>{#syntax#}@rem(numerator: T, denominator: T) T{#endsyntax#}</pre>
|
||||||
<p>
|
<p>
|
||||||
Remainder division. For unsigned integers this is the same as
|
Remainder division. For unsigned integers this is the same as
|
||||||
{#syntax#}numerator % denominator{#endsyntax#}. Caller guarantees {#syntax#}denominator > 0{#endsyntax#}.
|
{#syntax#}numerator % denominator{#endsyntax#}. Caller guarantees {#syntax#}denominator > 0{#endsyntax#}, otherwise the
|
||||||
|
operation will result in a {#link|Remainder Division by Zero#} when runtime safety checks are enabled.
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>{#syntax#}@rem(-5, 3) == -2{#endsyntax#}</li>
|
<li>{#syntax#}@rem(-5, 3) == -2{#endsyntax#}</li>
|
||||||
@@ -8854,14 +8920,14 @@ pub const PrefetchOptions = struct {
|
|||||||
{#header_close#}
|
{#header_close#}
|
||||||
|
|
||||||
{#header_open|@setCold#}
|
{#header_open|@setCold#}
|
||||||
<pre>{#syntax#}@setCold(is_cold: bool){#endsyntax#}</pre>
|
<pre>{#syntax#}@setCold(comptime is_cold: bool){#endsyntax#}</pre>
|
||||||
<p>
|
<p>
|
||||||
Tells the optimizer that a function is rarely called.
|
Tells the optimizer that a function is rarely called.
|
||||||
</p>
|
</p>
|
||||||
{#header_close#}
|
{#header_close#}
|
||||||
|
|
||||||
{#header_open|@setEvalBranchQuota#}
|
{#header_open|@setEvalBranchQuota#}
|
||||||
<pre>{#syntax#}@setEvalBranchQuota(new_quota: u32){#endsyntax#}</pre>
|
<pre>{#syntax#}@setEvalBranchQuota(comptime new_quota: u32){#endsyntax#}</pre>
|
||||||
<p>
|
<p>
|
||||||
Changes the maximum number of backwards branches that compile-time code
|
Changes the maximum number of backwards branches that compile-time code
|
||||||
execution can use before giving up and making a compile error.
|
execution can use before giving up and making a compile error.
|
||||||
@@ -8896,7 +8962,7 @@ test "foo" {
|
|||||||
{#header_close#}
|
{#header_close#}
|
||||||
|
|
||||||
{#header_open|@setFloatMode#}
|
{#header_open|@setFloatMode#}
|
||||||
<pre>{#syntax#}@setFloatMode(mode: @import("std").builtin.FloatMode){#endsyntax#}</pre>
|
<pre>{#syntax#}@setFloatMode(comptime mode: @import("std").builtin.FloatMode){#endsyntax#}</pre>
|
||||||
<p>
|
<p>
|
||||||
Sets the floating point mode of the current scope. Possible values are:
|
Sets the floating point mode of the current scope. Possible values are:
|
||||||
</p>
|
</p>
|
||||||
@@ -8931,7 +8997,7 @@ pub const FloatMode = enum {
|
|||||||
{#header_close#}
|
{#header_close#}
|
||||||
|
|
||||||
{#header_open|@setRuntimeSafety#}
|
{#header_open|@setRuntimeSafety#}
|
||||||
<pre>{#syntax#}@setRuntimeSafety(safety_on: bool) void{#endsyntax#}</pre>
|
<pre>{#syntax#}@setRuntimeSafety(comptime safety_on: bool) void{#endsyntax#}</pre>
|
||||||
<p>
|
<p>
|
||||||
Sets whether runtime safety checks are enabled for the scope that contains the function call.
|
Sets whether runtime safety checks are enabled for the scope that contains the function call.
|
||||||
</p>
|
</p>
|
||||||
@@ -8992,7 +9058,7 @@ test "@setRuntimeSafety" {
|
|||||||
</p>
|
</p>
|
||||||
{#see_also|@shlExact|@shrExact#}
|
{#see_also|@shlExact|@shrExact#}
|
||||||
{#header_close#}
|
{#header_close#}
|
||||||
|
|
||||||
{#header_open|@shrExact#}
|
{#header_open|@shrExact#}
|
||||||
<pre>{#syntax#}@shrExact(value: T, shift_amt: Log2T) T{#endsyntax#}</pre>
|
<pre>{#syntax#}@shrExact(value: T, shift_amt: Log2T) T{#endsyntax#}</pre>
|
||||||
<p>
|
<p>
|
||||||
@@ -9323,7 +9389,7 @@ fn doTheTest() !void {
|
|||||||
If no overflow or underflow occurs, returns {#syntax#}false{#endsyntax#}.
|
If no overflow or underflow occurs, returns {#syntax#}false{#endsyntax#}.
|
||||||
</p>
|
</p>
|
||||||
{#header_close#}
|
{#header_close#}
|
||||||
|
|
||||||
{#header_open|@tagName#}
|
{#header_open|@tagName#}
|
||||||
<pre>{#syntax#}@tagName(value: anytype) [:0]const u8{#endsyntax#}</pre>
|
<pre>{#syntax#}@tagName(value: anytype) [:0]const u8{#endsyntax#}</pre>
|
||||||
<p>
|
<p>
|
||||||
@@ -9372,17 +9438,11 @@ fn List(comptime T: type) type {
|
|||||||
or same-sized integer type.
|
or same-sized integer type.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
The following produces safety-checked {#link|Undefined Behavior#}:
|
This function always truncates the significant bits of the integer, regardless
|
||||||
|
of endianness on the target platform.
|
||||||
</p>
|
</p>
|
||||||
{#code_begin|test_err|cast truncated bits#}
|
|
||||||
test "integer cast panic" {
|
|
||||||
var a: u16 = 0xabcd;
|
|
||||||
var b: u8 = @intCast(u8, a);
|
|
||||||
_ = b;
|
|
||||||
}
|
|
||||||
{#code_end#}
|
|
||||||
<p>
|
<p>
|
||||||
However this is well defined and working code:
|
Calling {#syntax#}@truncate{#endsyntax#} on a number out of range of the destination type is well defined and working code:
|
||||||
</p>
|
</p>
|
||||||
{#code_begin|test|truncate#}
|
{#code_begin|test|truncate#}
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
@@ -9395,8 +9455,7 @@ test "integer truncation" {
|
|||||||
}
|
}
|
||||||
{#code_end#}
|
{#code_end#}
|
||||||
<p>
|
<p>
|
||||||
This function always truncates the significant bits of the integer, regardless
|
Use {#link|@intCast#} to convert numbers guaranteed to fit the destination type.
|
||||||
of endianness on the target platform.
|
|
||||||
</p>
|
</p>
|
||||||
{#header_close#}
|
{#header_close#}
|
||||||
|
|
||||||
@@ -9448,9 +9507,14 @@ test "integer truncation" {
|
|||||||
Provides type reflection.
|
Provides type reflection.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
For {#link|structs|struct#}, {#link|unions|union#}, {#link|enums|enum#}, and
|
Type information of {#link|structs|struct#}, {#link|unions|union#}, {#link|enums|enum#}, and
|
||||||
{#link|error sets|Error Set Type#}, the fields are guaranteed to be in the same
|
{#link|error sets|Error Set Type#} has fields which are are guaranteed to be in the same
|
||||||
order as declared. For declarations, the order is unspecified.
|
order as appearance in the source file.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Type information of {#link|structs|struct#}, {#link|unions|union#}, {#link|enums|enum#}, and
|
||||||
|
{#link|opaques|opaque#} has declarations, which are also guaranteed to be in the same
|
||||||
|
order as appearance in the source file.
|
||||||
</p>
|
</p>
|
||||||
{#header_close#}
|
{#header_close#}
|
||||||
|
|
||||||
@@ -10618,8 +10682,10 @@ lib.addCSourceFile("src/lib.c", &[_][]const u8{
|
|||||||
<li>{#syntax#}c_longlong{#endsyntax#}</li>
|
<li>{#syntax#}c_longlong{#endsyntax#}</li>
|
||||||
<li>{#syntax#}c_ulonglong{#endsyntax#}</li>
|
<li>{#syntax#}c_ulonglong{#endsyntax#}</li>
|
||||||
<li>{#syntax#}c_longdouble{#endsyntax#}</li>
|
<li>{#syntax#}c_longdouble{#endsyntax#}</li>
|
||||||
<li>{#syntax#}c_void{#endsyntax#}</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
<p>
|
||||||
|
To interop with the C {#syntax#}void{#endsyntax#} type, use {#syntax#}anyopaque{#endsyntax#}.
|
||||||
|
</p>
|
||||||
{#see_also|Primitive Types#}
|
{#see_also|Primitive Types#}
|
||||||
{#header_close#}
|
{#header_close#}
|
||||||
{#header_open|Import from C Header File#}
|
{#header_open|Import from C Header File#}
|
||||||
|
|||||||
106
lib/libc/glibc/csu/elf-init-2.33.c
vendored
Normal file
106
lib/libc/glibc/csu/elf-init-2.33.c
vendored
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
/* Startup support for ELF initializers/finalizers in the main executable.
|
||||||
|
Copyright (C) 2002-2020 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
In addition to the permissions in the GNU Lesser General Public
|
||||||
|
License, the Free Software Foundation gives you unlimited
|
||||||
|
permission to link the compiled version of this file with other
|
||||||
|
programs, and to distribute those programs without any restriction
|
||||||
|
coming from the use of this file. (The GNU Lesser General Public
|
||||||
|
License restrictions do apply in other respects; for example, they
|
||||||
|
cover modification of the file, and distribution when not linked
|
||||||
|
into another program.)
|
||||||
|
|
||||||
|
Note that people who make modified versions of this file are not
|
||||||
|
obligated to grant this special exception for their modified
|
||||||
|
versions; it is their choice whether to do so. The GNU Lesser
|
||||||
|
General Public License gives permission to release a modified
|
||||||
|
version without this exception; this exception also makes it
|
||||||
|
possible to release a modified version which carries forward this
|
||||||
|
exception.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* These magic symbols are provided by the linker. */
|
||||||
|
extern void (*__preinit_array_start []) (int, char **, char **)
|
||||||
|
attribute_hidden;
|
||||||
|
extern void (*__preinit_array_end []) (int, char **, char **)
|
||||||
|
attribute_hidden;
|
||||||
|
extern void (*__init_array_start []) (int, char **, char **)
|
||||||
|
attribute_hidden;
|
||||||
|
extern void (*__init_array_end []) (int, char **, char **)
|
||||||
|
attribute_hidden;
|
||||||
|
extern void (*__fini_array_start []) (void) attribute_hidden;
|
||||||
|
extern void (*__fini_array_end []) (void) attribute_hidden;
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NO_INITFINI
|
||||||
|
/* These function symbols are provided for the .init/.fini section entry
|
||||||
|
points automagically by the linker. */
|
||||||
|
extern void _init (void);
|
||||||
|
extern void _fini (void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* These functions are passed to __libc_start_main by the startup code.
|
||||||
|
These get statically linked into each program. For dynamically linked
|
||||||
|
programs, this module will come from libc_nonshared.a and differs from
|
||||||
|
the libc.a module in that it doesn't call the preinit array. */
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
__libc_csu_init (int argc, char **argv, char **envp)
|
||||||
|
{
|
||||||
|
/* For dynamically linked executables the preinit array is executed by
|
||||||
|
the dynamic linker (before initializing any shared object). */
|
||||||
|
|
||||||
|
#ifndef LIBC_NONSHARED
|
||||||
|
/* For static executables, preinit happens right before init. */
|
||||||
|
{
|
||||||
|
const size_t size = __preinit_array_end - __preinit_array_start;
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
(*__preinit_array_start [i]) (argc, argv, envp);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NO_INITFINI
|
||||||
|
_init ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const size_t size = __init_array_end - __init_array_start;
|
||||||
|
for (size_t i = 0; i < size; i++)
|
||||||
|
(*__init_array_start [i]) (argc, argv, envp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function should not be used anymore. We run the executable's
|
||||||
|
destructor now just like any other. We cannot remove the function,
|
||||||
|
though. */
|
||||||
|
void
|
||||||
|
__libc_csu_fini (void)
|
||||||
|
{
|
||||||
|
#ifndef LIBC_NONSHARED
|
||||||
|
size_t i = __fini_array_end - __fini_array_start;
|
||||||
|
while (i-- > 0)
|
||||||
|
(*__fini_array_start [i]) ();
|
||||||
|
|
||||||
|
# ifndef NO_INITFINI
|
||||||
|
_fini ();
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
112
lib/libc/glibc/sysdeps/aarch64/start-2.33.S
vendored
Normal file
112
lib/libc/glibc/sysdeps/aarch64/start-2.33.S
vendored
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
/* Copyright (C) 1995-2020 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2.1 of the
|
||||||
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library. If not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <sysdep.h>
|
||||||
|
|
||||||
|
/* This is the canonical entry point, usually the first thing in the text
|
||||||
|
segment.
|
||||||
|
|
||||||
|
Note that the code in the .init section has already been run.
|
||||||
|
This includes _init and _libc_init
|
||||||
|
|
||||||
|
|
||||||
|
At this entry point, most registers' values are unspecified, except:
|
||||||
|
|
||||||
|
x0/w0 Contains a function pointer to be registered with `atexit'.
|
||||||
|
This is how the dynamic linker arranges to have DT_FINI
|
||||||
|
functions called for shared libraries that have been loaded
|
||||||
|
before this code runs.
|
||||||
|
|
||||||
|
sp The stack contains the arguments and environment:
|
||||||
|
0(sp) argc
|
||||||
|
8(sp) argv[0]
|
||||||
|
...
|
||||||
|
(8*argc)(sp) NULL
|
||||||
|
(8*(argc+1))(sp) envp[0]
|
||||||
|
...
|
||||||
|
NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
.text
|
||||||
|
.globl _start
|
||||||
|
.type _start,#function
|
||||||
|
_start:
|
||||||
|
/* Create an initial frame with 0 LR and FP */
|
||||||
|
mov x29, #0
|
||||||
|
mov x30, #0
|
||||||
|
|
||||||
|
/* Setup rtld_fini in argument register */
|
||||||
|
mov x5, x0
|
||||||
|
|
||||||
|
/* Load argc and a pointer to argv */
|
||||||
|
ldr PTR_REG (1), [sp, #0]
|
||||||
|
add x2, sp, #PTR_SIZE
|
||||||
|
|
||||||
|
/* Setup stack limit in argument register */
|
||||||
|
mov x6, sp
|
||||||
|
|
||||||
|
#ifdef PIC
|
||||||
|
# ifdef SHARED
|
||||||
|
adrp x0, :got:main
|
||||||
|
ldr PTR_REG (0), [x0, #:got_lo12:main]
|
||||||
|
|
||||||
|
adrp x3, :got:__libc_csu_init
|
||||||
|
ldr PTR_REG (3), [x3, #:got_lo12:__libc_csu_init]
|
||||||
|
|
||||||
|
adrp x4, :got:__libc_csu_fini
|
||||||
|
ldr PTR_REG (4), [x4, #:got_lo12:__libc_csu_fini]
|
||||||
|
# else
|
||||||
|
adrp x0, __wrap_main
|
||||||
|
add x0, x0, :lo12:__wrap_main
|
||||||
|
adrp x3, __libc_csu_init
|
||||||
|
add x3, x3, :lo12:__libc_csu_init
|
||||||
|
adrp x4, __libc_csu_fini
|
||||||
|
add x4, x4, :lo12:__libc_csu_fini
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
/* Set up the other arguments in registers */
|
||||||
|
MOVL (0, main)
|
||||||
|
MOVL (3, __libc_csu_init)
|
||||||
|
MOVL (4, __libc_csu_fini)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* __libc_start_main (main, argc, argv, init, fini, rtld_fini,
|
||||||
|
stack_end) */
|
||||||
|
|
||||||
|
/* Let the libc call main and exit with its return code. */
|
||||||
|
bl __libc_start_main
|
||||||
|
|
||||||
|
/* should never get here....*/
|
||||||
|
bl abort
|
||||||
|
|
||||||
|
#if defined PIC && !defined SHARED
|
||||||
|
/* When main is not defined in the executable but in a shared library
|
||||||
|
then a wrapper is needed in crt1.o of the static-pie enabled libc,
|
||||||
|
because crt1.o and rcrt1.o share code and the later must avoid the
|
||||||
|
use of GOT relocations before __libc_start_main is called. */
|
||||||
|
__wrap_main:
|
||||||
|
b main
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define a symbol for the first piece of initialized data. */
|
||||||
|
.data
|
||||||
|
.globl __data_start
|
||||||
|
__data_start:
|
||||||
|
.long 0
|
||||||
|
.weak data_start
|
||||||
|
data_start = __data_start
|
||||||
85
lib/libc/glibc/sysdeps/alpha/start-2.33.S
vendored
Normal file
85
lib/libc/glibc/sysdeps/alpha/start-2.33.S
vendored
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
/* Startup code for Alpha/ELF.
|
||||||
|
Copyright (C) 1993-2020 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Richard Henderson <rth@tamu.edu>
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
In addition to the permissions in the GNU Lesser General Public
|
||||||
|
License, the Free Software Foundation gives you unlimited
|
||||||
|
permission to link the compiled version of this file with other
|
||||||
|
programs, and to distribute those programs without any restriction
|
||||||
|
coming from the use of this file. (The GNU Lesser General Public
|
||||||
|
License restrictions do apply in other respects; for example, they
|
||||||
|
cover modification of the file, and distribution when not linked
|
||||||
|
into another program.)
|
||||||
|
|
||||||
|
Note that people who make modified versions of this file are not
|
||||||
|
obligated to grant this special exception for their modified
|
||||||
|
versions; it is their choice whether to do so. The GNU Lesser
|
||||||
|
General Public License gives permission to release a modified
|
||||||
|
version without this exception; this exception also makes it
|
||||||
|
possible to release a modified version which carries forward this
|
||||||
|
exception.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library. If not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <sysdep.h>
|
||||||
|
|
||||||
|
.text
|
||||||
|
.align 3
|
||||||
|
.globl _start
|
||||||
|
.ent _start, 0
|
||||||
|
.type _start,@function
|
||||||
|
_start:
|
||||||
|
.frame $15, 0, $15
|
||||||
|
br gp, 1f
|
||||||
|
1: ldgp gp, 0(gp)
|
||||||
|
subq sp, 16, sp
|
||||||
|
mov 0, $15
|
||||||
|
.prologue 0
|
||||||
|
|
||||||
|
/* Load address of the user's main function. */
|
||||||
|
lda a0, main
|
||||||
|
|
||||||
|
ldl a1, 16(sp) /* get argc */
|
||||||
|
lda a2, 24(sp) /* get argv */
|
||||||
|
|
||||||
|
/* Load address of our own entry points to .fini and .init. */
|
||||||
|
lda a3, __libc_csu_init
|
||||||
|
lda a4, __libc_csu_fini
|
||||||
|
|
||||||
|
/* Store address of the shared library termination function. */
|
||||||
|
mov v0, a5
|
||||||
|
|
||||||
|
/* Provide the highest stack address to the user code. */
|
||||||
|
stq sp, 0(sp)
|
||||||
|
|
||||||
|
/* Call the user's main function, and exit with its value.
|
||||||
|
But let the libc call main. */
|
||||||
|
jsr ra, __libc_start_main
|
||||||
|
|
||||||
|
/* Die very horribly if exit returns. Call_pal hlt is callable from
|
||||||
|
kernel mode only; this will result in an illegal instruction trap. */
|
||||||
|
call_pal 0
|
||||||
|
.end _start
|
||||||
|
|
||||||
|
/* For ECOFF backwards compatibility. */
|
||||||
|
weak_alias (_start, __start)
|
||||||
|
|
||||||
|
/* Define a symbol for the first piece of initialized data. */
|
||||||
|
.data
|
||||||
|
.globl __data_start
|
||||||
|
__data_start:
|
||||||
|
.weak data_start
|
||||||
|
data_start = __data_start
|
||||||
148
lib/libc/glibc/sysdeps/arm/start-2.33.S
vendored
Normal file
148
lib/libc/glibc/sysdeps/arm/start-2.33.S
vendored
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
/* Startup code for ARM & ELF
|
||||||
|
Copyright (C) 1995-2020 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
In addition to the permissions in the GNU Lesser General Public
|
||||||
|
License, the Free Software Foundation gives you unlimited
|
||||||
|
permission to link the compiled version of this file with other
|
||||||
|
programs, and to distribute those programs without any restriction
|
||||||
|
coming from the use of this file. (The GNU Lesser General Public
|
||||||
|
License restrictions do apply in other respects; for example, they
|
||||||
|
cover modification of the file, and distribution when not linked
|
||||||
|
into another program.)
|
||||||
|
|
||||||
|
Note that people who make modified versions of this file are not
|
||||||
|
obligated to grant this special exception for their modified
|
||||||
|
versions; it is their choice whether to do so. The GNU Lesser
|
||||||
|
General Public License gives permission to release a modified
|
||||||
|
version without this exception; this exception also makes it
|
||||||
|
possible to release a modified version which carries forward this
|
||||||
|
exception.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library. If not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* This is the canonical entry point, usually the first thing in the text
|
||||||
|
segment.
|
||||||
|
|
||||||
|
Note that the code in the .init section has already been run.
|
||||||
|
This includes _init and _libc_init
|
||||||
|
|
||||||
|
|
||||||
|
At this entry point, most registers' values are unspecified, except:
|
||||||
|
|
||||||
|
a1 Contains a function pointer to be registered with `atexit'.
|
||||||
|
This is how the dynamic linker arranges to have DT_FINI
|
||||||
|
functions called for shared libraries that have been loaded
|
||||||
|
before this code runs.
|
||||||
|
|
||||||
|
sp The stack contains the arguments and environment:
|
||||||
|
0(sp) argc
|
||||||
|
4(sp) argv[0]
|
||||||
|
...
|
||||||
|
(4*argc)(sp) NULL
|
||||||
|
(4*(argc+1))(sp) envp[0]
|
||||||
|
...
|
||||||
|
NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Tag_ABI_align8_preserved: This code preserves 8-byte
|
||||||
|
alignment in any callee. */
|
||||||
|
.eabi_attribute 25, 1
|
||||||
|
/* Tag_ABI_align8_needed: This code may require 8-byte alignment from
|
||||||
|
the caller. */
|
||||||
|
.eabi_attribute 24, 1
|
||||||
|
|
||||||
|
#if defined(__thumb2__)
|
||||||
|
.thumb
|
||||||
|
.syntax unified
|
||||||
|
#endif
|
||||||
|
|
||||||
|
.text
|
||||||
|
.globl _start
|
||||||
|
.type _start,#function
|
||||||
|
_start:
|
||||||
|
/* Protect against unhandled exceptions. */
|
||||||
|
.fnstart
|
||||||
|
/* Clear the frame pointer and link register since this is the outermost frame. */
|
||||||
|
mov fp, #0
|
||||||
|
mov lr, #0
|
||||||
|
|
||||||
|
/* Pop argc off the stack and save a pointer to argv */
|
||||||
|
pop { a2 }
|
||||||
|
mov a3, sp
|
||||||
|
|
||||||
|
/* Push stack limit */
|
||||||
|
push { a3 }
|
||||||
|
|
||||||
|
/* Push rtld_fini */
|
||||||
|
push { a1 }
|
||||||
|
|
||||||
|
#ifdef PIC
|
||||||
|
ldr sl, .L_GOT
|
||||||
|
adr a4, .L_GOT
|
||||||
|
add sl, sl, a4
|
||||||
|
|
||||||
|
ldr ip, .L_GOT+4 /* __libc_csu_fini */
|
||||||
|
ldr ip, [sl, ip]
|
||||||
|
|
||||||
|
push { ip } /* Push __libc_csu_fini */
|
||||||
|
|
||||||
|
ldr a4, .L_GOT+8 /* __libc_csu_init */
|
||||||
|
ldr a4, [sl, a4]
|
||||||
|
|
||||||
|
ldr a1, .L_GOT+12 /* main */
|
||||||
|
ldr a1, [sl, a1]
|
||||||
|
|
||||||
|
/* __libc_start_main (main, argc, argv, init, fini, rtld_fini, stack_end) */
|
||||||
|
/* Let the libc call main and exit with its return code. */
|
||||||
|
bl __libc_start_main(PLT)
|
||||||
|
#else
|
||||||
|
/* Fetch address of __libc_csu_fini */
|
||||||
|
ldr ip, =__libc_csu_fini
|
||||||
|
|
||||||
|
/* Push __libc_csu_fini */
|
||||||
|
push { ip }
|
||||||
|
|
||||||
|
/* Set up the other arguments in registers */
|
||||||
|
ldr a1, =main
|
||||||
|
ldr a4, =__libc_csu_init
|
||||||
|
|
||||||
|
/* __libc_start_main (main, argc, argv, init, fini, rtld_fini, stack_end) */
|
||||||
|
/* Let the libc call main and exit with its return code. */
|
||||||
|
bl __libc_start_main
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* should never get here....*/
|
||||||
|
bl abort
|
||||||
|
|
||||||
|
#ifdef PIC
|
||||||
|
.align 2
|
||||||
|
.L_GOT:
|
||||||
|
.word _GLOBAL_OFFSET_TABLE_ - .L_GOT
|
||||||
|
.word __libc_csu_fini(GOT)
|
||||||
|
.word __libc_csu_init(GOT)
|
||||||
|
.word main(GOT)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
.cantunwind
|
||||||
|
.fnend
|
||||||
|
|
||||||
|
/* Define a symbol for the first piece of initialized data. */
|
||||||
|
.data
|
||||||
|
.globl __data_start
|
||||||
|
__data_start:
|
||||||
|
.long 0
|
||||||
|
.weak data_start
|
||||||
|
data_start = __data_start
|
||||||
152
lib/libc/glibc/sysdeps/hppa/start-2.33.S
vendored
Normal file
152
lib/libc/glibc/sysdeps/hppa/start-2.33.S
vendored
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
/* ELF startup code for HPPA.
|
||||||
|
Copyright (C) 2002-2020 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
In addition to the permissions in the GNU Lesser General Public
|
||||||
|
License, the Free Software Foundation gives you unlimited
|
||||||
|
permission to link the compiled version of this file with other
|
||||||
|
programs, and to distribute those programs without any restriction
|
||||||
|
coming from the use of this file. (The GNU Lesser General Public
|
||||||
|
License restrictions do apply in other respects; for example, they
|
||||||
|
cover modification of the file, and distribution when not linked
|
||||||
|
into another program.)
|
||||||
|
|
||||||
|
Note that people who make modified versions of this file are not
|
||||||
|
obligated to grant this special exception for their modified
|
||||||
|
versions; it is their choice whether to do so. The GNU Lesser
|
||||||
|
General Public License gives permission to release a modified
|
||||||
|
version without this exception; this exception also makes it
|
||||||
|
possible to release a modified version which carries forward this
|
||||||
|
exception.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library. If not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
.import main, code
|
||||||
|
.import $global$, data
|
||||||
|
.import __libc_start_main, code
|
||||||
|
.import __libc_csu_fini, code
|
||||||
|
.import __libc_csu_init, code
|
||||||
|
|
||||||
|
/* Have the linker create plabel words so we get PLABEL32
|
||||||
|
relocs and not 21/14. The use of 21/14 relocs is only
|
||||||
|
supported in the latest dynamic linker. */
|
||||||
|
#ifdef PIC
|
||||||
|
.section .data.rel.ro,"aw",@progbits
|
||||||
|
#else
|
||||||
|
.section .rodata,"a",@progbits
|
||||||
|
#endif
|
||||||
|
.align 4
|
||||||
|
.Lpmain:
|
||||||
|
.word P%main
|
||||||
|
.Lp__libc_start_main:
|
||||||
|
.word P%__libc_start_main
|
||||||
|
.Lp__libc_csu_fini:
|
||||||
|
.word P%__libc_csu_fini
|
||||||
|
.Lp__libc_csu_init:
|
||||||
|
.word P%__libc_csu_init
|
||||||
|
|
||||||
|
.text
|
||||||
|
.align 4
|
||||||
|
.globl _start
|
||||||
|
.export _start, ENTRY
|
||||||
|
.type _start,@function
|
||||||
|
_start:
|
||||||
|
/* At entry to the function we have:
|
||||||
|
|
||||||
|
r26 - Unused
|
||||||
|
r25 - argc
|
||||||
|
r24 - argv
|
||||||
|
r23 - False _dl_fini plabel address
|
||||||
|
|
||||||
|
This function is called from the lower half of RTLD_START.
|
||||||
|
|
||||||
|
The call to __libc_start_main expects:
|
||||||
|
|
||||||
|
1. r26 - Application main
|
||||||
|
2. r25 - argc
|
||||||
|
3. r24 - argv
|
||||||
|
4. r23 - __libc_csu_init
|
||||||
|
5. sp-52 - __libc_csu_fini
|
||||||
|
6. sp-56 - rtld_fini
|
||||||
|
7. sp-60 - stackend */
|
||||||
|
|
||||||
|
.proc
|
||||||
|
.callinfo
|
||||||
|
/* Clear previous-sp. */
|
||||||
|
stw %r0, -4(%sp)
|
||||||
|
/* Setup the stack and frame. */
|
||||||
|
stw %rp, -20(%sp)
|
||||||
|
ldo 64(%sp), %sp
|
||||||
|
stw %sp, -4(%sp)
|
||||||
|
stw %r19, -32(%sp)
|
||||||
|
|
||||||
|
/* argc and argv should be in 25 and 24 (2nd and 3rd argument) */
|
||||||
|
/* void (*rtld_fini) (void) (6th argument) */
|
||||||
|
stw %r23, -56(%sp)
|
||||||
|
|
||||||
|
/* Need to setup 1, 4, 5, and 7th arguments */
|
||||||
|
|
||||||
|
#ifdef PIC
|
||||||
|
/* Load $global$ address into %dp */
|
||||||
|
bl .+8, %dp
|
||||||
|
addil L'$global$-$PIC_pcrel$0+1, %dp
|
||||||
|
ldo R'$global$-$PIC_pcrel$0+5(%r1), %dp
|
||||||
|
|
||||||
|
/* load main (1st argument) */
|
||||||
|
addil LT'.Lpmain, %r19
|
||||||
|
ldw RT'.Lpmain(%r1), %r26
|
||||||
|
ldw 0(%r26),%r26
|
||||||
|
/* void (*init) (void) (4th argument) */
|
||||||
|
addil LT'.Lp__libc_csu_init, %r19
|
||||||
|
ldw RT'.Lp__libc_csu_init(%r1), %r23
|
||||||
|
ldw 0(%r23), %r23
|
||||||
|
/* void (*fini) (void) (5th argument) */
|
||||||
|
addil LT'.Lp__libc_csu_fini, %r19
|
||||||
|
ldw RT'.Lp__libc_csu_fini(%r1), %r22
|
||||||
|
ldw 0(%r22), %r22
|
||||||
|
#else
|
||||||
|
/* Load $global$ address into %dp */
|
||||||
|
ldil L%$global$, %dp
|
||||||
|
ldo R%$global$(%dp), %dp
|
||||||
|
|
||||||
|
/* load main (1st argument) */
|
||||||
|
ldil LR'.Lpmain, %r26
|
||||||
|
ldw RR'.Lpmain(%r26), %r26
|
||||||
|
/* void (*init) (void) (4th argument) */
|
||||||
|
ldil LR'.Lp__libc_csu_init, %r23
|
||||||
|
ldw RR'.Lp__libc_csu_init(%r23), %r23
|
||||||
|
/* void (*fini) (void) (5th argument) */
|
||||||
|
ldil LR'.Lp__libc_csu_fini, %r22
|
||||||
|
ldw RR'.Lp__libc_csu_fini(%r22), %r22
|
||||||
|
#endif
|
||||||
|
/* Store 5th argument */
|
||||||
|
stw %r22, -52(%sp)
|
||||||
|
/* void *stack_end (7th argument) */
|
||||||
|
stw %sp, -60(%sp)
|
||||||
|
bl __libc_start_main,%r2
|
||||||
|
nop
|
||||||
|
/* die horribly if it returned (it shouldn't) */
|
||||||
|
iitlbp %r0,(%sr0,%r0)
|
||||||
|
nop
|
||||||
|
|
||||||
|
.procend
|
||||||
|
|
||||||
|
/* Define a symbol for the first piece of initialized data. */
|
||||||
|
.data
|
||||||
|
.globl __data_start
|
||||||
|
__data_start:
|
||||||
|
.long 0
|
||||||
|
.weak data_start
|
||||||
|
data_start = __data_start
|
||||||
151
lib/libc/glibc/sysdeps/i386/start-2.33.S
vendored
Normal file
151
lib/libc/glibc/sysdeps/i386/start-2.33.S
vendored
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
/* Startup code compliant to the ELF i386 ABI.
|
||||||
|
Copyright (C) 1995-2020 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
In addition to the permissions in the GNU Lesser General Public
|
||||||
|
License, the Free Software Foundation gives you unlimited
|
||||||
|
permission to link the compiled version of this file with other
|
||||||
|
programs, and to distribute those programs without any restriction
|
||||||
|
coming from the use of this file. (The GNU Lesser General Public
|
||||||
|
License restrictions do apply in other respects; for example, they
|
||||||
|
cover modification of the file, and distribution when not linked
|
||||||
|
into another program.)
|
||||||
|
|
||||||
|
Note that people who make modified versions of this file are not
|
||||||
|
obligated to grant this special exception for their modified
|
||||||
|
versions; it is their choice whether to do so. The GNU Lesser
|
||||||
|
General Public License gives permission to release a modified
|
||||||
|
version without this exception; this exception also makes it
|
||||||
|
possible to release a modified version which carries forward this
|
||||||
|
exception.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* This is the canonical entry point, usually the first thing in the text
|
||||||
|
segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
|
||||||
|
point runs, most registers' values are unspecified, except for:
|
||||||
|
|
||||||
|
%edx Contains a function pointer to be registered with `atexit'.
|
||||||
|
This is how the dynamic linker arranges to have DT_FINI
|
||||||
|
functions called for shared libraries that have been loaded
|
||||||
|
before this code runs.
|
||||||
|
|
||||||
|
%esp The stack contains the arguments and environment:
|
||||||
|
0(%esp) argc
|
||||||
|
4(%esp) argv[0]
|
||||||
|
...
|
||||||
|
(4*argc)(%esp) NULL
|
||||||
|
(4*(argc+1))(%esp) envp[0]
|
||||||
|
...
|
||||||
|
NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sysdep.h>
|
||||||
|
|
||||||
|
ENTRY (_start)
|
||||||
|
/* Clearing frame pointer is insufficient, use CFI. */
|
||||||
|
cfi_undefined (eip)
|
||||||
|
/* Clear the frame pointer. The ABI suggests this be done, to mark
|
||||||
|
the outermost frame obviously. */
|
||||||
|
xorl %ebp, %ebp
|
||||||
|
|
||||||
|
/* Extract the arguments as encoded on the stack and set up
|
||||||
|
the arguments for `main': argc, argv. envp will be determined
|
||||||
|
later in __libc_start_main. */
|
||||||
|
popl %esi /* Pop the argument count. */
|
||||||
|
movl %esp, %ecx /* argv starts just at the current stack top.*/
|
||||||
|
|
||||||
|
/* Before pushing the arguments align the stack to a 16-byte
|
||||||
|
(SSE needs 16-byte alignment) boundary to avoid penalties from
|
||||||
|
misaligned accesses. Thanks to Edward Seidl <seidl@janed.com>
|
||||||
|
for pointing this out. */
|
||||||
|
andl $0xfffffff0, %esp
|
||||||
|
pushl %eax /* Push garbage because we allocate
|
||||||
|
28 more bytes. */
|
||||||
|
|
||||||
|
/* Provide the highest stack address to the user code (for stacks
|
||||||
|
which grow downwards). */
|
||||||
|
pushl %esp
|
||||||
|
|
||||||
|
pushl %edx /* Push address of the shared library
|
||||||
|
termination function. */
|
||||||
|
|
||||||
|
#ifdef PIC
|
||||||
|
/* Load PIC register. */
|
||||||
|
call 1f
|
||||||
|
addl $_GLOBAL_OFFSET_TABLE_, %ebx
|
||||||
|
|
||||||
|
/* Push address of our own entry points to .fini and .init. */
|
||||||
|
leal __libc_csu_fini@GOTOFF(%ebx), %eax
|
||||||
|
pushl %eax
|
||||||
|
leal __libc_csu_init@GOTOFF(%ebx), %eax
|
||||||
|
pushl %eax
|
||||||
|
|
||||||
|
pushl %ecx /* Push second argument: argv. */
|
||||||
|
pushl %esi /* Push first argument: argc. */
|
||||||
|
|
||||||
|
# ifdef SHARED
|
||||||
|
pushl main@GOT(%ebx)
|
||||||
|
# else
|
||||||
|
/* Avoid relocation in static PIE since _start is called before
|
||||||
|
it is relocated. Don't use "leal main@GOTOFF(%ebx), %eax"
|
||||||
|
since main may be in a shared object. Linker will convert
|
||||||
|
"movl main@GOT(%ebx), %eax" to "leal main@GOTOFF(%ebx), %eax"
|
||||||
|
if main is defined locally. */
|
||||||
|
movl main@GOT(%ebx), %eax
|
||||||
|
pushl %eax
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* Call the user's main function, and exit with its value.
|
||||||
|
But let the libc call main. */
|
||||||
|
call __libc_start_main@PLT
|
||||||
|
#else
|
||||||
|
/* Push address of our own entry points to .fini and .init. */
|
||||||
|
pushl $__libc_csu_fini
|
||||||
|
pushl $__libc_csu_init
|
||||||
|
|
||||||
|
pushl %ecx /* Push second argument: argv. */
|
||||||
|
pushl %esi /* Push first argument: argc. */
|
||||||
|
|
||||||
|
pushl $main
|
||||||
|
|
||||||
|
/* Call the user's main function, and exit with its value.
|
||||||
|
But let the libc call main. */
|
||||||
|
call __libc_start_main
|
||||||
|
#endif
|
||||||
|
|
||||||
|
hlt /* Crash if somehow `exit' does return. */
|
||||||
|
|
||||||
|
#ifdef PIC
|
||||||
|
1: movl (%esp), %ebx
|
||||||
|
ret
|
||||||
|
#endif
|
||||||
|
END (_start)
|
||||||
|
|
||||||
|
/* To fulfill the System V/i386 ABI we need this symbol. Yuck, it's so
|
||||||
|
meaningless since we don't support machines < 80386. */
|
||||||
|
.section .rodata
|
||||||
|
.globl _fp_hw
|
||||||
|
_fp_hw: .long 3
|
||||||
|
.size _fp_hw, 4
|
||||||
|
.type _fp_hw,@object
|
||||||
|
|
||||||
|
/* Define a symbol for the first piece of initialized data. */
|
||||||
|
.data
|
||||||
|
.globl __data_start
|
||||||
|
__data_start:
|
||||||
|
.long 0
|
||||||
|
.weak data_start
|
||||||
|
data_start = __data_start
|
||||||
118
lib/libc/glibc/sysdeps/ia64/start-2.33.S
vendored
Normal file
118
lib/libc/glibc/sysdeps/ia64/start-2.33.S
vendored
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
/* Copyright (C) 1999-2020 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Written by Jes Sorensen, <Jes.Sorensen@cern.ch>, April 1999.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
In addition to the permissions in the GNU Lesser General Public
|
||||||
|
License, the Free Software Foundation gives you unlimited
|
||||||
|
permission to link the compiled version of this file with other
|
||||||
|
programs, and to distribute those programs without any restriction
|
||||||
|
coming from the use of this file. (The GNU Lesser General Public
|
||||||
|
License restrictions do apply in other respects; for example, they
|
||||||
|
cover modification of the file, and distribution when not linked
|
||||||
|
into another program.)
|
||||||
|
|
||||||
|
Note that people who make modified versions of this file are not
|
||||||
|
obligated to grant this special exception for their modified
|
||||||
|
versions; it is their choice whether to do so. The GNU Lesser
|
||||||
|
General Public License gives permission to release a modified
|
||||||
|
version without this exception; this exception also makes it
|
||||||
|
possible to release a modified version which carries forward this
|
||||||
|
exception.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <sysdep.h>
|
||||||
|
|
||||||
|
#include <asm/fpu.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Arguments for __libc_start_main:
|
||||||
|
* out0: main
|
||||||
|
* out1: argc
|
||||||
|
* out2: argv
|
||||||
|
* out3: init
|
||||||
|
* out4: fini
|
||||||
|
* out5: rtld_fini
|
||||||
|
* out6: stack_end
|
||||||
|
*/
|
||||||
|
|
||||||
|
.align 32
|
||||||
|
.global _start
|
||||||
|
|
||||||
|
.proc _start
|
||||||
|
.type _start,@function
|
||||||
|
_start:
|
||||||
|
.prologue
|
||||||
|
.save rp, r0
|
||||||
|
.body
|
||||||
|
.prologue
|
||||||
|
{ .mlx
|
||||||
|
alloc r2 = ar.pfs,0,0,7,0
|
||||||
|
movl r3 = FPSR_DEFAULT
|
||||||
|
}
|
||||||
|
{ .mlx
|
||||||
|
adds out2 = 16, sp /* get address of argc value */
|
||||||
|
movl gp = @gprel(0f)
|
||||||
|
;;
|
||||||
|
}
|
||||||
|
0: { .mmi
|
||||||
|
ld8 out1 = [out2], 8 /* load argc and move out2 to become argv */
|
||||||
|
mov.m r10 = ar.bsp /* fetch rbs base address */
|
||||||
|
mov r9 = ip
|
||||||
|
;;
|
||||||
|
}
|
||||||
|
{ .mii
|
||||||
|
mov ar.fpsr = r3
|
||||||
|
sub gp = r9, gp /* back-compute gp value */
|
||||||
|
adds out6 = 16, sp /* highest non-environment stack address */
|
||||||
|
;;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
addl r11 = @ltoff(__libc_ia64_register_backing_store_base), gp
|
||||||
|
addl out0 = @ltoff(@fptr(main)), gp
|
||||||
|
addl out3 = @ltoff(@fptr(__libc_csu_init)), gp
|
||||||
|
;;
|
||||||
|
}
|
||||||
|
{ .mmi
|
||||||
|
ld8 r3 = [r11] /* pointer to __libc_ia64_register_backing_store_base */
|
||||||
|
ld8 out0 = [out0] /* pointer to `main' function descriptor */
|
||||||
|
addl out4 = @ltoff(@fptr(__libc_csu_fini)), gp
|
||||||
|
;;
|
||||||
|
}
|
||||||
|
{ .mmi
|
||||||
|
ld8 out3 = [out3] /* pointer to `init' function descriptor */
|
||||||
|
ld8 out4 = [out4] /* pointer to `fini' function descriptor */
|
||||||
|
nop 0
|
||||||
|
}
|
||||||
|
.body
|
||||||
|
{ .mib
|
||||||
|
st8 [r3] = r10
|
||||||
|
mov out5 = ret0 /* dynamic linker destructor */
|
||||||
|
br.call.sptk.few rp = __libc_start_main
|
||||||
|
}
|
||||||
|
{ .mib
|
||||||
|
break 0 /* break miserably if we ever return */
|
||||||
|
}
|
||||||
|
.endp _start
|
||||||
|
|
||||||
|
/* Define a symbol for the first piece of initialized data. */
|
||||||
|
.data
|
||||||
|
.globl __data_start
|
||||||
|
__data_start:
|
||||||
|
.long 0
|
||||||
|
.weak data_start
|
||||||
|
data_start = __data_start
|
||||||
|
|
||||||
|
.common __libc_ia64_register_backing_store_base, 8, 8
|
||||||
120
lib/libc/glibc/sysdeps/m68k/start-2.33.S
vendored
Normal file
120
lib/libc/glibc/sysdeps/m68k/start-2.33.S
vendored
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
/* Startup code compliant to the ELF m68k ABI.
|
||||||
|
Copyright (C) 1996-2020 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
In addition to the permissions in the GNU Lesser General Public
|
||||||
|
License, the Free Software Foundation gives you unlimited
|
||||||
|
permission to link the compiled version of this file with other
|
||||||
|
programs, and to distribute those programs without any restriction
|
||||||
|
coming from the use of this file. (The GNU Lesser General Public
|
||||||
|
License restrictions do apply in other respects; for example, they
|
||||||
|
cover modification of the file, and distribution when not linked
|
||||||
|
into another program.)
|
||||||
|
|
||||||
|
Note that people who make modified versions of this file are not
|
||||||
|
obligated to grant this special exception for their modified
|
||||||
|
versions; it is their choice whether to do so. The GNU Lesser
|
||||||
|
General Public License gives permission to release a modified
|
||||||
|
version without this exception; this exception also makes it
|
||||||
|
possible to release a modified version which carries forward this
|
||||||
|
exception.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library. If not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* This is the canonical entry point, usually the first thing in the text
|
||||||
|
segment. The SVR4/m68k ABI says that when the entry point runs,
|
||||||
|
most registers' values are unspecified, except for:
|
||||||
|
|
||||||
|
%a1 Contains a function pointer to be registered with `atexit'.
|
||||||
|
This is how the dynamic linker arranges to have DT_FINI
|
||||||
|
functions called for shared libraries that have been loaded
|
||||||
|
before this code runs.
|
||||||
|
|
||||||
|
%sp The stack contains the arguments and environment:
|
||||||
|
0(%sp) argc
|
||||||
|
4(%sp) argv[0]
|
||||||
|
...
|
||||||
|
(4*argc)(%sp) NULL
|
||||||
|
(4*(argc+1))(%sp) envp[0]
|
||||||
|
...
|
||||||
|
NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sysdep.h>
|
||||||
|
|
||||||
|
.text
|
||||||
|
.globl _start
|
||||||
|
.type _start,@function
|
||||||
|
_start:
|
||||||
|
/* Clear the frame pointer. The ABI suggests this be done, to mark
|
||||||
|
the outermost frame obviously. */
|
||||||
|
sub.l %fp, %fp
|
||||||
|
|
||||||
|
/* Extract the arguments as encoded on the stack and set up the
|
||||||
|
arguments for `main': argc, argv. envp will be determined
|
||||||
|
later in __libc_start_main. */
|
||||||
|
move.l (%sp)+, %d0 /* Pop the argument count. */
|
||||||
|
move.l %sp, %a0 /* The argument vector starts just at the
|
||||||
|
current stack top. */
|
||||||
|
|
||||||
|
/* Provide the highest stack address to the user code (for stacks
|
||||||
|
which grow downward). */
|
||||||
|
pea (%sp)
|
||||||
|
|
||||||
|
pea (%a1) /* Push address of the shared library
|
||||||
|
termination function. */
|
||||||
|
|
||||||
|
#ifdef PIC
|
||||||
|
/* Load PIC register. */
|
||||||
|
LOAD_GOT (%a5)
|
||||||
|
|
||||||
|
/* Push the address of our own entry points to `.fini' and
|
||||||
|
`.init'. */
|
||||||
|
move.l __libc_csu_fini@GOT(%a5), -(%sp)
|
||||||
|
move.l __libc_csu_init@GOT(%a5), -(%sp)
|
||||||
|
|
||||||
|
pea (%a0) /* Push second argument: argv. */
|
||||||
|
move.l %d0, -(%sp) /* Push first argument: argc. */
|
||||||
|
|
||||||
|
move.l main@GOT(%a5), -(%sp)
|
||||||
|
|
||||||
|
/* Call the user's main function, and exit with its value. But
|
||||||
|
let the libc call main. */
|
||||||
|
jbsr __libc_start_main@PLTPC
|
||||||
|
#else
|
||||||
|
/* Push the address of our own entry points to `.fini' and
|
||||||
|
`.init'. */
|
||||||
|
pea __libc_csu_fini
|
||||||
|
pea __libc_csu_init
|
||||||
|
|
||||||
|
pea (%a0) /* Push second argument: argv. */
|
||||||
|
move.l %d0, -(%sp) /* Push first argument: argc. */
|
||||||
|
|
||||||
|
pea main
|
||||||
|
|
||||||
|
/* Call the user's main function, and exit with its value. But
|
||||||
|
let the libc call main. */
|
||||||
|
jbsr __libc_start_main
|
||||||
|
#endif
|
||||||
|
|
||||||
|
illegal /* Crash if somehow `exit' does return. */
|
||||||
|
|
||||||
|
/* Define a symbol for the first piece of initialized data. */
|
||||||
|
.data
|
||||||
|
.globl __data_start
|
||||||
|
__data_start:
|
||||||
|
.long 0
|
||||||
|
.weak data_start
|
||||||
|
data_start = __data_start
|
||||||
84
lib/libc/glibc/sysdeps/microblaze/start-2.33.S
vendored
Normal file
84
lib/libc/glibc/sysdeps/microblaze/start-2.33.S
vendored
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/* Copyright (C) 1995-2020 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
In addition to the permissions in the GNU Lesser General Public
|
||||||
|
License, the Free Software Foundation gives you unlimited
|
||||||
|
permission to link the compiled version of this file with other
|
||||||
|
programs, and to distribute those programs without any restriction
|
||||||
|
coming from the use of this file. (The GNU Lesser General Public
|
||||||
|
License restrictions do apply in other respects; for example, they
|
||||||
|
cover modification of the file, and distribution when not linked
|
||||||
|
into another program.)
|
||||||
|
|
||||||
|
Note that people who make modified versions of this file are not
|
||||||
|
obligated to grant this special exception for their modified
|
||||||
|
versions; it is their choice whether to do so. The GNU Lesser
|
||||||
|
General Public License gives permission to release a modified
|
||||||
|
version without this exception; this exception also makes it
|
||||||
|
possible to release a modified version which carries forward this
|
||||||
|
exception.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library. If not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
.text
|
||||||
|
.globl _start
|
||||||
|
.type _start,@function
|
||||||
|
_start:
|
||||||
|
/* On entry the stack contains the following args:
|
||||||
|
r1+0 - argc
|
||||||
|
r1+4 - argv[0]
|
||||||
|
...
|
||||||
|
r1+4*(argc-1) - argv[argc-1]
|
||||||
|
r1+4*argc - NULL
|
||||||
|
r1+4*argc + 4 - envp[0]
|
||||||
|
...
|
||||||
|
NULL
|
||||||
|
*/
|
||||||
|
addk r3,r0,r0
|
||||||
|
addk r5,r1,r0
|
||||||
|
1:
|
||||||
|
addik r5,r5,4
|
||||||
|
lw r4,r5,r0
|
||||||
|
bneid r4,1b
|
||||||
|
addik r3,r3,1
|
||||||
|
addik r6,r3,-1
|
||||||
|
sw r6,r1,r0
|
||||||
|
addik r7,r1,4
|
||||||
|
addik r1,r1,-24
|
||||||
|
#ifdef SHARED
|
||||||
|
/* Setup PIC. */
|
||||||
|
mfs r20,rpc
|
||||||
|
addik r20,r20,_GLOBAL_OFFSET_TABLE_+8
|
||||||
|
lwi r5,r20,main@GOT
|
||||||
|
lwi r8,r20,__libc_csu_init@GOT
|
||||||
|
lwi r9,r20,__libc_csu_fini@GOT
|
||||||
|
brid __libc_start_main@PLT
|
||||||
|
addk r10,r0,r0
|
||||||
|
#else
|
||||||
|
addik r5,r0,main
|
||||||
|
addik r8,r0,__libc_csu_init
|
||||||
|
addik r9,r0,__libc_csu_fini
|
||||||
|
brid __libc_start_main
|
||||||
|
addk r10,r0,r0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define a symbol for the first piece of initialized data. */
|
||||||
|
.data
|
||||||
|
.globl __data_start
|
||||||
|
__data_start:
|
||||||
|
.long 0
|
||||||
|
.weak data_start
|
||||||
|
data_start = __data_start
|
||||||
185
lib/libc/glibc/sysdeps/mips/start-2.33.S
vendored
Normal file
185
lib/libc/glibc/sysdeps/mips/start-2.33.S
vendored
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
/* Startup code compliant to the ELF Mips ABI.
|
||||||
|
Copyright (C) 1995-2020 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
In addition to the permissions in the GNU Lesser General Public
|
||||||
|
License, the Free Software Foundation gives you unlimited
|
||||||
|
permission to link the compiled version of this file with other
|
||||||
|
programs, and to distribute those programs without any restriction
|
||||||
|
coming from the use of this file. (The GNU Lesser General Public
|
||||||
|
License restrictions do apply in other respects; for example, they
|
||||||
|
cover modification of the file, and distribution when not linked
|
||||||
|
into another program.)
|
||||||
|
|
||||||
|
Note that people who make modified versions of this file are not
|
||||||
|
obligated to grant this special exception for their modified
|
||||||
|
versions; it is their choice whether to do so. The GNU Lesser
|
||||||
|
General Public License gives permission to release a modified
|
||||||
|
version without this exception; this exception also makes it
|
||||||
|
possible to release a modified version which carries forward this
|
||||||
|
exception.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library. If not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#define __ASSEMBLY__ 1
|
||||||
|
#include <entry.h>
|
||||||
|
#include <sgidefs.h>
|
||||||
|
#include <sys/asm.h>
|
||||||
|
|
||||||
|
#ifndef ENTRY_POINT
|
||||||
|
#error ENTRY_POINT needs to be defined for start.S on MIPS/ELF.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This is the canonical entry point, usually the first thing in the text
|
||||||
|
segment. The SVR4/Mips ABI (pages 3-31, 3-32) says that when the entry
|
||||||
|
point runs, most registers' values are unspecified, except for:
|
||||||
|
|
||||||
|
v0 ($2) Contains a function pointer to be registered with `atexit'.
|
||||||
|
This is how the dynamic linker arranges to have DT_FINI
|
||||||
|
functions called for shared libraries that have been loaded
|
||||||
|
before this code runs.
|
||||||
|
|
||||||
|
sp ($29) The stack contains the arguments and environment:
|
||||||
|
0(%esp) argc
|
||||||
|
4(%esp) argv[0]
|
||||||
|
...
|
||||||
|
(4*argc)(%esp) NULL
|
||||||
|
(4*(argc+1))(%esp) envp[0]
|
||||||
|
...
|
||||||
|
NULL
|
||||||
|
ra ($31) The return address register is set to zero so that programs
|
||||||
|
that search backword through stack frames recognize the last
|
||||||
|
stack frame.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* We need to call:
|
||||||
|
__libc_start_main (int (*main) (int, char **, char **), int argc,
|
||||||
|
char **argv, void (*init) (void), void (*fini) (void),
|
||||||
|
void (*rtld_fini) (void), void *stack_end)
|
||||||
|
*/
|
||||||
|
|
||||||
|
.text
|
||||||
|
.globl ENTRY_POINT
|
||||||
|
.type ENTRY_POINT,@function
|
||||||
|
#ifndef __mips16
|
||||||
|
ENTRY_POINT:
|
||||||
|
# ifdef __PIC__
|
||||||
|
SETUP_GPX($0)
|
||||||
|
SETUP_GPX64($25,$0)
|
||||||
|
# else
|
||||||
|
PTR_LA $28, _gp /* Setup GP correctly if we're non-PIC. */
|
||||||
|
move $31, $0
|
||||||
|
# endif
|
||||||
|
|
||||||
|
PTR_LA $4, main /* main */
|
||||||
|
PTR_L $5, 0($29) /* argc */
|
||||||
|
PTR_ADDIU $6, $29, PTRSIZE /* argv */
|
||||||
|
|
||||||
|
/* Allocate space on the stack for seven arguments (o32 only)
|
||||||
|
and make sure the stack is aligned to double words (8 bytes)
|
||||||
|
on o32 and quad words (16 bytes) on n32 and n64. */
|
||||||
|
|
||||||
|
and $29, -2 * SZREG
|
||||||
|
# if _MIPS_SIM == _ABIO32
|
||||||
|
PTR_SUBIU $29, 32
|
||||||
|
# endif
|
||||||
|
PTR_LA $7, __libc_csu_init /* init */
|
||||||
|
PTR_LA $8, __libc_csu_fini
|
||||||
|
# if _MIPS_SIM == _ABIO32
|
||||||
|
PTR_S $8, 16($29) /* fini */
|
||||||
|
PTR_S $2, 20($29) /* rtld_fini */
|
||||||
|
PTR_S $29, 24($29) /* stack_end */
|
||||||
|
# else
|
||||||
|
move $9, $2 /* rtld_fini */
|
||||||
|
move $10, $29 /* stack_end */
|
||||||
|
# endif
|
||||||
|
PTR_LA $25, __libc_start_main
|
||||||
|
jalr $25
|
||||||
|
hlt: b hlt /* Crash if somehow it does return. */
|
||||||
|
|
||||||
|
#elif _MIPS_SIM == _ABIO32 /* __mips16 */
|
||||||
|
/* MIPS16 entry point. */
|
||||||
|
.set mips16
|
||||||
|
ENTRY_POINT:
|
||||||
|
# ifdef __PIC__
|
||||||
|
li $3, %hi(_gp_disp)
|
||||||
|
addiu $4, $pc, %lo(_gp_disp)
|
||||||
|
sll $3, 16
|
||||||
|
addu $3, $4
|
||||||
|
move $gp, $3
|
||||||
|
# else
|
||||||
|
li $3, %hi(_gp)
|
||||||
|
sll $3, 16
|
||||||
|
addiu $3, %lo(_gp)
|
||||||
|
move $gp, $3
|
||||||
|
# endif
|
||||||
|
/* Tie end of stack frames. */
|
||||||
|
li $4, 0
|
||||||
|
move $31, $4
|
||||||
|
/* Create new SP value in $7, including alignment. */
|
||||||
|
li $4, 2 * SZREG
|
||||||
|
neg $4, $4
|
||||||
|
move $7, $sp
|
||||||
|
and $7, $4
|
||||||
|
addiu $7, -32
|
||||||
|
/* Load arguments with original SP. */
|
||||||
|
lw $5, 0($sp)
|
||||||
|
addiu $6, $sp, PTRSIZE
|
||||||
|
/* Update SP. */
|
||||||
|
move $sp, $7
|
||||||
|
/* Lay out last arguments, and call __libc_start_main(). */
|
||||||
|
# ifdef __PIC__
|
||||||
|
sw $7, 24($sp) /* stack_end */
|
||||||
|
lw $4, %got(__libc_csu_fini)($3)
|
||||||
|
lw $7, %got(__libc_csu_init)($3) /* init */
|
||||||
|
sw $4, 16($sp) /* fini */
|
||||||
|
lw $4, %got(main)($3) /* main */
|
||||||
|
lw $3, %call16(__libc_start_main)($3)
|
||||||
|
sw $2, 20($sp) /* rtld_fini */
|
||||||
|
move $25, $3
|
||||||
|
jalr $3
|
||||||
|
# else
|
||||||
|
lw $4, 1f
|
||||||
|
sw $7, 24($sp) /* stack_end */
|
||||||
|
lw $7, 2f /* init */
|
||||||
|
sw $4, 16($sp) /* fini */
|
||||||
|
lw $4, 3f /* main */
|
||||||
|
sw $2, 20($sp) /* rtld_fini */
|
||||||
|
/* Load and call __libc_start_main(). */
|
||||||
|
lw $3, 4f
|
||||||
|
jalr $3
|
||||||
|
# endif
|
||||||
|
hlt: b hlt /* Crash if somehow it does return. */
|
||||||
|
# ifndef __PIC__
|
||||||
|
.align 2
|
||||||
|
1: .word __libc_csu_fini
|
||||||
|
2: .word __libc_csu_init
|
||||||
|
3: .word main
|
||||||
|
4: .word __libc_start_main
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#else /* __mips16 && _MIPS_SIM != _ABIO32 */
|
||||||
|
# error "MIPS16 support for N32/N64 not implemented"
|
||||||
|
|
||||||
|
#endif /* __mips16 */
|
||||||
|
|
||||||
|
/* Define a symbol for the first piece of initialized data. */
|
||||||
|
.data
|
||||||
|
.globl __data_start
|
||||||
|
__data_start:
|
||||||
|
.long 0
|
||||||
|
.weak data_start
|
||||||
|
data_start = __data_start
|
||||||
95
lib/libc/glibc/sysdeps/powerpc/powerpc32/start-2.33.S
vendored
Normal file
95
lib/libc/glibc/sysdeps/powerpc/powerpc32/start-2.33.S
vendored
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
/* Startup code for programs linked with GNU libc.
|
||||||
|
Copyright (C) 1998-2020 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
In addition to the permissions in the GNU Lesser General Public
|
||||||
|
License, the Free Software Foundation gives you unlimited
|
||||||
|
permission to link the compiled version of this file with other
|
||||||
|
programs, and to distribute those programs without any restriction
|
||||||
|
coming from the use of this file. (The GNU Lesser General Public
|
||||||
|
License restrictions do apply in other respects; for example, they
|
||||||
|
cover modification of the file, and distribution when not linked
|
||||||
|
into another program.)
|
||||||
|
|
||||||
|
Note that people who make modified versions of this file are not
|
||||||
|
obligated to grant this special exception for their modified
|
||||||
|
versions; it is their choice whether to do so. The GNU Lesser
|
||||||
|
General Public License gives permission to release a modified
|
||||||
|
version without this exception; this exception also makes it
|
||||||
|
possible to release a modified version which carries forward this
|
||||||
|
exception.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <sysdep.h>
|
||||||
|
|
||||||
|
/* We do not want .eh_frame info for crt1.o since crt1.o is linked
|
||||||
|
before crtbegin.o, the file defining __EH_FRAME_BEGIN__. */
|
||||||
|
#undef cfi_startproc
|
||||||
|
#define cfi_startproc
|
||||||
|
#undef cfi_endproc
|
||||||
|
#define cfi_endproc
|
||||||
|
|
||||||
|
/* These are the various addresses we require. */
|
||||||
|
#ifdef PIC
|
||||||
|
.section ".data"
|
||||||
|
#else
|
||||||
|
.section ".rodata"
|
||||||
|
#endif
|
||||||
|
.align 2
|
||||||
|
L(start_addresses):
|
||||||
|
.long _SDA_BASE_
|
||||||
|
.long main
|
||||||
|
.long __libc_csu_init
|
||||||
|
.long __libc_csu_fini
|
||||||
|
ASM_SIZE_DIRECTIVE(L(start_addresses))
|
||||||
|
|
||||||
|
.section ".text"
|
||||||
|
ENTRY(_start)
|
||||||
|
/* Save the stack pointer, in case we're statically linked under Linux. */
|
||||||
|
mr r9,r1
|
||||||
|
/* Set up an initial stack frame, and clear the LR. */
|
||||||
|
clrrwi r1,r1,4
|
||||||
|
#ifdef PIC
|
||||||
|
SETUP_GOT_ACCESS(r13,got_label)
|
||||||
|
li r0,0
|
||||||
|
#else
|
||||||
|
li r0,0
|
||||||
|
#endif
|
||||||
|
stwu r1,-16(r1)
|
||||||
|
mtlr r0
|
||||||
|
stw r0,0(r1)
|
||||||
|
/* Set r13 to point at the 'small data area', and put the address of
|
||||||
|
start_addresses in r8. Also load the GOT pointer so that new PLT
|
||||||
|
calls work, like the one to __libc_start_main. */
|
||||||
|
#ifdef PIC
|
||||||
|
addis r30,r13,_GLOBAL_OFFSET_TABLE_-got_label@ha
|
||||||
|
addis r8,r13,L(start_addresses)-got_label@ha
|
||||||
|
addi r30,r30,_GLOBAL_OFFSET_TABLE_-got_label@l
|
||||||
|
lwzu r13, L(start_addresses)-got_label@l(r8)
|
||||||
|
#else
|
||||||
|
lis r8,L(start_addresses)@ha
|
||||||
|
lwzu r13,L(start_addresses)@l(r8)
|
||||||
|
#endif
|
||||||
|
/* and continue in libc-start, in glibc. */
|
||||||
|
b JUMPTARGET(__libc_start_main)
|
||||||
|
END(_start)
|
||||||
|
|
||||||
|
/* Define a symbol for the first piece of initialized data. */
|
||||||
|
.section ".data"
|
||||||
|
.globl __data_start
|
||||||
|
__data_start:
|
||||||
|
.long 0
|
||||||
|
weak_alias (__data_start, data_start)
|
||||||
92
lib/libc/glibc/sysdeps/powerpc/powerpc64/start-2.33.S
vendored
Normal file
92
lib/libc/glibc/sysdeps/powerpc/powerpc64/start-2.33.S
vendored
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
/* Startup code for programs linked with GNU libc. PowerPC64 version.
|
||||||
|
Copyright (C) 1998-2020 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
In addition to the permissions in the GNU Lesser General Public
|
||||||
|
License, the Free Software Foundation gives you unlimited
|
||||||
|
permission to link the compiled version of this file with other
|
||||||
|
programs, and to distribute those programs without any restriction
|
||||||
|
coming from the use of this file. (The GNU Lesser General Public
|
||||||
|
License restrictions do apply in other respects; for example, they
|
||||||
|
cover modification of the file, and distribution when not linked
|
||||||
|
into another program.)
|
||||||
|
|
||||||
|
Note that people who make modified versions of this file are not
|
||||||
|
obligated to grant this special exception for their modified
|
||||||
|
versions; it is their choice whether to do so. The GNU Lesser
|
||||||
|
General Public License gives permission to release a modified
|
||||||
|
version without this exception; this exception also makes it
|
||||||
|
possible to release a modified version which carries forward this
|
||||||
|
exception.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <sysdep.h>
|
||||||
|
|
||||||
|
/* We do not want .eh_frame info for crt1.o since crt1.o is linked
|
||||||
|
before crtbegin.o, the file defining __EH_FRAME_BEGIN__. */
|
||||||
|
#undef cfi_startproc
|
||||||
|
#define cfi_startproc
|
||||||
|
#undef cfi_endproc
|
||||||
|
#define cfi_endproc
|
||||||
|
|
||||||
|
/* These are the various addresses we require. */
|
||||||
|
#ifdef PIC
|
||||||
|
.section ".data.rel.ro.local","aw"
|
||||||
|
#else
|
||||||
|
.section ".rodata"
|
||||||
|
#endif
|
||||||
|
.align 3
|
||||||
|
L(start_addresses):
|
||||||
|
.quad 0 /* was _SDA_BASE_ but not in 64-bit ABI*/
|
||||||
|
/* function descriptors so don't need JUMPTARGET */
|
||||||
|
.quad main
|
||||||
|
.quad __libc_csu_init
|
||||||
|
.quad __libc_csu_fini
|
||||||
|
|
||||||
|
ASM_SIZE_DIRECTIVE(L(start_addresses))
|
||||||
|
|
||||||
|
.section ".toc","aw"
|
||||||
|
.L01:
|
||||||
|
.tc L(start_addresses)[TC],L(start_addresses)
|
||||||
|
.section ".text"
|
||||||
|
ENTRY (_start)
|
||||||
|
/* Save the stack pointer, in case we're statically linked under Linux. */
|
||||||
|
mr r9,r1
|
||||||
|
/* Set up an initial stack frame, and clear the LR. */
|
||||||
|
clrrdi r1,r1,4
|
||||||
|
li r0,0
|
||||||
|
stdu r1,-128(r1)
|
||||||
|
mtlr r0
|
||||||
|
std r0,0(r1)
|
||||||
|
|
||||||
|
/* put the address of start_addresses in r8... **
|
||||||
|
** PPC64 ABI uses R13 for thread local, so we leave it alone */
|
||||||
|
ld r8,.L01@toc(r2)
|
||||||
|
|
||||||
|
/* and continue in libc-start, in glibc. */
|
||||||
|
b JUMPTARGET(__libc_start_main)
|
||||||
|
/* Older versions of ld need this nop to recognize that it's OK to call via a
|
||||||
|
TOC adjusting stub. */
|
||||||
|
nop
|
||||||
|
|
||||||
|
END(_start)
|
||||||
|
|
||||||
|
/* Define a symbol for the first piece of initialized data. */
|
||||||
|
.section ".data"
|
||||||
|
.globl __data_start
|
||||||
|
__data_start:
|
||||||
|
.long 0
|
||||||
|
weak_alias (__data_start, data_start)
|
||||||
86
lib/libc/glibc/sysdeps/riscv/start-2.33.S
vendored
Normal file
86
lib/libc/glibc/sysdeps/riscv/start-2.33.S
vendored
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
/* Startup code compliant to the ELF RISC-V ABI.
|
||||||
|
Copyright (C) 1995-2020 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
In addition to the permissions in the GNU Lesser General Public
|
||||||
|
License, the Free Software Foundation gives you unlimited
|
||||||
|
permission to link the compiled version of this file with other
|
||||||
|
programs, and to distribute those programs without any restriction
|
||||||
|
coming from the use of this file. (The GNU Lesser General Public
|
||||||
|
License restrictions do apply in other respects; for example, they
|
||||||
|
cover modification of the file, and distribution when not linked
|
||||||
|
into another program.)
|
||||||
|
|
||||||
|
Note that people who make modified versions of this file are not
|
||||||
|
obligated to grant this special exception for their modified
|
||||||
|
versions; it is their choice whether to do so. The GNU Lesser
|
||||||
|
General Public License gives permission to release a modified
|
||||||
|
version without this exception; this exception also makes it
|
||||||
|
possible to release a modified version which carries forward this
|
||||||
|
exception.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library. If not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#define __ASSEMBLY__ 1
|
||||||
|
#include <entry.h>
|
||||||
|
#include <sysdep.h>
|
||||||
|
#include <sys/asm.h>
|
||||||
|
|
||||||
|
/* The entry point's job is to call __libc_start_main. Per the ABI,
|
||||||
|
a0 contains the address of a function to be passed to atexit.
|
||||||
|
__libc_start_main wants this in a5. */
|
||||||
|
|
||||||
|
ENTRY (ENTRY_POINT)
|
||||||
|
/* Terminate call stack by noting ra is undefined. Use a dummy
|
||||||
|
.cfi_label to force starting the FDE. */
|
||||||
|
.cfi_label .Ldummy
|
||||||
|
cfi_undefined (ra)
|
||||||
|
call load_gp
|
||||||
|
mv a5, a0 /* rtld_fini. */
|
||||||
|
/* main may be in a shared library. */
|
||||||
|
la a0, main
|
||||||
|
REG_L a1, 0(sp) /* argc. */
|
||||||
|
addi a2, sp, SZREG /* argv. */
|
||||||
|
andi sp, sp, ALMASK /* Align stack. */
|
||||||
|
lla a3, __libc_csu_init
|
||||||
|
lla a4, __libc_csu_fini
|
||||||
|
mv a6, sp /* stack_end. */
|
||||||
|
|
||||||
|
call __libc_start_main@plt
|
||||||
|
ebreak
|
||||||
|
END (ENTRY_POINT)
|
||||||
|
|
||||||
|
/* Dynamic links need the global pointer to be initialized prior to calling
|
||||||
|
any shared library's initializers, so we use preinit_array to load it.
|
||||||
|
This doesn't cut it for static links, though, since the global pointer
|
||||||
|
needs to be initialized before calling __libc_start_main in that case.
|
||||||
|
So we redundantly initialize it at the beginning of _start. */
|
||||||
|
|
||||||
|
load_gp:
|
||||||
|
.option push
|
||||||
|
.option norelax
|
||||||
|
lla gp, __global_pointer$
|
||||||
|
.option pop
|
||||||
|
ret
|
||||||
|
|
||||||
|
.section .preinit_array,"aw"
|
||||||
|
.dc.a load_gp
|
||||||
|
|
||||||
|
/* Define a symbol for the first piece of initialized data. */
|
||||||
|
.data
|
||||||
|
.globl __data_start
|
||||||
|
__data_start:
|
||||||
|
.weak data_start
|
||||||
|
data_start = __data_start
|
||||||
218
lib/libc/glibc/sysdeps/s390/s390-32/start-2.33.S
vendored
Normal file
218
lib/libc/glibc/sysdeps/s390/s390-32/start-2.33.S
vendored
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
/* Startup code compliant to the ELF s390 ABI.
|
||||||
|
Copyright (C) 2000-2020 Free Software Foundation, Inc.
|
||||||
|
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
In addition to the permissions in the GNU Lesser General Public
|
||||||
|
License, the Free Software Foundation gives you unlimited
|
||||||
|
permission to link the compiled version of this file with other
|
||||||
|
programs, and to distribute those programs without any restriction
|
||||||
|
coming from the use of this file. (The GNU Lesser General Public
|
||||||
|
License restrictions do apply in other respects; for example, they
|
||||||
|
cover modification of the file, and distribution when not linked
|
||||||
|
into another program.)
|
||||||
|
|
||||||
|
Note that people who make modified versions of this file are not
|
||||||
|
obligated to grant this special exception for their modified
|
||||||
|
versions; it is their choice whether to do so. The GNU Lesser
|
||||||
|
General Public License gives permission to release a modified
|
||||||
|
version without this exception; this exception also makes it
|
||||||
|
possible to release a modified version which carries forward this
|
||||||
|
exception.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <sysdep.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is the canonical entry point, usually the first thing in the text
|
||||||
|
segment. Most registers' values are unspecified, except for:
|
||||||
|
|
||||||
|
%r14 Contains a function pointer to be registered with `atexit'.
|
||||||
|
This is how the dynamic linker arranges to have DT_FINI
|
||||||
|
functions called for shared libraries that have been loaded
|
||||||
|
before this code runs.
|
||||||
|
|
||||||
|
%r15 The stack contains the arguments and environment:
|
||||||
|
0(%r15) argc
|
||||||
|
4(%r15) argv[0]
|
||||||
|
...
|
||||||
|
(4*argc)(%r15) NULL
|
||||||
|
(4*(argc+1))(%r15) envp[0]
|
||||||
|
...
|
||||||
|
NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
.text
|
||||||
|
.globl _start
|
||||||
|
.type _start,@function
|
||||||
|
_start:
|
||||||
|
cfi_startproc
|
||||||
|
/* Mark r14 as undefined in order to stop unwinding here! */
|
||||||
|
cfi_undefined (r14)
|
||||||
|
|
||||||
|
/* Check if the kernel provides highgprs facility if needed by
|
||||||
|
the binary. */
|
||||||
|
|
||||||
|
lr %r6,%r15
|
||||||
|
la %r6,4(%r6) /* Skip the argument counter. */
|
||||||
|
|
||||||
|
.L11: l %r5,0(%r6) /* Skip the argument vector. */
|
||||||
|
la %r6,4(%r6)
|
||||||
|
ltr %r5,%r5
|
||||||
|
jne .L11
|
||||||
|
|
||||||
|
.L12: l %r5,0(%r6) /* Skip the environment vector. */
|
||||||
|
la %r6,4(%r6)
|
||||||
|
ltr %r5,%r5
|
||||||
|
jne .L12
|
||||||
|
|
||||||
|
/* Usually the auxiliary vector can be expected directly after
|
||||||
|
the environment variables. But we have to skip extra zeros
|
||||||
|
because the loader might have removed unsecure variables for
|
||||||
|
setuid programs. */
|
||||||
|
|
||||||
|
.L26: l %r5,0(%r6)
|
||||||
|
la %r6,4(%r6)
|
||||||
|
ltr %r5,%r5
|
||||||
|
jz .L26
|
||||||
|
|
||||||
|
ahi %r6,-4
|
||||||
|
|
||||||
|
/* Obtain the needed values from the auxiliary vector. */
|
||||||
|
|
||||||
|
lhi %r7,16 /* AT_HWCAP */
|
||||||
|
lhi %r8,3 /* AT_PHDR */
|
||||||
|
lhi %r9,5 /* AT_PHNUM */
|
||||||
|
lhi %r2,4 /* AT_PHENT */
|
||||||
|
.L13: l %r5,0(%r6)
|
||||||
|
clr %r5,%r7
|
||||||
|
jne .L15
|
||||||
|
l %r10,4(%r6) /* r10 = AT_HWCAP value. */
|
||||||
|
.L15: clr %r5,%r8
|
||||||
|
jne .L16
|
||||||
|
l %r11,4(%r6) /* r11 = AT_PHDR value. */
|
||||||
|
.L16: clr %r5,%r9
|
||||||
|
jne .L17
|
||||||
|
l %r12,4(%r6) /* r12 = AT_PHNUM value. */
|
||||||
|
.L17: clr %r5,%r2
|
||||||
|
jne .L18
|
||||||
|
l %r0,4(%r6) /* r0 = AT_PHENT value. */
|
||||||
|
.L18: ltr %r5,%r5
|
||||||
|
la %r6,8(%r6)
|
||||||
|
jnz .L13
|
||||||
|
|
||||||
|
/* Locate the ELF header by looking for the first PT_LOAD
|
||||||
|
segment with a p_offset of zero. */
|
||||||
|
|
||||||
|
lr %r4,%r11 /* Backup AT_PHDR. */
|
||||||
|
lhi %r7,1 /* PT_LOAD id */
|
||||||
|
lhi %r8,0
|
||||||
|
.L19: cl %r7,0(%r4) /* p_type == PT_LOAD? */
|
||||||
|
jne .L20
|
||||||
|
cl %r8,4(%r4) /* p_offset == 0? */
|
||||||
|
jne .L20
|
||||||
|
l %r9,8(%r4) /* r9 = PT_LOAD.p_vaddr <- ELF header address */
|
||||||
|
j .L24
|
||||||
|
.L20: alr %r4,%r0 /* r4 += AT_PHENT value */
|
||||||
|
brct %r12,.L19
|
||||||
|
|
||||||
|
j .+2 /* Trap, there must be such a phdr. */
|
||||||
|
|
||||||
|
.L24: lr %r4,%r11 /* Backup AT_PHDR. */
|
||||||
|
lhi %r2,6 /* PT_PHDR id */
|
||||||
|
.L23: cl %r2,0(%r4)
|
||||||
|
jne .L22
|
||||||
|
l %r3,8(%r4) /* r3 = PT_PHDR p_vaddr */
|
||||||
|
j .L25
|
||||||
|
.L22: alr %r4,%r0 /* r4 += AT_PHENT value */
|
||||||
|
brct %r12,.L23
|
||||||
|
|
||||||
|
j .L14 /* No PT_PHDR found - skip checking. */
|
||||||
|
|
||||||
|
.L25: slr %r11,%r3 /* AT_PHDR - PT_PHDR.p_vaddr (relocation offset)*/
|
||||||
|
alr %r9,%r11 /* PT_LOAD.p_vaddr += relocation offset */
|
||||||
|
|
||||||
|
l %r5,36(%r9) /* Load the e_flags field. */
|
||||||
|
tml %r5,1
|
||||||
|
jz .L14 /* Binary does not require highgprs facility. */
|
||||||
|
|
||||||
|
tml %r10,512 /* Check the AT_HWCAP value. */
|
||||||
|
jz 2 /* Trap if no highgprs facility available. */
|
||||||
|
.L14:
|
||||||
|
|
||||||
|
/* Setup pointer to literal pool of _start */
|
||||||
|
basr %r13,0
|
||||||
|
.L0: ahi %r13,.Llit-.L0
|
||||||
|
|
||||||
|
/* load argc and argv from stack */
|
||||||
|
la %r4,4(%r15) # get argv
|
||||||
|
l %r3,0(%r15) # get argc
|
||||||
|
|
||||||
|
/* align the stack to a double word boundary */
|
||||||
|
lhi %r0,-8
|
||||||
|
nr %r15,%r0
|
||||||
|
|
||||||
|
/* Setup a stack frame and a parameter area */
|
||||||
|
ahi %r15,-104 # make room on stack
|
||||||
|
xc 0(4,%r15),0(%r15) # clear back-chain
|
||||||
|
|
||||||
|
/* set up arguments for __libc_start_main:
|
||||||
|
main, argc, argv, envp, _init, _fini, rtld_fini, stack_end
|
||||||
|
Note that envp will be determined later in __libc_start_main
|
||||||
|
*/
|
||||||
|
stm %r14,%r15,96(%r15) # store rtld_fini/stack_end to parameter area
|
||||||
|
la %r7,96(%r15)
|
||||||
|
l %r6,.L2-.Llit(%r13) # load pointer to __libc_csu_fini
|
||||||
|
l %r5,.L1-.Llit(%r13) # load pointer to __libc_csu_init
|
||||||
|
l %r2,.L3-.Llit(%r13) # load pointer to main
|
||||||
|
l %r1,.L4-.Llit(%r13) # load pointer to __libc_start_main
|
||||||
|
#ifdef PIC
|
||||||
|
l %r12,.L5-.Llit(%r13) # load .got pointer
|
||||||
|
la %r6,0(%r13,%r6)
|
||||||
|
la %r5,0(%r13,%r5)
|
||||||
|
la %r12,0(%r13,%r12)
|
||||||
|
l %r2,0(%r12,%r2)
|
||||||
|
la %r1,0(%r13,%r1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ok, now branch to the libc main routine */
|
||||||
|
basr %r14,%r1
|
||||||
|
|
||||||
|
/* crash if __libc_start_main returns */
|
||||||
|
.word 0
|
||||||
|
|
||||||
|
cfi_endproc
|
||||||
|
.Llit:
|
||||||
|
#ifndef PIC
|
||||||
|
.L1: .long __libc_csu_init
|
||||||
|
.L2: .long __libc_csu_fini
|
||||||
|
.L3: .long main
|
||||||
|
.L4: .long __libc_start_main
|
||||||
|
#else
|
||||||
|
.L1: .long __libc_csu_init-.Llit
|
||||||
|
.L2: .long __libc_csu_fini-.Llit
|
||||||
|
.L3: .long main@GOT
|
||||||
|
.L4: .long __libc_start_main@plt-.Llit
|
||||||
|
.L5: .long _GLOBAL_OFFSET_TABLE_-.Llit
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define a symbol for the first piece of initialized data. */
|
||||||
|
.data
|
||||||
|
.globl __data_start
|
||||||
|
__data_start:
|
||||||
|
.long 0
|
||||||
|
.weak data_start
|
||||||
|
data_start = __data_start
|
||||||
107
lib/libc/glibc/sysdeps/s390/s390-64/start-2.33.S
vendored
Normal file
107
lib/libc/glibc/sysdeps/s390/s390-64/start-2.33.S
vendored
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
/* Startup code compliant to the 64 bit S/390 ELF ABI.
|
||||||
|
Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
||||||
|
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
In addition to the permissions in the GNU Lesser General Public
|
||||||
|
License, the Free Software Foundation gives you unlimited
|
||||||
|
permission to link the compiled version of this file with other
|
||||||
|
programs, and to distribute those programs without any restriction
|
||||||
|
coming from the use of this file. (The GNU Lesser General Public
|
||||||
|
License restrictions do apply in other respects; for example, they
|
||||||
|
cover modification of the file, and distribution when not linked
|
||||||
|
into another program.)
|
||||||
|
|
||||||
|
Note that people who make modified versions of this file are not
|
||||||
|
obligated to grant this special exception for their modified
|
||||||
|
versions; it is their choice whether to do so. The GNU Lesser
|
||||||
|
General Public License gives permission to release a modified
|
||||||
|
version without this exception; this exception also makes it
|
||||||
|
possible to release a modified version which carries forward this
|
||||||
|
exception.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <sysdep.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is the canonical entry point, usually the first thing in the text
|
||||||
|
segment. Most registers' values are unspecified, except for:
|
||||||
|
|
||||||
|
%r14 Contains a function pointer to be registered with `atexit'.
|
||||||
|
This is how the dynamic linker arranges to have DT_FINI
|
||||||
|
functions called for shared libraries that have been loaded
|
||||||
|
before this code runs.
|
||||||
|
|
||||||
|
%r15 The stack contains the arguments and environment:
|
||||||
|
0(%r15) argc
|
||||||
|
8(%r15) argv[0]
|
||||||
|
...
|
||||||
|
(8*argc)(%r15) NULL
|
||||||
|
(8*(argc+1))(%r15) envp[0]
|
||||||
|
...
|
||||||
|
NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
.text
|
||||||
|
.globl _start
|
||||||
|
.type _start,@function
|
||||||
|
_start:
|
||||||
|
cfi_startproc
|
||||||
|
/* Mark r14 as undefined in order to stop unwinding here! */
|
||||||
|
cfi_undefined (r14)
|
||||||
|
/* Load argc and argv from stack. */
|
||||||
|
la %r4,8(%r15) # get argv
|
||||||
|
lg %r3,0(%r15) # get argc
|
||||||
|
|
||||||
|
/* Align the stack to a double word boundary. */
|
||||||
|
lghi %r0,-16
|
||||||
|
ngr %r15,%r0
|
||||||
|
|
||||||
|
/* Setup a stack frame and a parameter area. */
|
||||||
|
aghi %r15,-176 # make room on stack
|
||||||
|
xc 0(8,%r15),0(%r15) # clear back-chain
|
||||||
|
|
||||||
|
/* Set up arguments for __libc_start_main:
|
||||||
|
main, argc, argv, envp, _init, _fini, rtld_fini, stack_end
|
||||||
|
Note that envp will be determined later in __libc_start_main.
|
||||||
|
*/
|
||||||
|
stmg %r14,%r15,160(%r15) # store rtld_fini/stack_end to parameter area
|
||||||
|
la %r7,160(%r15)
|
||||||
|
larl %r6,__libc_csu_fini # load pointer to __libc_csu_fini
|
||||||
|
larl %r5,__libc_csu_init # load pointer to __libc_csu_init
|
||||||
|
|
||||||
|
/* Ok, now branch to the libc main routine. */
|
||||||
|
#ifdef PIC
|
||||||
|
larl %r2,main@GOTENT # load pointer to main
|
||||||
|
lg %r2,0(%r2)
|
||||||
|
brasl %r14,__libc_start_main@plt
|
||||||
|
#else
|
||||||
|
larl %r2,main # load pointer to main
|
||||||
|
brasl %r14,__libc_start_main
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Crash if __libc_start_main returns. */
|
||||||
|
.word 0
|
||||||
|
|
||||||
|
cfi_endproc
|
||||||
|
|
||||||
|
/* Define a symbol for the first piece of initialized data. */
|
||||||
|
.data
|
||||||
|
.globl __data_start
|
||||||
|
__data_start:
|
||||||
|
.long 0
|
||||||
|
.weak data_start
|
||||||
|
data_start = __data_start
|
||||||
111
lib/libc/glibc/sysdeps/sh/start-2.33.S
vendored
Normal file
111
lib/libc/glibc/sysdeps/sh/start-2.33.S
vendored
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
/* Startup code for SH & ELF.
|
||||||
|
Copyright (C) 1999-2020 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
In addition to the permissions in the GNU Lesser General Public
|
||||||
|
License, the Free Software Foundation gives you unlimited
|
||||||
|
permission to link the compiled version of this file with other
|
||||||
|
programs, and to distribute those programs without any restriction
|
||||||
|
coming from the use of this file. (The GNU Lesser General Public
|
||||||
|
License restrictions do apply in other respects; for example, they
|
||||||
|
cover modification of the file, and distribution when not linked
|
||||||
|
into another program.)
|
||||||
|
|
||||||
|
Note that people who make modified versions of this file are not
|
||||||
|
obligated to grant this special exception for their modified
|
||||||
|
versions; it is their choice whether to do so. The GNU Lesser
|
||||||
|
General Public License gives permission to release a modified
|
||||||
|
version without this exception; this exception also makes it
|
||||||
|
possible to release a modified version which carries forward this
|
||||||
|
exception.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* This is the canonical entry point, usually the first thing in the text
|
||||||
|
segment.
|
||||||
|
|
||||||
|
Note that the code in the .init section has already been run.
|
||||||
|
This includes _init and _libc_init
|
||||||
|
|
||||||
|
|
||||||
|
At this entry point, most registers' values are unspecified, except:
|
||||||
|
|
||||||
|
r4 Contains a function pointer to be registered with `atexit'.
|
||||||
|
This is how the dynamic linker arranges to have DT_FINI
|
||||||
|
functions called for shared libraries that have been loaded
|
||||||
|
before this code runs.
|
||||||
|
|
||||||
|
sp The stack contains the arguments and environment:
|
||||||
|
0(sp) argc
|
||||||
|
4(sp) argv[0]
|
||||||
|
...
|
||||||
|
(4*argc)(sp) NULL
|
||||||
|
(4*(argc+1))(sp) envp[0]
|
||||||
|
...
|
||||||
|
NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
.text
|
||||||
|
.globl _start
|
||||||
|
.type _start,@function
|
||||||
|
_start:
|
||||||
|
/* Clear the frame pointer since this is the outermost frame. */
|
||||||
|
mov #0, r14
|
||||||
|
|
||||||
|
/* Pop argc off the stack and save a pointer to argv */
|
||||||
|
mov.l @r15+,r5
|
||||||
|
mov r15, r6
|
||||||
|
|
||||||
|
/* Push the last arguments to main() onto the stack */
|
||||||
|
mov.l r4,@-r15
|
||||||
|
mov.l L_fini,r0
|
||||||
|
mov.l r0,@-r15
|
||||||
|
|
||||||
|
/* Set up the other arguments for main() that go in registers */
|
||||||
|
mov.l L_main,r4
|
||||||
|
mov.l L_init,r7
|
||||||
|
|
||||||
|
/* __libc_start_main (main, argc, argv, init, fini, rtld_fini) */
|
||||||
|
|
||||||
|
/* Let the libc call main and exit with its return code. */
|
||||||
|
mov.l L_libc_start_main,r1
|
||||||
|
jsr @r1
|
||||||
|
nop
|
||||||
|
/* should never get here....*/
|
||||||
|
mov.l L_abort,r1
|
||||||
|
jsr @r1
|
||||||
|
nop
|
||||||
|
.align 2
|
||||||
|
L_main:
|
||||||
|
.long main
|
||||||
|
L_init:
|
||||||
|
.long __libc_csu_init
|
||||||
|
L_fini:
|
||||||
|
.long __libc_csu_fini
|
||||||
|
L_libc_start_main:
|
||||||
|
.long __libc_start_main
|
||||||
|
L_abort:
|
||||||
|
.long abort
|
||||||
|
/* Define a symbol for the first piece of initialized data. */
|
||||||
|
.data
|
||||||
|
.globl __data_start
|
||||||
|
__data_start:
|
||||||
|
.long 0
|
||||||
|
.weak data_start
|
||||||
|
data_start = __data_start
|
||||||
|
.global __fpscr_values
|
||||||
|
__fpscr_values:
|
||||||
|
.long 0
|
||||||
|
.long 0x80000
|
||||||
99
lib/libc/glibc/sysdeps/sparc/sparc32/start-2.33.S
vendored
Normal file
99
lib/libc/glibc/sysdeps/sparc/sparc32/start-2.33.S
vendored
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
/* Startup code for elf32-sparc
|
||||||
|
Copyright (C) 1997-2020 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Richard Henderson <richard@gnu.ai.mit.edu>, 1997.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
In addition to the permissions in the GNU Lesser General Public
|
||||||
|
License, the Free Software Foundation gives you unlimited
|
||||||
|
permission to link the compiled version of this file with other
|
||||||
|
programs, and to distribute those programs without any restriction
|
||||||
|
coming from the use of this file. (The GNU Lesser General Public
|
||||||
|
License restrictions do apply in other respects; for example, they
|
||||||
|
cover modification of the file, and distribution when not linked
|
||||||
|
into another program.)
|
||||||
|
|
||||||
|
Note that people who make modified versions of this file are not
|
||||||
|
obligated to grant this special exception for their modified
|
||||||
|
versions; it is their choice whether to do so. The GNU Lesser
|
||||||
|
General Public License gives permission to release a modified
|
||||||
|
version without this exception; this exception also makes it
|
||||||
|
possible to release a modified version which carries forward this
|
||||||
|
exception.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <sysdep.h>
|
||||||
|
|
||||||
|
|
||||||
|
.section ".text"
|
||||||
|
.align 4
|
||||||
|
.global _start
|
||||||
|
.type _start,#function
|
||||||
|
_start:
|
||||||
|
#ifdef PIC
|
||||||
|
SETUP_PIC_REG(l7)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Terminate the stack frame, and reserve space for functions to
|
||||||
|
drop their arguments. */
|
||||||
|
mov %g0, %fp
|
||||||
|
sub %sp, 6*4, %sp
|
||||||
|
|
||||||
|
/* Extract the arguments and environment as encoded on the stack. The
|
||||||
|
argument info starts after one register window (16 words) past the SP. */
|
||||||
|
ld [%sp+22*4], %o1
|
||||||
|
add %sp, 23*4, %o2
|
||||||
|
|
||||||
|
/* Load the addresses of the user entry points. */
|
||||||
|
#ifndef PIC
|
||||||
|
sethi %hi(main), %o0
|
||||||
|
sethi %hi(__libc_csu_init), %o3
|
||||||
|
sethi %hi(__libc_csu_fini), %o4
|
||||||
|
or %o0, %lo(main), %o0
|
||||||
|
or %o3, %lo(__libc_csu_init), %o3
|
||||||
|
or %o4, %lo(__libc_csu_fini), %o4
|
||||||
|
#else
|
||||||
|
sethi %gdop_hix22(main), %o0
|
||||||
|
sethi %gdop_hix22(__libc_csu_init), %o3
|
||||||
|
sethi %gdop_hix22(__libc_csu_fini), %o4
|
||||||
|
xor %o0, %gdop_lox10(main), %o0
|
||||||
|
xor %o3, %gdop_lox10(__libc_csu_init), %o3
|
||||||
|
xor %o4, %gdop_lox10(__libc_csu_fini), %o4
|
||||||
|
ld [%l7 + %o0], %o0, %gdop(main)
|
||||||
|
ld [%l7 + %o3], %o3, %gdop(__libc_csu_init)
|
||||||
|
ld [%l7 + %o4], %o4, %gdop(__libc_csu_fini)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* When starting a binary via the dynamic linker, %g1 contains the
|
||||||
|
address of the shared library termination function, which will be
|
||||||
|
registered with atexit(). If we are statically linked, this will
|
||||||
|
be NULL. */
|
||||||
|
mov %g1, %o5
|
||||||
|
|
||||||
|
/* Let libc do the rest of the initialization, and call main. */
|
||||||
|
call __libc_start_main
|
||||||
|
nop
|
||||||
|
|
||||||
|
/* Die very horribly if exit returns. */
|
||||||
|
unimp
|
||||||
|
|
||||||
|
.size _start, .-_start
|
||||||
|
|
||||||
|
/* Define a symbol for the first piece of initialized data. */
|
||||||
|
.data
|
||||||
|
.globl __data_start
|
||||||
|
__data_start:
|
||||||
|
.long 0
|
||||||
|
weak_alias (__data_start, data_start)
|
||||||
100
lib/libc/glibc/sysdeps/sparc/sparc64/start-2.33.S
vendored
Normal file
100
lib/libc/glibc/sysdeps/sparc/sparc64/start-2.33.S
vendored
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
/* Startup code for elf64-sparc
|
||||||
|
Copyright (C) 1997-2020 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Richard Henderson <richard@gnu.ai.mit.edu>, 1997.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
In addition to the permissions in the GNU Lesser General Public
|
||||||
|
License, the Free Software Foundation gives you unlimited
|
||||||
|
permission to link the compiled version of this file with other
|
||||||
|
programs, and to distribute those programs without any restriction
|
||||||
|
coming from the use of this file. (The GNU Lesser General Public
|
||||||
|
License restrictions do apply in other respects; for example, they
|
||||||
|
cover modification of the file, and distribution when not linked
|
||||||
|
into another program.)
|
||||||
|
|
||||||
|
Note that people who make modified versions of this file are not
|
||||||
|
obligated to grant this special exception for their modified
|
||||||
|
versions; it is their choice whether to do so. The GNU Lesser
|
||||||
|
General Public License gives permission to release a modified
|
||||||
|
version without this exception; this exception also makes it
|
||||||
|
possible to release a modified version which carries forward this
|
||||||
|
exception.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <sysdep.h>
|
||||||
|
|
||||||
|
|
||||||
|
.section ".text"
|
||||||
|
.align 4
|
||||||
|
.global _start
|
||||||
|
.type _start,#function
|
||||||
|
_start:
|
||||||
|
#ifdef PIC
|
||||||
|
SETUP_PIC_REG(l7)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Terminate the stack frame, and reserve space for functions to
|
||||||
|
drop their arguments. */
|
||||||
|
mov %g0, %fp
|
||||||
|
sub %sp, 6*8, %sp
|
||||||
|
|
||||||
|
/* Extract the arguments and environment as encoded on the stack. The
|
||||||
|
argument info starts after one register window (16 words) past the SP,
|
||||||
|
plus the bias we added, plus the magic v9 STACK_BIAS. */
|
||||||
|
ldx [%sp+STACK_BIAS+22*8], %o1
|
||||||
|
add %sp, STACK_BIAS+23*8, %o2
|
||||||
|
|
||||||
|
/* Load the addresses of the user entry points. */
|
||||||
|
#ifndef PIC
|
||||||
|
sethi %hi(main), %o0
|
||||||
|
sethi %hi(__libc_csu_init), %o3
|
||||||
|
sethi %hi(__libc_csu_fini), %o4
|
||||||
|
or %o0, %lo(main), %o0
|
||||||
|
or %o3, %lo(__libc_csu_init), %o3
|
||||||
|
or %o4, %lo(__libc_csu_fini), %o4
|
||||||
|
#else
|
||||||
|
sethi %gdop_hix22(main), %o0
|
||||||
|
sethi %gdop_hix22(__libc_csu_init), %o3
|
||||||
|
sethi %gdop_hix22(__libc_csu_fini), %o4
|
||||||
|
xor %o0, %gdop_lox10(main), %o0
|
||||||
|
xor %o3, %gdop_lox10(__libc_csu_init), %o3
|
||||||
|
xor %o4, %gdop_lox10(__libc_csu_fini), %o4
|
||||||
|
ldx [%l7 + %o0], %o0, %gdop(main)
|
||||||
|
ldx [%l7 + %o3], %o3, %gdop(__libc_csu_init)
|
||||||
|
ldx [%l7 + %o4], %o4, %gdop(__libc_csu_fini)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* When starting a binary via the dynamic linker, %g1 contains the
|
||||||
|
address of the shared library termination function, which will be
|
||||||
|
registered with atexit(). If we are statically linked, this will
|
||||||
|
be NULL. */
|
||||||
|
mov %g1, %o5
|
||||||
|
|
||||||
|
/* Let libc do the rest of the initialization, and call main. */
|
||||||
|
call __libc_start_main
|
||||||
|
nop
|
||||||
|
|
||||||
|
/* Die very horribly if exit returns. */
|
||||||
|
illtrap 0
|
||||||
|
|
||||||
|
.size _start, .-_start
|
||||||
|
|
||||||
|
/* Define a symbol for the first piece of initialized data. */
|
||||||
|
.data
|
||||||
|
.globl __data_start
|
||||||
|
__data_start:
|
||||||
|
.long 0
|
||||||
|
weak_alias (__data_start, data_start)
|
||||||
131
lib/libc/glibc/sysdeps/x86_64/start-2.33.S
vendored
Normal file
131
lib/libc/glibc/sysdeps/x86_64/start-2.33.S
vendored
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
/* Startup code compliant to the ELF x86-64 ABI.
|
||||||
|
Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Andreas Jaeger <aj@suse.de>, 2001.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
In addition to the permissions in the GNU Lesser General Public
|
||||||
|
License, the Free Software Foundation gives you unlimited
|
||||||
|
permission to link the compiled version of this file with other
|
||||||
|
programs, and to distribute those programs without any restriction
|
||||||
|
coming from the use of this file. (The GNU Lesser General Public
|
||||||
|
License restrictions do apply in other respects; for example, they
|
||||||
|
cover modification of the file, and distribution when not linked
|
||||||
|
into another program.)
|
||||||
|
|
||||||
|
Note that people who make modified versions of this file are not
|
||||||
|
obligated to grant this special exception for their modified
|
||||||
|
versions; it is their choice whether to do so. The GNU Lesser
|
||||||
|
General Public License gives permission to release a modified
|
||||||
|
version without this exception; this exception also makes it
|
||||||
|
possible to release a modified version which carries forward this
|
||||||
|
exception.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* This is the canonical entry point, usually the first thing in the text
|
||||||
|
segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
|
||||||
|
point runs, most registers' values are unspecified, except for:
|
||||||
|
|
||||||
|
%rdx Contains a function pointer to be registered with `atexit'.
|
||||||
|
This is how the dynamic linker arranges to have DT_FINI
|
||||||
|
functions called for shared libraries that have been loaded
|
||||||
|
before this code runs.
|
||||||
|
|
||||||
|
%rsp The stack contains the arguments and environment:
|
||||||
|
0(%rsp) argc
|
||||||
|
LP_SIZE(%rsp) argv[0]
|
||||||
|
...
|
||||||
|
(LP_SIZE*argc)(%rsp) NULL
|
||||||
|
(LP_SIZE*(argc+1))(%rsp) envp[0]
|
||||||
|
...
|
||||||
|
NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sysdep.h>
|
||||||
|
|
||||||
|
ENTRY (_start)
|
||||||
|
/* Clearing frame pointer is insufficient, use CFI. */
|
||||||
|
cfi_undefined (rip)
|
||||||
|
/* Clear the frame pointer. The ABI suggests this be done, to mark
|
||||||
|
the outermost frame obviously. */
|
||||||
|
xorl %ebp, %ebp
|
||||||
|
|
||||||
|
/* Extract the arguments as encoded on the stack and set up
|
||||||
|
the arguments for __libc_start_main (int (*main) (int, char **, char **),
|
||||||
|
int argc, char *argv,
|
||||||
|
void (*init) (void), void (*fini) (void),
|
||||||
|
void (*rtld_fini) (void), void *stack_end).
|
||||||
|
The arguments are passed via registers and on the stack:
|
||||||
|
main: %rdi
|
||||||
|
argc: %rsi
|
||||||
|
argv: %rdx
|
||||||
|
init: %rcx
|
||||||
|
fini: %r8
|
||||||
|
rtld_fini: %r9
|
||||||
|
stack_end: stack. */
|
||||||
|
|
||||||
|
mov %RDX_LP, %R9_LP /* Address of the shared library termination
|
||||||
|
function. */
|
||||||
|
#ifdef __ILP32__
|
||||||
|
mov (%rsp), %esi /* Simulate popping 4-byte argument count. */
|
||||||
|
add $4, %esp
|
||||||
|
#else
|
||||||
|
popq %rsi /* Pop the argument count. */
|
||||||
|
#endif
|
||||||
|
/* argv starts just at the current stack top. */
|
||||||
|
mov %RSP_LP, %RDX_LP
|
||||||
|
/* Align the stack to a 16 byte boundary to follow the ABI. */
|
||||||
|
and $~15, %RSP_LP
|
||||||
|
|
||||||
|
/* Push garbage because we push 8 more bytes. */
|
||||||
|
pushq %rax
|
||||||
|
|
||||||
|
/* Provide the highest stack address to the user code (for stacks
|
||||||
|
which grow downwards). */
|
||||||
|
pushq %rsp
|
||||||
|
|
||||||
|
#ifdef PIC
|
||||||
|
/* Pass address of our own entry points to .fini and .init. */
|
||||||
|
mov __libc_csu_fini@GOTPCREL(%rip), %R8_LP
|
||||||
|
mov __libc_csu_init@GOTPCREL(%rip), %RCX_LP
|
||||||
|
|
||||||
|
mov main@GOTPCREL(%rip), %RDI_LP
|
||||||
|
#else
|
||||||
|
/* Pass address of our own entry points to .fini and .init. */
|
||||||
|
mov $__libc_csu_fini, %R8_LP
|
||||||
|
mov $__libc_csu_init, %RCX_LP
|
||||||
|
|
||||||
|
mov $main, %RDI_LP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Call the user's main function, and exit with its value.
|
||||||
|
But let the libc call main. Since __libc_start_main in
|
||||||
|
libc.so is called very early, lazy binding isn't relevant
|
||||||
|
here. Use indirect branch via GOT to avoid extra branch
|
||||||
|
to PLT slot. In case of static executable, ld in binutils
|
||||||
|
2.26 or above can convert indirect branch into direct
|
||||||
|
branch. */
|
||||||
|
call *__libc_start_main@GOTPCREL(%rip)
|
||||||
|
|
||||||
|
hlt /* Crash if somehow `exit' does return. */
|
||||||
|
END (_start)
|
||||||
|
|
||||||
|
/* Define a symbol for the first piece of initialized data. */
|
||||||
|
.data
|
||||||
|
.globl __data_start
|
||||||
|
__data_start:
|
||||||
|
.long 0
|
||||||
|
.weak data_start
|
||||||
|
data_start = __data_start
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
#define POLLRDHUP 0x2000
|
#define POLLRDHUP 0x2000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define POLLFREE (__poll_t)0x4000 /* currently only for epoll */
|
#define POLLFREE (__poll_t)0x4000
|
||||||
|
|
||||||
#define POLL_BUSY_LOOP (__poll_t)0x8000
|
#define POLL_BUSY_LOOP (__poll_t)0x8000
|
||||||
|
|
||||||
|
|||||||
@@ -196,6 +196,13 @@ struct drm_virtgpu_context_init {
|
|||||||
__u64 ctx_set_params;
|
__u64 ctx_set_params;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Event code that's given when VIRTGPU_CONTEXT_PARAM_POLL_RINGS_MASK is in
|
||||||
|
* effect. The event size is sizeof(drm_event), since there is no additional
|
||||||
|
* payload.
|
||||||
|
*/
|
||||||
|
#define VIRTGPU_EVENT_FENCE_SIGNALED 0x90000000
|
||||||
|
|
||||||
#define DRM_IOCTL_VIRTGPU_MAP \
|
#define DRM_IOCTL_VIRTGPU_MAP \
|
||||||
DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_MAP, struct drm_virtgpu_map)
|
DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_MAP, struct drm_virtgpu_map)
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#define __BIG_ENDIAN_BITFIELD
|
#define __BIG_ENDIAN_BITFIELD
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <linux/stddef.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/swab.h>
|
#include <linux/swab.h>
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#define __LITTLE_ENDIAN_BITFIELD
|
#define __LITTLE_ENDIAN_BITFIELD
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <linux/stddef.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/swab.h>
|
#include <linux/swab.h>
|
||||||
|
|
||||||
|
|||||||
@@ -117,7 +117,7 @@
|
|||||||
#define ETH_P_IFE 0xED3E /* ForCES inter-FE LFB type */
|
#define ETH_P_IFE 0xED3E /* ForCES inter-FE LFB type */
|
||||||
#define ETH_P_AF_IUCV 0xFBFB /* IBM af_iucv [ NOT AN OFFICIALLY REGISTERED ID ] */
|
#define ETH_P_AF_IUCV 0xFBFB /* IBM af_iucv [ NOT AN OFFICIALLY REGISTERED ID ] */
|
||||||
|
|
||||||
#define ETH_P_802_3_MIN 0x0600 /* If the value in the ethernet type is less than this value
|
#define ETH_P_802_3_MIN 0x0600 /* If the value in the ethernet type is more than this value
|
||||||
* then the frame is Ethernet II. Else it is 802.3 */
|
* then the frame is Ethernet II. Else it is 802.3 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
18
lib/libc/include/any-linux-any/linux/mptcp.h
vendored
18
lib/libc/include/any-linux-any/linux/mptcp.h
vendored
@@ -134,19 +134,21 @@ struct mptcp_info {
|
|||||||
* MPTCP_EVENT_REMOVED: token, rem_id
|
* MPTCP_EVENT_REMOVED: token, rem_id
|
||||||
* An address has been lost by the peer.
|
* An address has been lost by the peer.
|
||||||
*
|
*
|
||||||
* MPTCP_EVENT_SUB_ESTABLISHED: token, family, saddr4 | saddr6,
|
* MPTCP_EVENT_SUB_ESTABLISHED: token, family, loc_id, rem_id,
|
||||||
* daddr4 | daddr6, sport, dport, backup,
|
* saddr4 | saddr6, daddr4 | daddr6, sport,
|
||||||
* if_idx [, error]
|
* dport, backup, if_idx [, error]
|
||||||
* A new subflow has been established. 'error' should not be set.
|
* A new subflow has been established. 'error' should not be set.
|
||||||
*
|
*
|
||||||
* MPTCP_EVENT_SUB_CLOSED: token, family, saddr4 | saddr6, daddr4 | daddr6,
|
* MPTCP_EVENT_SUB_CLOSED: token, family, loc_id, rem_id, saddr4 | saddr6,
|
||||||
* sport, dport, backup, if_idx [, error]
|
* daddr4 | daddr6, sport, dport, backup, if_idx
|
||||||
|
* [, error]
|
||||||
* A subflow has been closed. An error (copy of sk_err) could be set if an
|
* A subflow has been closed. An error (copy of sk_err) could be set if an
|
||||||
* error has been detected for this subflow.
|
* error has been detected for this subflow.
|
||||||
*
|
*
|
||||||
* MPTCP_EVENT_SUB_PRIORITY: token, family, saddr4 | saddr6, daddr4 | daddr6,
|
* MPTCP_EVENT_SUB_PRIORITY: token, family, loc_id, rem_id, saddr4 | saddr6,
|
||||||
* sport, dport, backup, if_idx [, error]
|
* daddr4 | daddr6, sport, dport, backup, if_idx
|
||||||
* The priority of a subflow has changed. 'error' should not be set.
|
* [, error]
|
||||||
|
* The priority of a subflow has changed. 'error' should not be set.
|
||||||
*/
|
*/
|
||||||
enum mptcp_event_type {
|
enum mptcp_event_type {
|
||||||
MPTCP_EVENT_UNSPEC = 0,
|
MPTCP_EVENT_UNSPEC = 0,
|
||||||
|
|||||||
6
lib/libc/include/any-linux-any/linux/nfc.h
vendored
6
lib/libc/include/any-linux-any/linux/nfc.h
vendored
@@ -263,7 +263,7 @@ enum nfc_sdp_attr {
|
|||||||
#define NFC_SE_ENABLED 0x1
|
#define NFC_SE_ENABLED 0x1
|
||||||
|
|
||||||
struct sockaddr_nfc {
|
struct sockaddr_nfc {
|
||||||
sa_family_t sa_family;
|
__kernel_sa_family_t sa_family;
|
||||||
__u32 dev_idx;
|
__u32 dev_idx;
|
||||||
__u32 target_idx;
|
__u32 target_idx;
|
||||||
__u32 nfc_protocol;
|
__u32 nfc_protocol;
|
||||||
@@ -271,14 +271,14 @@ struct sockaddr_nfc {
|
|||||||
|
|
||||||
#define NFC_LLCP_MAX_SERVICE_NAME 63
|
#define NFC_LLCP_MAX_SERVICE_NAME 63
|
||||||
struct sockaddr_nfc_llcp {
|
struct sockaddr_nfc_llcp {
|
||||||
sa_family_t sa_family;
|
__kernel_sa_family_t sa_family;
|
||||||
__u32 dev_idx;
|
__u32 dev_idx;
|
||||||
__u32 target_idx;
|
__u32 target_idx;
|
||||||
__u32 nfc_protocol;
|
__u32 nfc_protocol;
|
||||||
__u8 dsap; /* Destination SAP, if known */
|
__u8 dsap; /* Destination SAP, if known */
|
||||||
__u8 ssap; /* Source SAP to be bound to */
|
__u8 ssap; /* Source SAP to be bound to */
|
||||||
char service_name[NFC_LLCP_MAX_SERVICE_NAME]; /* Service name URI */;
|
char service_name[NFC_LLCP_MAX_SERVICE_NAME]; /* Service name URI */;
|
||||||
size_t service_name_len;
|
__kernel_size_t service_name_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* NFC socket protocols */
|
/* NFC socket protocols */
|
||||||
|
|||||||
13
lib/libc/include/any-linux-any/linux/resource.h
vendored
13
lib/libc/include/any-linux-any/linux/resource.h
vendored
@@ -66,10 +66,17 @@ struct rlimit64 {
|
|||||||
#define _STK_LIM (8*1024*1024)
|
#define _STK_LIM (8*1024*1024)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GPG2 wants 64kB of mlocked memory, to make sure pass phrases
|
* Limit the amount of locked memory by some sane default:
|
||||||
* and other sensitive information are never written to disk.
|
* root can always increase this limit if needed.
|
||||||
|
*
|
||||||
|
* The main use-cases are (1) preventing sensitive memory
|
||||||
|
* from being swapped; (2) real-time operations; (3) via
|
||||||
|
* IOURING_REGISTER_BUFFERS.
|
||||||
|
*
|
||||||
|
* The first two don't need much. The latter will take as
|
||||||
|
* much as it can get. 8MB is a reasonably sane default.
|
||||||
*/
|
*/
|
||||||
#define MLOCK_LIMIT ((PAGE_SIZE > 64*1024) ? PAGE_SIZE : 64*1024)
|
#define MLOCK_LIMIT (8*1024*1024)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Due to binary compatibility, the actual resource numbers
|
* Due to binary compatibility, the actual resource numbers
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#define LINUX_VERSION_CODE 331776
|
#define LINUX_VERSION_CODE 331778
|
||||||
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + ((c) > 255 ? 255 : (c)))
|
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + ((c) > 255 ? 255 : (c)))
|
||||||
#define LINUX_VERSION_MAJOR 5
|
#define LINUX_VERSION_MAJOR 5
|
||||||
#define LINUX_VERSION_PATCHLEVEL 16
|
#define LINUX_VERSION_PATCHLEVEL 16
|
||||||
#define LINUX_VERSION_SUBLEVEL 0
|
#define LINUX_VERSION_SUBLEVEL 2
|
||||||
8
lib/libc/include/generic-glibc/features.h
vendored
8
lib/libc/include/generic-glibc/features.h
vendored
@@ -220,8 +220,12 @@
|
|||||||
# define _DEFAULT_SOURCE 1
|
# define _DEFAULT_SOURCE 1
|
||||||
# undef _ATFILE_SOURCE
|
# undef _ATFILE_SOURCE
|
||||||
# define _ATFILE_SOURCE 1
|
# define _ATFILE_SOURCE 1
|
||||||
|
|
||||||
|
# if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 34) || __GLIBC__ > 2
|
||||||
# undef _DYNAMIC_STACK_SIZE_SOURCE
|
# undef _DYNAMIC_STACK_SIZE_SOURCE
|
||||||
# define _DYNAMIC_STACK_SIZE_SOURCE 1
|
# define _DYNAMIC_STACK_SIZE_SOURCE 1
|
||||||
|
# endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If nothing (other than _GNU_SOURCE and _DEFAULT_SOURCE) is defined,
|
/* If nothing (other than _GNU_SOURCE and _DEFAULT_SOURCE) is defined,
|
||||||
@@ -477,7 +481,7 @@
|
|||||||
/* Major and minor version number of the GNU C library package. Use
|
/* Major and minor version number of the GNU C library package. Use
|
||||||
these macros to test for features in specific releases. */
|
these macros to test for features in specific releases. */
|
||||||
#define __GLIBC__ 2
|
#define __GLIBC__ 2
|
||||||
#define __GLIBC_MINOR__ 34
|
/* Zig patch: we pass `-D__GLIBC_MINOR__=XX` depending on the target. */
|
||||||
|
|
||||||
#define __GLIBC_PREREQ(maj, min) \
|
#define __GLIBC_PREREQ(maj, min) \
|
||||||
((__GLIBC__ << 16) + __GLIBC_MINOR__ >= ((maj) << 16) + (min))
|
((__GLIBC__ << 16) + __GLIBC_MINOR__ >= ((maj) << 16) + (min))
|
||||||
@@ -512,4 +516,4 @@
|
|||||||
#include <gnu/stubs.h>
|
#include <gnu/stubs.h>
|
||||||
|
|
||||||
|
|
||||||
#endif /* features.h */
|
#endif /* features.h */
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ pub const StaticResetEvent = @import("Thread/StaticResetEvent.zig");
|
|||||||
pub const Mutex = @import("Thread/Mutex.zig");
|
pub const Mutex = @import("Thread/Mutex.zig");
|
||||||
pub const Semaphore = @import("Thread/Semaphore.zig");
|
pub const Semaphore = @import("Thread/Semaphore.zig");
|
||||||
pub const Condition = @import("Thread/Condition.zig");
|
pub const Condition = @import("Thread/Condition.zig");
|
||||||
|
pub const RwLock = @import("Thread/RwLock.zig");
|
||||||
|
|
||||||
pub const use_pthreads = target.os.tag != .windows and target.os.tag != .wasi and builtin.link_libc;
|
pub const use_pthreads = target.os.tag != .windows and target.os.tag != .wasi and builtin.link_libc;
|
||||||
const is_gnu = target.abi.isGnu();
|
const is_gnu = target.abi.isGnu();
|
||||||
@@ -1151,3 +1152,27 @@ test "Thread.detach" {
|
|||||||
event.wait();
|
event.wait();
|
||||||
try std.testing.expectEqual(value, 1);
|
try std.testing.expectEqual(value, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn testWaitForSignal(mutex: *Mutex, cond: *Condition) void {
|
||||||
|
mutex.lock();
|
||||||
|
defer mutex.unlock();
|
||||||
|
cond.signal();
|
||||||
|
cond.wait(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Condition.signal" {
|
||||||
|
if (builtin.single_threaded) return error.SkipZigTest;
|
||||||
|
|
||||||
|
var mutex = Mutex{};
|
||||||
|
var cond = Condition{};
|
||||||
|
|
||||||
|
var thread: Thread = undefined;
|
||||||
|
{
|
||||||
|
mutex.lock();
|
||||||
|
defer mutex.unlock();
|
||||||
|
thread = try Thread.spawn(.{}, testWaitForSignal, .{ &mutex, &cond });
|
||||||
|
cond.wait(&mutex);
|
||||||
|
cond.signal();
|
||||||
|
}
|
||||||
|
thread.join();
|
||||||
|
}
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ pub const AtomicCondition = struct {
|
|||||||
.linux => {
|
.linux => {
|
||||||
switch (linux.getErrno(linux.futex_wait(
|
switch (linux.getErrno(linux.futex_wait(
|
||||||
&cond.futex,
|
&cond.futex,
|
||||||
linux.FUTEX_PRIVATE_FLAG | linux.FUTEX_WAIT,
|
linux.FUTEX.PRIVATE_FLAG | linux.FUTEX.WAIT,
|
||||||
0,
|
0,
|
||||||
null,
|
null,
|
||||||
))) {
|
))) {
|
||||||
@@ -128,7 +128,7 @@ pub const AtomicCondition = struct {
|
|||||||
.linux => {
|
.linux => {
|
||||||
switch (linux.getErrno(linux.futex_wake(
|
switch (linux.getErrno(linux.futex_wake(
|
||||||
&cond.futex,
|
&cond.futex,
|
||||||
linux.FUTEX_PRIVATE_FLAG | linux.FUTEX_WAKE,
|
linux.FUTEX.PRIVATE_FLAG | linux.FUTEX.WAKE,
|
||||||
1,
|
1,
|
||||||
))) {
|
))) {
|
||||||
.SUCCESS => {},
|
.SUCCESS => {},
|
||||||
|
|||||||
@@ -3,15 +3,12 @@
|
|||||||
//! This API requires being initialized at runtime, and initialization
|
//! This API requires being initialized at runtime, and initialization
|
||||||
//! can fail. Once initialized, the core operations cannot fail.
|
//! can fail. Once initialized, the core operations cannot fail.
|
||||||
|
|
||||||
impl: Impl,
|
impl: Impl = .{},
|
||||||
|
|
||||||
const RwLock = @This();
|
const RwLock = @This();
|
||||||
const std = @import("../std.zig");
|
const std = @import("../std.zig");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const Mutex = std.Thread.Mutex;
|
|
||||||
const Semaphore = std.Semaphore;
|
|
||||||
const CondVar = std.CondVar;
|
|
||||||
|
|
||||||
pub const Impl = if (builtin.single_threaded)
|
pub const Impl = if (builtin.single_threaded)
|
||||||
SingleThreadedRwLock
|
SingleThreadedRwLock
|
||||||
@@ -20,14 +17,6 @@ else if (std.Thread.use_pthreads)
|
|||||||
else
|
else
|
||||||
DefaultRwLock;
|
DefaultRwLock;
|
||||||
|
|
||||||
pub fn init(rwl: *RwLock) void {
|
|
||||||
return rwl.impl.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deinit(rwl: *RwLock) void {
|
|
||||||
return rwl.impl.deinit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Attempts to obtain exclusive lock ownership.
|
/// Attempts to obtain exclusive lock ownership.
|
||||||
/// Returns `true` if the lock is obtained, `false` otherwise.
|
/// Returns `true` if the lock is obtained, `false` otherwise.
|
||||||
pub fn tryLock(rwl: *RwLock) bool {
|
pub fn tryLock(rwl: *RwLock) bool {
|
||||||
@@ -64,20 +53,8 @@ pub fn unlockShared(rwl: *RwLock) void {
|
|||||||
/// Single-threaded applications use this for deadlock checks in
|
/// Single-threaded applications use this for deadlock checks in
|
||||||
/// debug mode, and no-ops in release modes.
|
/// debug mode, and no-ops in release modes.
|
||||||
pub const SingleThreadedRwLock = struct {
|
pub const SingleThreadedRwLock = struct {
|
||||||
state: enum { unlocked, locked_exclusive, locked_shared },
|
state: enum { unlocked, locked_exclusive, locked_shared } = .unlocked,
|
||||||
shared_count: usize,
|
shared_count: usize = 0,
|
||||||
|
|
||||||
pub fn init(rwl: *SingleThreadedRwLock) void {
|
|
||||||
rwl.* = .{
|
|
||||||
.state = .unlocked,
|
|
||||||
.shared_count = 0,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deinit(rwl: *SingleThreadedRwLock) void {
|
|
||||||
assert(rwl.state == .unlocked);
|
|
||||||
assert(rwl.shared_count == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Attempts to obtain exclusive lock ownership.
|
/// Attempts to obtain exclusive lock ownership.
|
||||||
/// Returns `true` if the lock is obtained, `false` otherwise.
|
/// Returns `true` if the lock is obtained, `false` otherwise.
|
||||||
@@ -152,55 +129,41 @@ pub const SingleThreadedRwLock = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const PthreadRwLock = struct {
|
pub const PthreadRwLock = struct {
|
||||||
rwlock: pthread_rwlock_t,
|
rwlock: std.c.pthread_rwlock_t = .{},
|
||||||
|
|
||||||
pub fn init(rwl: *PthreadRwLock) void {
|
|
||||||
rwl.* = .{ .rwlock = .{} };
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deinit(rwl: *PthreadRwLock) void {
|
|
||||||
const safe_rc: std.os.E = switch (builtin.os.tag) {
|
|
||||||
.dragonfly, .netbsd => .AGAIN,
|
|
||||||
else => .SUCCESS,
|
|
||||||
};
|
|
||||||
const rc = std.c.pthread_rwlock_destroy(&rwl.rwlock);
|
|
||||||
assert(rc == .SUCCESS or rc == safe_rc);
|
|
||||||
rwl.* = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn tryLock(rwl: *PthreadRwLock) bool {
|
pub fn tryLock(rwl: *PthreadRwLock) bool {
|
||||||
return pthread_rwlock_trywrlock(&rwl.rwlock) == .SUCCESS;
|
return std.c.pthread_rwlock_trywrlock(&rwl.rwlock) == .SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lock(rwl: *PthreadRwLock) void {
|
pub fn lock(rwl: *PthreadRwLock) void {
|
||||||
const rc = pthread_rwlock_wrlock(&rwl.rwlock);
|
const rc = std.c.pthread_rwlock_wrlock(&rwl.rwlock);
|
||||||
assert(rc == .SUCCESS);
|
assert(rc == .SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unlock(rwl: *PthreadRwLock) void {
|
pub fn unlock(rwl: *PthreadRwLock) void {
|
||||||
const rc = pthread_rwlock_unlock(&rwl.rwlock);
|
const rc = std.c.pthread_rwlock_unlock(&rwl.rwlock);
|
||||||
assert(rc == .SUCCESS);
|
assert(rc == .SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tryLockShared(rwl: *PthreadRwLock) bool {
|
pub fn tryLockShared(rwl: *PthreadRwLock) bool {
|
||||||
return pthread_rwlock_tryrdlock(&rwl.rwlock) == .SUCCESS;
|
return std.c.pthread_rwlock_tryrdlock(&rwl.rwlock) == .SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lockShared(rwl: *PthreadRwLock) void {
|
pub fn lockShared(rwl: *PthreadRwLock) void {
|
||||||
const rc = pthread_rwlock_rdlock(&rwl.rwlock);
|
const rc = std.c.pthread_rwlock_rdlock(&rwl.rwlock);
|
||||||
assert(rc == .SUCCESS);
|
assert(rc == .SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unlockShared(rwl: *PthreadRwLock) void {
|
pub fn unlockShared(rwl: *PthreadRwLock) void {
|
||||||
const rc = pthread_rwlock_unlock(&rwl.rwlock);
|
const rc = std.c.pthread_rwlock_unlock(&rwl.rwlock);
|
||||||
assert(rc == .SUCCESS);
|
assert(rc == .SUCCESS);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const DefaultRwLock = struct {
|
pub const DefaultRwLock = struct {
|
||||||
state: usize,
|
state: usize = 0,
|
||||||
mutex: Mutex,
|
mutex: std.Thread.Mutex = .{},
|
||||||
semaphore: Semaphore,
|
semaphore: std.Thread.Semaphore = .{},
|
||||||
|
|
||||||
const IS_WRITING: usize = 1;
|
const IS_WRITING: usize = 1;
|
||||||
const WRITER: usize = 1 << 1;
|
const WRITER: usize = 1 << 1;
|
||||||
@@ -209,20 +172,6 @@ pub const DefaultRwLock = struct {
|
|||||||
const READER_MASK: usize = std.math.maxInt(Count) << @ctz(usize, READER);
|
const READER_MASK: usize = std.math.maxInt(Count) << @ctz(usize, READER);
|
||||||
const Count = std.meta.Int(.unsigned, @divFloor(std.meta.bitCount(usize) - 1, 2));
|
const Count = std.meta.Int(.unsigned, @divFloor(std.meta.bitCount(usize) - 1, 2));
|
||||||
|
|
||||||
pub fn init(rwl: *DefaultRwLock) void {
|
|
||||||
rwl.* = .{
|
|
||||||
.state = 0,
|
|
||||||
.mutex = Mutex.init(),
|
|
||||||
.semaphore = Semaphore.init(0),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deinit(rwl: *DefaultRwLock) void {
|
|
||||||
rwl.semaphore.deinit();
|
|
||||||
rwl.mutex.deinit();
|
|
||||||
rwl.* = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn tryLock(rwl: *DefaultRwLock) bool {
|
pub fn tryLock(rwl: *DefaultRwLock) bool {
|
||||||
if (rwl.mutex.tryLock()) {
|
if (rwl.mutex.tryLock()) {
|
||||||
const state = @atomicLoad(usize, &rwl.state, .SeqCst);
|
const state = @atomicLoad(usize, &rwl.state, .SeqCst);
|
||||||
|
|||||||
@@ -1552,6 +1552,8 @@ pub const LibExeObjStep = struct {
|
|||||||
|
|
||||||
subsystem: ?std.Target.SubSystem = null,
|
subsystem: ?std.Target.SubSystem = null,
|
||||||
|
|
||||||
|
entry_symbol_name: ?[]const u8 = null,
|
||||||
|
|
||||||
/// Overrides the default stack size
|
/// Overrides the default stack size
|
||||||
stack_size: ?u64 = null,
|
stack_size: ?u64 = null,
|
||||||
|
|
||||||
@@ -2253,6 +2255,11 @@ pub const LibExeObjStep = struct {
|
|||||||
try zig_args.append(@tagName(builder.color));
|
try zig_args.append(@tagName(builder.color));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (self.entry_symbol_name) |entry| {
|
||||||
|
try zig_args.append("--entry");
|
||||||
|
try zig_args.append(entry);
|
||||||
|
}
|
||||||
|
|
||||||
if (self.stack_size) |stack_size| {
|
if (self.stack_size) |stack_size| {
|
||||||
try zig_args.append("--stack");
|
try zig_args.append("--stack");
|
||||||
try zig_args.append(try std.fmt.allocPrint(builder.allocator, "{}", .{stack_size}));
|
try zig_args.append(try std.fmt.allocPrint(builder.allocator, "{}", .{stack_size}));
|
||||||
@@ -2651,6 +2658,8 @@ pub const LibExeObjStep = struct {
|
|||||||
try zig_args.append(bin_name);
|
try zig_args.append(bin_name);
|
||||||
try zig_args.append("--test-cmd");
|
try zig_args.append("--test-cmd");
|
||||||
try zig_args.append("--dir=.");
|
try zig_args.append("--dir=.");
|
||||||
|
try zig_args.append("--test-cmd");
|
||||||
|
try zig_args.append("--allow-unknown-exports"); // TODO: Remove when stage2 is default compiler
|
||||||
try zig_args.append("--test-cmd-bin");
|
try zig_args.append("--test-cmd-bin");
|
||||||
} else {
|
} else {
|
||||||
try zig_args.append("--test-no-exec");
|
try zig_args.append("--test-no-exec");
|
||||||
|
|||||||
@@ -357,6 +357,8 @@ pub extern "c" fn openlog(ident: [*:0]const u8, logopt: c_int, facility: c_int)
|
|||||||
pub extern "c" fn closelog() void;
|
pub extern "c" fn closelog() void;
|
||||||
pub extern "c" fn setlogmask(maskpri: c_int) c_int;
|
pub extern "c" fn setlogmask(maskpri: c_int) c_int;
|
||||||
|
|
||||||
|
pub extern "c" fn if_nametoindex([*:0]const u8) c_int;
|
||||||
|
|
||||||
pub const max_align_t = if (builtin.abi == .msvc)
|
pub const max_align_t = if (builtin.abi == .msvc)
|
||||||
f64
|
f64
|
||||||
else if (builtin.target.isDarwin())
|
else if (builtin.target.isDarwin())
|
||||||
|
|||||||
@@ -6,6 +6,26 @@ const native_arch = builtin.target.cpu.arch;
|
|||||||
const maxInt = std.math.maxInt;
|
const maxInt = std.math.maxInt;
|
||||||
const iovec_const = std.os.iovec_const;
|
const iovec_const = std.os.iovec_const;
|
||||||
|
|
||||||
|
const arch_bits = switch (native_arch) {
|
||||||
|
.aarch64 => @import("darwin/aarch64.zig"),
|
||||||
|
.x86_64 => @import("darwin/x86_64.zig"),
|
||||||
|
else => struct {},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const ucontext_t = extern struct {
|
||||||
|
onstack: c_int,
|
||||||
|
sigmask: sigset_t,
|
||||||
|
stack: stack_t,
|
||||||
|
link: ?*ucontext_t,
|
||||||
|
mcsize: u64,
|
||||||
|
mcontext: *mcontext_t,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const mcontext_t = extern struct {
|
||||||
|
es: arch_bits.exception_state,
|
||||||
|
ss: arch_bits.thread_state,
|
||||||
|
};
|
||||||
|
|
||||||
extern "c" fn __error() *c_int;
|
extern "c" fn __error() *c_int;
|
||||||
pub extern "c" fn NSVersionOfRunTimeLibrary(library_name: [*:0]const u8) u32;
|
pub extern "c" fn NSVersionOfRunTimeLibrary(library_name: [*:0]const u8) u32;
|
||||||
pub extern "c" fn _NSGetExecutablePath(buf: [*:0]u8, bufsize: *u32) c_int;
|
pub extern "c" fn _NSGetExecutablePath(buf: [*:0]u8, bufsize: *u32) c_int;
|
||||||
@@ -108,6 +128,8 @@ pub fn sigaddset(set: *sigset_t, signo: u5) void {
|
|||||||
|
|
||||||
pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
|
pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
|
||||||
|
|
||||||
|
pub const IFNAMESIZE = 16;
|
||||||
|
|
||||||
pub const AI = struct {
|
pub const AI = struct {
|
||||||
/// get address to use bind()
|
/// get address to use bind()
|
||||||
pub const PASSIVE = 0x00000001;
|
pub const PASSIVE = 0x00000001;
|
||||||
|
|||||||
18
lib/std/c/darwin/aarch64.zig
Normal file
18
lib/std/c/darwin/aarch64.zig
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
// See C headers in
|
||||||
|
// lib/libc/include/aarch64-macos.12-gnu/mach/arm/_structs.h
|
||||||
|
|
||||||
|
pub const exception_state = extern struct {
|
||||||
|
far: u64, // Virtual Fault Address
|
||||||
|
esr: u32, // Exception syndrome
|
||||||
|
exception: u32, // Number of arm exception taken
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const thread_state = extern struct {
|
||||||
|
regs: [29]u64, // General purpose registers
|
||||||
|
fp: u64, // Frame pointer x29
|
||||||
|
lr: u64, // Link register x30
|
||||||
|
sp: u64, // Stack pointer x31
|
||||||
|
pc: u64, // Program counter
|
||||||
|
cpsr: u32, // Current program status register
|
||||||
|
__pad: u32,
|
||||||
|
};
|
||||||
30
lib/std/c/darwin/x86_64.zig
Normal file
30
lib/std/c/darwin/x86_64.zig
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
pub const exception_state = extern struct {
|
||||||
|
trapno: u16,
|
||||||
|
cpu: u16,
|
||||||
|
err: u32,
|
||||||
|
faultvaddr: u64,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const thread_state = extern struct {
|
||||||
|
rax: u64,
|
||||||
|
rbx: u64,
|
||||||
|
rcx: u64,
|
||||||
|
rdx: u64,
|
||||||
|
rdi: u64,
|
||||||
|
rsi: u64,
|
||||||
|
rbp: u64,
|
||||||
|
rsp: u64,
|
||||||
|
r8: u64,
|
||||||
|
r9: u64,
|
||||||
|
r10: u64,
|
||||||
|
r11: u64,
|
||||||
|
r12: u64,
|
||||||
|
r13: u64,
|
||||||
|
r14: u64,
|
||||||
|
r15: u64,
|
||||||
|
rip: u64,
|
||||||
|
rflags: u64,
|
||||||
|
cs: u64,
|
||||||
|
fs: u64,
|
||||||
|
gs: u64,
|
||||||
|
};
|
||||||
@@ -56,6 +56,7 @@ pub const STDOUT_FILENO = linux.STDOUT_FILENO;
|
|||||||
pub const SYS = linux.SYS;
|
pub const SYS = linux.SYS;
|
||||||
pub const Sigaction = linux.Sigaction;
|
pub const Sigaction = linux.Sigaction;
|
||||||
pub const TCP = linux.TCP;
|
pub const TCP = linux.TCP;
|
||||||
|
pub const TCSA = linux.TCSA;
|
||||||
pub const VDSO = linux.VDSO;
|
pub const VDSO = linux.VDSO;
|
||||||
pub const W = linux.W;
|
pub const W = linux.W;
|
||||||
pub const W_OK = linux.W_OK;
|
pub const W_OK = linux.W_OK;
|
||||||
@@ -85,11 +86,13 @@ pub const pollfd = linux.pollfd;
|
|||||||
pub const rlim_t = linux.rlim_t;
|
pub const rlim_t = linux.rlim_t;
|
||||||
pub const rlimit = linux.rlimit;
|
pub const rlimit = linux.rlimit;
|
||||||
pub const rlimit_resource = linux.rlimit_resource;
|
pub const rlimit_resource = linux.rlimit_resource;
|
||||||
|
pub const rusage = linux.rusage;
|
||||||
pub const siginfo_t = linux.siginfo_t;
|
pub const siginfo_t = linux.siginfo_t;
|
||||||
pub const sigset_t = linux.sigset_t;
|
pub const sigset_t = linux.sigset_t;
|
||||||
pub const sockaddr = linux.sockaddr;
|
pub const sockaddr = linux.sockaddr;
|
||||||
pub const socklen_t = linux.socklen_t;
|
pub const socklen_t = linux.socklen_t;
|
||||||
pub const stack_t = linux.stack_t;
|
pub const stack_t = linux.stack_t;
|
||||||
|
pub const tcflag_t = linux.tcflag_t;
|
||||||
pub const termios = linux.termios;
|
pub const termios = linux.termios;
|
||||||
pub const time_t = linux.time_t;
|
pub const time_t = linux.time_t;
|
||||||
pub const timespec = linux.timespec;
|
pub const timespec = linux.timespec;
|
||||||
|
|||||||
@@ -703,8 +703,48 @@ pub const T = struct {
|
|||||||
pub const IOCXMTFRAME = 0x80087444;
|
pub const IOCXMTFRAME = 0x80087444;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// BSD Authentication
|
||||||
|
pub const auth_item_t = c_int;
|
||||||
|
|
||||||
|
pub const AUTHV = struct {
|
||||||
|
pub const ALL: auth_item_t = 0;
|
||||||
|
pub const CHALLENGE: auth_item_t = 1;
|
||||||
|
pub const CLASS: auth_item_t = 2;
|
||||||
|
pub const NAME: auth_item_t = 3;
|
||||||
|
pub const SERVICE: auth_item_t = 4;
|
||||||
|
pub const STYLE: auth_item_t = 5;
|
||||||
|
pub const INTERACTIVE: auth_item_t = 6;
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const BI = struct {
|
||||||
|
pub const AUTH = "authorize"; // Accepted authentication
|
||||||
|
pub const REJECT = "reject"; // Rejected authentication
|
||||||
|
pub const CHALLENGE = "reject challenge"; // Reject with a challenge
|
||||||
|
pub const SILENT = "reject silent"; // Reject silently
|
||||||
|
pub const REMOVE = "remove"; // remove file on error
|
||||||
|
pub const ROOTOKAY = "authorize root"; // root authenticated
|
||||||
|
pub const SECURE = "authorize secure"; // okay on non-secure line
|
||||||
|
pub const SETENV = "setenv"; // set environment variable
|
||||||
|
pub const UNSETENV = "unsetenv"; // unset environment variable
|
||||||
|
pub const VALUE = "value"; // set local variable
|
||||||
|
pub const EXPIRED = "reject expired"; // account expired
|
||||||
|
pub const PWEXPIRED = "reject pwexpired"; // password expired
|
||||||
|
pub const FDPASS = "fd"; // child is passing an fd
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const AUTH = struct {
|
||||||
|
pub const OKAY: c_int = 0x01; // user authenticated
|
||||||
|
pub const ROOTOKAY: c_int = 0x02; // authenticated as root
|
||||||
|
pub const SECURE: c_int = 0x04; // secure login
|
||||||
|
pub const SILENT: c_int = 0x08; // silent rejection
|
||||||
|
pub const CHALLENGE: c_int = 0x10; // a challenge was given
|
||||||
|
pub const EXPIRED: c_int = 0x20; // account expired
|
||||||
|
pub const PWEXPIRED: c_int = 0x40; // password expired
|
||||||
|
pub const ALLOW: c_int = (OKAY | ROOTOKAY | SECURE);
|
||||||
|
};
|
||||||
|
|
||||||
// Term
|
// Term
|
||||||
const V = struct {
|
pub const V = struct {
|
||||||
pub const EOF = 0; // ICANON
|
pub const EOF = 0; // ICANON
|
||||||
pub const EOL = 1; // ICANON
|
pub const EOL = 1; // ICANON
|
||||||
pub const EOL2 = 2; // ICANON
|
pub const EOL2 = 2; // ICANON
|
||||||
@@ -942,7 +982,7 @@ comptime {
|
|||||||
std.debug.assert(@sizeOf(siginfo_t) == 136);
|
std.debug.assert(@sizeOf(siginfo_t) == 136);
|
||||||
}
|
}
|
||||||
|
|
||||||
const arch_bits = switch (builtin.cpu.arch) {
|
pub usingnamespace switch (builtin.cpu.arch) {
|
||||||
.x86_64 => struct {
|
.x86_64 => struct {
|
||||||
pub const ucontext_t = extern struct {
|
pub const ucontext_t = extern struct {
|
||||||
sc_rdi: c_long,
|
sc_rdi: c_long,
|
||||||
@@ -972,7 +1012,7 @@ const arch_bits = switch (builtin.cpu.arch) {
|
|||||||
sc_rsp: c_long,
|
sc_rsp: c_long,
|
||||||
sc_ss: c_long,
|
sc_ss: c_long,
|
||||||
|
|
||||||
sc_fpstate: arch_bits.fxsave64,
|
sc_fpstate: fxsave64,
|
||||||
__sc_unused: c_int,
|
__sc_unused: c_int,
|
||||||
sc_mask: c_int,
|
sc_mask: c_int,
|
||||||
sc_cookie: c_long,
|
sc_cookie: c_long,
|
||||||
@@ -995,8 +1035,6 @@ const arch_bits = switch (builtin.cpu.arch) {
|
|||||||
},
|
},
|
||||||
else => struct {},
|
else => struct {},
|
||||||
};
|
};
|
||||||
pub const ucontext_t = arch_bits.ucontext_t;
|
|
||||||
pub const fxsave64 = arch_bits.fxsave64;
|
|
||||||
|
|
||||||
pub const sigset_t = c_uint;
|
pub const sigset_t = c_uint;
|
||||||
pub const empty_sigset: sigset_t = 0;
|
pub const empty_sigset: sigset_t = 0;
|
||||||
|
|||||||
@@ -252,6 +252,35 @@ pub const ChildProcess = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const WindowsAsyncReadResult = enum {
|
||||||
|
pending,
|
||||||
|
closed,
|
||||||
|
full,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn windowsAsyncRead(
|
||||||
|
handle: windows.HANDLE,
|
||||||
|
overlapped: *windows.OVERLAPPED,
|
||||||
|
buf: *std.ArrayList(u8),
|
||||||
|
bump_amt: usize,
|
||||||
|
max_output_bytes: usize,
|
||||||
|
) !WindowsAsyncReadResult {
|
||||||
|
while (true) {
|
||||||
|
const new_capacity = std.math.min(buf.items.len + bump_amt, max_output_bytes);
|
||||||
|
try buf.ensureTotalCapacity(new_capacity);
|
||||||
|
const next_buf = buf.unusedCapacitySlice();
|
||||||
|
if (next_buf.len == 0) return .full;
|
||||||
|
var read_bytes: u32 = undefined;
|
||||||
|
const read_result = windows.kernel32.ReadFile(handle, next_buf.ptr, math.cast(u32, next_buf.len) catch maxInt(u32), &read_bytes, overlapped);
|
||||||
|
if (read_result == 0) return switch (windows.kernel32.GetLastError()) {
|
||||||
|
.IO_PENDING => .pending,
|
||||||
|
.BROKEN_PIPE => .closed,
|
||||||
|
else => |err| windows.unexpectedError(err),
|
||||||
|
};
|
||||||
|
buf.items.len += read_bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn collectOutputWindows(child: *const ChildProcess, outs: [2]*std.ArrayList(u8), max_output_bytes: usize) !void {
|
fn collectOutputWindows(child: *const ChildProcess, outs: [2]*std.ArrayList(u8), max_output_bytes: usize) !void {
|
||||||
const bump_amt = 512;
|
const bump_amt = 512;
|
||||||
const handles = [_]windows.HANDLE{
|
const handles = [_]windows.HANDLE{
|
||||||
@@ -274,15 +303,17 @@ pub const ChildProcess = struct {
|
|||||||
|
|
||||||
// Windows Async IO requires an initial call to ReadFile before waiting on the handle
|
// Windows Async IO requires an initial call to ReadFile before waiting on the handle
|
||||||
for ([_]u1{ 0, 1 }) |i| {
|
for ([_]u1{ 0, 1 }) |i| {
|
||||||
const new_capacity = std.math.min(outs[i].items.len + bump_amt, max_output_bytes);
|
switch (try windowsAsyncRead(handles[i], &overlapped[i], outs[i], bump_amt, max_output_bytes)) {
|
||||||
try outs[i].ensureTotalCapacity(new_capacity);
|
.pending => {
|
||||||
const buf = outs[i].unusedCapacitySlice();
|
wait_objects[wait_object_count] = handles[i];
|
||||||
_ = windows.kernel32.ReadFile(handles[i], buf.ptr, math.cast(u32, buf.len) catch maxInt(u32), null, &overlapped[i]);
|
wait_object_count += 1;
|
||||||
wait_objects[wait_object_count] = handles[i];
|
},
|
||||||
wait_object_count += 1;
|
.closed => {}, // don't add to the wait_objects list
|
||||||
|
.full => return if (i == 0) error.StdoutStreamTooLong else error.StderrStreamTooLong,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (wait_object_count > 0) {
|
||||||
const status = windows.kernel32.WaitForMultipleObjects(wait_object_count, &wait_objects, 0, windows.INFINITE);
|
const status = windows.kernel32.WaitForMultipleObjects(wait_object_count, &wait_objects, 0, windows.INFINITE);
|
||||||
if (status == windows.WAIT_FAILED) {
|
if (status == windows.WAIT_FAILED) {
|
||||||
switch (windows.kernel32.GetLastError()) {
|
switch (windows.kernel32.GetLastError()) {
|
||||||
@@ -306,23 +337,21 @@ pub const ChildProcess = struct {
|
|||||||
var read_bytes: u32 = undefined;
|
var read_bytes: u32 = undefined;
|
||||||
if (windows.kernel32.GetOverlappedResult(handles[i], &overlapped[i], &read_bytes, 0) == 0) {
|
if (windows.kernel32.GetOverlappedResult(handles[i], &overlapped[i], &read_bytes, 0) == 0) {
|
||||||
switch (windows.kernel32.GetLastError()) {
|
switch (windows.kernel32.GetLastError()) {
|
||||||
.BROKEN_PIPE => {
|
.BROKEN_PIPE => continue,
|
||||||
if (wait_object_count == 0)
|
|
||||||
break;
|
|
||||||
continue;
|
|
||||||
},
|
|
||||||
else => |err| return windows.unexpectedError(err),
|
else => |err| return windows.unexpectedError(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outs[i].items.len += read_bytes;
|
outs[i].items.len += read_bytes;
|
||||||
const new_capacity = std.math.min(outs[i].items.len + bump_amt, max_output_bytes);
|
|
||||||
try outs[i].ensureTotalCapacity(new_capacity);
|
switch (try windowsAsyncRead(handles[i], &overlapped[i], outs[i], bump_amt, max_output_bytes)) {
|
||||||
const buf = outs[i].unusedCapacitySlice();
|
.pending => {
|
||||||
if (buf.len == 0) return if (i == 0) error.StdoutStreamTooLong else error.StderrStreamTooLong;
|
wait_objects[wait_object_count] = handles[i];
|
||||||
_ = windows.kernel32.ReadFile(handles[i], buf.ptr, math.cast(u32, buf.len) catch maxInt(u32), null, &overlapped[i]);
|
wait_object_count += 1;
|
||||||
wait_objects[wait_object_count] = handles[i];
|
},
|
||||||
wait_object_count += 1;
|
.closed => {}, // don't add to the wait_objects list
|
||||||
|
.full => return if (i == 0) error.StdoutStreamTooLong else error.StderrStreamTooLong,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ pub const nacl = struct {
|
|||||||
pub const utils = @import("crypto/utils.zig");
|
pub const utils = @import("crypto/utils.zig");
|
||||||
|
|
||||||
/// This is a thread-local, cryptographically secure pseudo random number generator.
|
/// This is a thread-local, cryptographically secure pseudo random number generator.
|
||||||
pub const random = &@import("crypto/tlcsprng.zig").interface;
|
pub const random = @import("crypto/tlcsprng.zig").interface;
|
||||||
|
|
||||||
const std = @import("std.zig");
|
const std = @import("std.zig");
|
||||||
|
|
||||||
|
|||||||
@@ -126,12 +126,29 @@ test "expand 128-bit key" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "expand 256-bit key" {
|
test "expand 256-bit key" {
|
||||||
const key = [_]u8{ 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 };
|
const key = [_]u8{
|
||||||
|
0x60, 0x3d, 0xeb, 0x10,
|
||||||
|
0x15, 0xca, 0x71, 0xbe,
|
||||||
|
0x2b, 0x73, 0xae, 0xf0,
|
||||||
|
0x85, 0x7d, 0x77, 0x81,
|
||||||
|
0x1f, 0x35, 0x2c, 0x07,
|
||||||
|
0x3b, 0x61, 0x08, 0xd7,
|
||||||
|
0x2d, 0x98, 0x10, 0xa3,
|
||||||
|
0x09, 0x14, 0xdf, 0xf4,
|
||||||
|
};
|
||||||
const exp_enc = [_]*const [32:0]u8{
|
const exp_enc = [_]*const [32:0]u8{
|
||||||
"603deb1015ca71be2b73aef0857d7781", "1f352c073b6108d72d9810a30914dff4", "9ba354118e6925afa51a8b5f2067fcde", "a8b09c1a93d194cdbe49846eb75d5b9a", "d59aecb85bf3c917fee94248de8ebe96", "b5a9328a2678a647983122292f6c79b3", "812c81addadf48ba24360af2fab8b464", "98c5bfc9bebd198e268c3ba709e04214", "68007bacb2df331696e939e46c518d80", "c814e20476a9fb8a5025c02d59c58239", "de1369676ccc5a71fa2563959674ee15", "5886ca5d2e2f31d77e0af1fa27cf73c3", "749c47ab18501ddae2757e4f7401905a", "cafaaae3e4d59b349adf6acebd10190d", "fe4890d1e6188d0b046df344706c631e",
|
"603deb1015ca71be2b73aef0857d7781", "1f352c073b6108d72d9810a30914dff4", "9ba354118e6925afa51a8b5f2067fcde",
|
||||||
|
"a8b09c1a93d194cdbe49846eb75d5b9a", "d59aecb85bf3c917fee94248de8ebe96", "b5a9328a2678a647983122292f6c79b3",
|
||||||
|
"812c81addadf48ba24360af2fab8b464", "98c5bfc9bebd198e268c3ba709e04214", "68007bacb2df331696e939e46c518d80",
|
||||||
|
"c814e20476a9fb8a5025c02d59c58239", "de1369676ccc5a71fa2563959674ee15", "5886ca5d2e2f31d77e0af1fa27cf73c3",
|
||||||
|
"749c47ab18501ddae2757e4f7401905a", "cafaaae3e4d59b349adf6acebd10190d", "fe4890d1e6188d0b046df344706c631e",
|
||||||
};
|
};
|
||||||
const exp_dec = [_]*const [32:0]u8{
|
const exp_dec = [_]*const [32:0]u8{
|
||||||
"fe4890d1e6188d0b046df344706c631e", "ada23f4963e23b2455427c8a5c709104", "57c96cf6074f07c0706abb07137f9241", "b668b621ce40046d36a047ae0932ed8e", "34ad1e4450866b367725bcc763152946", "32526c367828b24cf8e043c33f92aa20", "c440b289642b757227a3d7f114309581", "d669a7334a7ade7a80c8f18fc772e9e3", "25ba3c22a06bc7fb4388a28333934270", "54fb808b9c137949cab22ff547ba186c", "6c3d632985d1fbd9e3e36578701be0f3", "4a7459f9c8e8f9c256a156bc8d083799", "42107758e9ec98f066329ea193f8858b", "8ec6bff6829ca03b9e49af7edba96125", "603deb1015ca71be2b73aef0857d7781",
|
"fe4890d1e6188d0b046df344706c631e", "ada23f4963e23b2455427c8a5c709104", "57c96cf6074f07c0706abb07137f9241",
|
||||||
|
"b668b621ce40046d36a047ae0932ed8e", "34ad1e4450866b367725bcc763152946", "32526c367828b24cf8e043c33f92aa20",
|
||||||
|
"c440b289642b757227a3d7f114309581", "d669a7334a7ade7a80c8f18fc772e9e3", "25ba3c22a06bc7fb4388a28333934270",
|
||||||
|
"54fb808b9c137949cab22ff547ba186c", "6c3d632985d1fbd9e3e36578701be0f3", "4a7459f9c8e8f9c256a156bc8d083799",
|
||||||
|
"42107758e9ec98f066329ea193f8858b", "8ec6bff6829ca03b9e49af7edba96125", "603deb1015ca71be2b73aef0857d7781",
|
||||||
};
|
};
|
||||||
const enc = Aes256.initEnc(key);
|
const enc = Aes256.initEnc(key);
|
||||||
const dec = Aes256.initDec(key);
|
const dec = Aes256.initDec(key);
|
||||||
|
|||||||
@@ -26,12 +26,279 @@ pub const hash_length: usize = 60;
|
|||||||
|
|
||||||
const State = struct {
|
const State = struct {
|
||||||
sboxes: [4][256]u32 = [4][256]u32{
|
sboxes: [4][256]u32 = [4][256]u32{
|
||||||
.{ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a },
|
.{
|
||||||
.{ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 },
|
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
|
||||||
.{ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 },
|
0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
|
||||||
.{ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 },
|
0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
|
||||||
|
0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
|
||||||
|
0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
|
||||||
|
0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
|
||||||
|
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
|
||||||
|
0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
|
||||||
|
0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
|
||||||
|
0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
|
||||||
|
0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
|
||||||
|
0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
|
||||||
|
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
|
||||||
|
0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
|
||||||
|
0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
|
||||||
|
0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
|
||||||
|
0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
|
||||||
|
0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
|
||||||
|
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
|
||||||
|
0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
|
||||||
|
0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
|
||||||
|
0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
|
||||||
|
0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
|
||||||
|
0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
|
||||||
|
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
|
||||||
|
0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
|
||||||
|
0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
|
||||||
|
0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
|
||||||
|
0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
|
||||||
|
0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
|
||||||
|
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
|
||||||
|
0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
|
||||||
|
0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
|
||||||
|
0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
|
||||||
|
0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
|
||||||
|
0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
|
||||||
|
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
|
||||||
|
0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
|
||||||
|
0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
|
||||||
|
0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
|
||||||
|
0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
|
||||||
|
0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
|
||||||
|
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
|
||||||
|
0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
|
||||||
|
0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
|
||||||
|
0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
|
||||||
|
0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
|
||||||
|
0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
|
||||||
|
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
|
||||||
|
0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
|
||||||
|
0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
|
||||||
|
0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
|
||||||
|
0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
|
||||||
|
0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
|
||||||
|
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
|
||||||
|
0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
|
||||||
|
0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
|
||||||
|
0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
|
||||||
|
0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
|
||||||
|
0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
|
||||||
|
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
|
||||||
|
0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
|
||||||
|
0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
|
||||||
|
0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
|
||||||
|
0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
|
||||||
|
0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
|
||||||
|
0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
|
||||||
|
0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
|
||||||
|
0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
|
||||||
|
0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
|
||||||
|
0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
|
||||||
|
0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
|
||||||
|
0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
|
||||||
|
0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
|
||||||
|
0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
|
||||||
|
0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
|
||||||
|
0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
|
||||||
|
0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
|
||||||
|
0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
|
||||||
|
0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
|
||||||
|
0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
|
||||||
|
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
|
||||||
|
0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
|
||||||
|
0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
|
||||||
|
0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
|
||||||
|
0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
|
||||||
|
0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
|
||||||
|
0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
|
||||||
|
0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
|
||||||
|
0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
|
||||||
|
0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
|
||||||
|
0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
|
||||||
|
0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
|
||||||
|
0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
|
||||||
|
0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
|
||||||
|
0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
|
||||||
|
0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
|
||||||
|
0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
|
||||||
|
0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
|
||||||
|
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
|
||||||
|
0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
|
||||||
|
0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
|
||||||
|
0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
|
||||||
|
0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
|
||||||
|
0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
|
||||||
|
0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
|
||||||
|
0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
|
||||||
|
0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
|
||||||
|
0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
|
||||||
|
0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
|
||||||
|
0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
|
||||||
|
0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
|
||||||
|
0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
|
||||||
|
0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
|
||||||
|
0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
|
||||||
|
0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
|
||||||
|
0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
|
||||||
|
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
|
||||||
|
0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
|
||||||
|
0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
|
||||||
|
0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
|
||||||
|
0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
|
||||||
|
0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
|
||||||
|
0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
|
||||||
|
0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
|
||||||
|
0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
|
||||||
|
0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
|
||||||
|
0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
|
||||||
|
0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
|
||||||
|
0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
|
||||||
|
0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
|
||||||
|
0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
|
||||||
|
0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
|
||||||
|
0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
|
||||||
|
0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
|
||||||
|
0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
|
||||||
|
0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
|
||||||
|
0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
|
||||||
|
0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
|
||||||
|
0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
|
||||||
|
0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
|
||||||
|
0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
|
||||||
|
0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
|
||||||
|
0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
|
||||||
|
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
|
||||||
|
0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
|
||||||
|
0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
|
||||||
|
0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
|
||||||
|
0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
|
||||||
|
0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
|
||||||
|
0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
|
||||||
|
0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
|
||||||
|
0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
|
||||||
|
0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
|
||||||
|
0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
|
||||||
|
0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
|
||||||
|
0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
|
||||||
|
0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
|
||||||
|
0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
|
||||||
|
0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
|
||||||
|
0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
|
||||||
|
0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
|
||||||
|
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
|
||||||
|
0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
|
||||||
|
0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
|
||||||
|
0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
|
||||||
|
0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
|
||||||
|
0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
|
||||||
|
0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
|
||||||
|
0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
|
||||||
|
0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
|
||||||
|
0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
|
||||||
|
0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
|
||||||
|
0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
|
||||||
|
0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
|
||||||
|
0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
|
||||||
|
0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
|
||||||
|
0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
|
||||||
|
0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
|
||||||
|
0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
|
||||||
|
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
|
||||||
|
0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
|
||||||
|
0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
|
||||||
|
0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
|
||||||
|
0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
|
||||||
|
0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
|
||||||
|
0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
|
||||||
|
0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
|
||||||
|
0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
|
||||||
|
0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
|
||||||
|
0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
|
||||||
|
0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
|
||||||
|
0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
|
||||||
|
0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
|
||||||
|
0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
|
||||||
|
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
|
||||||
|
0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
|
||||||
|
0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
|
||||||
|
0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
|
||||||
|
0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
|
||||||
|
0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
|
||||||
|
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
|
||||||
|
0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
|
||||||
|
0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
|
||||||
|
0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
|
||||||
|
0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
|
||||||
|
0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
|
||||||
|
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
|
||||||
|
0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
|
||||||
|
0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
|
||||||
|
0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
|
||||||
|
0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
|
||||||
|
0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
|
||||||
|
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
|
||||||
|
0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
|
||||||
|
0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
|
||||||
|
0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
|
||||||
|
0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
|
||||||
|
0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
|
||||||
|
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
|
||||||
|
0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
|
||||||
|
0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
|
||||||
|
0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
|
||||||
|
0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
|
||||||
|
0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
|
||||||
|
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
|
||||||
|
0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
|
||||||
|
0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
|
||||||
|
0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
|
||||||
|
0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
|
||||||
|
0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
|
||||||
|
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
|
||||||
|
0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
|
||||||
|
0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
|
||||||
|
0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
|
||||||
|
0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
|
||||||
|
0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
|
||||||
|
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
|
||||||
|
0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
|
||||||
|
0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
|
||||||
|
0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
|
||||||
|
0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
|
||||||
|
0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
|
||||||
|
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
|
||||||
|
0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
|
||||||
|
0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
|
||||||
|
0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
|
||||||
|
0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
|
||||||
|
0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
|
||||||
|
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
|
||||||
|
0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
|
||||||
|
0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
|
||||||
|
0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
subkeys: [18]u32 = [18]u32{
|
||||||
|
0x243f6a88, 0x85a308d3, 0x13198a2e,
|
||||||
|
0x03707344, 0xa4093822, 0x299f31d0,
|
||||||
|
0x082efa98, 0xec4e6c89, 0x452821e6,
|
||||||
|
0x38d01377, 0xbe5466cf, 0x34e90c6c,
|
||||||
|
0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5,
|
||||||
|
0xb5470917, 0x9216d5d9, 0x8979fb1b,
|
||||||
},
|
},
|
||||||
subkeys: [18]u32 = [18]u32{ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b },
|
|
||||||
|
|
||||||
fn toWord(data: []const u8, current: *usize) u32 {
|
fn toWord(data: []const u8, current: *usize) u32 {
|
||||||
var t: u32 = 0;
|
var t: u32 = 0;
|
||||||
|
|||||||
@@ -13,7 +13,38 @@
|
|||||||
//
|
//
|
||||||
// Computed values:
|
// Computed values:
|
||||||
// eval z = z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192)
|
// eval z = z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192)
|
||||||
// bytes_eval z = z[0] + (z[1] << 8) + (z[2] << 16) + (z[3] << 24) + (z[4] << 32) + (z[5] << 40) + (z[6] << 48) + (z[7] << 56) + (z[8] << 64) + (z[9] << 72) + (z[10] << 80) + (z[11] << 88) + (z[12] << 96) + (z[13] << 104) + (z[14] << 112) + (z[15] << 120) + (z[16] << 128) + (z[17] << 136) + (z[18] << 144) + (z[19] << 152) + (z[20] << 160) + (z[21] << 168) + (z[22] << 176) + (z[23] << 184) + (z[24] << 192) + (z[25] << 200) + (z[26] << 208) + (z[27] << 216) + (z[28] << 224) + (z[29] << 232) + (z[30] << 240) + (z[31] << 248)
|
// bytes_eval z = z[0]
|
||||||
|
// + (z[1] << 8)
|
||||||
|
// + (z[2] << 16)
|
||||||
|
// + (z[3] << 24)
|
||||||
|
// + (z[4] << 32)
|
||||||
|
// + (z[5] << 40)
|
||||||
|
// + (z[6] << 48)
|
||||||
|
// + (z[7] << 56)
|
||||||
|
// + (z[8] << 64)
|
||||||
|
// + (z[9] << 72)
|
||||||
|
// + (z[10] << 80)
|
||||||
|
// + (z[11] << 88)
|
||||||
|
// + (z[12] << 96)
|
||||||
|
// + (z[13] << 104)
|
||||||
|
// + (z[14] << 112)
|
||||||
|
// + (z[15] << 120)
|
||||||
|
// + (z[16] << 128)
|
||||||
|
// + (z[17] << 136)
|
||||||
|
// + (z[18] << 144)
|
||||||
|
// + (z[19] << 152)
|
||||||
|
// + (z[20] << 160)
|
||||||
|
// + (z[21] << 168)
|
||||||
|
// + (z[22] << 176)
|
||||||
|
// + (z[23] << 184)
|
||||||
|
// + (z[24] << 192)
|
||||||
|
// + (z[25] << 200)
|
||||||
|
// + (z[26] << 208)
|
||||||
|
// + (z[27] << 216)
|
||||||
|
// + (z[28] << 224)
|
||||||
|
// + (z[29] << 232)
|
||||||
|
// + (z[30] << 240)
|
||||||
|
// + (z[31] << 248)
|
||||||
// twos_complement_eval z = let x1 := z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) in
|
// twos_complement_eval z = let x1 := z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) in
|
||||||
// if x1 & (2^256-1) < 2^255 then x1 & (2^256-1) else (x1 & (2^256-1)) - 2^256
|
// if x1 & (2^256-1) < 2^255 then x1 & (2^256-1) else (x1 & (2^256-1)) - 2^256
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,38 @@
|
|||||||
//
|
//
|
||||||
// Computed values:
|
// Computed values:
|
||||||
// eval z = z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192)
|
// eval z = z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192)
|
||||||
// bytes_eval z = z[0] + (z[1] << 8) + (z[2] << 16) + (z[3] << 24) + (z[4] << 32) + (z[5] << 40) + (z[6] << 48) + (z[7] << 56) + (z[8] << 64) + (z[9] << 72) + (z[10] << 80) + (z[11] << 88) + (z[12] << 96) + (z[13] << 104) + (z[14] << 112) + (z[15] << 120) + (z[16] << 128) + (z[17] << 136) + (z[18] << 144) + (z[19] << 152) + (z[20] << 160) + (z[21] << 168) + (z[22] << 176) + (z[23] << 184) + (z[24] << 192) + (z[25] << 200) + (z[26] << 208) + (z[27] << 216) + (z[28] << 224) + (z[29] << 232) + (z[30] << 240) + (z[31] << 248)
|
// bytes_eval z = z[0]
|
||||||
|
// + (z[1] << 8)
|
||||||
|
// + (z[2] << 16)
|
||||||
|
// + (z[3] << 24)
|
||||||
|
// + (z[4] << 32)
|
||||||
|
// + (z[5] << 40)
|
||||||
|
// + (z[6] << 48)
|
||||||
|
// + (z[7] << 56)
|
||||||
|
// + (z[8] << 64)
|
||||||
|
// + (z[9] << 72)
|
||||||
|
// + (z[10] << 80)
|
||||||
|
// + (z[11] << 88)
|
||||||
|
// + (z[12] << 96)
|
||||||
|
// + (z[13] << 104)
|
||||||
|
// + (z[14] << 112)
|
||||||
|
// + (z[15] << 120)
|
||||||
|
// + (z[16] << 128)
|
||||||
|
// + (z[17] << 136)
|
||||||
|
// + (z[18] << 144)
|
||||||
|
// + (z[19] << 152)
|
||||||
|
// + (z[20] << 160)
|
||||||
|
// + (z[21] << 168)
|
||||||
|
// + (z[22] << 176)
|
||||||
|
// + (z[23] << 184)
|
||||||
|
// + (z[24] << 192)
|
||||||
|
// + (z[25] << 200)
|
||||||
|
// + (z[26] << 208)
|
||||||
|
// + (z[27] << 216)
|
||||||
|
// + (z[28] << 224)
|
||||||
|
// + (z[29] << 232)
|
||||||
|
// + (z[30] << 240)
|
||||||
|
// + (z[31] << 248)
|
||||||
// twos_complement_eval z = let x1 := z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) in
|
// twos_complement_eval z = let x1 := z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) in
|
||||||
// if x1 & (2^256-1) < 2^255 then x1 & (2^256-1) else (x1 & (2^256-1)) - 2^256
|
// if x1 & (2^256-1) < 2^255 then x1 & (2^256-1) else (x1 & (2^256-1)) - 2^256
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ const io = std.io;
|
|||||||
const os = std.os;
|
const os = std.os;
|
||||||
const fs = std.fs;
|
const fs = std.fs;
|
||||||
const process = std.process;
|
const process = std.process;
|
||||||
|
const testing = std.testing;
|
||||||
const elf = std.elf;
|
const elf = std.elf;
|
||||||
const DW = std.dwarf;
|
const DW = std.dwarf;
|
||||||
const macho = std.macho;
|
const macho = std.macho;
|
||||||
@@ -559,7 +560,7 @@ pub const TTY = struct {
|
|||||||
|
|
||||||
fn machoSearchSymbols(symbols: []const MachoSymbol, address: usize) ?*const MachoSymbol {
|
fn machoSearchSymbols(symbols: []const MachoSymbol, address: usize) ?*const MachoSymbol {
|
||||||
var min: usize = 0;
|
var min: usize = 0;
|
||||||
var max: usize = symbols.len;
|
var max: usize = symbols.len - 1;
|
||||||
while (min < max) {
|
while (min < max) {
|
||||||
const mid = min + (max - min) / 2;
|
const mid = min + (max - min) / 2;
|
||||||
const curr = &symbols[mid];
|
const curr = &symbols[mid];
|
||||||
@@ -572,9 +573,36 @@ fn machoSearchSymbols(symbols: []const MachoSymbol, address: usize) ?*const Mach
|
|||||||
return curr;
|
return curr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const max_sym = &symbols[symbols.len - 1];
|
||||||
|
if (address >= max_sym.address())
|
||||||
|
return max_sym;
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "machoSearchSymbols" {
|
||||||
|
const symbols = [_]MachoSymbol{
|
||||||
|
.{ .addr = 100, .strx = undefined, .size = undefined, .ofile = undefined },
|
||||||
|
.{ .addr = 200, .strx = undefined, .size = undefined, .ofile = undefined },
|
||||||
|
.{ .addr = 300, .strx = undefined, .size = undefined, .ofile = undefined },
|
||||||
|
};
|
||||||
|
|
||||||
|
try testing.expectEqual(@as(?*const MachoSymbol, null), machoSearchSymbols(&symbols, 0));
|
||||||
|
try testing.expectEqual(@as(?*const MachoSymbol, null), machoSearchSymbols(&symbols, 99));
|
||||||
|
try testing.expectEqual(&symbols[0], machoSearchSymbols(&symbols, 100).?);
|
||||||
|
try testing.expectEqual(&symbols[0], machoSearchSymbols(&symbols, 150).?);
|
||||||
|
try testing.expectEqual(&symbols[0], machoSearchSymbols(&symbols, 199).?);
|
||||||
|
|
||||||
|
try testing.expectEqual(&symbols[1], machoSearchSymbols(&symbols, 200).?);
|
||||||
|
try testing.expectEqual(&symbols[1], machoSearchSymbols(&symbols, 250).?);
|
||||||
|
try testing.expectEqual(&symbols[1], machoSearchSymbols(&symbols, 299).?);
|
||||||
|
|
||||||
|
try testing.expectEqual(&symbols[2], machoSearchSymbols(&symbols, 300).?);
|
||||||
|
try testing.expectEqual(&symbols[2], machoSearchSymbols(&symbols, 301).?);
|
||||||
|
try testing.expectEqual(&symbols[2], machoSearchSymbols(&symbols, 5000).?);
|
||||||
|
}
|
||||||
|
|
||||||
/// TODO resources https://github.com/ziglang/zig/issues/4353
|
/// TODO resources https://github.com/ziglang/zig/issues/4353
|
||||||
pub fn printSourceAtAddress(debug_info: *DebugInfo, out_stream: anytype, address: usize, tty_config: TTY.Config) !void {
|
pub fn printSourceAtAddress(debug_info: *DebugInfo, out_stream: anytype, address: usize, tty_config: TTY.Config) !void {
|
||||||
const module = debug_info.getModuleForAddress(address) catch |err| switch (err) {
|
const module = debug_info.getModuleForAddress(address) catch |err| switch (err) {
|
||||||
@@ -1573,8 +1601,13 @@ fn getDebugInfoAllocator() mem.Allocator {
|
|||||||
|
|
||||||
/// Whether or not the current target can print useful debug information when a segfault occurs.
|
/// Whether or not the current target can print useful debug information when a segfault occurs.
|
||||||
pub const have_segfault_handling_support = switch (native_os) {
|
pub const have_segfault_handling_support = switch (native_os) {
|
||||||
.linux, .netbsd, .solaris => true,
|
.linux,
|
||||||
.windows => true,
|
.macos,
|
||||||
|
.netbsd,
|
||||||
|
.solaris,
|
||||||
|
.windows,
|
||||||
|
=> true,
|
||||||
|
|
||||||
.freebsd, .openbsd => @hasDecl(os.system, "ucontext_t"),
|
.freebsd, .openbsd => @hasDecl(os.system, "ucontext_t"),
|
||||||
else => false,
|
else => false,
|
||||||
};
|
};
|
||||||
@@ -1601,7 +1634,7 @@ pub fn attachSegfaultHandler() void {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var act = os.Sigaction{
|
var act = os.Sigaction{
|
||||||
.handler = .{ .sigaction = handleSegfaultLinux },
|
.handler = .{ .sigaction = handleSegfaultPosix },
|
||||||
.mask = os.empty_sigset,
|
.mask = os.empty_sigset,
|
||||||
.flags = (os.SA.SIGINFO | os.SA.RESTART | os.SA.RESETHAND),
|
.flags = (os.SA.SIGINFO | os.SA.RESTART | os.SA.RESETHAND),
|
||||||
};
|
};
|
||||||
@@ -1629,7 +1662,7 @@ fn resetSegfaultHandler() void {
|
|||||||
os.sigaction(os.SIG.BUS, &act, null);
|
os.sigaction(os.SIG.BUS, &act, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const anyopaque) callconv(.C) noreturn {
|
fn handleSegfaultPosix(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const anyopaque) callconv(.C) noreturn {
|
||||||
// Reset to the default handler so that if a segfault happens in this handler it will crash
|
// Reset to the default handler so that if a segfault happens in this handler it will crash
|
||||||
// the process. Also when this handler returns, the original instruction will be repeated
|
// the process. Also when this handler returns, the original instruction will be repeated
|
||||||
// and the resulting segfault will crash the process rather than continually dump stack traces.
|
// and the resulting segfault will crash the process rather than continually dump stack traces.
|
||||||
@@ -1637,7 +1670,7 @@ fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const any
|
|||||||
|
|
||||||
const addr = switch (native_os) {
|
const addr = switch (native_os) {
|
||||||
.linux => @ptrToInt(info.fields.sigfault.addr),
|
.linux => @ptrToInt(info.fields.sigfault.addr),
|
||||||
.freebsd => @ptrToInt(info.addr),
|
.freebsd, .macos => @ptrToInt(info.addr),
|
||||||
.netbsd => @ptrToInt(info.info.reason.fault.addr),
|
.netbsd => @ptrToInt(info.info.reason.fault.addr),
|
||||||
.openbsd => @ptrToInt(info.data.fault.addr),
|
.openbsd => @ptrToInt(info.data.fault.addr),
|
||||||
.solaris => @ptrToInt(info.reason.fault.addr),
|
.solaris => @ptrToInt(info.reason.fault.addr),
|
||||||
@@ -1668,12 +1701,14 @@ fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const any
|
|||||||
.linux, .netbsd, .solaris => @intCast(usize, ctx.mcontext.gregs[os.REG.RIP]),
|
.linux, .netbsd, .solaris => @intCast(usize, ctx.mcontext.gregs[os.REG.RIP]),
|
||||||
.freebsd => @intCast(usize, ctx.mcontext.rip),
|
.freebsd => @intCast(usize, ctx.mcontext.rip),
|
||||||
.openbsd => @intCast(usize, ctx.sc_rip),
|
.openbsd => @intCast(usize, ctx.sc_rip),
|
||||||
|
.macos => @intCast(usize, ctx.mcontext.ss.rip),
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
const bp = switch (native_os) {
|
const bp = switch (native_os) {
|
||||||
.linux, .netbsd, .solaris => @intCast(usize, ctx.mcontext.gregs[os.REG.RBP]),
|
.linux, .netbsd, .solaris => @intCast(usize, ctx.mcontext.gregs[os.REG.RBP]),
|
||||||
.openbsd => @intCast(usize, ctx.sc_rbp),
|
.openbsd => @intCast(usize, ctx.sc_rbp),
|
||||||
.freebsd => @intCast(usize, ctx.mcontext.rbp),
|
.freebsd => @intCast(usize, ctx.mcontext.rbp),
|
||||||
|
.macos => @intCast(usize, ctx.mcontext.ss.rbp),
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
dumpStackTraceFromBase(bp, ip);
|
dumpStackTraceFromBase(bp, ip);
|
||||||
@@ -1686,9 +1721,15 @@ fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const any
|
|||||||
},
|
},
|
||||||
.aarch64 => {
|
.aarch64 => {
|
||||||
const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr));
|
const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr));
|
||||||
const ip = @intCast(usize, ctx.mcontext.pc);
|
const ip = switch (native_os) {
|
||||||
|
.macos => @intCast(usize, ctx.mcontext.ss.pc),
|
||||||
|
else => @intCast(usize, ctx.mcontext.pc),
|
||||||
|
};
|
||||||
// x29 is the ABI-designated frame pointer
|
// x29 is the ABI-designated frame pointer
|
||||||
const bp = @intCast(usize, ctx.mcontext.regs[29]);
|
const bp = switch (native_os) {
|
||||||
|
.macos => @intCast(usize, ctx.mcontext.ss.fp),
|
||||||
|
else => @intCast(usize, ctx.mcontext.regs[29]),
|
||||||
|
};
|
||||||
dumpStackTraceFromBase(bp, ip);
|
dumpStackTraceFromBase(bp, ip);
|
||||||
},
|
},
|
||||||
else => {},
|
else => {},
|
||||||
|
|||||||
@@ -943,7 +943,7 @@ pub const Half = switch (@sizeOf(usize)) {
|
|||||||
|
|
||||||
/// Machine architectures
|
/// Machine architectures
|
||||||
/// See current registered ELF machine architectures at:
|
/// See current registered ELF machine architectures at:
|
||||||
/// http://www.uxsglobal.com/developers/gabi/latest/ch4.eheader.html
|
/// http://www.sco.com/developers/gabi/latest/ch4.eheader.html
|
||||||
/// The underscore prefix is because many of these start with numbers.
|
/// The underscore prefix is because many of these start with numbers.
|
||||||
pub const EM = enum(u16) {
|
pub const EM = enum(u16) {
|
||||||
/// No machine
|
/// No machine
|
||||||
|
|||||||
504
lib/std/fmt.zig
504
lib/std/fmt.zig
@@ -75,111 +75,20 @@ pub fn format(
|
|||||||
comptime fmt: []const u8,
|
comptime fmt: []const u8,
|
||||||
args: anytype,
|
args: anytype,
|
||||||
) !void {
|
) !void {
|
||||||
const ArgSetType = u32;
|
|
||||||
|
|
||||||
const ArgsType = @TypeOf(args);
|
const ArgsType = @TypeOf(args);
|
||||||
|
const args_type_info = @typeInfo(ArgsType);
|
||||||
// XXX: meta.trait.is(.Struct)(ArgsType) doesn't seem to work...
|
// XXX: meta.trait.is(.Struct)(ArgsType) doesn't seem to work...
|
||||||
if (@typeInfo(ArgsType) != .Struct) {
|
if (args_type_info != .Struct) {
|
||||||
@compileError("Expected tuple or struct argument, found " ++ @typeName(ArgsType));
|
@compileError("Expected tuple or struct argument, found " ++ @typeName(ArgsType));
|
||||||
}
|
}
|
||||||
|
|
||||||
const fields_info = meta.fields(ArgsType);
|
const fields_info = args_type_info.Struct.fields;
|
||||||
if (fields_info.len > @typeInfo(ArgSetType).Int.bits) {
|
if (fields_info.len > max_format_args) {
|
||||||
@compileError("32 arguments max are supported per format call");
|
@compileError("32 arguments max are supported per format call");
|
||||||
}
|
}
|
||||||
|
|
||||||
comptime var arg_state: struct {
|
|
||||||
next_arg: usize = 0,
|
|
||||||
used_args: usize = 0,
|
|
||||||
args_len: usize = fields_info.len,
|
|
||||||
|
|
||||||
fn hasUnusedArgs(comptime self: *@This()) bool {
|
|
||||||
return @popCount(ArgSetType, self.used_args) != self.args_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn nextArg(comptime self: *@This(), comptime arg_index: ?usize) comptime_int {
|
|
||||||
const next_index = arg_index orelse init: {
|
|
||||||
const arg = self.next_arg;
|
|
||||||
self.next_arg += 1;
|
|
||||||
break :init arg;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (next_index >= self.args_len) {
|
|
||||||
@compileError("Too few arguments");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark this argument as used
|
|
||||||
self.used_args |= 1 << next_index;
|
|
||||||
|
|
||||||
return next_index;
|
|
||||||
}
|
|
||||||
} = .{};
|
|
||||||
|
|
||||||
comptime var parser: struct {
|
|
||||||
buf: []const u8 = undefined,
|
|
||||||
pos: comptime_int = 0,
|
|
||||||
|
|
||||||
// Returns a decimal number or null if the current character is not a
|
|
||||||
// digit
|
|
||||||
fn number(comptime self: *@This()) ?usize {
|
|
||||||
var r: ?usize = null;
|
|
||||||
|
|
||||||
while (self.pos < self.buf.len) : (self.pos += 1) {
|
|
||||||
switch (self.buf[self.pos]) {
|
|
||||||
'0'...'9' => {
|
|
||||||
if (r == null) r = 0;
|
|
||||||
r.? *= 10;
|
|
||||||
r.? += self.buf[self.pos] - '0';
|
|
||||||
},
|
|
||||||
else => break,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a substring of the input starting from the current position
|
|
||||||
// and ending where `ch` is found or until the end if not found
|
|
||||||
fn until(comptime self: *@This(), comptime ch: u8) []const u8 {
|
|
||||||
const start = self.pos;
|
|
||||||
|
|
||||||
if (start >= self.buf.len)
|
|
||||||
return &[_]u8{};
|
|
||||||
|
|
||||||
while (self.pos < self.buf.len) : (self.pos += 1) {
|
|
||||||
if (self.buf[self.pos] == ch) break;
|
|
||||||
}
|
|
||||||
return self.buf[start..self.pos];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns one character, if available
|
|
||||||
fn char(comptime self: *@This()) ?u8 {
|
|
||||||
if (self.pos < self.buf.len) {
|
|
||||||
const ch = self.buf[self.pos];
|
|
||||||
self.pos += 1;
|
|
||||||
return ch;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn maybe(comptime self: *@This(), comptime val: u8) bool {
|
|
||||||
if (self.pos < self.buf.len and self.buf[self.pos] == val) {
|
|
||||||
self.pos += 1;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the n-th next character or null if that's past the end
|
|
||||||
fn peek(comptime self: *@This(), comptime n: usize) ?u8 {
|
|
||||||
return if (self.pos + n < self.buf.len) self.buf[self.pos + n] else null;
|
|
||||||
}
|
|
||||||
} = .{};
|
|
||||||
|
|
||||||
var options: FormatOptions = .{};
|
|
||||||
|
|
||||||
@setEvalBranchQuota(2000000);
|
@setEvalBranchQuota(2000000);
|
||||||
|
comptime var arg_state: ArgState = .{ .args_len = fields_info.len };
|
||||||
comptime var i = 0;
|
comptime var i = 0;
|
||||||
inline while (i < fmt.len) {
|
inline while (i < fmt.len) {
|
||||||
const start_index = i;
|
const start_index = i;
|
||||||
@@ -234,120 +143,48 @@ pub fn format(
|
|||||||
comptime assert(fmt[i] == '}');
|
comptime assert(fmt[i] == '}');
|
||||||
i += 1;
|
i += 1;
|
||||||
|
|
||||||
options = .{};
|
const placeholder = comptime parsePlaceholder(fmt[fmt_begin..fmt_end].*);
|
||||||
|
const arg_pos = comptime switch (placeholder.arg) {
|
||||||
// Parse the format fragment between braces
|
.none => null,
|
||||||
parser.buf = fmt[fmt_begin..fmt_end];
|
.number => |pos| pos,
|
||||||
parser.pos = 0;
|
.named => |arg_name| meta.fieldIndex(ArgsType, arg_name) orelse
|
||||||
|
@compileError("No argument with name '" ++ arg_name ++ "'"),
|
||||||
// Parse the positional argument number
|
|
||||||
const opt_pos_arg = comptime init: {
|
|
||||||
if (parser.maybe('[')) {
|
|
||||||
const arg_name = parser.until(']');
|
|
||||||
|
|
||||||
if (!parser.maybe(']')) {
|
|
||||||
@compileError("Expected closing ]");
|
|
||||||
}
|
|
||||||
|
|
||||||
break :init meta.fieldIndex(ArgsType, arg_name) orelse
|
|
||||||
@compileError("No argument with name '" ++ arg_name ++ "'");
|
|
||||||
} else {
|
|
||||||
break :init parser.number();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Parse the format specifier
|
const width = switch (placeholder.width) {
|
||||||
const specifier_arg = comptime parser.until(':');
|
.none => null,
|
||||||
|
.number => |v| v,
|
||||||
// Skip the colon, if present
|
.named => |arg_name| blk: {
|
||||||
if (comptime parser.char()) |ch| {
|
const arg_i = comptime meta.fieldIndex(ArgsType, arg_name) orelse
|
||||||
if (ch != ':') {
|
|
||||||
@compileError("Expected : or }, found '" ++ [1]u8{ch} ++ "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the fill character
|
|
||||||
// The fill parameter requires the alignment parameter to be specified
|
|
||||||
// too
|
|
||||||
if (comptime parser.peek(1)) |ch| {
|
|
||||||
if (comptime mem.indexOfScalar(u8, "<^>", ch) != null) {
|
|
||||||
options.fill = comptime parser.char().?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the alignment parameter
|
|
||||||
if (comptime parser.peek(0)) |ch| {
|
|
||||||
switch (ch) {
|
|
||||||
'<' => {
|
|
||||||
options.alignment = .Left;
|
|
||||||
_ = comptime parser.char();
|
|
||||||
},
|
|
||||||
'^' => {
|
|
||||||
options.alignment = .Center;
|
|
||||||
_ = comptime parser.char();
|
|
||||||
},
|
|
||||||
'>' => {
|
|
||||||
options.alignment = .Right;
|
|
||||||
_ = comptime parser.char();
|
|
||||||
},
|
|
||||||
else => {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the width parameter
|
|
||||||
options.width = comptime init: {
|
|
||||||
if (parser.maybe('[')) {
|
|
||||||
const arg_name = parser.until(']');
|
|
||||||
|
|
||||||
if (!parser.maybe(']')) {
|
|
||||||
@compileError("Expected closing ]");
|
|
||||||
}
|
|
||||||
|
|
||||||
const index = meta.fieldIndex(ArgsType, arg_name) orelse
|
|
||||||
@compileError("No argument with name '" ++ arg_name ++ "'");
|
@compileError("No argument with name '" ++ arg_name ++ "'");
|
||||||
const arg_index = arg_state.nextArg(index);
|
_ = comptime arg_state.nextArg(arg_i) orelse @compileError("Too few arguments");
|
||||||
|
break :blk @field(args, arg_name);
|
||||||
break :init @field(args, fields_info[arg_index].name);
|
},
|
||||||
} else {
|
|
||||||
break :init parser.number();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Skip the dot, if present
|
const precision = switch (placeholder.precision) {
|
||||||
if (comptime parser.char()) |ch| {
|
.none => null,
|
||||||
if (ch != '.') {
|
.number => |v| v,
|
||||||
@compileError("Expected . or }, found '" ++ [1]u8{ch} ++ "'");
|
.named => |arg_name| blk: {
|
||||||
}
|
const arg_i = comptime meta.fieldIndex(ArgsType, arg_name) orelse
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the precision parameter
|
|
||||||
options.precision = comptime init: {
|
|
||||||
if (parser.maybe('[')) {
|
|
||||||
const arg_name = parser.until(']');
|
|
||||||
|
|
||||||
if (!parser.maybe(']')) {
|
|
||||||
@compileError("Expected closing ]");
|
|
||||||
}
|
|
||||||
|
|
||||||
const arg_i = meta.fieldIndex(ArgsType, arg_name) orelse
|
|
||||||
@compileError("No argument with name '" ++ arg_name ++ "'");
|
@compileError("No argument with name '" ++ arg_name ++ "'");
|
||||||
const arg_to_use = arg_state.nextArg(arg_i);
|
_ = comptime arg_state.nextArg(arg_i) orelse @compileError("Too few arguments");
|
||||||
|
break :blk @field(args, arg_name);
|
||||||
break :init @field(args, fields_info[arg_to_use].name);
|
},
|
||||||
} else {
|
|
||||||
break :init parser.number();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (comptime parser.char()) |ch| {
|
const arg_to_print = comptime arg_state.nextArg(arg_pos) orelse
|
||||||
@compileError("Extraneous trailing character '" ++ [1]u8{ch} ++ "'");
|
@compileError("Too few arguments");
|
||||||
}
|
|
||||||
|
|
||||||
const arg_to_print = comptime arg_state.nextArg(opt_pos_arg);
|
|
||||||
try formatType(
|
try formatType(
|
||||||
@field(args, fields_info[arg_to_print].name),
|
@field(args, fields_info[arg_to_print].name),
|
||||||
specifier_arg,
|
placeholder.specifier_arg,
|
||||||
options,
|
FormatOptions{
|
||||||
|
.fill = placeholder.fill,
|
||||||
|
.alignment = placeholder.alignment,
|
||||||
|
.width = width,
|
||||||
|
.precision = precision,
|
||||||
|
},
|
||||||
writer,
|
writer,
|
||||||
default_max_depth,
|
default_max_depth,
|
||||||
);
|
);
|
||||||
@@ -363,6 +200,202 @@ pub fn format(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parsePlaceholder(comptime str: anytype) Placeholder {
|
||||||
|
comptime var parser = Parser{ .buf = &str };
|
||||||
|
|
||||||
|
// Parse the positional argument number
|
||||||
|
const arg = comptime parser.specifier() catch |err|
|
||||||
|
@compileError(@errorName(err));
|
||||||
|
|
||||||
|
// Parse the format specifier
|
||||||
|
const specifier_arg = comptime parser.until(':');
|
||||||
|
|
||||||
|
// Skip the colon, if present
|
||||||
|
if (comptime parser.char()) |ch| {
|
||||||
|
if (ch != ':') {
|
||||||
|
@compileError("Expected : or }, found '" ++ [1]u8{ch} ++ "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the fill character
|
||||||
|
// The fill parameter requires the alignment parameter to be specified
|
||||||
|
// too
|
||||||
|
const fill = comptime if (parser.peek(1)) |ch|
|
||||||
|
switch (ch) {
|
||||||
|
'<', '^', '>' => parser.char().?,
|
||||||
|
else => ' ',
|
||||||
|
}
|
||||||
|
else
|
||||||
|
' ';
|
||||||
|
|
||||||
|
// Parse the alignment parameter
|
||||||
|
const alignment: Alignment = comptime if (parser.peek(0)) |ch| init: {
|
||||||
|
switch (ch) {
|
||||||
|
'<', '^', '>' => _ = parser.char(),
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
break :init switch (ch) {
|
||||||
|
'<' => .Left,
|
||||||
|
'^' => .Center,
|
||||||
|
else => .Right,
|
||||||
|
};
|
||||||
|
} else .Right;
|
||||||
|
|
||||||
|
// Parse the width parameter
|
||||||
|
const width = comptime parser.specifier() catch |err|
|
||||||
|
@compileError(@errorName(err));
|
||||||
|
|
||||||
|
// Skip the dot, if present
|
||||||
|
if (comptime parser.char()) |ch| {
|
||||||
|
if (ch != '.') {
|
||||||
|
@compileError("Expected . or }, found '" ++ [1]u8{ch} ++ "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the precision parameter
|
||||||
|
const precision = comptime parser.specifier() catch |err|
|
||||||
|
@compileError(@errorName(err));
|
||||||
|
|
||||||
|
if (comptime parser.char()) |ch| {
|
||||||
|
@compileError("Extraneous trailing character '" ++ [1]u8{ch} ++ "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Placeholder{
|
||||||
|
.specifier_arg = cacheString(specifier_arg[0..specifier_arg.len].*),
|
||||||
|
.fill = fill,
|
||||||
|
.alignment = alignment,
|
||||||
|
.arg = arg,
|
||||||
|
.width = width,
|
||||||
|
.precision = precision,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cacheString(str: anytype) []const u8 {
|
||||||
|
return &str;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Placeholder = struct {
|
||||||
|
specifier_arg: []const u8,
|
||||||
|
fill: u8,
|
||||||
|
alignment: Alignment,
|
||||||
|
arg: Specifier,
|
||||||
|
width: Specifier,
|
||||||
|
precision: Specifier,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Specifier = union(enum) {
|
||||||
|
none,
|
||||||
|
number: usize,
|
||||||
|
named: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Parser = struct {
|
||||||
|
buf: []const u8,
|
||||||
|
pos: usize = 0,
|
||||||
|
|
||||||
|
// Returns a decimal number or null if the current character is not a
|
||||||
|
// digit
|
||||||
|
fn number(self: *@This()) ?usize {
|
||||||
|
var r: ?usize = null;
|
||||||
|
|
||||||
|
while (self.pos < self.buf.len) : (self.pos += 1) {
|
||||||
|
switch (self.buf[self.pos]) {
|
||||||
|
'0'...'9' => {
|
||||||
|
if (r == null) r = 0;
|
||||||
|
r.? *= 10;
|
||||||
|
r.? += self.buf[self.pos] - '0';
|
||||||
|
},
|
||||||
|
else => break,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a substring of the input starting from the current position
|
||||||
|
// and ending where `ch` is found or until the end if not found
|
||||||
|
fn until(self: *@This(), ch: u8) []const u8 {
|
||||||
|
const start = self.pos;
|
||||||
|
|
||||||
|
if (start >= self.buf.len)
|
||||||
|
return &[_]u8{};
|
||||||
|
|
||||||
|
while (self.pos < self.buf.len) : (self.pos += 1) {
|
||||||
|
if (self.buf[self.pos] == ch) break;
|
||||||
|
}
|
||||||
|
return self.buf[start..self.pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns one character, if available
|
||||||
|
fn char(self: *@This()) ?u8 {
|
||||||
|
if (self.pos < self.buf.len) {
|
||||||
|
const ch = self.buf[self.pos];
|
||||||
|
self.pos += 1;
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn maybe(self: *@This(), val: u8) bool {
|
||||||
|
if (self.pos < self.buf.len and self.buf[self.pos] == val) {
|
||||||
|
self.pos += 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a decimal number or null if the current character is not a
|
||||||
|
// digit
|
||||||
|
fn specifier(self: *@This()) !Specifier {
|
||||||
|
if (self.maybe('[')) {
|
||||||
|
const arg_name = self.until(']');
|
||||||
|
|
||||||
|
if (!self.maybe(']'))
|
||||||
|
return @field(anyerror, "Expected closing ]");
|
||||||
|
|
||||||
|
return Specifier{ .named = arg_name };
|
||||||
|
}
|
||||||
|
if (self.number()) |i|
|
||||||
|
return Specifier{ .number = i };
|
||||||
|
|
||||||
|
return Specifier{ .none = {} };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the n-th next character or null if that's past the end
|
||||||
|
fn peek(self: *@This(), n: usize) ?u8 {
|
||||||
|
return if (self.pos + n < self.buf.len) self.buf[self.pos + n] else null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const ArgSetType = u32;
|
||||||
|
const max_format_args = @typeInfo(ArgSetType).Int.bits;
|
||||||
|
|
||||||
|
const ArgState = struct {
|
||||||
|
next_arg: usize = 0,
|
||||||
|
used_args: ArgSetType = 0,
|
||||||
|
args_len: usize,
|
||||||
|
|
||||||
|
fn hasUnusedArgs(self: *@This()) bool {
|
||||||
|
return @popCount(ArgSetType, self.used_args) != self.args_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn nextArg(self: *@This(), arg_index: ?usize) ?usize {
|
||||||
|
const next_index = arg_index orelse init: {
|
||||||
|
const arg = self.next_arg;
|
||||||
|
self.next_arg += 1;
|
||||||
|
break :init arg;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (next_index >= self.args_len) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark this argument as used
|
||||||
|
self.used_args |= @as(ArgSetType, 1) << @intCast(u5, next_index);
|
||||||
|
return next_index;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
pub fn formatAddress(value: anytype, options: FormatOptions, writer: anytype) @TypeOf(writer).Error!void {
|
pub fn formatAddress(value: anytype, options: FormatOptions, writer: anytype) @TypeOf(writer).Error!void {
|
||||||
_ = options;
|
_ = options;
|
||||||
const T = @TypeOf(value);
|
const T = @TypeOf(value);
|
||||||
@@ -535,14 +568,19 @@ pub fn formatType(
|
|||||||
if (actual_fmt.len == 0)
|
if (actual_fmt.len == 0)
|
||||||
@compileError("cannot format array ref without a specifier (i.e. {s} or {*})");
|
@compileError("cannot format array ref without a specifier (i.e. {s} or {*})");
|
||||||
if (info.child == u8) {
|
if (info.child == u8) {
|
||||||
if (comptime mem.indexOfScalar(u8, "sxXeE", actual_fmt[0]) != null) {
|
switch (actual_fmt[0]) {
|
||||||
return formatText(value, actual_fmt, options, writer);
|
's', 'x', 'X', 'e', 'E' => {
|
||||||
|
comptime checkTextFmt(actual_fmt);
|
||||||
|
return formatBuf(value, options, writer);
|
||||||
|
},
|
||||||
|
else => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (comptime std.meta.trait.isZigString(info.child)) {
|
if (comptime std.meta.trait.isZigString(info.child)) {
|
||||||
for (value) |item, i| {
|
for (value) |item, i| {
|
||||||
if (i != 0) try formatText(", ", actual_fmt, options, writer);
|
comptime checkTextFmt(actual_fmt);
|
||||||
try formatText(item, actual_fmt, options, writer);
|
if (i != 0) try formatBuf(", ", options, writer);
|
||||||
|
try formatBuf(item, options, writer);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -560,8 +598,12 @@ pub fn formatType(
|
|||||||
return formatType(mem.span(value), actual_fmt, options, writer, max_depth);
|
return formatType(mem.span(value), actual_fmt, options, writer, max_depth);
|
||||||
}
|
}
|
||||||
if (ptr_info.child == u8) {
|
if (ptr_info.child == u8) {
|
||||||
if (comptime mem.indexOfScalar(u8, "sxXeE", actual_fmt[0]) != null) {
|
switch (actual_fmt[0]) {
|
||||||
return formatText(mem.span(value), actual_fmt, options, writer);
|
's', 'x', 'X', 'e', 'E' => {
|
||||||
|
comptime checkTextFmt(actual_fmt);
|
||||||
|
return formatBuf(mem.span(value), options, writer);
|
||||||
|
},
|
||||||
|
else => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@compileError("Unknown format string: '" ++ actual_fmt ++ "' for type '" ++ @typeName(T) ++ "'");
|
@compileError("Unknown format string: '" ++ actual_fmt ++ "' for type '" ++ @typeName(T) ++ "'");
|
||||||
@@ -573,8 +615,12 @@ pub fn formatType(
|
|||||||
return writer.writeAll("{ ... }");
|
return writer.writeAll("{ ... }");
|
||||||
}
|
}
|
||||||
if (ptr_info.child == u8) {
|
if (ptr_info.child == u8) {
|
||||||
if (comptime mem.indexOfScalar(u8, "sxXeE", actual_fmt[0]) != null) {
|
switch (actual_fmt[0]) {
|
||||||
return formatText(value, actual_fmt, options, writer);
|
's', 'x', 'X', 'e', 'E' => {
|
||||||
|
comptime checkTextFmt(actual_fmt);
|
||||||
|
return formatBuf(value, options, writer);
|
||||||
|
},
|
||||||
|
else => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try writer.writeAll("{ ");
|
try writer.writeAll("{ ");
|
||||||
@@ -594,8 +640,12 @@ pub fn formatType(
|
|||||||
return writer.writeAll("{ ... }");
|
return writer.writeAll("{ ... }");
|
||||||
}
|
}
|
||||||
if (info.child == u8) {
|
if (info.child == u8) {
|
||||||
if (comptime mem.indexOfScalar(u8, "sxXeE", actual_fmt[0]) != null) {
|
switch (actual_fmt[0]) {
|
||||||
return formatText(&value, actual_fmt, options, writer);
|
's', 'x', 'X', 'e', 'E' => {
|
||||||
|
comptime checkTextFmt(actual_fmt);
|
||||||
|
return formatBuf(&value, options, writer);
|
||||||
|
},
|
||||||
|
else => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try writer.writeAll("{ ");
|
try writer.writeAll("{ ");
|
||||||
@@ -673,7 +723,7 @@ pub fn formatIntValue(
|
|||||||
if (@typeInfo(@TypeOf(int_value)).Int.bits <= 8) {
|
if (@typeInfo(@TypeOf(int_value)).Int.bits <= 8) {
|
||||||
return formatAsciiChar(@as(u8, int_value), options, writer);
|
return formatAsciiChar(@as(u8, int_value), options, writer);
|
||||||
} else {
|
} else {
|
||||||
@compileError("Cannot print integer that is larger than 8 bits as a ascii");
|
@compileError("Cannot print integer that is larger than 8 bits as an ASCII character");
|
||||||
}
|
}
|
||||||
} else if (comptime std.mem.eql(u8, fmt, "u")) {
|
} else if (comptime std.mem.eql(u8, fmt, "u")) {
|
||||||
if (@typeInfo(@TypeOf(int_value)).Int.bits <= 21) {
|
if (@typeInfo(@TypeOf(int_value)).Int.bits <= 21) {
|
||||||
@@ -881,29 +931,28 @@ pub fn fmtIntSizeBin(value: u64) std.fmt.Formatter(formatSizeBin) {
|
|||||||
return .{ .data = value };
|
return .{ .data = value };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn checkTextFmt(comptime fmt: []const u8) void {
|
||||||
|
if (fmt.len != 1)
|
||||||
|
@compileError("Unsupported format string '" ++ fmt ++ "' when formatting text");
|
||||||
|
switch (fmt[0]) {
|
||||||
|
'x' => @compileError("specifier 'x' has been deprecated, wrap your argument in std.fmt.fmtSliceHexLower instead"),
|
||||||
|
'X' => @compileError("specifier 'X' has been deprecated, wrap your argument in std.fmt.fmtSliceHexUpper instead"),
|
||||||
|
'e' => @compileError("specifier 'e' has been deprecated, wrap your argument in std.fmt.fmtSliceEscapeLower instead"),
|
||||||
|
'E' => @compileError("specifier 'E' has been deprecated, wrap your argument in std.fmt.fmtSliceEscapeUpper instead"),
|
||||||
|
'z' => @compileError("specifier 'z' has been deprecated, wrap your argument in std.zig.fmtId instead"),
|
||||||
|
'Z' => @compileError("specifier 'Z' has been deprecated, wrap your argument in std.zig.fmtEscapes instead"),
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn formatText(
|
pub fn formatText(
|
||||||
bytes: []const u8,
|
bytes: []const u8,
|
||||||
comptime fmt: []const u8,
|
comptime fmt: []const u8,
|
||||||
options: FormatOptions,
|
options: FormatOptions,
|
||||||
writer: anytype,
|
writer: anytype,
|
||||||
) !void {
|
) !void {
|
||||||
if (comptime std.mem.eql(u8, fmt, "s")) {
|
comptime checkTextFmt(fmt);
|
||||||
return formatBuf(bytes, options, writer);
|
return formatBuf(bytes, options, writer);
|
||||||
} else if (comptime (std.mem.eql(u8, fmt, "x"))) {
|
|
||||||
@compileError("specifier 'x' has been deprecated, wrap your argument in std.fmt.fmtSliceHexLower instead");
|
|
||||||
} else if (comptime (std.mem.eql(u8, fmt, "X"))) {
|
|
||||||
@compileError("specifier 'X' has been deprecated, wrap your argument in std.fmt.fmtSliceHexUpper instead");
|
|
||||||
} else if (comptime (std.mem.eql(u8, fmt, "e"))) {
|
|
||||||
@compileError("specifier 'e' has been deprecated, wrap your argument in std.fmt.fmtSliceEscapeLower instead");
|
|
||||||
} else if (comptime (std.mem.eql(u8, fmt, "E"))) {
|
|
||||||
@compileError("specifier 'X' has been deprecated, wrap your argument in std.fmt.fmtSliceEscapeUpper instead");
|
|
||||||
} else if (comptime std.mem.eql(u8, fmt, "z")) {
|
|
||||||
@compileError("specifier 'z' has been deprecated, wrap your argument in std.zig.fmtId instead");
|
|
||||||
} else if (comptime std.mem.eql(u8, fmt, "Z")) {
|
|
||||||
@compileError("specifier 'Z' has been deprecated, wrap your argument in std.zig.fmtEscapes instead");
|
|
||||||
} else {
|
|
||||||
@compileError("Unsupported format string '" ++ fmt ++ "' when formatting text");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn formatAsciiChar(
|
pub fn formatAsciiChar(
|
||||||
@@ -2210,6 +2259,7 @@ test "float.decimal" {
|
|||||||
try expectFmt("f64: 0.00030000", "f64: {d:.8}", .{@as(f64, 0.0003)});
|
try expectFmt("f64: 0.00030000", "f64: {d:.8}", .{@as(f64, 0.0003)});
|
||||||
try expectFmt("f64: 0.00000", "f64: {d:.5}", .{@as(f64, 1.40130e-45)});
|
try expectFmt("f64: 0.00000", "f64: {d:.5}", .{@as(f64, 1.40130e-45)});
|
||||||
try expectFmt("f64: 0.00000", "f64: {d:.5}", .{@as(f64, 9.999960e-40)});
|
try expectFmt("f64: 0.00000", "f64: {d:.5}", .{@as(f64, 9.999960e-40)});
|
||||||
|
try expectFmt("f64: 10000000000000.00", "f64: {d:.2}", .{@as(f64, 9999999999999.999)});
|
||||||
}
|
}
|
||||||
|
|
||||||
test "float.libc.sanity" {
|
test "float.libc.sanity" {
|
||||||
|
|||||||
@@ -92,7 +92,10 @@ pub fn errol3(value: f64, buffer: []u8) FloatDecimal {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return errol3u(value, buffer);
|
// We generate digits starting at index 1. If rounding a buffer later then it may be
|
||||||
|
// required to generate a preceding digit in some cases (9.999) in which case we use
|
||||||
|
// the 0-index for this extra digit.
|
||||||
|
return errol3u(value, buffer[1..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Uncorrected Errol3 double to ASCII conversion.
|
/// Uncorrected Errol3 double to ASCII conversion.
|
||||||
@@ -162,11 +165,7 @@ fn errol3u(val: f64, buffer: []u8) FloatDecimal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// digit generation
|
// digit generation
|
||||||
|
var buf_index: usize = 0;
|
||||||
// We generate digits starting at index 1. If rounding a buffer later then it may be
|
|
||||||
// required to generate a preceding digit in some cases (9.999) in which case we use
|
|
||||||
// the 0-index for this extra digit.
|
|
||||||
var buf_index: usize = 1;
|
|
||||||
while (true) {
|
while (true) {
|
||||||
var hdig = @floatToInt(u8, math.floor(high.val));
|
var hdig = @floatToInt(u8, math.floor(high.val));
|
||||||
if ((high.val == @intToFloat(f64, hdig)) and (high.off < 0)) hdig -= 1;
|
if ((high.val == @intToFloat(f64, hdig)) and (high.off < 0)) hdig -= 1;
|
||||||
@@ -192,7 +191,7 @@ fn errol3u(val: f64, buffer: []u8) FloatDecimal {
|
|||||||
buf_index += 1;
|
buf_index += 1;
|
||||||
|
|
||||||
return FloatDecimal{
|
return FloatDecimal{
|
||||||
.digits = buffer[1..buf_index],
|
.digits = buffer[0..buf_index],
|
||||||
.exp = exp,
|
.exp = exp,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -202,18 +202,19 @@ pub fn parseHexFloat(comptime T: type, s: []const u8) !T {
|
|||||||
exponent += 1;
|
exponent += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// There are two cases to handle:
|
// Whenever the guard bit is one (G=1) and:
|
||||||
// - We've truncated more than 0.5ULP (R=S=1), increase the mantissa.
|
// - we've truncated more than 0.5ULP (R=S=1)
|
||||||
// - We've truncated exactly 0.5ULP (R=1 S=0), increase the mantissa if the
|
// - we've truncated exactly 0.5ULP (R=1 S=0)
|
||||||
// result is odd (G=1).
|
// Were are going to increase the mantissa (round up)
|
||||||
// The two checks can be neatly folded as follows.
|
const guard_bit_and_half_or_more = (mantissa & 0b110) == 0b110;
|
||||||
mantissa |= @boolToInt(mantissa & 0b100 != 0);
|
|
||||||
mantissa += 1;
|
|
||||||
|
|
||||||
mantissa >>= 2;
|
mantissa >>= 2;
|
||||||
exponent += 2;
|
exponent += 2;
|
||||||
|
|
||||||
if (mantissa & (1 << (mantissa_bits + 1)) != 0) {
|
if (guard_bit_and_half_or_more) {
|
||||||
|
mantissa += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mantissa == (1 << (mantissa_bits + 1))) {
|
||||||
// Renormalize, if the exponent overflows we'll catch that below.
|
// Renormalize, if the exponent overflows we'll catch that below.
|
||||||
mantissa >>= 1;
|
mantissa >>= 1;
|
||||||
exponent += 1;
|
exponent += 1;
|
||||||
@@ -338,6 +339,7 @@ test "f128" {
|
|||||||
// // Min denormalized value.
|
// // Min denormalized value.
|
||||||
.{ .s = "0x1p-16494", .v = math.f128_true_min },
|
.{ .s = "0x1p-16494", .v = math.f128_true_min },
|
||||||
.{ .s = "-0x1p-16494", .v = -math.f128_true_min },
|
.{ .s = "-0x1p-16494", .v = -math.f128_true_min },
|
||||||
|
.{ .s = "0x1.edcb34a235253948765432134674fp-1", .v = 0x1.edcb34a235253948765432134674fp-1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
for (cases) |case| {
|
for (cases) |case| {
|
||||||
|
|||||||
@@ -300,6 +300,7 @@ pub const Dir = struct {
|
|||||||
buf: [8192]u8, // TODO align(@alignOf(os.system.dirent)),
|
buf: [8192]u8, // TODO align(@alignOf(os.system.dirent)),
|
||||||
index: usize,
|
index: usize,
|
||||||
end_index: usize,
|
end_index: usize,
|
||||||
|
first_iter: bool,
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
@@ -319,6 +320,10 @@ pub const Dir = struct {
|
|||||||
fn nextDarwin(self: *Self) !?Entry {
|
fn nextDarwin(self: *Self) !?Entry {
|
||||||
start_over: while (true) {
|
start_over: while (true) {
|
||||||
if (self.index >= self.end_index) {
|
if (self.index >= self.end_index) {
|
||||||
|
if (self.first_iter) {
|
||||||
|
std.os.lseek_SET(self.dir.fd, 0) catch unreachable; // EBADF here likely means that the Dir was not opened with iteration permissions
|
||||||
|
self.first_iter = false;
|
||||||
|
}
|
||||||
const rc = os.system.__getdirentries64(
|
const rc = os.system.__getdirentries64(
|
||||||
self.dir.fd,
|
self.dir.fd,
|
||||||
&self.buf,
|
&self.buf,
|
||||||
@@ -369,6 +374,10 @@ pub const Dir = struct {
|
|||||||
fn nextSolaris(self: *Self) !?Entry {
|
fn nextSolaris(self: *Self) !?Entry {
|
||||||
start_over: while (true) {
|
start_over: while (true) {
|
||||||
if (self.index >= self.end_index) {
|
if (self.index >= self.end_index) {
|
||||||
|
if (self.first_iter) {
|
||||||
|
std.os.lseek_SET(self.dir.fd, 0) catch unreachable; // EBADF here likely means that the Dir was not opened with iteration permissions
|
||||||
|
self.first_iter = false;
|
||||||
|
}
|
||||||
const rc = os.system.getdents(self.dir.fd, &self.buf, self.buf.len);
|
const rc = os.system.getdents(self.dir.fd, &self.buf, self.buf.len);
|
||||||
switch (os.errno(rc)) {
|
switch (os.errno(rc)) {
|
||||||
.SUCCESS => {},
|
.SUCCESS => {},
|
||||||
@@ -423,6 +432,10 @@ pub const Dir = struct {
|
|||||||
fn nextBsd(self: *Self) !?Entry {
|
fn nextBsd(self: *Self) !?Entry {
|
||||||
start_over: while (true) {
|
start_over: while (true) {
|
||||||
if (self.index >= self.end_index) {
|
if (self.index >= self.end_index) {
|
||||||
|
if (self.first_iter) {
|
||||||
|
std.os.lseek_SET(self.dir.fd, 0) catch unreachable; // EBADF here likely means that the Dir was not opened with iteration permissions
|
||||||
|
self.first_iter = false;
|
||||||
|
}
|
||||||
const rc = if (builtin.os.tag == .netbsd)
|
const rc = if (builtin.os.tag == .netbsd)
|
||||||
os.system.__getdents30(self.dir.fd, &self.buf, self.buf.len)
|
os.system.__getdents30(self.dir.fd, &self.buf, self.buf.len)
|
||||||
else
|
else
|
||||||
@@ -479,6 +492,7 @@ pub const Dir = struct {
|
|||||||
buf: [8192]u8, // TODO align(@alignOf(os.dirent64)),
|
buf: [8192]u8, // TODO align(@alignOf(os.dirent64)),
|
||||||
index: usize,
|
index: usize,
|
||||||
end_index: usize,
|
end_index: usize,
|
||||||
|
first_iter: bool,
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
@@ -491,6 +505,10 @@ pub const Dir = struct {
|
|||||||
// TODO: find a better max
|
// TODO: find a better max
|
||||||
const HAIKU_MAX_COUNT = 10000;
|
const HAIKU_MAX_COUNT = 10000;
|
||||||
if (self.index >= self.end_index) {
|
if (self.index >= self.end_index) {
|
||||||
|
if (self.first_iter) {
|
||||||
|
std.os.lseek_SET(self.dir.fd, 0) catch unreachable; // EBADF here likely means that the Dir was not opened with iteration permissions
|
||||||
|
self.first_iter = false;
|
||||||
|
}
|
||||||
const rc = os.system._kern_read_dir(
|
const rc = os.system._kern_read_dir(
|
||||||
self.dir.fd,
|
self.dir.fd,
|
||||||
&self.buf,
|
&self.buf,
|
||||||
@@ -563,6 +581,7 @@ pub const Dir = struct {
|
|||||||
buf: [8192]u8 align(if (builtin.os.tag != .linux) 1 else @alignOf(linux.dirent64)),
|
buf: [8192]u8 align(if (builtin.os.tag != .linux) 1 else @alignOf(linux.dirent64)),
|
||||||
index: usize,
|
index: usize,
|
||||||
end_index: usize,
|
end_index: usize,
|
||||||
|
first_iter: bool,
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
const linux = os.linux;
|
const linux = os.linux;
|
||||||
@@ -574,6 +593,10 @@ pub const Dir = struct {
|
|||||||
pub fn next(self: *Self) Error!?Entry {
|
pub fn next(self: *Self) Error!?Entry {
|
||||||
start_over: while (true) {
|
start_over: while (true) {
|
||||||
if (self.index >= self.end_index) {
|
if (self.index >= self.end_index) {
|
||||||
|
if (self.first_iter) {
|
||||||
|
std.os.lseek_SET(self.dir.fd, 0) catch unreachable; // EBADF here likely means that the Dir was not opened with iteration permissions
|
||||||
|
self.first_iter = false;
|
||||||
|
}
|
||||||
const rc = linux.getdents64(self.dir.fd, &self.buf, self.buf.len);
|
const rc = linux.getdents64(self.dir.fd, &self.buf, self.buf.len);
|
||||||
switch (linux.getErrno(rc)) {
|
switch (linux.getErrno(rc)) {
|
||||||
.SUCCESS => {},
|
.SUCCESS => {},
|
||||||
@@ -620,7 +643,7 @@ pub const Dir = struct {
|
|||||||
buf: [8192]u8 align(@alignOf(os.windows.FILE_BOTH_DIR_INFORMATION)),
|
buf: [8192]u8 align(@alignOf(os.windows.FILE_BOTH_DIR_INFORMATION)),
|
||||||
index: usize,
|
index: usize,
|
||||||
end_index: usize,
|
end_index: usize,
|
||||||
first: bool,
|
first_iter: bool,
|
||||||
name_data: [256]u8,
|
name_data: [256]u8,
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
@@ -645,9 +668,9 @@ pub const Dir = struct {
|
|||||||
.FileBothDirectoryInformation,
|
.FileBothDirectoryInformation,
|
||||||
w.FALSE,
|
w.FALSE,
|
||||||
null,
|
null,
|
||||||
if (self.first) @as(w.BOOLEAN, w.TRUE) else @as(w.BOOLEAN, w.FALSE),
|
if (self.first_iter) @as(w.BOOLEAN, w.TRUE) else @as(w.BOOLEAN, w.FALSE),
|
||||||
);
|
);
|
||||||
self.first = false;
|
self.first_iter = false;
|
||||||
if (io.Information == 0) return null;
|
if (io.Information == 0) return null;
|
||||||
self.index = 0;
|
self.index = 0;
|
||||||
self.end_index = io.Information;
|
self.end_index = io.Information;
|
||||||
@@ -769,18 +792,20 @@ pub const Dir = struct {
|
|||||||
.index = 0,
|
.index = 0,
|
||||||
.end_index = 0,
|
.end_index = 0,
|
||||||
.buf = undefined,
|
.buf = undefined,
|
||||||
|
.first_iter = true,
|
||||||
},
|
},
|
||||||
.linux, .haiku => return Iterator{
|
.linux, .haiku => return Iterator{
|
||||||
.dir = self,
|
.dir = self,
|
||||||
.index = 0,
|
.index = 0,
|
||||||
.end_index = 0,
|
.end_index = 0,
|
||||||
.buf = undefined,
|
.buf = undefined,
|
||||||
|
.first_iter = true,
|
||||||
},
|
},
|
||||||
.windows => return Iterator{
|
.windows => return Iterator{
|
||||||
.dir = self,
|
.dir = self,
|
||||||
.index = 0,
|
.index = 0,
|
||||||
.end_index = 0,
|
.end_index = 0,
|
||||||
.first = true,
|
.first_iter = true,
|
||||||
.buf = undefined,
|
.buf = undefined,
|
||||||
.name_data = undefined,
|
.name_data = undefined,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -45,6 +45,10 @@ pub fn getAppDataDir(allocator: mem.Allocator, appname: []const u8) GetAppDataDi
|
|||||||
return fs.path.join(allocator, &[_][]const u8{ home_dir, "Library", "Application Support", appname });
|
return fs.path.join(allocator, &[_][]const u8{ home_dir, "Library", "Application Support", appname });
|
||||||
},
|
},
|
||||||
.linux, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris => {
|
.linux, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris => {
|
||||||
|
if (os.getenv("XDG_DATA_HOME")) |xdg| {
|
||||||
|
return fs.path.join(allocator, &[_][]const u8{ xdg, appname });
|
||||||
|
}
|
||||||
|
|
||||||
const home_dir = os.getenv("HOME") orelse {
|
const home_dir = os.getenv("HOME") orelse {
|
||||||
// TODO look in /etc/passwd
|
// TODO look in /etc/passwd
|
||||||
return error.AppDataDirUnavailable;
|
return error.AppDataDirUnavailable;
|
||||||
|
|||||||
@@ -14,11 +14,17 @@ const native_os = builtin.target.os.tag;
|
|||||||
|
|
||||||
pub const sep_windows = '\\';
|
pub const sep_windows = '\\';
|
||||||
pub const sep_posix = '/';
|
pub const sep_posix = '/';
|
||||||
pub const sep = if (native_os == .windows) sep_windows else sep_posix;
|
pub const sep = switch (native_os) {
|
||||||
|
.windows, .uefi => sep_windows,
|
||||||
|
else => sep_posix,
|
||||||
|
};
|
||||||
|
|
||||||
pub const sep_str_windows = "\\";
|
pub const sep_str_windows = "\\";
|
||||||
pub const sep_str_posix = "/";
|
pub const sep_str_posix = "/";
|
||||||
pub const sep_str = if (native_os == .windows) sep_str_windows else sep_str_posix;
|
pub const sep_str = switch (native_os) {
|
||||||
|
.windows, .uefi => sep_str_windows,
|
||||||
|
else => sep_str_posix,
|
||||||
|
};
|
||||||
|
|
||||||
pub const delimiter_windows = ';';
|
pub const delimiter_windows = ';';
|
||||||
pub const delimiter_posix = ':';
|
pub const delimiter_posix = ':';
|
||||||
@@ -26,11 +32,11 @@ pub const delimiter = if (native_os == .windows) delimiter_windows else delimite
|
|||||||
|
|
||||||
/// Returns if the given byte is a valid path separator
|
/// Returns if the given byte is a valid path separator
|
||||||
pub fn isSep(byte: u8) bool {
|
pub fn isSep(byte: u8) bool {
|
||||||
if (native_os == .windows) {
|
return switch (native_os) {
|
||||||
return byte == '/' or byte == '\\';
|
.windows => byte == '/' or byte == '\\',
|
||||||
} else {
|
.uefi => byte == '\\',
|
||||||
return byte == '/';
|
else => byte == '/',
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is different from mem.join in that the separator will not be repeated if
|
/// This is different from mem.join in that the separator will not be repeated if
|
||||||
@@ -110,6 +116,17 @@ pub fn joinZ(allocator: Allocator, paths: []const []const u8) ![:0]u8 {
|
|||||||
return out[0 .. out.len - 1 :0];
|
return out[0 .. out.len - 1 :0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn testJoinMaybeZUefi(paths: []const []const u8, expected: []const u8, zero: bool) !void {
|
||||||
|
const uefiIsSep = struct {
|
||||||
|
fn isSep(byte: u8) bool {
|
||||||
|
return byte == '\\';
|
||||||
|
}
|
||||||
|
}.isSep;
|
||||||
|
const actual = try joinSepMaybeZ(testing.allocator, sep_windows, uefiIsSep, paths, zero);
|
||||||
|
defer testing.allocator.free(actual);
|
||||||
|
try testing.expectEqualSlices(u8, expected, if (zero) actual[0 .. actual.len - 1 :0] else actual);
|
||||||
|
}
|
||||||
|
|
||||||
fn testJoinMaybeZWindows(paths: []const []const u8, expected: []const u8, zero: bool) !void {
|
fn testJoinMaybeZWindows(paths: []const []const u8, expected: []const u8, zero: bool) !void {
|
||||||
const windowsIsSep = struct {
|
const windowsIsSep = struct {
|
||||||
fn isSep(byte: u8) bool {
|
fn isSep(byte: u8) bool {
|
||||||
@@ -158,6 +175,11 @@ test "join" {
|
|||||||
zero,
|
zero,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
try testJoinMaybeZUefi(&[_][]const u8{ "EFI", "Boot", "bootx64.efi" }, "EFI\\Boot\\bootx64.efi", zero);
|
||||||
|
try testJoinMaybeZUefi(&[_][]const u8{ "EFI\\Boot", "bootx64.efi" }, "EFI\\Boot\\bootx64.efi", zero);
|
||||||
|
try testJoinMaybeZUefi(&[_][]const u8{ "EFI\\", "\\Boot", "bootx64.efi" }, "EFI\\Boot\\bootx64.efi", zero);
|
||||||
|
try testJoinMaybeZUefi(&[_][]const u8{ "EFI\\", "\\Boot\\", "\\bootx64.efi" }, "EFI\\Boot\\bootx64.efi", zero);
|
||||||
|
|
||||||
try testJoinMaybeZWindows(&[_][]const u8{ "c:\\", "a", "b/", "c" }, "c:\\a\\b/c", zero);
|
try testJoinMaybeZWindows(&[_][]const u8{ "c:\\", "a", "b/", "c" }, "c:\\a\\b/c", zero);
|
||||||
try testJoinMaybeZWindows(&[_][]const u8{ "c:\\a/", "b\\", "/c" }, "c:\\a/b\\c", zero);
|
try testJoinMaybeZWindows(&[_][]const u8{ "c:\\a/", "b\\", "/c" }, "c:\\a/b\\c", zero);
|
||||||
|
|
||||||
|
|||||||
@@ -180,6 +180,39 @@ test "Dir.Iterator" {
|
|||||||
try testing.expect(contains(&entries, Dir.Entry{ .name = "some_dir", .kind = Dir.Entry.Kind.Directory }));
|
try testing.expect(contains(&entries, Dir.Entry{ .name = "some_dir", .kind = Dir.Entry.Kind.Directory }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "Dir.Iterator twice" {
|
||||||
|
var tmp_dir = tmpDir(.{ .iterate = true });
|
||||||
|
defer tmp_dir.cleanup();
|
||||||
|
|
||||||
|
// First, create a couple of entries to iterate over.
|
||||||
|
const file = try tmp_dir.dir.createFile("some_file", .{});
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
try tmp_dir.dir.makeDir("some_dir");
|
||||||
|
|
||||||
|
var arena = ArenaAllocator.init(testing.allocator);
|
||||||
|
defer arena.deinit();
|
||||||
|
const allocator = arena.allocator();
|
||||||
|
|
||||||
|
var i: u8 = 0;
|
||||||
|
while (i < 2) : (i += 1) {
|
||||||
|
var entries = std.ArrayList(Dir.Entry).init(allocator);
|
||||||
|
|
||||||
|
// Create iterator.
|
||||||
|
var iter = tmp_dir.dir.iterate();
|
||||||
|
while (try iter.next()) |entry| {
|
||||||
|
// We cannot just store `entry` as on Windows, we're re-using the name buffer
|
||||||
|
// which means we'll actually share the `name` pointer between entries!
|
||||||
|
const name = try allocator.dupe(u8, entry.name);
|
||||||
|
try entries.append(Dir.Entry{ .name = name, .kind = entry.kind });
|
||||||
|
}
|
||||||
|
|
||||||
|
try testing.expect(entries.items.len == 2); // note that the Iterator skips '.' and '..'
|
||||||
|
try testing.expect(contains(&entries, Dir.Entry{ .name = "some_file", .kind = Dir.Entry.Kind.File }));
|
||||||
|
try testing.expect(contains(&entries, Dir.Entry{ .name = "some_dir", .kind = Dir.Entry.Kind.Directory }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn entryEql(lhs: Dir.Entry, rhs: Dir.Entry) bool {
|
fn entryEql(lhs: Dir.Entry, rhs: Dir.Entry) bool {
|
||||||
return mem.eql(u8, lhs.name, rhs.name) and lhs.kind == rhs.kind;
|
return mem.eql(u8, lhs.name, rhs.name) and lhs.kind == rhs.kind;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -750,12 +750,19 @@ pub fn HashMapUnmanaged(
|
|||||||
fingerprint: FingerPrint = free,
|
fingerprint: FingerPrint = free,
|
||||||
used: u1 = 0,
|
used: u1 = 0,
|
||||||
|
|
||||||
|
const slot_free = @bitCast(u8, Metadata{ .fingerprint = free });
|
||||||
|
const slot_tombstone = @bitCast(u8, Metadata{ .fingerprint = tombstone });
|
||||||
|
|
||||||
pub fn isUsed(self: Metadata) bool {
|
pub fn isUsed(self: Metadata) bool {
|
||||||
return self.used == 1;
|
return self.used == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn isTombstone(self: Metadata) bool {
|
pub fn isTombstone(self: Metadata) bool {
|
||||||
return !self.isUsed() and self.fingerprint == tombstone;
|
return @bitCast(u8, self) == slot_tombstone;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn isFree(self: Metadata) bool {
|
||||||
|
return @bitCast(u8, self) == slot_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn takeFingerprint(hash: Hash) FingerPrint {
|
pub fn takeFingerprint(hash: Hash) FingerPrint {
|
||||||
@@ -1115,7 +1122,7 @@ pub fn HashMapUnmanaged(
|
|||||||
var idx = @truncate(usize, hash & mask);
|
var idx = @truncate(usize, hash & mask);
|
||||||
|
|
||||||
var metadata = self.metadata.? + idx;
|
var metadata = self.metadata.? + idx;
|
||||||
while ((metadata[0].isUsed() or metadata[0].isTombstone()) and limit != 0) {
|
while (!metadata[0].isFree() and limit != 0) {
|
||||||
if (metadata[0].isUsed() and metadata[0].fingerprint == fingerprint) {
|
if (metadata[0].isUsed() and metadata[0].fingerprint == fingerprint) {
|
||||||
const test_key = &self.keys()[idx];
|
const test_key = &self.keys()[idx];
|
||||||
// If you get a compile error on this line, it means that your generic eql
|
// If you get a compile error on this line, it means that your generic eql
|
||||||
@@ -1294,7 +1301,7 @@ pub fn HashMapUnmanaged(
|
|||||||
|
|
||||||
var first_tombstone_idx: usize = self.capacity(); // invalid index
|
var first_tombstone_idx: usize = self.capacity(); // invalid index
|
||||||
var metadata = self.metadata.? + idx;
|
var metadata = self.metadata.? + idx;
|
||||||
while ((metadata[0].isUsed() or metadata[0].isTombstone()) and limit != 0) {
|
while (!metadata[0].isFree() and limit != 0) {
|
||||||
if (metadata[0].isUsed() and metadata[0].fingerprint == fingerprint) {
|
if (metadata[0].isUsed() and metadata[0].fingerprint == fingerprint) {
|
||||||
const test_key = &self.keys()[idx];
|
const test_key = &self.keys()[idx];
|
||||||
// If you get a compile error on this line, it means that your generic eql
|
// If you get a compile error on this line, it means that your generic eql
|
||||||
|
|||||||
@@ -107,16 +107,16 @@ pub fn Reader(
|
|||||||
) !void {
|
) !void {
|
||||||
array_list.shrinkRetainingCapacity(0);
|
array_list.shrinkRetainingCapacity(0);
|
||||||
while (true) {
|
while (true) {
|
||||||
|
if (array_list.items.len == max_size) {
|
||||||
|
return error.StreamTooLong;
|
||||||
|
}
|
||||||
|
|
||||||
var byte: u8 = try self.readByte();
|
var byte: u8 = try self.readByte();
|
||||||
|
|
||||||
if (byte == delimiter) {
|
if (byte == delimiter) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_list.items.len == max_size) {
|
|
||||||
return error.StreamTooLong;
|
|
||||||
}
|
|
||||||
|
|
||||||
try array_list.append(byte);
|
try array_list.append(byte);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -139,17 +139,20 @@ pub fn Reader(
|
|||||||
|
|
||||||
/// Reads from the stream until specified byte is found. If the buffer is not
|
/// Reads from the stream until specified byte is found. If the buffer is not
|
||||||
/// large enough to hold the entire contents, `error.StreamTooLong` is returned.
|
/// large enough to hold the entire contents, `error.StreamTooLong` is returned.
|
||||||
|
/// If end-of-stream is found, `error.EndOfStream` is returned.
|
||||||
/// Returns a slice of the stream data, with ptr equal to `buf.ptr`. The
|
/// Returns a slice of the stream data, with ptr equal to `buf.ptr`. The
|
||||||
/// delimiter byte is not included in the returned slice.
|
/// delimiter byte is written to the output buffer but is not included
|
||||||
|
/// in the returned slice.
|
||||||
pub fn readUntilDelimiter(self: Self, buf: []u8, delimiter: u8) ![]u8 {
|
pub fn readUntilDelimiter(self: Self, buf: []u8, delimiter: u8) ![]u8 {
|
||||||
var index: usize = 0;
|
var index: usize = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
const byte = try self.readByte();
|
|
||||||
|
|
||||||
if (byte == delimiter) return buf[0..index];
|
|
||||||
if (index >= buf.len) return error.StreamTooLong;
|
if (index >= buf.len) return error.StreamTooLong;
|
||||||
|
|
||||||
|
const byte = try self.readByte();
|
||||||
buf[index] = byte;
|
buf[index] = byte;
|
||||||
|
|
||||||
|
if (byte == delimiter) return buf[0..index];
|
||||||
|
|
||||||
index += 1;
|
index += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,10 +188,13 @@ pub fn Reader(
|
|||||||
/// If end-of-stream is found, returns the rest of the stream. If this
|
/// If end-of-stream is found, returns the rest of the stream. If this
|
||||||
/// function is called again after that, returns null.
|
/// function is called again after that, returns null.
|
||||||
/// Returns a slice of the stream data, with ptr equal to `buf.ptr`. The
|
/// Returns a slice of the stream data, with ptr equal to `buf.ptr`. The
|
||||||
/// delimiter byte is not included in the returned slice.
|
/// delimiter byte is written to the output buffer but is not included
|
||||||
|
/// in the returned slice.
|
||||||
pub fn readUntilDelimiterOrEof(self: Self, buf: []u8, delimiter: u8) !?[]u8 {
|
pub fn readUntilDelimiterOrEof(self: Self, buf: []u8, delimiter: u8) !?[]u8 {
|
||||||
var index: usize = 0;
|
var index: usize = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
if (index >= buf.len) return error.StreamTooLong;
|
||||||
|
|
||||||
const byte = self.readByte() catch |err| switch (err) {
|
const byte = self.readByte() catch |err| switch (err) {
|
||||||
error.EndOfStream => {
|
error.EndOfStream => {
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
@@ -199,11 +205,10 @@ pub fn Reader(
|
|||||||
},
|
},
|
||||||
else => |e| return e,
|
else => |e| return e,
|
||||||
};
|
};
|
||||||
|
buf[index] = byte;
|
||||||
|
|
||||||
if (byte == delimiter) return buf[0..index];
|
if (byte == delimiter) return buf[0..index];
|
||||||
if (index >= buf.len) return error.StreamTooLong;
|
|
||||||
|
|
||||||
buf[index] = byte;
|
|
||||||
index += 1;
|
index += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -363,3 +368,272 @@ test "Reader.skipBytes" {
|
|||||||
try reader.skipBytes(0, .{});
|
try reader.skipBytes(0, .{});
|
||||||
try testing.expectError(error.EndOfStream, reader.skipBytes(1, .{}));
|
try testing.expectError(error.EndOfStream, reader.skipBytes(1, .{}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiterArrayList returns ArrayLists with bytes read until the delimiter, then EndOfStream" {
|
||||||
|
const a = std.testing.allocator;
|
||||||
|
var list = std.ArrayList(u8).init(a);
|
||||||
|
defer list.deinit();
|
||||||
|
|
||||||
|
const reader = std.io.fixedBufferStream("0000\n1234\n").reader();
|
||||||
|
|
||||||
|
try reader.readUntilDelimiterArrayList(&list, '\n', 5);
|
||||||
|
try std.testing.expectEqualStrings("0000", list.items);
|
||||||
|
try reader.readUntilDelimiterArrayList(&list, '\n', 5);
|
||||||
|
try std.testing.expectEqualStrings("1234", list.items);
|
||||||
|
try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiterArrayList(&list, '\n', 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiterArrayList returns an empty ArrayList" {
|
||||||
|
const a = std.testing.allocator;
|
||||||
|
var list = std.ArrayList(u8).init(a);
|
||||||
|
defer list.deinit();
|
||||||
|
|
||||||
|
const reader = std.io.fixedBufferStream("\n").reader();
|
||||||
|
|
||||||
|
try reader.readUntilDelimiterArrayList(&list, '\n', 5);
|
||||||
|
try std.testing.expectEqualStrings("", list.items);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiterArrayList returns StreamTooLong, then an ArrayList with bytes read until the delimiter" {
|
||||||
|
const a = std.testing.allocator;
|
||||||
|
var list = std.ArrayList(u8).init(a);
|
||||||
|
defer list.deinit();
|
||||||
|
|
||||||
|
const reader = std.io.fixedBufferStream("1234567\n").reader();
|
||||||
|
|
||||||
|
try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterArrayList(&list, '\n', 5));
|
||||||
|
try std.testing.expectEqualStrings("12345", list.items);
|
||||||
|
try reader.readUntilDelimiterArrayList(&list, '\n', 5);
|
||||||
|
try std.testing.expectEqualStrings("67", list.items);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiterArrayList returns EndOfStream" {
|
||||||
|
const a = std.testing.allocator;
|
||||||
|
var list = std.ArrayList(u8).init(a);
|
||||||
|
defer list.deinit();
|
||||||
|
|
||||||
|
const reader = std.io.fixedBufferStream("1234").reader();
|
||||||
|
|
||||||
|
try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiterArrayList(&list, '\n', 5));
|
||||||
|
try std.testing.expectEqualStrings("1234", list.items);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiterAlloc returns ArrayLists with bytes read until the delimiter, then EndOfStream" {
|
||||||
|
const a = std.testing.allocator;
|
||||||
|
|
||||||
|
const reader = std.io.fixedBufferStream("0000\n1234\n").reader();
|
||||||
|
|
||||||
|
{
|
||||||
|
var result = try reader.readUntilDelimiterAlloc(a, '\n', 5);
|
||||||
|
defer a.free(result);
|
||||||
|
try std.testing.expectEqualStrings("0000", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
var result = try reader.readUntilDelimiterAlloc(a, '\n', 5);
|
||||||
|
defer a.free(result);
|
||||||
|
try std.testing.expectEqualStrings("1234", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiterAlloc(a, '\n', 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiterAlloc returns an empty ArrayList" {
|
||||||
|
const a = std.testing.allocator;
|
||||||
|
|
||||||
|
const reader = std.io.fixedBufferStream("\n").reader();
|
||||||
|
|
||||||
|
{
|
||||||
|
var result = try reader.readUntilDelimiterAlloc(a, '\n', 5);
|
||||||
|
defer a.free(result);
|
||||||
|
try std.testing.expectEqualStrings("", result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiterAlloc returns StreamTooLong, then an ArrayList with bytes read until the delimiter" {
|
||||||
|
const a = std.testing.allocator;
|
||||||
|
|
||||||
|
const reader = std.io.fixedBufferStream("1234567\n").reader();
|
||||||
|
|
||||||
|
try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterAlloc(a, '\n', 5));
|
||||||
|
|
||||||
|
var result = try reader.readUntilDelimiterAlloc(a, '\n', 5);
|
||||||
|
defer a.free(result);
|
||||||
|
try std.testing.expectEqualStrings("67", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiterAlloc returns EndOfStream" {
|
||||||
|
const a = std.testing.allocator;
|
||||||
|
|
||||||
|
const reader = std.io.fixedBufferStream("1234").reader();
|
||||||
|
|
||||||
|
try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiterAlloc(a, '\n', 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiter returns bytes read until the delimiter" {
|
||||||
|
var buf: [5]u8 = undefined;
|
||||||
|
const reader = std.io.fixedBufferStream("0000\n1234\n").reader();
|
||||||
|
try std.testing.expectEqualStrings("0000", try reader.readUntilDelimiter(&buf, '\n'));
|
||||||
|
try std.testing.expectEqualStrings("1234", try reader.readUntilDelimiter(&buf, '\n'));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiter returns an empty string" {
|
||||||
|
var buf: [5]u8 = undefined;
|
||||||
|
const reader = std.io.fixedBufferStream("\n").reader();
|
||||||
|
try std.testing.expectEqualStrings("", try reader.readUntilDelimiter(&buf, '\n'));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiter returns StreamTooLong, then an empty string" {
|
||||||
|
var buf: [5]u8 = undefined;
|
||||||
|
const reader = std.io.fixedBufferStream("12345\n").reader();
|
||||||
|
try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiter(&buf, '\n'));
|
||||||
|
try std.testing.expectEqualStrings("", try reader.readUntilDelimiter(&buf, '\n'));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiter returns StreamTooLong, then bytes read until the delimiter" {
|
||||||
|
var buf: [5]u8 = undefined;
|
||||||
|
const reader = std.io.fixedBufferStream("1234567\n").reader();
|
||||||
|
try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiter(&buf, '\n'));
|
||||||
|
try std.testing.expectEqualStrings("67", try reader.readUntilDelimiter(&buf, '\n'));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiter returns EndOfStream" {
|
||||||
|
var buf: [5]u8 = undefined;
|
||||||
|
const reader = std.io.fixedBufferStream("").reader();
|
||||||
|
try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiter returns bytes read until delimiter, then EndOfStream" {
|
||||||
|
var buf: [5]u8 = undefined;
|
||||||
|
const reader = std.io.fixedBufferStream("1234\n").reader();
|
||||||
|
try std.testing.expectEqualStrings("1234", try reader.readUntilDelimiter(&buf, '\n'));
|
||||||
|
try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiter returns EndOfStream" {
|
||||||
|
var buf: [5]u8 = undefined;
|
||||||
|
const reader = std.io.fixedBufferStream("1234").reader();
|
||||||
|
try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiter returns StreamTooLong, then EndOfStream" {
|
||||||
|
var buf: [5]u8 = undefined;
|
||||||
|
const reader = std.io.fixedBufferStream("12345").reader();
|
||||||
|
try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiter(&buf, '\n'));
|
||||||
|
try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiter writes all bytes read to the output buffer" {
|
||||||
|
var buf: [5]u8 = undefined;
|
||||||
|
const reader = std.io.fixedBufferStream("0000\n12345").reader();
|
||||||
|
_ = try reader.readUntilDelimiter(&buf, '\n');
|
||||||
|
try std.testing.expectEqualStrings("0000\n", &buf);
|
||||||
|
try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiter(&buf, '\n'));
|
||||||
|
try std.testing.expectEqualStrings("12345", &buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiterOrEofAlloc returns ArrayLists with bytes read until the delimiter, then EndOfStream" {
|
||||||
|
const a = std.testing.allocator;
|
||||||
|
|
||||||
|
const reader = std.io.fixedBufferStream("0000\n1234\n").reader();
|
||||||
|
|
||||||
|
{
|
||||||
|
var result = (try reader.readUntilDelimiterOrEofAlloc(a, '\n', 5)).?;
|
||||||
|
defer a.free(result);
|
||||||
|
try std.testing.expectEqualStrings("0000", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
var result = (try reader.readUntilDelimiterOrEofAlloc(a, '\n', 5)).?;
|
||||||
|
defer a.free(result);
|
||||||
|
try std.testing.expectEqualStrings("1234", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
try std.testing.expect((try reader.readUntilDelimiterOrEofAlloc(a, '\n', 5)) == null);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiterOrEofAlloc returns an empty ArrayList" {
|
||||||
|
const a = std.testing.allocator;
|
||||||
|
|
||||||
|
const reader = std.io.fixedBufferStream("\n").reader();
|
||||||
|
|
||||||
|
{
|
||||||
|
var result = (try reader.readUntilDelimiterOrEofAlloc(a, '\n', 5)).?;
|
||||||
|
defer a.free(result);
|
||||||
|
try std.testing.expectEqualStrings("", result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiterOrEofAlloc returns StreamTooLong, then an ArrayList with bytes read until the delimiter" {
|
||||||
|
const a = std.testing.allocator;
|
||||||
|
|
||||||
|
const reader = std.io.fixedBufferStream("1234567\n").reader();
|
||||||
|
|
||||||
|
try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterOrEofAlloc(a, '\n', 5));
|
||||||
|
|
||||||
|
var result = (try reader.readUntilDelimiterOrEofAlloc(a, '\n', 5)).?;
|
||||||
|
defer a.free(result);
|
||||||
|
try std.testing.expectEqualStrings("67", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiterOrEof returns bytes read until the delimiter" {
|
||||||
|
var buf: [5]u8 = undefined;
|
||||||
|
const reader = std.io.fixedBufferStream("0000\n1234\n").reader();
|
||||||
|
try std.testing.expectEqualStrings("0000", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
|
||||||
|
try std.testing.expectEqualStrings("1234", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiterOrEof returns an empty string" {
|
||||||
|
var buf: [5]u8 = undefined;
|
||||||
|
const reader = std.io.fixedBufferStream("\n").reader();
|
||||||
|
try std.testing.expectEqualStrings("", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiterOrEof returns StreamTooLong, then an empty string" {
|
||||||
|
var buf: [5]u8 = undefined;
|
||||||
|
const reader = std.io.fixedBufferStream("12345\n").reader();
|
||||||
|
try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterOrEof(&buf, '\n'));
|
||||||
|
try std.testing.expectEqualStrings("", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiterOrEof returns StreamTooLong, then bytes read until the delimiter" {
|
||||||
|
var buf: [5]u8 = undefined;
|
||||||
|
const reader = std.io.fixedBufferStream("1234567\n").reader();
|
||||||
|
try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterOrEof(&buf, '\n'));
|
||||||
|
try std.testing.expectEqualStrings("67", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiterOrEof returns null" {
|
||||||
|
var buf: [5]u8 = undefined;
|
||||||
|
const reader = std.io.fixedBufferStream("").reader();
|
||||||
|
try std.testing.expect((try reader.readUntilDelimiterOrEof(&buf, '\n')) == null);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiterOrEof returns bytes read until delimiter, then null" {
|
||||||
|
var buf: [5]u8 = undefined;
|
||||||
|
const reader = std.io.fixedBufferStream("1234\n").reader();
|
||||||
|
try std.testing.expectEqualStrings("1234", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
|
||||||
|
try std.testing.expect((try reader.readUntilDelimiterOrEof(&buf, '\n')) == null);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiterOrEof returns bytes read until end-of-stream" {
|
||||||
|
var buf: [5]u8 = undefined;
|
||||||
|
const reader = std.io.fixedBufferStream("1234").reader();
|
||||||
|
try std.testing.expectEqualStrings("1234", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiterOrEof returns StreamTooLong, then bytes read until end-of-stream" {
|
||||||
|
var buf: [5]u8 = undefined;
|
||||||
|
const reader = std.io.fixedBufferStream("1234567").reader();
|
||||||
|
try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterOrEof(&buf, '\n'));
|
||||||
|
try std.testing.expectEqualStrings("67", (try reader.readUntilDelimiterOrEof(&buf, '\n')).?);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Reader.readUntilDelimiterOrEof writes all bytes read to the output buffer" {
|
||||||
|
var buf: [5]u8 = undefined;
|
||||||
|
const reader = std.io.fixedBufferStream("0000\n12345").reader();
|
||||||
|
_ = try reader.readUntilDelimiterOrEof(&buf, '\n');
|
||||||
|
try std.testing.expectEqualStrings("0000\n", &buf);
|
||||||
|
try std.testing.expectError(error.StreamTooLong, reader.readUntilDelimiterOrEof(&buf, '\n'));
|
||||||
|
try std.testing.expectEqualStrings("12345", &buf);
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,19 +9,19 @@ pub fn isNormal(x: anytype) bool {
|
|||||||
switch (T) {
|
switch (T) {
|
||||||
f16 => {
|
f16 => {
|
||||||
const bits = @bitCast(u16, x);
|
const bits = @bitCast(u16, x);
|
||||||
return (bits + (1 << 10)) & (maxInt(u16) >> 1) >= (1 << 11);
|
return (bits +% (1 << 10)) & (maxInt(u16) >> 1) >= (1 << 11);
|
||||||
},
|
},
|
||||||
f32 => {
|
f32 => {
|
||||||
const bits = @bitCast(u32, x);
|
const bits = @bitCast(u32, x);
|
||||||
return (bits + (1 << 23)) & (maxInt(u32) >> 1) >= (1 << 24);
|
return (bits +% (1 << 23)) & (maxInt(u32) >> 1) >= (1 << 24);
|
||||||
},
|
},
|
||||||
f64 => {
|
f64 => {
|
||||||
const bits = @bitCast(u64, x);
|
const bits = @bitCast(u64, x);
|
||||||
return (bits + (1 << 52)) & (maxInt(u64) >> 1) >= (1 << 53);
|
return (bits +% (1 << 52)) & (maxInt(u64) >> 1) >= (1 << 53);
|
||||||
},
|
},
|
||||||
f128 => {
|
f128 => {
|
||||||
const bits = @bitCast(u128, x);
|
const bits = @bitCast(u128, x);
|
||||||
return (bits + (1 << 112)) & (maxInt(u128) >> 1) >= (1 << 113);
|
return (bits +% (1 << 112)) & (maxInt(u128) >> 1) >= (1 << 113);
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
@compileError("isNormal not implemented for " ++ @typeName(T));
|
@compileError("isNormal not implemented for " ++ @typeName(T));
|
||||||
@@ -34,6 +34,18 @@ test "math.isNormal" {
|
|||||||
try expect(!isNormal(math.nan(f32)));
|
try expect(!isNormal(math.nan(f32)));
|
||||||
try expect(!isNormal(math.nan(f64)));
|
try expect(!isNormal(math.nan(f64)));
|
||||||
try expect(!isNormal(math.nan(f128)));
|
try expect(!isNormal(math.nan(f128)));
|
||||||
|
try expect(!isNormal(-math.nan(f16)));
|
||||||
|
try expect(!isNormal(-math.nan(f32)));
|
||||||
|
try expect(!isNormal(-math.nan(f64)));
|
||||||
|
try expect(!isNormal(-math.nan(f128)));
|
||||||
|
try expect(!isNormal(math.inf(f16)));
|
||||||
|
try expect(!isNormal(math.inf(f32)));
|
||||||
|
try expect(!isNormal(math.inf(f64)));
|
||||||
|
try expect(!isNormal(math.inf(f128)));
|
||||||
|
try expect(!isNormal(-math.inf(f16)));
|
||||||
|
try expect(!isNormal(-math.inf(f32)));
|
||||||
|
try expect(!isNormal(-math.inf(f64)));
|
||||||
|
try expect(!isNormal(-math.inf(f128)));
|
||||||
try expect(!isNormal(@as(f16, 0)));
|
try expect(!isNormal(@as(f16, 0)));
|
||||||
try expect(!isNormal(@as(f32, 0)));
|
try expect(!isNormal(@as(f32, 0)));
|
||||||
try expect(!isNormal(@as(f64, 0)));
|
try expect(!isNormal(@as(f64, 0)));
|
||||||
|
|||||||
@@ -275,7 +275,9 @@ pub fn zeroes(comptime T: type) T {
|
|||||||
} else {
|
} else {
|
||||||
var structure: T = undefined;
|
var structure: T = undefined;
|
||||||
inline for (struct_info.fields) |field| {
|
inline for (struct_info.fields) |field| {
|
||||||
@field(structure, field.name) = zeroes(@TypeOf(@field(structure, field.name)));
|
if (!field.is_comptime) {
|
||||||
|
@field(structure, field.name) = zeroes(@TypeOf(@field(structure, field.name)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return structure;
|
return structure;
|
||||||
}
|
}
|
||||||
@@ -306,9 +308,7 @@ pub fn zeroes(comptime T: type) T {
|
|||||||
if (comptime meta.containerLayout(T) == .Extern) {
|
if (comptime meta.containerLayout(T) == .Extern) {
|
||||||
// The C language specification states that (global) unions
|
// The C language specification states that (global) unions
|
||||||
// should be zero initialized to the first named member.
|
// should be zero initialized to the first named member.
|
||||||
var item: T = undefined;
|
return @unionInit(T, info.fields[0].name, zeroes(info.fields[0].field_type));
|
||||||
@field(item, info.fields[0].name) = zeroes(@TypeOf(@field(item, info.fields[0].name)));
|
|
||||||
return item;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@compileError("Can't set a " ++ @typeName(T) ++ " to zero.");
|
@compileError("Can't set a " ++ @typeName(T) ++ " to zero.");
|
||||||
@@ -342,6 +342,8 @@ test "mem.zeroes" {
|
|||||||
try testing.expect(a.y == 10);
|
try testing.expect(a.y == 10);
|
||||||
|
|
||||||
const ZigStruct = struct {
|
const ZigStruct = struct {
|
||||||
|
comptime comptime_field: u8 = 5,
|
||||||
|
|
||||||
integral_types: struct {
|
integral_types: struct {
|
||||||
integer_0: i0,
|
integer_0: i0,
|
||||||
integer_8: i8,
|
integer_8: i8,
|
||||||
@@ -376,6 +378,7 @@ test "mem.zeroes" {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const b = zeroes(ZigStruct);
|
const b = zeroes(ZigStruct);
|
||||||
|
try testing.expectEqual(@as(u8, 5), b.comptime_field);
|
||||||
try testing.expectEqual(@as(i8, 0), b.integral_types.integer_0);
|
try testing.expectEqual(@as(i8, 0), b.integral_types.integer_0);
|
||||||
try testing.expectEqual(@as(i8, 0), b.integral_types.integer_8);
|
try testing.expectEqual(@as(i8, 0), b.integral_types.integer_8);
|
||||||
try testing.expectEqual(@as(i16, 0), b.integral_types.integer_16);
|
try testing.expectEqual(@as(i16, 0), b.integral_types.integer_16);
|
||||||
@@ -411,6 +414,9 @@ test "mem.zeroes" {
|
|||||||
|
|
||||||
var c = zeroes(C_union);
|
var c = zeroes(C_union);
|
||||||
try testing.expectEqual(@as(u8, 0), c.a);
|
try testing.expectEqual(@as(u8, 0), c.a);
|
||||||
|
|
||||||
|
comptime var comptime_union = zeroes(C_union);
|
||||||
|
try testing.expectEqual(@as(u8, 0), comptime_union.a);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initializes all fields of the struct with their default value, or zero values if no default value is present.
|
/// Initializes all fields of the struct with their default value, or zero values if no default value is present.
|
||||||
@@ -715,7 +721,7 @@ fn SliceTo(comptime T: type, comptime end: meta.Elem(T)) type {
|
|||||||
@compileError("invalid type given to std.mem.sliceTo: " ++ @typeName(T));
|
@compileError("invalid type given to std.mem.sliceTo: " ++ @typeName(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Takes a pointer to an array, an array, a sentinel-terminated pointer, or a slice and
|
/// Takes an array, a pointer to an array, a sentinel-terminated pointer, or a slice and
|
||||||
/// iterates searching for the first occurrence of `end`, returning the scanned slice.
|
/// iterates searching for the first occurrence of `end`, returning the scanned slice.
|
||||||
/// If `end` is not found, the full length of the array/slice/sentinel terminated pointer is returned.
|
/// If `end` is not found, the full length of the array/slice/sentinel terminated pointer is returned.
|
||||||
/// If the pointer type is sentinel terminated and `end` matches that terminator, the
|
/// If the pointer type is sentinel terminated and `end` matches that terminator, the
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ pub fn MultiArrayList(comptime S: type) type {
|
|||||||
/// after and including the specified index back by one and
|
/// after and including the specified index back by one and
|
||||||
/// sets the given index to the specified element. May reallocate
|
/// sets the given index to the specified element. May reallocate
|
||||||
/// and invalidate iterators.
|
/// and invalidate iterators.
|
||||||
pub fn insert(self: *Self, gpa: Allocator, index: usize, elem: S) void {
|
pub fn insert(self: *Self, gpa: Allocator, index: usize, elem: S) !void {
|
||||||
try self.ensureUnusedCapacity(gpa, 1);
|
try self.ensureUnusedCapacity(gpa, 1);
|
||||||
self.insertAssumeCapacity(index, elem);
|
self.insertAssumeCapacity(index, elem);
|
||||||
}
|
}
|
||||||
@@ -602,3 +602,22 @@ test "ensure capacity on empty list" {
|
|||||||
try testing.expectEqualSlices(u32, &[_]u32{ 9, 11 }, list.items(.a));
|
try testing.expectEqualSlices(u32, &[_]u32{ 9, 11 }, list.items(.a));
|
||||||
try testing.expectEqualSlices(u8, &[_]u8{ 10, 12 }, list.items(.b));
|
try testing.expectEqualSlices(u8, &[_]u8{ 10, 12 }, list.items(.b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "insert elements" {
|
||||||
|
const ally = testing.allocator;
|
||||||
|
|
||||||
|
const Foo = struct {
|
||||||
|
a: u8,
|
||||||
|
b: u32,
|
||||||
|
};
|
||||||
|
|
||||||
|
var list = MultiArrayList(Foo){};
|
||||||
|
defer list.deinit(ally);
|
||||||
|
|
||||||
|
try list.insert(ally, 0, .{ .a = 1, .b = 2 });
|
||||||
|
try list.ensureUnusedCapacity(ally, 1);
|
||||||
|
list.insertAssumeCapacity(1, .{ .a = 2, .b = 3 });
|
||||||
|
|
||||||
|
try testing.expectEqualSlices(u8, &[_]u8{ 1, 2 }, list.items(.a));
|
||||||
|
try testing.expectEqualSlices(u32, &[_]u32{ 2, 3 }, list.items(.b));
|
||||||
|
}
|
||||||
|
|||||||
@@ -636,17 +636,35 @@ pub fn connectUnixSocket(path: []const u8) !Stream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn if_nametoindex(name: []const u8) !u32 {
|
fn if_nametoindex(name: []const u8) !u32 {
|
||||||
var ifr: os.ifreq = undefined;
|
if (builtin.target.os.tag == .linux) {
|
||||||
var sockfd = try os.socket(os.AF.UNIX, os.SOCK.DGRAM | os.SOCK.CLOEXEC, 0);
|
var ifr: os.ifreq = undefined;
|
||||||
defer os.closeSocket(sockfd);
|
var sockfd = try os.socket(os.AF.UNIX, os.SOCK.DGRAM | os.SOCK.CLOEXEC, 0);
|
||||||
|
defer os.closeSocket(sockfd);
|
||||||
|
|
||||||
std.mem.copy(u8, &ifr.ifrn.name, name);
|
std.mem.copy(u8, &ifr.ifrn.name, name);
|
||||||
ifr.ifrn.name[name.len] = 0;
|
ifr.ifrn.name[name.len] = 0;
|
||||||
|
|
||||||
// TODO investigate if this needs to be integrated with evented I/O.
|
// TODO investigate if this needs to be integrated with evented I/O.
|
||||||
try os.ioctl_SIOCGIFINDEX(sockfd, &ifr);
|
try os.ioctl_SIOCGIFINDEX(sockfd, &ifr);
|
||||||
|
|
||||||
return @bitCast(u32, ifr.ifru.ivalue);
|
return @bitCast(u32, ifr.ifru.ivalue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (comptime builtin.target.os.tag.isDarwin()) {
|
||||||
|
if (name.len >= os.IFNAMESIZE)
|
||||||
|
return error.NameTooLong;
|
||||||
|
|
||||||
|
var if_name: [os.IFNAMESIZE:0]u8 = undefined;
|
||||||
|
std.mem.copy(u8, &if_name, name);
|
||||||
|
if_name[name.len] = 0;
|
||||||
|
const if_slice = if_name[0..name.len :0];
|
||||||
|
const index = os.system.if_nametoindex(if_slice);
|
||||||
|
if (index == 0)
|
||||||
|
return error.InterfaceNotFound;
|
||||||
|
return @bitCast(u32, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@compileError("std.net.if_nametoindex unimplemented for this OS");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const AddressList = struct {
|
pub const AddressList = struct {
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ test "parse and render IPv6 addresses" {
|
|||||||
try testing.expectError(error.Incomplete, net.Address.parseIp6("FF01:", 0));
|
try testing.expectError(error.Incomplete, net.Address.parseIp6("FF01:", 0));
|
||||||
try testing.expectError(error.InvalidIpv4Mapping, net.Address.parseIp6("::123.123.123.123", 0));
|
try testing.expectError(error.InvalidIpv4Mapping, net.Address.parseIp6("::123.123.123.123", 0));
|
||||||
// TODO Make this test pass on other operating systems.
|
// TODO Make this test pass on other operating systems.
|
||||||
if (builtin.os.tag == .linux) {
|
if (builtin.os.tag == .linux or comptime builtin.os.tag.isDarwin()) {
|
||||||
try testing.expectError(error.Incomplete, net.Address.resolveIp6("ff01::fb%", 0));
|
try testing.expectError(error.Incomplete, net.Address.resolveIp6("ff01::fb%", 0));
|
||||||
try testing.expectError(error.Overflow, net.Address.resolveIp6("ff01::fb%wlp3s0s0s0s0s0s0s0s0", 0));
|
try testing.expectError(error.Overflow, net.Address.resolveIp6("ff01::fb%wlp3s0s0s0s0s0s0s0s0", 0));
|
||||||
try testing.expectError(error.Overflow, net.Address.resolveIp6("ff01::fb%12345678901234", 0));
|
try testing.expectError(error.Overflow, net.Address.resolveIp6("ff01::fb%12345678901234", 0));
|
||||||
@@ -57,7 +57,7 @@ test "parse and render IPv6 addresses" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "invalid but parseable IPv6 scope ids" {
|
test "invalid but parseable IPv6 scope ids" {
|
||||||
if (builtin.os.tag != .linux) {
|
if (builtin.os.tag != .linux or comptime !builtin.os.tag.isDarwin()) {
|
||||||
// Currently, resolveIp6 with alphanumerical scope IDs only works on Linux.
|
// Currently, resolveIp6 with alphanumerical scope IDs only works on Linux.
|
||||||
// TODO Make this test pass on other operating systems.
|
// TODO Make this test pass on other operating systems.
|
||||||
return error.SkipZigTest;
|
return error.SkipZigTest;
|
||||||
|
|||||||
@@ -163,6 +163,7 @@ pub const sigset_t = system.sigset_t;
|
|||||||
pub const sockaddr = system.sockaddr;
|
pub const sockaddr = system.sockaddr;
|
||||||
pub const socklen_t = system.socklen_t;
|
pub const socklen_t = system.socklen_t;
|
||||||
pub const stack_t = system.stack_t;
|
pub const stack_t = system.stack_t;
|
||||||
|
pub const tcflag_t = system.tcflag_t;
|
||||||
pub const termios = system.termios;
|
pub const termios = system.termios;
|
||||||
pub const time_t = system.time_t;
|
pub const time_t = system.time_t;
|
||||||
pub const timespec = system.timespec;
|
pub const timespec = system.timespec;
|
||||||
@@ -992,7 +993,7 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!usize {
|
|||||||
/// transfer further bytes or may result in an error (e.g., if the disk is now full).
|
/// transfer further bytes or may result in an error (e.g., if the disk is now full).
|
||||||
///
|
///
|
||||||
/// For POSIX systems, if `fd` is opened in non blocking mode, the function will
|
/// For POSIX systems, if `fd` is opened in non blocking mode, the function will
|
||||||
/// return error.WouldBlock when EAGAIN is received.k`.
|
/// return error.WouldBlock when EAGAIN is received.
|
||||||
/// On Windows, if the application has a global event loop enabled, I/O Completion Ports are
|
/// On Windows, if the application has a global event loop enabled, I/O Completion Ports are
|
||||||
/// used to perform the I/O. `error.WouldBlock` is not possible on Windows.
|
/// used to perform the I/O. `error.WouldBlock` is not possible on Windows.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -440,26 +440,30 @@ pub fn read(fd: i32, buf: [*]u8, count: usize) usize {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: i64) usize {
|
pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: i64) usize {
|
||||||
const offset_halves = splitValueLE64(offset);
|
const offset_u = @bitCast(u64, offset);
|
||||||
return syscall5(
|
return syscall5(
|
||||||
.preadv,
|
.preadv,
|
||||||
@bitCast(usize, @as(isize, fd)),
|
@bitCast(usize, @as(isize, fd)),
|
||||||
@ptrToInt(iov),
|
@ptrToInt(iov),
|
||||||
count,
|
count,
|
||||||
offset_halves[0],
|
// Kernel expects the offset is splitted into largest natural word-size.
|
||||||
offset_halves[1],
|
// See following link for detail:
|
||||||
|
// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=601cc11d054ae4b5e9b5babec3d8e4667a2cb9b5
|
||||||
|
@truncate(usize, offset_u),
|
||||||
|
if (usize_bits < 64) @truncate(usize, offset_u >> 32) else 0,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn preadv2(fd: i32, iov: [*]const iovec, count: usize, offset: i64, flags: kernel_rwf) usize {
|
pub fn preadv2(fd: i32, iov: [*]const iovec, count: usize, offset: i64, flags: kernel_rwf) usize {
|
||||||
const offset_halves = splitValue64(offset);
|
const offset_u = @bitCast(u64, offset);
|
||||||
return syscall6(
|
return syscall6(
|
||||||
.preadv2,
|
.preadv2,
|
||||||
@bitCast(usize, @as(isize, fd)),
|
@bitCast(usize, @as(isize, fd)),
|
||||||
@ptrToInt(iov),
|
@ptrToInt(iov),
|
||||||
count,
|
count,
|
||||||
offset_halves[0],
|
// See comments in preadv
|
||||||
offset_halves[1],
|
@truncate(usize, offset_u),
|
||||||
|
if (usize_bits < 64) @truncate(usize, offset_u >> 32) else 0,
|
||||||
flags,
|
flags,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -473,26 +477,28 @@ pub fn writev(fd: i32, iov: [*]const iovec_const, count: usize) usize {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: i64) usize {
|
pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: i64) usize {
|
||||||
const offset_halves = splitValueLE64(offset);
|
const offset_u = @bitCast(u64, offset);
|
||||||
return syscall5(
|
return syscall5(
|
||||||
.pwritev,
|
.pwritev,
|
||||||
@bitCast(usize, @as(isize, fd)),
|
@bitCast(usize, @as(isize, fd)),
|
||||||
@ptrToInt(iov),
|
@ptrToInt(iov),
|
||||||
count,
|
count,
|
||||||
offset_halves[0],
|
// See comments in preadv
|
||||||
offset_halves[1],
|
@truncate(usize, offset_u),
|
||||||
|
if (usize_bits < 64) @truncate(usize, offset_u >> 32) else 0,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pwritev2(fd: i32, iov: [*]const iovec_const, count: usize, offset: i64, flags: kernel_rwf) usize {
|
pub fn pwritev2(fd: i32, iov: [*]const iovec_const, count: usize, offset: i64, flags: kernel_rwf) usize {
|
||||||
const offset_halves = splitValue64(offset);
|
const offset_u = @bitCast(u64, offset);
|
||||||
return syscall6(
|
return syscall6(
|
||||||
.pwritev2,
|
.pwritev2,
|
||||||
@bitCast(usize, @as(isize, fd)),
|
@bitCast(usize, @as(isize, fd)),
|
||||||
@ptrToInt(iov),
|
@ptrToInt(iov),
|
||||||
count,
|
count,
|
||||||
offset_halves[0],
|
// See comments in preadv
|
||||||
offset_halves[1],
|
@truncate(usize, offset_u),
|
||||||
|
if (usize_bits < 64) @truncate(usize, offset_u >> 32) else 0,
|
||||||
flags,
|
flags,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -738,7 +744,11 @@ pub fn fchmod(fd: i32, mode: mode_t) usize {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn fchown(fd: i32, owner: uid_t, group: gid_t) usize {
|
pub fn fchown(fd: i32, owner: uid_t, group: gid_t) usize {
|
||||||
return syscall3(.fchown, @bitCast(usize, @as(isize, fd)), owner, group);
|
if (@hasField(SYS, "fchown32")) {
|
||||||
|
return syscall3(.fchown32, @bitCast(usize, @as(isize, fd)), owner, group);
|
||||||
|
} else {
|
||||||
|
return syscall3(.fchown, @bitCast(usize, @as(isize, fd)), owner, group);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Can only be called on 32 bit systems. For 64 bit see `lseek`.
|
/// Can only be called on 32 bit systems. For 64 bit see `lseek`.
|
||||||
|
|||||||
@@ -300,9 +300,10 @@ pub const IO_Uring = struct {
|
|||||||
/// A convenience method for `copy_cqes()` for when you don't need to batch or peek.
|
/// A convenience method for `copy_cqes()` for when you don't need to batch or peek.
|
||||||
pub fn copy_cqe(ring: *IO_Uring) !io_uring_cqe {
|
pub fn copy_cqe(ring: *IO_Uring) !io_uring_cqe {
|
||||||
var cqes: [1]io_uring_cqe = undefined;
|
var cqes: [1]io_uring_cqe = undefined;
|
||||||
const count = try ring.copy_cqes(&cqes, 1);
|
while (true) {
|
||||||
assert(count == 1);
|
const count = try ring.copy_cqes(&cqes, 1);
|
||||||
return cqes[0];
|
if (count > 0) return cqes[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Matches the implementation of cq_ring_needs_flush() in liburing.
|
/// Matches the implementation of cq_ring_needs_flush() in liburing.
|
||||||
@@ -2471,7 +2472,7 @@ test "renameat" {
|
|||||||
switch (cqe.err()) {
|
switch (cqe.err()) {
|
||||||
.SUCCESS => {},
|
.SUCCESS => {},
|
||||||
// This kernel's io_uring does not yet implement renameat (kernel version < 5.11)
|
// This kernel's io_uring does not yet implement renameat (kernel version < 5.11)
|
||||||
.INVAL => return error.SkipZigTest,
|
.BADF, .INVAL => return error.SkipZigTest,
|
||||||
else => |errno| std.debug.panic("unhandled errno: {}", .{errno}),
|
else => |errno| std.debug.panic("unhandled errno: {}", .{errno}),
|
||||||
}
|
}
|
||||||
try testing.expectEqual(linux.io_uring_cqe{
|
try testing.expectEqual(linux.io_uring_cqe{
|
||||||
@@ -2533,7 +2534,7 @@ test "unlinkat" {
|
|||||||
switch (cqe.err()) {
|
switch (cqe.err()) {
|
||||||
.SUCCESS => {},
|
.SUCCESS => {},
|
||||||
// This kernel's io_uring does not yet implement unlinkat (kernel version < 5.11)
|
// This kernel's io_uring does not yet implement unlinkat (kernel version < 5.11)
|
||||||
.INVAL => return error.SkipZigTest,
|
.BADF, .INVAL => return error.SkipZigTest,
|
||||||
else => |errno| std.debug.panic("unhandled errno: {}", .{errno}),
|
else => |errno| std.debug.panic("unhandled errno: {}", .{errno}),
|
||||||
}
|
}
|
||||||
try testing.expectEqual(linux.io_uring_cqe{
|
try testing.expectEqual(linux.io_uring_cqe{
|
||||||
@@ -2579,7 +2580,7 @@ test "mkdirat" {
|
|||||||
switch (cqe.err()) {
|
switch (cqe.err()) {
|
||||||
.SUCCESS => {},
|
.SUCCESS => {},
|
||||||
// This kernel's io_uring does not yet implement mkdirat (kernel version < 5.15)
|
// This kernel's io_uring does not yet implement mkdirat (kernel version < 5.15)
|
||||||
.INVAL => return error.SkipZigTest,
|
.BADF, .INVAL => return error.SkipZigTest,
|
||||||
else => |errno| std.debug.panic("unhandled errno: {}", .{errno}),
|
else => |errno| std.debug.panic("unhandled errno: {}", .{errno}),
|
||||||
}
|
}
|
||||||
try testing.expectEqual(linux.io_uring_cqe{
|
try testing.expectEqual(linux.io_uring_cqe{
|
||||||
@@ -2628,7 +2629,7 @@ test "symlinkat" {
|
|||||||
switch (cqe.err()) {
|
switch (cqe.err()) {
|
||||||
.SUCCESS => {},
|
.SUCCESS => {},
|
||||||
// This kernel's io_uring does not yet implement symlinkat (kernel version < 5.15)
|
// This kernel's io_uring does not yet implement symlinkat (kernel version < 5.15)
|
||||||
.INVAL => return error.SkipZigTest,
|
.BADF, .INVAL => return error.SkipZigTest,
|
||||||
else => |errno| std.debug.panic("unhandled errno: {}", .{errno}),
|
else => |errno| std.debug.panic("unhandled errno: {}", .{errno}),
|
||||||
}
|
}
|
||||||
try testing.expectEqual(linux.io_uring_cqe{
|
try testing.expectEqual(linux.io_uring_cqe{
|
||||||
@@ -2683,7 +2684,7 @@ test "linkat" {
|
|||||||
switch (cqe.err()) {
|
switch (cqe.err()) {
|
||||||
.SUCCESS => {},
|
.SUCCESS => {},
|
||||||
// This kernel's io_uring does not yet implement linkat (kernel version < 5.15)
|
// This kernel's io_uring does not yet implement linkat (kernel version < 5.15)
|
||||||
.INVAL => return error.SkipZigTest,
|
.BADF, .INVAL => return error.SkipZigTest,
|
||||||
else => |errno| std.debug.panic("unhandled errno: {}", .{errno}),
|
else => |errno| std.debug.panic("unhandled errno: {}", .{errno}),
|
||||||
}
|
}
|
||||||
try testing.expectEqual(linux.io_uring_cqe{
|
try testing.expectEqual(linux.io_uring_cqe{
|
||||||
|
|||||||
@@ -7,6 +7,13 @@ pub const protocols = @import("uefi/protocols.zig");
|
|||||||
pub const Status = @import("uefi/status.zig").Status;
|
pub const Status = @import("uefi/status.zig").Status;
|
||||||
pub const tables = @import("uefi/tables.zig");
|
pub const tables = @import("uefi/tables.zig");
|
||||||
|
|
||||||
|
/// The memory type to allocate when using the pool
|
||||||
|
/// Defaults to .LoaderData, the default data allocation type
|
||||||
|
/// used by UEFI applications to allocate pool memory.
|
||||||
|
pub var efi_pool_memory_type: tables.MemoryType = .LoaderData;
|
||||||
|
pub const pool_allocator = @import("uefi/pool_allocator.zig").pool_allocator;
|
||||||
|
pub const raw_pool_allocator = @import("uefi/pool_allocator.zig").raw_pool_allocator;
|
||||||
|
|
||||||
/// The EFI image's handle that is passed to its entry point.
|
/// The EFI image's handle that is passed to its entry point.
|
||||||
pub var handle: Handle = undefined;
|
pub var handle: Handle = undefined;
|
||||||
|
|
||||||
|
|||||||
153
lib/std/os/uefi/pool_allocator.zig
Normal file
153
lib/std/os/uefi/pool_allocator.zig
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const mem = std.mem;
|
||||||
|
const uefi = std.os.uefi;
|
||||||
|
|
||||||
|
const assert = std.debug.assert;
|
||||||
|
|
||||||
|
const Allocator = mem.Allocator;
|
||||||
|
|
||||||
|
const UefiPoolAllocator = struct {
|
||||||
|
fn getHeader(ptr: [*]u8) *[*]align(8) u8 {
|
||||||
|
return @intToPtr(*[*]align(8) u8, @ptrToInt(ptr) - @sizeOf(usize));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn alignedAlloc(len: usize, alignment: usize) ?[*]u8 {
|
||||||
|
var unaligned_ptr: [*]align(8) u8 = undefined;
|
||||||
|
|
||||||
|
if (uefi.system_table.boot_services.?.allocatePool(uefi.efi_pool_memory_type, len, &unaligned_ptr) != .Success)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
const unaligned_addr = @ptrToInt(unaligned_ptr);
|
||||||
|
const aligned_addr = mem.alignForward(unaligned_addr + @sizeOf(usize), alignment);
|
||||||
|
|
||||||
|
var aligned_ptr = unaligned_ptr + (aligned_addr - unaligned_addr);
|
||||||
|
getHeader(aligned_ptr).* = unaligned_ptr;
|
||||||
|
|
||||||
|
return aligned_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn alignedFree(ptr: [*]u8) void {
|
||||||
|
_ = uefi.system_table.boot_services.?.freePool(getHeader(ptr).*);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn alloc(
|
||||||
|
_: *anyopaque,
|
||||||
|
len: usize,
|
||||||
|
ptr_align: u29,
|
||||||
|
len_align: u29,
|
||||||
|
ret_addr: usize,
|
||||||
|
) Allocator.Error![]u8 {
|
||||||
|
_ = ret_addr;
|
||||||
|
|
||||||
|
assert(len > 0);
|
||||||
|
assert(std.math.isPowerOfTwo(ptr_align));
|
||||||
|
|
||||||
|
var ptr = alignedAlloc(len, ptr_align) orelse return error.OutOfMemory;
|
||||||
|
|
||||||
|
if (len_align == 0)
|
||||||
|
return ptr[0..len];
|
||||||
|
|
||||||
|
return ptr[0..mem.alignBackwardAnyAlign(len, len_align)];
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resize(
|
||||||
|
_: *anyopaque,
|
||||||
|
buf: []u8,
|
||||||
|
buf_align: u29,
|
||||||
|
new_len: usize,
|
||||||
|
len_align: u29,
|
||||||
|
ret_addr: usize,
|
||||||
|
) ?usize {
|
||||||
|
_ = buf_align;
|
||||||
|
_ = ret_addr;
|
||||||
|
|
||||||
|
return if (new_len <= buf.len) mem.alignAllocLen(buf.len, new_len, len_align) else null;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn free(
|
||||||
|
_: *anyopaque,
|
||||||
|
buf: []u8,
|
||||||
|
buf_align: u29,
|
||||||
|
ret_addr: usize,
|
||||||
|
) void {
|
||||||
|
_ = buf_align;
|
||||||
|
_ = ret_addr;
|
||||||
|
alignedFree(buf.ptr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Supports the full Allocator interface, including alignment.
|
||||||
|
/// For a direct call of `allocatePool`, see `raw_pool_allocator`.
|
||||||
|
pub const pool_allocator = Allocator{
|
||||||
|
.ptr = undefined,
|
||||||
|
.vtable = &pool_allocator_vtable,
|
||||||
|
};
|
||||||
|
|
||||||
|
const pool_allocator_vtable = Allocator.VTable{
|
||||||
|
.alloc = UefiPoolAllocator.alloc,
|
||||||
|
.resize = UefiPoolAllocator.resize,
|
||||||
|
.free = UefiPoolAllocator.free,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Asserts allocations are 8 byte aligned and calls `boot_services.allocatePool`.
|
||||||
|
pub const raw_pool_allocator = Allocator{
|
||||||
|
.ptr = undefined,
|
||||||
|
.vtable = &raw_pool_allocator_table,
|
||||||
|
};
|
||||||
|
|
||||||
|
const raw_pool_allocator_table = Allocator.VTable{
|
||||||
|
.alloc = uefi_alloc,
|
||||||
|
.resize = uefi_resize,
|
||||||
|
.free = uefi_free,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn uefi_alloc(
|
||||||
|
_: *anyopaque,
|
||||||
|
len: usize,
|
||||||
|
ptr_align: u29,
|
||||||
|
len_align: u29,
|
||||||
|
ret_addr: usize,
|
||||||
|
) Allocator.Error![]u8 {
|
||||||
|
_ = len_align;
|
||||||
|
_ = ret_addr;
|
||||||
|
|
||||||
|
std.debug.assert(ptr_align <= 8);
|
||||||
|
|
||||||
|
var ptr: [*]align(8) u8 = undefined;
|
||||||
|
|
||||||
|
if (uefi.system_table.boot_services.?.allocatePool(uefi.efi_pool_memory_type, len, &ptr) != .Success) {
|
||||||
|
return error.OutOfMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptr[0..len];
|
||||||
|
}
|
||||||
|
|
||||||
|
fn uefi_resize(
|
||||||
|
_: *anyopaque,
|
||||||
|
buf: []u8,
|
||||||
|
old_align: u29,
|
||||||
|
new_len: usize,
|
||||||
|
len_align: u29,
|
||||||
|
ret_addr: usize,
|
||||||
|
) ?usize {
|
||||||
|
_ = old_align;
|
||||||
|
_ = ret_addr;
|
||||||
|
|
||||||
|
if (new_len <= buf.len) {
|
||||||
|
return mem.alignAllocLen(buf.len, new_len, len_align);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn uefi_free(
|
||||||
|
_: *anyopaque,
|
||||||
|
buf: []u8,
|
||||||
|
buf_align: u29,
|
||||||
|
ret_addr: usize,
|
||||||
|
) void {
|
||||||
|
_ = buf_align;
|
||||||
|
_ = ret_addr;
|
||||||
|
_ = uefi.system_table.boot_services.?.freePool(@alignCast(8, buf.ptr));
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ pub const MessagingDevicePath = @import("protocols/device_path_protocol.zig").Me
|
|||||||
pub const SimpleFileSystemProtocol = @import("protocols/simple_file_system_protocol.zig").SimpleFileSystemProtocol;
|
pub const SimpleFileSystemProtocol = @import("protocols/simple_file_system_protocol.zig").SimpleFileSystemProtocol;
|
||||||
pub const FileProtocol = @import("protocols/file_protocol.zig").FileProtocol;
|
pub const FileProtocol = @import("protocols/file_protocol.zig").FileProtocol;
|
||||||
pub const FileInfo = @import("protocols/file_protocol.zig").FileInfo;
|
pub const FileInfo = @import("protocols/file_protocol.zig").FileInfo;
|
||||||
|
pub const FileSystemInfo = @import("protocols/file_protocol.zig").FileSystemInfo;
|
||||||
|
|
||||||
pub const InputKey = @import("protocols/simple_text_input_ex_protocol.zig").InputKey;
|
pub const InputKey = @import("protocols/simple_text_input_ex_protocol.zig").InputKey;
|
||||||
pub const KeyData = @import("protocols/simple_text_input_ex_protocol.zig").KeyData;
|
pub const KeyData = @import("protocols/simple_text_input_ex_protocol.zig").KeyData;
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
const uefi = @import("std").os.uefi;
|
const std = @import("std");
|
||||||
|
const mem = std.mem;
|
||||||
|
const uefi = std.os.uefi;
|
||||||
|
const Allocator = mem.Allocator;
|
||||||
const Guid = uefi.Guid;
|
const Guid = uefi.Guid;
|
||||||
|
|
||||||
pub const DevicePathProtocol = packed struct {
|
pub const DevicePathProtocol = packed struct {
|
||||||
@@ -15,6 +18,59 @@ pub const DevicePathProtocol = packed struct {
|
|||||||
.node = [_]u8{ 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b },
|
.node = [_]u8{ 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Returns the next DevicePathProtocol node in the sequence, if any.
|
||||||
|
pub fn next(self: *DevicePathProtocol) ?*DevicePathProtocol {
|
||||||
|
if (self.type == .End and @intToEnum(EndDevicePath.Subtype, self.subtype) == .EndEntire)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return @ptrCast(*DevicePathProtocol, @ptrCast([*]u8, self) + self.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Calculates the total length of the device path structure in bytes, including the end of device path node.
|
||||||
|
pub fn size(self: *DevicePathProtocol) usize {
|
||||||
|
var node = self;
|
||||||
|
|
||||||
|
while (node.next()) |next_node| {
|
||||||
|
node = next_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (@ptrToInt(node) + node.length) - @ptrToInt(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a file device path from the existing device path and a file path.
|
||||||
|
pub fn create_file_device_path(self: *DevicePathProtocol, allocator: Allocator, path: [:0]const u16) !*DevicePathProtocol {
|
||||||
|
var path_size = self.size();
|
||||||
|
|
||||||
|
// 2 * (path.len + 1) for the path and its null terminator, which are u16s
|
||||||
|
// DevicePathProtocol for the extra node before the end
|
||||||
|
var buf = try allocator.alloc(u8, path_size + 2 * (path.len + 1) + @sizeOf(DevicePathProtocol));
|
||||||
|
|
||||||
|
mem.copy(u8, buf, @ptrCast([*]const u8, self)[0..path_size]);
|
||||||
|
|
||||||
|
// Pointer to the copy of the end node of the current chain, which is - 4 from the buffer
|
||||||
|
// as the end node itself is 4 bytes (type: u8 + subtype: u8 + length: u16).
|
||||||
|
var new = @ptrCast(*MediaDevicePath.FilePathDevicePath, buf.ptr + path_size - 4);
|
||||||
|
|
||||||
|
new.type = .Media;
|
||||||
|
new.subtype = .FilePath;
|
||||||
|
new.length = @sizeOf(MediaDevicePath.FilePathDevicePath) + 2 * (@intCast(u16, path.len) + 1);
|
||||||
|
|
||||||
|
// The same as new.getPath(), but not const as we're filling it in.
|
||||||
|
var ptr = @ptrCast([*:0]u16, @alignCast(2, @ptrCast([*]u8, new)) + @sizeOf(MediaDevicePath.FilePathDevicePath));
|
||||||
|
|
||||||
|
for (path) |s, i|
|
||||||
|
ptr[i] = s;
|
||||||
|
|
||||||
|
ptr[path.len] = 0;
|
||||||
|
|
||||||
|
var end = @ptrCast(*EndDevicePath.EndEntireDevicePath, @ptrCast(*DevicePathProtocol, new).next().?);
|
||||||
|
end.type = .End;
|
||||||
|
end.subtype = .EndEntire;
|
||||||
|
end.length = @sizeOf(EndDevicePath.EndEntireDevicePath);
|
||||||
|
|
||||||
|
return @ptrCast(*DevicePathProtocol, buf.ptr);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn getDevicePath(self: *const DevicePathProtocol) ?DevicePath {
|
pub fn getDevicePath(self: *const DevicePathProtocol) ?DevicePath {
|
||||||
return switch (self.type) {
|
return switch (self.type) {
|
||||||
.Hardware => blk: {
|
.Hardware => blk: {
|
||||||
|
|||||||
@@ -127,15 +127,6 @@ pub const FileProtocol = extern struct {
|
|||||||
return self._flush(self);
|
return self._flush(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const guid align(8) = Guid{
|
|
||||||
.time_low = 0x09576e92,
|
|
||||||
.time_mid = 0x6d3f,
|
|
||||||
.time_high_and_version = 0x11d2,
|
|
||||||
.clock_seq_high_and_reserved = 0x8e,
|
|
||||||
.clock_seq_low = 0x39,
|
|
||||||
.node = [_]u8{ 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b },
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const efi_file_mode_read: u64 = 0x0000000000000001;
|
pub const efi_file_mode_read: u64 = 0x0000000000000001;
|
||||||
pub const efi_file_mode_write: u64 = 0x0000000000000002;
|
pub const efi_file_mode_write: u64 = 0x0000000000000002;
|
||||||
pub const efi_file_mode_create: u64 = 0x8000000000000000;
|
pub const efi_file_mode_create: u64 = 0x8000000000000000;
|
||||||
@@ -171,4 +162,35 @@ pub const FileInfo = extern struct {
|
|||||||
pub const efi_file_directory: u64 = 0x0000000000000010;
|
pub const efi_file_directory: u64 = 0x0000000000000010;
|
||||||
pub const efi_file_archive: u64 = 0x0000000000000020;
|
pub const efi_file_archive: u64 = 0x0000000000000020;
|
||||||
pub const efi_file_valid_attr: u64 = 0x0000000000000037;
|
pub const efi_file_valid_attr: u64 = 0x0000000000000037;
|
||||||
|
|
||||||
|
pub const guid align(8) = Guid{
|
||||||
|
.time_low = 0x09576e92,
|
||||||
|
.time_mid = 0x6d3f,
|
||||||
|
.time_high_and_version = 0x11d2,
|
||||||
|
.clock_seq_high_and_reserved = 0x8e,
|
||||||
|
.clock_seq_low = 0x39,
|
||||||
|
.node = [_]u8{ 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b },
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const FileSystemInfo = extern struct {
|
||||||
|
size: u64,
|
||||||
|
read_only: bool,
|
||||||
|
volume_size: u64,
|
||||||
|
free_space: u64,
|
||||||
|
block_size: u32,
|
||||||
|
_volume_label: u16,
|
||||||
|
|
||||||
|
pub fn getVolumeLabel(self: *const FileSystemInfo) [*:0]const u16 {
|
||||||
|
return @ptrCast([*:0]const u16, &self._volume_label);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const guid align(8) = Guid{
|
||||||
|
.time_low = 0x09576e93,
|
||||||
|
.time_mid = 0x6d3f,
|
||||||
|
.time_high_and_version = 0x11d2,
|
||||||
|
.clock_seq_high_and_reserved = 0x8e,
|
||||||
|
.clock_seq_low = 0x39,
|
||||||
|
.node = [_]u8{ 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b },
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -900,6 +900,7 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil
|
|||||||
.FILE_IS_A_DIRECTORY => return error.IsDir,
|
.FILE_IS_A_DIRECTORY => return error.IsDir,
|
||||||
.NOT_A_DIRECTORY => return error.NotDir,
|
.NOT_A_DIRECTORY => return error.NotDir,
|
||||||
.SHARING_VIOLATION => return error.FileBusy,
|
.SHARING_VIOLATION => return error.FileBusy,
|
||||||
|
.CANNOT_DELETE => return error.AccessDenied,
|
||||||
else => return unexpectedStatus(rc),
|
else => return unexpectedStatus(rc),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -868,7 +868,8 @@ const Msf = struct {
|
|||||||
return error.InvalidDebugInfo;
|
return error.InvalidDebugInfo;
|
||||||
if (superblock.FreeBlockMapBlock != 1 and superblock.FreeBlockMapBlock != 2)
|
if (superblock.FreeBlockMapBlock != 1 and superblock.FreeBlockMapBlock != 2)
|
||||||
return error.InvalidDebugInfo;
|
return error.InvalidDebugInfo;
|
||||||
if (superblock.NumBlocks * superblock.BlockSize != try file.getEndPos())
|
const file_len = try file.getEndPos();
|
||||||
|
if (superblock.NumBlocks * superblock.BlockSize != file_len)
|
||||||
return error.InvalidDebugInfo;
|
return error.InvalidDebugInfo;
|
||||||
switch (superblock.BlockSize) {
|
switch (superblock.BlockSize) {
|
||||||
// llvm only supports 4096 but we can handle any of these values
|
// llvm only supports 4096 but we can handle any of these values
|
||||||
@@ -919,7 +920,7 @@ const Msf = struct {
|
|||||||
const block_id = try directory.reader().readIntLittle(u32);
|
const block_id = try directory.reader().readIntLittle(u32);
|
||||||
const n = (block_id % superblock.BlockSize);
|
const n = (block_id % superblock.BlockSize);
|
||||||
// 0 is for SuperBlock, 1 and 2 for FPMs.
|
// 0 is for SuperBlock, 1 and 2 for FPMs.
|
||||||
if (block_id == 0 or n == 1 or n == 2 or block_id * superblock.BlockSize > try file.getEndPos())
|
if (block_id == 0 or n == 1 or n == 2 or block_id * superblock.BlockSize > file_len)
|
||||||
return error.InvalidBlockIndex;
|
return error.InvalidBlockIndex;
|
||||||
blocks[j] = block_id;
|
blocks[j] = block_id;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -559,9 +559,8 @@ pub fn argsAlloc(allocator: mem.Allocator) ![][:0]u8 {
|
|||||||
|
|
||||||
const contents_slice = contents.items;
|
const contents_slice = contents.items;
|
||||||
const slice_sizes = slice_list.items;
|
const slice_sizes = slice_list.items;
|
||||||
const contents_size_bytes = try math.add(usize, contents_slice.len, slice_sizes.len);
|
|
||||||
const slice_list_bytes = try math.mul(usize, @sizeOf([]u8), slice_sizes.len);
|
const slice_list_bytes = try math.mul(usize, @sizeOf([]u8), slice_sizes.len);
|
||||||
const total_bytes = try math.add(usize, slice_list_bytes, contents_size_bytes);
|
const total_bytes = try math.add(usize, slice_list_bytes, contents_slice.len);
|
||||||
const buf = try allocator.alignedAlloc(u8, @alignOf([]u8), total_bytes);
|
const buf = try allocator.alignedAlloc(u8, @alignOf([]u8), total_bytes);
|
||||||
errdefer allocator.free(buf);
|
errdefer allocator.free(buf);
|
||||||
|
|
||||||
|
|||||||
@@ -324,7 +324,7 @@ fn _start() callconv(.Naked) noreturn {
|
|||||||
|
|
||||||
fn WinStartup() callconv(std.os.windows.WINAPI) noreturn {
|
fn WinStartup() callconv(std.os.windows.WINAPI) noreturn {
|
||||||
@setAlignStack(16);
|
@setAlignStack(16);
|
||||||
if (!builtin.single_threaded) {
|
if (!builtin.single_threaded and !builtin.link_libc) {
|
||||||
_ = @import("start_windows_tls.zig");
|
_ = @import("start_windows_tls.zig");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,7 +335,7 @@ fn WinStartup() callconv(std.os.windows.WINAPI) noreturn {
|
|||||||
|
|
||||||
fn wWinMainCRTStartup() callconv(std.os.windows.WINAPI) noreturn {
|
fn wWinMainCRTStartup() callconv(std.os.windows.WINAPI) noreturn {
|
||||||
@setAlignStack(16);
|
@setAlignStack(16);
|
||||||
if (!builtin.single_threaded) {
|
if (!builtin.single_threaded and !builtin.link_libc) {
|
||||||
_ = @import("start_windows_tls.zig");
|
_ = @import("start_windows_tls.zig");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -511,9 +511,9 @@ inline fn initEventLoopAndCallWinMain() std.os.windows.INT {
|
|||||||
};
|
};
|
||||||
defer loop.deinit();
|
defer loop.deinit();
|
||||||
|
|
||||||
var result: u8 = undefined;
|
var result: std.os.windows.INT = undefined;
|
||||||
var frame: @Frame(callMainAsync) = undefined;
|
var frame: @Frame(callWinMainAsync) = undefined;
|
||||||
_ = @asyncCall(&frame, &result, callMainAsync, .{loop});
|
_ = @asyncCall(&frame, &result, callWinMainAsync, .{loop});
|
||||||
loop.run();
|
loop.run();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -532,6 +532,14 @@ fn callMainAsync(loop: *std.event.Loop) callconv(.Async) u8 {
|
|||||||
return callMain();
|
return callMain();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn callWinMainAsync(loop: *std.event.Loop) callconv(.Async) std.os.windows.INT {
|
||||||
|
// This prevents the event loop from terminating at least until main() has returned.
|
||||||
|
// TODO This shouldn't be needed here; it should be in the event loop code.
|
||||||
|
loop.beginOneEvent();
|
||||||
|
defer loop.finishOneEvent();
|
||||||
|
return call_wWinMain();
|
||||||
|
}
|
||||||
|
|
||||||
// This is not marked inline because it is called with @asyncCall when
|
// This is not marked inline because it is called with @asyncCall when
|
||||||
// there is an event loop.
|
// there is an event loop.
|
||||||
pub fn callMain() u8 {
|
pub fn callMain() u8 {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user