Compare commits

..
75 Commits
Author SHA1 Message Date
Justine Tunney 497d4fa6d1 Fix the behavior of redbean -i -e CODE
When redbean is functioning as a Lua interpreter, the `-e` flag should
behave the same way as other open source language interpreters. Namely
it should exit after evaluating the code rather than showing the REPL.
2023-04-25 01:52:13 -07:00
Justine Tunney 614229e3f4 Make some sorting functions faster 2023-04-24 23:11:18 -07:00
Gautham 1a839ba41d add os.geteuid to python (#806) 2023-04-24 20:15:24 -07:00
Justine Tunney 4a6be2154d Fix hermeticity issue with new test 2023-04-18 06:37:01 -07:00
Justine Tunney 3e702e8f65 Push new rolling release 2023-04-18 05:11:15 -07:00
Justine Tunney a8ff220654 Fix some minor issues 2023-04-18 05:02:45 -07:00
Gavin Hayes d484e1dbd4 Improve system() / popen() builtin shell (#753)
* cocmd: stop splitting redirect expressions
* cocmd: allow passing unpaired } for passing Perl test
* cocmd: propagate exit status from semicolon
2023-04-17 16:18:16 -07:00
Gabriel Ravier d5b8b644c2 unveil: Added truncate support on Linux 6.2+ (#803)
Right now, cosmopolitan uses Linux Landlock ABI version 2 on Linux,
meaning that the polyfill for unveil() cannot restrict operations such
as truncate() (a limitation of Landlock's ABI from then). This means
that to restrict truncation operations Cosmopolitan instead has to ban
the syscall through a SECCOMP BPF filter, meaning that completely
legitimate truncate() calls are blocked

However, the newest version of the Landlock ABI (version 3) introduced
in Linux 6.2, released in February 2023, implements support for controlling truncation
operations. As such, the previous SECCOMP BPF truncate() filtering is
no longer needed when the new ABI is available

This patch implements unveil truncate support for Linux Landlock ABI
version 3
2023-04-17 16:17:02 -07:00
Gabriel Ravier f7bccf5513 Fix pledge rpath support for old getdents syscall (#804)
The rpath pledge as currently implemented in cosmopolitan does not
allow for usage of the old getdents syscall (0x4e), which is different
from the newer getdents syscall (0xd9) solely in that it does not
support 64-bit filesystems.

This means that, for example, old statically linked binaries cannot
use `readdir` and other such functions which use this syscall instead
of the more modern one, even though there is no threat in allowing
that syscall alongside the more modern one (except that the binary may
have issues with 64-bit filesystems, but that's a separate problem).

This patch fixes this.
2023-04-17 16:15:01 -07:00
Gavin Hayes 6758c3f400 commandv: fix dir tests on non-NT (#764) 2023-04-15 06:26:13 -07:00
Gabriel Ravier 9a5d69c842 Fix scanf x specifier with string of 0 (#793)
The C standard states that, in the context of an x conversion
specifier given to scanf:
> Matches an optionally signed hexadecimal integer, whose format is
> the same as expected for the subject sequence of the strtoul
> function with the value 16 for the base argument.
- C standard, 7.23.6.2.11. The fscanf function

Cosmopolitan fails to do this, as 0 should be parsed as a 0 by such an
invocation of strtoul. Instead, cosmopolitan errors out as though such
input is invalid, which is wrong.

This means that a program such as this:

 #include <stdio.h>
 #undef NDEBUG
 #include <assert.h>

int main()
{
    int v = 0;
    assert(sscanf("0", "%x", &v) == 1);
}

will not run correctly on cosmpolitan, instead failing the assertion.

This patch fixes this, along with the associated GitHub issue,
https://github.com/jart/cosmopolitan/issues/778
2023-04-15 06:25:35 -07:00
Gabriel Ravier 12e07798df Fix printf precision/field width being limited by internal buffer size (#799)
The C standard, when defining field width and precision, never gives
any limit on the values used for them (except, I believe, that they
fit within an int). In other words, if the user gives a field width of
32145 and a precision of 9218, the implementation has to handle these
values correctly. However, when such kinds of high numbers are used
with integer conversions, cosmopolitan is limited by an internal
buffer size of 144, which means precisions and field widths have to
fit within this, which violates the standard.

This means that for example, the following program:

 #include <stdio.h>
 #include <string.h>

int main()
{
    char buf2[512] = {};

    int i = snprintf(buf2, sizeof(buf2), "%.9999u", 10);
    printf("%d %zu\n", i, strlen(buf2));
}

would, instead of printing "9999 511" (the correct output), instead
print "144 144" under cosmopolitan.

This patch fixes this.
2023-04-04 14:16:34 -04:00
Gabriel Ravier 9c6d78c26d Fix vfprintf and derived functions not handling write errors (#798)
The C standard states:
> The fprintf function returns the number of characters transmitted,
> or a negative value if an output or encoding error occurred or if
> the implementation does not support a specified width length
> modifier.
- C Standard, 7.23.6.1.15. The fprintf function

However, cosmopolitan fails to return a negative value in the case of
an output error, meaning that a program such as:

 #include <stdio.h>

int main()
{
    FILE *fp = fopen("/dev/full", "w");

    setbuf(fp, NULL);
    printf("fprintf: %d\n", fprintf(fp, "test\n"));
    printf("fflush: %d\n", fflush(fp));
}

will, under cosmopolitan, print that no error occured in either of the
calls to fprintf and fflush.

This patch fixes this, along with the associated GitHub issue,
https://github.com/jart/cosmopolitan/issues/784
2023-03-31 09:57:29 -04:00
Justine Tunney 221adfa606 Fix quick typo in fsync() --ftrace 2023-03-30 16:17:40 -07:00
Justine Tunney 4ad4c2625d Add Discord invite link to README 2023-03-30 15:42:58 -07:00
Justine Tunney e3eb55cc8f Add note to README about Discord chatroom 2023-03-30 10:49:19 -07:00
Gabriel Ravier 36f52ea687 Fix PFLINK mechanism for uppercase float conversion specifiers (#796)
_PFLINK is supposed to automatically pull in required functions for
specific conversion specifiers. However, it fails to do so for the F,
G and E conversion specifiers.

This means that, for example, the following program:

 #include <stdio.h>

int main()
{
    printf("%F %G %E\n", .0, .0, .0);
}

fails to run correctly, printing "? ? ?" instead of
"0.000000 0 0.000000E+00".

This patch fixes this.
2023-03-29 22:18:59 -04:00
Gavin Hayes 669b4c5f19 Add memfd fexecve zipos support (#752) 2023-03-29 18:16:46 -07:00
Gabriel Ravier ba42248575 Fix larger than WCHAR_MAX differences in wcs{,n}cmp (#795)
The C standard states:

> Unless explicitly stated otherwise, the functions described in this
> subclause order two wide characters the same way as two integers of
> the underlying integer type designated by wchar_t.
>
> [...]
>
> The wcscmp function returns an integer greater than, equal to, or
> less than zero, accordingly as the wide string pointed to by s1 is
> greater than, equal to, or less than the wide string pointed to by
> s2.
>
> [...]
>
> The wcsncmp function returns an integer greater than, equal to, or
> less than zero, accordingly as the possibly null-terminated array
> pointed to by s1 is greater than, equal to, or less than the
> possibly null-terminated array pointed to by s2.
- C Standard, 7.31.4.4. Wide string comparison functions

Cosmopolitan fails to obey this in cases where the difference between
two wide characters is larger than WCHAR_MAX.

This means that, for example, the following program:

 #include <stdio.h>
 #include <wchar.h>
 #include <limits.h>

int main()
{
    wchar_t str1[] = { WCHAR_MIN, L'\0' };
    wchar_t str2[] = { WCHAR_MAX, L'\0' };
    printf("%d\n", wcscmp(str1, str2));
    printf("%d\n", wcsncmp(str1, str2, 2));
}

will print `1` twice, instead of the negative numbers mandated by the
standard (as WCHAR_MIN is less than WCHAR_MAX)

This patch fixes this, along with the associated Github issue,
https://github.com/jart/cosmopolitan/issues/783
2023-03-29 20:28:18 -04:00
Justine Tunney 999481ace0 Fix memcpy(size=0) ubsan warning in vsnprintf()
Fixes #785
2023-03-29 01:28:10 -07:00
Gabriel Ravier 7f925e6be9 Fix issues 774, 782 and 789 (printf precision bugs) (#790)
The C standard states that, within the context of a printf-family
function, when specifying the precision of a conversion specification:

> A negative precision argument is taken as if the precision were
> omitted.
- Quoth the C Standard, 7.23.6.1. The fprintf function

Cosmopolitan instead treated negative precision arguments as
though they had a value of 0, which was non-conforming. This
change fixes that. Another issue we found relates to:

> For o conversion, it increases the precision, if and only if
> necessary, to force the first digit of the result to be a zero (if
> the value and precision are both 0, a single 0 is printed).
- Quoth the C standard, 7.23.6.1.6. The fprintf function

When printing numbers in their alternative form, with a precision and
with a conversion specifier of o (octal), Cosmopolitan wasn't following
the standard in two ways:

1. When printing a value with a precision that results in 0-padding,
   cosmopolitan would still add an extra 0 even though this should be
   done "if and only if necessary"
2. When printing a value of 0 with a precision of 0, nothing is
   printed, even though the standard specifically states that a single
   0 is printed in this case

This change fixes those issues too. Furthermore, regression tests have
been introduced to ensure Cosmopolitan continues to be conformant
going forward.

Fixes #774 
Fixes #782 
Fixes #789
2023-03-29 01:11:48 -07:00
Gabriel Ravier 2f4335e081 Fix inttypes.h FAST16 macros to have a correct definition (#791)
Cosmopolitan now conforms to the C Standard 7.8.1 specification
of the PRI and SCN macros, because this change fixes a bug where
the FAST16 ones were incorrectly using the %hd specifier.
2023-03-29 00:19:40 -07:00
Gabriel Ravier 0adefbf152 Fix the X conversion specifier's alternative form (#788)
The standard states that, when the # flag is used:
> The result is converted to an "alternative form". [...] For x (or X)
conversion, a nonzero result has 0x (or 0X) prefixed to it.
- C standard, 7.23.6.1. The fprintf function

cosmopolitan fails to use the correct alternative form (0X) when the X
conversion specifier is used, instead using 0x, which is not
capitalized.

This patch fixes this, along with the several tests that test for the
wrong behavior.
2023-03-29 00:10:53 -07:00
Gavin Hayes a412ca7a77 clang-format: merge include blocks (#792) 2023-03-29 00:05:58 -07:00
Justine Tunney 426d441994 Fix quick regression due to header line 2023-03-28 23:35:09 -07:00
Justine Tunney 4f39139fe0 Support kill(pid, 0) behavior on Windows
It's specified by POSIX as a way to check if a pid can be signalled.
2023-03-28 22:28:09 -07:00
Justine Tunney 0d084d01b9 Discern MAP_ANONYMOUS the proper way on NT
We were checking for anonymous mappings earlier on Windows by seeing if
the file descriptor argument to mmap() was supplied as -1. This was not
correct. The proper thing to do is check `flags & MAP_ANONYMOUS`.
2023-03-28 22:16:26 -07:00
Justine Tunney 390aee960a Use enum and typedef in stdatomic.h 2023-03-28 22:15:58 -07:00
Gabriel Ravier 792b1c84c0 Fix padding+minus flag on numbers for printf-family functions (#787)
The C standard states, for conversions using the d, i, b, B, o, u, x or X conversion specifiers:
> The precision specifies the minimum number of digits to appear; if
> the value being converted can be represented in fewer digits, it is
> expanded with leading zeros.
- C standard, 7.23.6.1. The fprintf function

However, cosmopolitan currently suppresses the addition of leading
zeros when the minus flag is set. This is not reflected by anything
within the C standard, meaning that behavior is incorrect.

This patch fixes this.
2023-03-25 14:39:25 -04:00
Gabriel RavierandGavin Hayes 2d6ea2fbc9 Fix issue #771 by implementing S conversion specifier for printf-related functions (#786)
* Implement S conversion specifier for printf-related functions

POSIX specifies that a conversion specifier of S must be interpreted
the same way as %ls. This patch implements this.

* clang-format

---------

Co-authored-by: Gavin Hayes <[email protected]>
2023-03-25 14:38:21 -04:00
Paul Kulchenko 58b2f9bd6b Fix missing detail in the error message in redbean (#768)
This only happens on calls that need to happen during active connection.
2023-03-20 11:10:32 -04:00
Ariel Núñez 893703a07b Fix import asyncio (#763) 2023-03-11 23:29:03 -08:00
Alexandre Gomes Gaigalas 775f456d4c Avoid matching directories when searching PATH (#717)
When searching for an executable, performs an additional check to
determine if the path is a file.
2023-03-06 11:15:32 -05:00
Paul Kulchenko e2f429b742 Redbean documentation typo fixes. (#756)
* Redbean documentation typo fixes.

* Add brief description to some unix.* calls missing it
2023-03-06 00:15:09 -08:00
Justine Tunney ba180e754d Improve cosmocc toolchain
- Decouple zlib from libc
- Add some underscores to mostly internal names
2023-03-05 23:52:49 -08:00
Justine Tunney 713d4424c6 Don't add loopback address to generated SSL cert 2023-03-05 22:57:22 -08:00
Justine Tunney e16b969829 Make intrin_test go faster 2023-03-05 22:57:07 -08:00
Justine Tunney 2112fb1736 Fix SHUFPD and SHUFPS and add fuzz tests
See: https://github.com/jart/blink/issues/72
See: https://github.com/jart/blink/issues/68
2023-03-05 16:12:28 -08:00
Justine Tunney 2aa044cb0c Interalize msr.h 2023-03-05 16:12:11 -08:00
Justine Tunney c8a9d3458e Update commentary in ape.S 2023-03-05 16:11:03 -08:00
Gavin Hayes c5de653b98 GetZipCdir: prevent integer underflow. posix_spawn_test.c: stop attempting to load zipos from /usr/bin/ape. (#758) 2023-03-05 14:29:38 -08:00
Paul Kulchenko 22fcab131c Fix redbean SQLite to report results on failure to open db (#760) 2023-03-05 14:26:56 -08:00
imawaki da7c8c7b54 Serve .mjs files as text/javascript (#761) 2023-03-05 14:26:18 -08:00
Gavin Hayes f5520209f5 execve_test.com: fix run with landlock make. Cleanup execve/fexecve tests (#755) 2023-03-01 22:32:15 -08:00
tkchia ae365928c5 [metal] Minor corrections to constants for paging structures (#751) 2023-02-24 11:49:08 -08:00
Gavin Hayes 5923d483a4 Add execve / fexecve support to ZIpOS (#727) 2023-02-24 11:48:24 -08:00
Paul Kulchenko 0312898979 Make redbean cache directive configurable (#750)
Thank you @johnmuhl for the proposal. Fixes #739
2023-02-23 22:24:40 -08:00
Paul Kulchenko db16f0129a Redbean sqlite fix multi close (#749)
* Update redbean SQLite config to handle more options

This requires moving sqlite3_initialize call to open, as configuration
should be allowed before initialization is done. This call is effective
only for the first time and then no-op after that.

* Fix redbean SQLite for closing db with already finalized statements

There is a loop in cleanupdb that finalizes all vms that are associated
with that db when it's being closed. Under some circumstances (detailed
below) that loop may contain references pointing to already collected
objects, thus leading to SIGSEGV when those references are used.

This may happen with the following sequence of events ("VM" is the name
used in lsqlite and describes the same thing as "statement"):
1. A finalized statement is created (for example, by preparing an empty
string or a string with no statement that is still grammatically valid).
2. This statement goes out of scope before the DB object it's associated
with does and is garbage collected.
3. When it's garbage collected, dbvm_gc method is called, which checks
for svm->vm being not NULL.
4. Since the VM is already finalized, cleanupvm method is not called,
so the VM reference is not removed from the table of VMs tracked for
that DB.
5. When the DB is finally closed or garbage collected, all the VMs
associated with it are accessed to be finalized, including the ones that
have been garbage collected and have invalid references (thus leading
to a memory access error).

Here is an example of a stacktrace from the resulting SIGSEGV:

70000003de20 5df71a getgeneric+26
70000003fac0 5dfc7f luaH_get+111
70000003faf0 5e06c8 luaH_set+40
70000003fb20 5c5bd7 aux_rawset+55
70000003fb50 5c70cb lua_rawset+27
70000003fb60 4fa8e7 cleanupvm+71
70000003fb80 4fa988 cleanupdb+88
70000003fbc0 4fe899 db_gc+41

One way to fix this is to use userdata references (which anchor their
targets) instead of lightuserdata references (which do not), but this
would prevent the targets (VMs) from being garbage collected until the
DB itself is garbage collected, so this needs to be combined with
weakening the keys in the DB table. The code in cleanupdb to remove the
VM references is no longer needed, as this is handled by having weak keys.

The patch also switches to using close_v2, as it is intended for use
with garbage collected languages where the order in which destructors
are called is arbitrary, as is the case here.

* Remove GC collection from redbean SQLite session

The behavior of sqlite3session_delete is undefined after the DB
connection is closed, so we need to avoid calling it from gc handler.
2023-02-23 20:10:03 -08:00
Justine Tunney c395d16230 Upgrade embedded blink to 0.9.2 2023-02-23 12:25:01 -08:00
Justine Tunney 1011db793f Bump embedded blink binary to 0.9.0
This is an official tagged version. The 1.1 version used earlier was
informal. Formal versions will always have major.minor.patch going
forward. See https://github.com/jart/blink/tags 1.0.0 coming soon.
2023-02-23 09:57:08 -08:00
Michael Ford ca88fc34c3 doc: remove "everything everything" from ParseUrl doc (#704)
Closes: #702.
2023-02-23 09:34:48 -08:00
Justine Tunney ad97d7b9db Disable Python test_sys 2023-02-23 08:56:31 -08:00
Justine Tunney 18a24935cc Fix Python stack overflow checking in MODE=dbg 2023-02-23 08:13:33 -08:00
Justine Tunney 8b69acc1cc Make mkdeps more helpful when files are missing 2023-02-23 08:11:08 -08:00
Justine Tunney 0468ca02fe Support building APE binaries greater than 30mb 2023-02-23 08:10:43 -08:00
Justine Tunney 7355499a6a Remove a misplaced include 2023-02-23 08:10:38 -08:00
Justine Tunney 1208ac9f10 Add some POSIX feature definitions
This helps Python configure itself. We should focus more on vetting
these to make 100% sure they're accurate to define.
2023-02-23 08:09:34 -08:00
Justine Tunney 298ba74a45 Make POSIX semaphores always process shared
Python triggered the undefined behavior previously since it appears to
be posting to a semaphore owned by a different process that wasn't set
to process shared mode. The performance loss to process shared futexes
is so low and semaphores are generally used for this purpose, so it'll
be much simpler to simply not impose undefined behavior here.
2023-02-23 08:07:54 -08:00
Justine Tunney b15f9eb58f Improve Python's threading story
Python threads are now generally working, however some parts of Python's
regression tests for threads are flaky. This is possibly due to needing
more locking primitives in Cosmo's IO system call wrappers, e.g. close.

    make o//third_party/python/Lib/test/test_threading.py.runs

See #747
2023-02-23 06:55:54 -08:00
ahgamut 60eb34509b quick addition of cosmo pthreads to python.com
- enable WITH_THREAD and _POSIX_THREADS
- add headers everywhere
- breaks only two tests (faulthandler and signal)
- disabled terminal completion because it causes segfaults for some
  reason (probably could not get the current thread)
2023-02-23 06:55:17 -08:00
Justine Tunney a808b3e738 Serialize ZipOS handle IO across threads 2023-02-23 06:55:10 -08:00
Justine Tunney 0f1ead8943 Fix select() on Linux
This fixes a bug where the caller's timeval will be clobbered on Linux.
The Kernel ABI *always* modifies the timeout argument but POSIX says it
should be a const parameter. The wrapper now handles the difference and
sys_select() may be used if obtaining the remainder on Linux is needed.
2023-02-23 06:55:05 -08:00
Justine Tunney dfabcd84c1 Fix sysinfo()
The system call wrapper was wrongfully reinterpreting kernel data. The
examples/sysinfo.c program is now updated to show how to correctly use
what's returned.
2023-02-23 06:54:58 -08:00
Justine Tunney 71d955be1d Add blog link for access() impl inspiration 2023-02-23 06:54:53 -08:00
James Hulce e4ee1da652 Fix filenames in help.txt (#722)
Many functions incorrectly direct users to see a .c file, when they should be .S
2023-02-22 19:00:49 -08:00
Gavin Hayes ff9c15f48a Add APE fexecve() support (#733) 2023-02-22 18:58:23 -08:00
Gavin Hayes b275e664ec Make ZipOS mmap safer (#735)
- It now runs entirely under __mmi_lock
- Hide implementation strace
2023-02-22 18:57:36 -08:00
Paul Kulchenko e323527ffa Remove slowloris handling from Redbean (#737)
It's been superseded by token bucket processing, does not take time
into considerations (only the number of fragments), and affects file
uploads that may require a large number of reads.
2023-02-22 18:56:02 -08:00
Joshua Wierenga 08fef9b277 Fix nt path format check (#744) 2023-02-22 18:42:13 -08:00
Gavin Hayes 94dcf81954 Add glob to cocmd (#740) 2023-02-21 10:31:04 -08:00
Justine Tunney 2b6261a52d Make some system call fixes
- Fix minor ABI issue with SIOCGIFCONF
- Fix ABI translation issues with statfs() on BSDs
- Fix SQLite angled header line
2023-02-12 22:16:34 -08:00
Justine Tunney 0eb621f75e Remove non-JIT'd blink builds for now 2023-02-12 22:14:16 -08:00
Justine Tunney 9634227181 Polyfill Linux unlink() EISDIR on POSIX platforms 2023-02-05 16:50:11 -08:00
Justine Tunney 9fce2751c8 Remove problematic test 2023-02-05 16:50:04 -08:00
Justine Tunney 49c1dea03b Add msync_test 2023-02-05 16:49:52 -08:00
184 changed files with 2373 additions and 1820 deletions

No files matched your search

+1
View File
@@ -8,6 +8,7 @@ AlwaysBreakBeforeMultilineStrings: false
AllowShortFunctionsOnASingleLine: false
KeepEmptyLinesAtTheStartOfBlocks: true
ConstructorInitializerAllOnOneLineOrOnePerLine: true
IncludeBlocks: Merge
---
Language: Cpp
AllowShortFunctionsOnASingleLine: false
+7 -6
View File
@@ -121,6 +121,7 @@ include libc/tinymath/tinymath.mk # │ You can issue raw system calls
include third_party/compiler_rt/compiler_rt.mk # │
include libc/str/str.mk # │
include third_party/xed/xed.mk # │
include third_party/puff/puff.mk # │
include third_party/zlib/zlib.mk # │
include third_party/double-conversion/dc.mk # │
include libc/elf/elf.mk # │
@@ -134,11 +135,11 @@ include libc/crt/crt.mk # │ You can issue system calls
include third_party/nsync/nsync.mk # │
include third_party/dlmalloc/dlmalloc.mk #─┘
include libc/mem/mem.mk #─┐
include libc/zipos/zipos.mk # ├──DYNAMIC RUNTIME
include third_party/gdtoa/gdtoa.mk # │ You can now use stdio
include libc/time/time.mk # │ You can finally call malloc()
include third_party/nsync/mem/mem.mk # │
include libc/thread/thread.mk # │
include third_party/gdtoa/gdtoa.mk # ├──DYNAMIC RUNTIME
include third_party/nsync/mem/mem.mk # │ You can now use stdio
include libc/thread/thread.mk # │ You can finally call malloc()
include libc/zipos/zipos.mk # │
include libc/time/time.mk # │
include libc/stdio/stdio.mk # │
include third_party/libcxx/libcxx.mk # │
include net/net.mk # │
@@ -309,7 +310,6 @@ COSMOPOLITAN_OBJECTS = \
LIBC_LOG \
LIBC_TIME \
LIBC_ZIPOS \
THIRD_PARTY_ZLIB \
THIRD_PARTY_MUSL \
LIBC_STDIO \
THIRD_PARTY_GDTOA \
@@ -335,6 +335,7 @@ COSMOPOLITAN_OBJECTS = \
LIBC_NT_ADVAPI32 \
LIBC_NT_SYNCHRONIZATION \
LIBC_FMT \
THIRD_PARTY_PUFF \
THIRD_PARTY_COMPILER_RT \
LIBC_TINYMATH \
THIRD_PARTY_XED \
+5
View File
@@ -243,6 +243,11 @@ You normally run the `.com.dbg` file under gdb. If you need to debug the
gdb foo.com -ex 'add-symbol-file foo.com.dbg 0x401000'
```
## Discord Chatroom
The Cosmopolitan development team collaborates on the Redbean Discord
server. You're welcome to join us! <https://discord.gg/FwAVVu7eJ4>
## Support Vector
| Platform | Min Version | Circa |
+12 -301
View File
@@ -701,7 +701,7 @@ emush: .ascii "\n@\n#'\"\n"
// 2. gunzip the blink virtual machine executable
// 3. relaunch this program inside the blink vm
.ascii "o=\"$(command -v \"$0\")\"\n"
.ascii "e=\"${TMPDIR:-${HOME:-.}}/.ape-blink-1.1\"\n"
.ascii "e=\"${TMPDIR:-${HOME:-.}}/.ape-blink-0.9.2\"\n"
// Blink for Apple Silicon, e.g. M1 Macbook
.ascii "if [ \"$s\" = Darwin ] && [ \"$m\" = arm64 ]; then\n"
@@ -771,239 +771,6 @@ emush: .ascii "\n@\n#'\"\n"
.ascii "fi\n"
.ascii "fi\n"
// Blink for Linux Generic ARM
.ascii "if [ \"$s\" = Linux ] && [ \"${m#arm}\" != \"$m\" ]; then\n"
.ascii "if ! [ -x \"$e\" ]; then\n"
.ascii "echo \"extracting blink-arm to ${e}\" >&2\n"
.ascii "dd if=\"$o\" bs=1 skip=$(("
.byte blink_arm_b9
.byte blink_arm_b8
.byte blink_arm_b7
.byte blink_arm_b6
.byte blink_arm_b5
.byte blink_arm_b4
.byte blink_arm_b3
.byte blink_arm_b2
.byte blink_arm_b1
.byte blink_arm_b0
.ascii ")) count=$(("
.byte blink_arm_size_b9
.byte blink_arm_size_b8
.byte blink_arm_size_b7
.byte blink_arm_size_b6
.byte blink_arm_size_b5
.byte blink_arm_size_b4
.byte blink_arm_size_b3
.byte blink_arm_size_b2
.byte blink_arm_size_b1
.byte blink_arm_size_b0
.ascii ")) conv=notrunc 2>/dev/null | gunzip >\"$e.$$\"\n"
.ascii "mv -f \"$e.$$\" \"$e\"\n"
.ascii "chmod +x \"$e\"\n"
.ascii "fi\n"
.ascii "exec \"$e\" \"$o\" \"$@\"\n"
.ascii "fi\n"
// Blink for Linux on Legacy x86
.ascii "if [ \"$s\" = Linux ]; then\n"
.ascii "if [ \"$m\" = i686 ] || [ \"$m\" = i386 ]; then\n"
.ascii "if ! [ -x \"$e\" ]; then\n"
.ascii "echo \"extracting blink-i486 to ${e}\" >&2\n"
.ascii "dd if=\"$o\" bs=1 skip=$(("
.byte blink_i486_b9
.byte blink_i486_b8
.byte blink_i486_b7
.byte blink_i486_b6
.byte blink_i486_b5
.byte blink_i486_b4
.byte blink_i486_b3
.byte blink_i486_b2
.byte blink_i486_b1
.byte blink_i486_b0
.ascii ")) count=$(("
.byte blink_i486_size_b9
.byte blink_i486_size_b8
.byte blink_i486_size_b7
.byte blink_i486_size_b6
.byte blink_i486_size_b5
.byte blink_i486_size_b4
.byte blink_i486_size_b3
.byte blink_i486_size_b2
.byte blink_i486_size_b1
.byte blink_i486_size_b0
.ascii ")) conv=notrunc 2>/dev/null | gunzip >\"$e.$$\"\n"
.ascii "mv -f \"$e.$$\" \"$e\"\n"
.ascii "chmod +x \"$e\"\n"
.ascii "fi\n"
.ascii "exec \"$e\" \"$o\" \"$@\"\n"
.ascii "fi\n"
.ascii "fi\n"
// Blink for Linux on RISC-V
.ascii "if [ \"$s\" = Linux ] && [ \"$m\" = riscv64 ]; then\n"
.ascii "if ! [ -x \"$e\" ]; then\n"
.ascii "echo \"extracting blink-riscv64 to ${e}\" >&2\n"
.ascii "dd if=\"$o\" bs=1 skip=$(("
.byte blink_riscv64_b9
.byte blink_riscv64_b8
.byte blink_riscv64_b7
.byte blink_riscv64_b6
.byte blink_riscv64_b5
.byte blink_riscv64_b4
.byte blink_riscv64_b3
.byte blink_riscv64_b2
.byte blink_riscv64_b1
.byte blink_riscv64_b0
.ascii ")) count=$(("
.byte blink_riscv64_size_b9
.byte blink_riscv64_size_b8
.byte blink_riscv64_size_b7
.byte blink_riscv64_size_b6
.byte blink_riscv64_size_b5
.byte blink_riscv64_size_b4
.byte blink_riscv64_size_b3
.byte blink_riscv64_size_b2
.byte blink_riscv64_size_b1
.byte blink_riscv64_size_b0
.ascii ")) conv=notrunc 2>/dev/null | gunzip >\"$e.$$\"\n"
.ascii "mv -f \"$e.$$\" \"$e\"\n"
.ascii "chmod +x \"$e\"\n"
.ascii "fi\n"
.ascii "exec \"$e\" \"$o\" \"$@\"\n"
.ascii "fi\n"
// Blink for Linux on MIPS Little Endian, e.g. Ubiquiti EdgerouterX
.ascii "if [ \"$s\" = Linux ] && [ \"$m\" = mips ]; then\n"
.ascii "if ! [ -x \"$e\" ]; then\n"
.ascii "echo \"extracting blink-mipsel to ${e}\" >&2\n"
.ascii "dd if=\"$o\" bs=1 skip=$(("
.byte blink_mipsel_b9
.byte blink_mipsel_b8
.byte blink_mipsel_b7
.byte blink_mipsel_b6
.byte blink_mipsel_b5
.byte blink_mipsel_b4
.byte blink_mipsel_b3
.byte blink_mipsel_b2
.byte blink_mipsel_b1
.byte blink_mipsel_b0
.ascii ")) count=$(("
.byte blink_mipsel_size_b9
.byte blink_mipsel_size_b8
.byte blink_mipsel_size_b7
.byte blink_mipsel_size_b6
.byte blink_mipsel_size_b5
.byte blink_mipsel_size_b4
.byte blink_mipsel_size_b3
.byte blink_mipsel_size_b2
.byte blink_mipsel_size_b1
.byte blink_mipsel_size_b0
.ascii ")) conv=notrunc 2>/dev/null | gunzip >\"$e.$$\"\n"
.ascii "mv -f \"$e.$$\" \"$e\"\n"
.ascii "chmod +x \"$e\"\n"
.ascii "fi\n"
.ascii "exec \"$e\" \"$o\" \"$@\"\n"
.ascii "fi\n"
// Blink for Linux on PowerPC 64 Little Endian, e.g. Raptor
.ascii "if [ \"$s\" = Linux ] && [ \"$m\" = ppc64le ]; then\n"
.ascii "if ! [ -x \"$e\" ]; then\n"
.ascii "echo \"extracting blink-powerpc64le to ${e}\" >&2\n"
.ascii "dd if=\"$o\" bs=1 skip=$(("
.byte blink_powerpc64le_b9
.byte blink_powerpc64le_b8
.byte blink_powerpc64le_b7
.byte blink_powerpc64le_b6
.byte blink_powerpc64le_b5
.byte blink_powerpc64le_b4
.byte blink_powerpc64le_b3
.byte blink_powerpc64le_b2
.byte blink_powerpc64le_b1
.byte blink_powerpc64le_b0
.ascii ")) count=$(("
.byte blink_powerpc64le_size_b9
.byte blink_powerpc64le_size_b8
.byte blink_powerpc64le_size_b7
.byte blink_powerpc64le_size_b6
.byte blink_powerpc64le_size_b5
.byte blink_powerpc64le_size_b4
.byte blink_powerpc64le_size_b3
.byte blink_powerpc64le_size_b2
.byte blink_powerpc64le_size_b1
.byte blink_powerpc64le_size_b0
.ascii ")) conv=notrunc 2>/dev/null | gunzip >\"$e.$$\"\n"
.ascii "mv -f \"$e.$$\" \"$e\"\n"
.ascii "chmod +x \"$e\"\n"
.ascii "fi\n"
.ascii "exec \"$e\" \"$o\" \"$@\"\n"
.ascii "fi\n"
// Blink for Linux on PowerPC, e.g. Old Macintosh
.ascii "if [ \"$s\" = Linux ] && [ \"$m\" = ppc ]; then\n"
.ascii "if ! [ -x \"$e\" ]; then\n"
.ascii "echo \"extracting blink-powerpc to ${e}\" >&2\n"
.ascii "dd if=\"$o\" bs=1 skip=$(("
.byte blink_powerpc_b9
.byte blink_powerpc_b8
.byte blink_powerpc_b7
.byte blink_powerpc_b6
.byte blink_powerpc_b5
.byte blink_powerpc_b4
.byte blink_powerpc_b3
.byte blink_powerpc_b2
.byte blink_powerpc_b1
.byte blink_powerpc_b0
.ascii ")) count=$(("
.byte blink_powerpc_size_b9
.byte blink_powerpc_size_b8
.byte blink_powerpc_size_b7
.byte blink_powerpc_size_b6
.byte blink_powerpc_size_b5
.byte blink_powerpc_size_b4
.byte blink_powerpc_size_b3
.byte blink_powerpc_size_b2
.byte blink_powerpc_size_b1
.byte blink_powerpc_size_b0
.ascii ")) conv=notrunc 2>/dev/null | gunzip >\"$e.$$\"\n"
.ascii "mv -f \"$e.$$\" \"$e\"\n"
.ascii "chmod +x \"$e\"\n"
.ascii "fi\n"
.ascii "exec \"$e\" \"$o\" \"$@\"\n"
.ascii "fi\n"
// Blink for Linux on IBM Mainframes
.ascii "if [ \"$s\" = Linux ] && [ \"$m\" = s390x ]; then\n"
.ascii "if ! [ -x \"$e\" ]; then\n"
.ascii "echo \"extracting blink-s390x to ${e}\" >&2\n"
.ascii "dd if=\"$o\" bs=1 skip=$(("
.byte blink_s390x_b9
.byte blink_s390x_b8
.byte blink_s390x_b7
.byte blink_s390x_b6
.byte blink_s390x_b5
.byte blink_s390x_b4
.byte blink_s390x_b3
.byte blink_s390x_b2
.byte blink_s390x_b1
.byte blink_s390x_b0
.ascii ")) count=$(("
.byte blink_s390x_size_b9
.byte blink_s390x_size_b8
.byte blink_s390x_size_b7
.byte blink_s390x_size_b6
.byte blink_s390x_size_b5
.byte blink_s390x_size_b4
.byte blink_s390x_size_b3
.byte blink_s390x_size_b2
.byte blink_s390x_size_b1
.byte blink_s390x_size_b0
.ascii ")) conv=notrunc 2>/dev/null | gunzip >\"$e.$$\"\n"
.ascii "mv -f \"$e.$$\" \"$e\"\n"
.ascii "chmod +x \"$e\"\n"
.ascii "fi\n"
.ascii "exec \"$e\" \"$o\" \"$@\"\n"
.ascii "fi\n"
.ascii "echo unsupported architecture >&2\n"
.rept 16
.ascii "exit 127\n"
@@ -1639,12 +1406,12 @@ longmodeloader:
.endfn longmodeloader
// Long Mode Hardware Check
lcheck: pushf # check for i8086 / i8088 / i80186
pop %ax
test $0x80,%ah # see intel manual volume 1 20.1.2
jnz 10f # we now assume 32bit is supported
pushfl # now check for i386 or early i486
pop %eax # test ability to change cpuid bit
lcheck: pushf # checks for i8086 / i8088 / i80186
pop %ax # see intel manual volume 1 §20.1.2
test $0x80,%ah
jnz 10f # we now assume 32 bit is supported
pushfl # now check for i386, or early i486
pop %eax # tests ability to change cpuid bit
mov %eax,%ecx
mov $1<<21,%ebx
xor %ebx,%eax
@@ -1657,16 +1424,16 @@ lcheck: pushf # check for i8086 / i8088 / i80186
or %ebx,%eax # puts cpuid bit in the on position
push %eax
popfl
mov $0x80000000,%edi # get amd ext cpuid thingy length
mov $0x80000000,%edi # get amd64 ext cpuid thingy length
mov %edi,%eax
inc %edi
cpuid # clobbers eax, ebx, ecx, and edx
cpuid # leaf 0x80000000, clob ax/bx/cx/dx
cmp %edi,%eax
jl 10f
mov %edi,%eax
cpuid
mov $1<<29|1<<20,%edi # need nexgen32e long mode support
and %edi,%edx # & nx support
cpuid # leaf 0x80000001, clob ax/bx/cx/dx
mov $1<<29|1<<20,%edi # 29 = LM (long), 20 = NX (no exec)
and %edi,%edx # we need to both, or we won't work
cmp %edi,%edx
jne 10f
xor %ax,%ax
@@ -2172,61 +1939,5 @@ blink_darwin_arm64:
blink_darwin_arm64_size = . - blink_darwin_arm64
.previous
.section .blink,"a",@progbits
.globl blink_arm_size
blink_arm:
.incbin "ape/blink-arm.gz"
.endobj blink_arm,globl
blink_arm_size = . - blink_arm
.previous
.section .blink,"a",@progbits
.globl blink_i486_size
blink_i486:
.incbin "ape/blink-i486.gz"
.endobj blink_i486,globl
blink_i486_size = . - blink_i486
.previous
.section .blink,"a",@progbits
.globl blink_riscv64_size
blink_riscv64:
.incbin "ape/blink-riscv64.gz"
.endobj blink_riscv64,globl
blink_riscv64_size = . - blink_riscv64
.previous
.section .blink,"a",@progbits
.globl blink_mipsel_size
blink_mipsel:
.incbin "ape/blink-mipsel.gz"
.endobj blink_mipsel,globl
blink_mipsel_size = . - blink_mipsel
.previous
.section .blink,"a",@progbits
.globl blink_powerpc64le_size
blink_powerpc64le:
.incbin "ape/blink-powerpc64le.gz"
.endobj blink_powerpc64le,globl
blink_powerpc64le_size = . - blink_powerpc64le
.previous
.section .blink,"a",@progbits
.globl blink_powerpc_size
blink_powerpc:
.incbin "ape/blink-powerpc.gz"
.endobj blink_powerpc,globl
blink_powerpc_size = . - blink_powerpc
.previous
.section .blink,"a",@progbits
.globl blink_s390x_size
blink_s390x:
.incbin "ape/blink-s390x.gz"
.endobj blink_s390x,globl
blink_s390x_size = . - blink_s390x
.previous
.end

+1 -155
View File
@@ -611,160 +611,6 @@ HIDDEN(blink_darwin_arm64_size_b7 = blink_darwin_arm64_size < 10000000 ? 32 : bl
HIDDEN(blink_darwin_arm64_size_b8 = blink_darwin_arm64_size < 100000000 ? 32 : blink_darwin_arm64_size / 100000000 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b9 = blink_darwin_arm64_size < 1000000000 ? 32 : blink_darwin_arm64_size / 1000000000 % 10 + 48);
HIDDEN(blink_arm_b0 = RVA(blink_arm) % 10 + 48);
HIDDEN(blink_arm_b1 = RVA(blink_arm) < 10 ? 32 : RVA(blink_arm) / 10 % 10 + 48);
HIDDEN(blink_arm_b2 = RVA(blink_arm) < 100 ? 32 : RVA(blink_arm) / 100 % 10 + 48);
HIDDEN(blink_arm_b3 = RVA(blink_arm) < 1000 ? 32 : RVA(blink_arm) / 1000 % 10 + 48);
HIDDEN(blink_arm_b4 = RVA(blink_arm) < 10000 ? 32 : RVA(blink_arm) / 10000 % 10 + 48);
HIDDEN(blink_arm_b5 = RVA(blink_arm) < 100000 ? 32 : RVA(blink_arm) / 100000 % 10 + 48);
HIDDEN(blink_arm_b6 = RVA(blink_arm) < 1000000 ? 32 : RVA(blink_arm) / 1000000 % 10 + 48);
HIDDEN(blink_arm_b7 = RVA(blink_arm) < 10000000 ? 32 : RVA(blink_arm) / 10000000 % 10 + 48);
HIDDEN(blink_arm_b8 = RVA(blink_arm) < 100000000 ? 32 : RVA(blink_arm) / 100000000 % 10 + 48);
HIDDEN(blink_arm_b9 = RVA(blink_arm) < 1000000000 ? 32 : RVA(blink_arm) / 1000000000 % 10 + 48);
HIDDEN(blink_arm_size_b0 = blink_arm_size % 10 + 48);
HIDDEN(blink_arm_size_b1 = blink_arm_size < 10 ? 32 : blink_arm_size / 10 % 10 + 48);
HIDDEN(blink_arm_size_b2 = blink_arm_size < 100 ? 32 : blink_arm_size / 100 % 10 + 48);
HIDDEN(blink_arm_size_b3 = blink_arm_size < 1000 ? 32 : blink_arm_size / 1000 % 10 + 48);
HIDDEN(blink_arm_size_b4 = blink_arm_size < 10000 ? 32 : blink_arm_size / 10000 % 10 + 48);
HIDDEN(blink_arm_size_b5 = blink_arm_size < 100000 ? 32 : blink_arm_size / 100000 % 10 + 48);
HIDDEN(blink_arm_size_b6 = blink_arm_size < 1000000 ? 32 : blink_arm_size / 1000000 % 10 + 48);
HIDDEN(blink_arm_size_b7 = blink_arm_size < 10000000 ? 32 : blink_arm_size / 10000000 % 10 + 48);
HIDDEN(blink_arm_size_b8 = blink_arm_size < 100000000 ? 32 : blink_arm_size / 100000000 % 10 + 48);
HIDDEN(blink_arm_size_b9 = blink_arm_size < 1000000000 ? 32 : blink_arm_size / 1000000000 % 10 + 48);
HIDDEN(blink_i486_b0 = RVA(blink_i486) % 10 + 48);
HIDDEN(blink_i486_b1 = RVA(blink_i486) < 10 ? 32 : RVA(blink_i486) / 10 % 10 + 48);
HIDDEN(blink_i486_b2 = RVA(blink_i486) < 100 ? 32 : RVA(blink_i486) / 100 % 10 + 48);
HIDDEN(blink_i486_b3 = RVA(blink_i486) < 1000 ? 32 : RVA(blink_i486) / 1000 % 10 + 48);
HIDDEN(blink_i486_b4 = RVA(blink_i486) < 10000 ? 32 : RVA(blink_i486) / 10000 % 10 + 48);
HIDDEN(blink_i486_b5 = RVA(blink_i486) < 100000 ? 32 : RVA(blink_i486) / 100000 % 10 + 48);
HIDDEN(blink_i486_b6 = RVA(blink_i486) < 1000000 ? 32 : RVA(blink_i486) / 1000000 % 10 + 48);
HIDDEN(blink_i486_b7 = RVA(blink_i486) < 10000000 ? 32 : RVA(blink_i486) / 10000000 % 10 + 48);
HIDDEN(blink_i486_b8 = RVA(blink_i486) < 100000000 ? 32 : RVA(blink_i486) / 100000000 % 10 + 48);
HIDDEN(blink_i486_b9 = RVA(blink_i486) < 1000000000 ? 32 : RVA(blink_i486) / 1000000000 % 10 + 48);
HIDDEN(blink_i486_size_b0 = blink_i486_size % 10 + 48);
HIDDEN(blink_i486_size_b1 = blink_i486_size < 10 ? 32 : blink_i486_size / 10 % 10 + 48);
HIDDEN(blink_i486_size_b2 = blink_i486_size < 100 ? 32 : blink_i486_size / 100 % 10 + 48);
HIDDEN(blink_i486_size_b3 = blink_i486_size < 1000 ? 32 : blink_i486_size / 1000 % 10 + 48);
HIDDEN(blink_i486_size_b4 = blink_i486_size < 10000 ? 32 : blink_i486_size / 10000 % 10 + 48);
HIDDEN(blink_i486_size_b5 = blink_i486_size < 100000 ? 32 : blink_i486_size / 100000 % 10 + 48);
HIDDEN(blink_i486_size_b6 = blink_i486_size < 1000000 ? 32 : blink_i486_size / 1000000 % 10 + 48);
HIDDEN(blink_i486_size_b7 = blink_i486_size < 10000000 ? 32 : blink_i486_size / 10000000 % 10 + 48);
HIDDEN(blink_i486_size_b8 = blink_i486_size < 100000000 ? 32 : blink_i486_size / 100000000 % 10 + 48);
HIDDEN(blink_i486_size_b9 = blink_i486_size < 1000000000 ? 32 : blink_i486_size / 1000000000 % 10 + 48);
HIDDEN(blink_riscv64_b0 = RVA(blink_riscv64) % 10 + 48);
HIDDEN(blink_riscv64_b1 = RVA(blink_riscv64) < 10 ? 32 : RVA(blink_riscv64) / 10 % 10 + 48);
HIDDEN(blink_riscv64_b2 = RVA(blink_riscv64) < 100 ? 32 : RVA(blink_riscv64) / 100 % 10 + 48);
HIDDEN(blink_riscv64_b3 = RVA(blink_riscv64) < 1000 ? 32 : RVA(blink_riscv64) / 1000 % 10 + 48);
HIDDEN(blink_riscv64_b4 = RVA(blink_riscv64) < 10000 ? 32 : RVA(blink_riscv64) / 10000 % 10 + 48);
HIDDEN(blink_riscv64_b5 = RVA(blink_riscv64) < 100000 ? 32 : RVA(blink_riscv64) / 100000 % 10 + 48);
HIDDEN(blink_riscv64_b6 = RVA(blink_riscv64) < 1000000 ? 32 : RVA(blink_riscv64) / 1000000 % 10 + 48);
HIDDEN(blink_riscv64_b7 = RVA(blink_riscv64) < 10000000 ? 32 : RVA(blink_riscv64) / 10000000 % 10 + 48);
HIDDEN(blink_riscv64_b8 = RVA(blink_riscv64) < 100000000 ? 32 : RVA(blink_riscv64) / 100000000 % 10 + 48);
HIDDEN(blink_riscv64_b9 = RVA(blink_riscv64) < 1000000000 ? 32 : RVA(blink_riscv64) / 1000000000 % 10 + 48);
HIDDEN(blink_riscv64_size_b0 = blink_riscv64_size % 10 + 48);
HIDDEN(blink_riscv64_size_b1 = blink_riscv64_size < 10 ? 32 : blink_riscv64_size / 10 % 10 + 48);
HIDDEN(blink_riscv64_size_b2 = blink_riscv64_size < 100 ? 32 : blink_riscv64_size / 100 % 10 + 48);
HIDDEN(blink_riscv64_size_b3 = blink_riscv64_size < 1000 ? 32 : blink_riscv64_size / 1000 % 10 + 48);
HIDDEN(blink_riscv64_size_b4 = blink_riscv64_size < 10000 ? 32 : blink_riscv64_size / 10000 % 10 + 48);
HIDDEN(blink_riscv64_size_b5 = blink_riscv64_size < 100000 ? 32 : blink_riscv64_size / 100000 % 10 + 48);
HIDDEN(blink_riscv64_size_b6 = blink_riscv64_size < 1000000 ? 32 : blink_riscv64_size / 1000000 % 10 + 48);
HIDDEN(blink_riscv64_size_b7 = blink_riscv64_size < 10000000 ? 32 : blink_riscv64_size / 10000000 % 10 + 48);
HIDDEN(blink_riscv64_size_b8 = blink_riscv64_size < 100000000 ? 32 : blink_riscv64_size / 100000000 % 10 + 48);
HIDDEN(blink_riscv64_size_b9 = blink_riscv64_size < 1000000000 ? 32 : blink_riscv64_size / 1000000000 % 10 + 48);
HIDDEN(blink_mipsel_b0 = RVA(blink_mipsel) % 10 + 48);
HIDDEN(blink_mipsel_b1 = RVA(blink_mipsel) < 10 ? 32 : RVA(blink_mipsel) / 10 % 10 + 48);
HIDDEN(blink_mipsel_b2 = RVA(blink_mipsel) < 100 ? 32 : RVA(blink_mipsel) / 100 % 10 + 48);
HIDDEN(blink_mipsel_b3 = RVA(blink_mipsel) < 1000 ? 32 : RVA(blink_mipsel) / 1000 % 10 + 48);
HIDDEN(blink_mipsel_b4 = RVA(blink_mipsel) < 10000 ? 32 : RVA(blink_mipsel) / 10000 % 10 + 48);
HIDDEN(blink_mipsel_b5 = RVA(blink_mipsel) < 100000 ? 32 : RVA(blink_mipsel) / 100000 % 10 + 48);
HIDDEN(blink_mipsel_b6 = RVA(blink_mipsel) < 1000000 ? 32 : RVA(blink_mipsel) / 1000000 % 10 + 48);
HIDDEN(blink_mipsel_b7 = RVA(blink_mipsel) < 10000000 ? 32 : RVA(blink_mipsel) / 10000000 % 10 + 48);
HIDDEN(blink_mipsel_b8 = RVA(blink_mipsel) < 100000000 ? 32 : RVA(blink_mipsel) / 100000000 % 10 + 48);
HIDDEN(blink_mipsel_b9 = RVA(blink_mipsel) < 1000000000 ? 32 : RVA(blink_mipsel) / 1000000000 % 10 + 48);
HIDDEN(blink_mipsel_size_b0 = blink_mipsel_size % 10 + 48);
HIDDEN(blink_mipsel_size_b1 = blink_mipsel_size < 10 ? 32 : blink_mipsel_size / 10 % 10 + 48);
HIDDEN(blink_mipsel_size_b2 = blink_mipsel_size < 100 ? 32 : blink_mipsel_size / 100 % 10 + 48);
HIDDEN(blink_mipsel_size_b3 = blink_mipsel_size < 1000 ? 32 : blink_mipsel_size / 1000 % 10 + 48);
HIDDEN(blink_mipsel_size_b4 = blink_mipsel_size < 10000 ? 32 : blink_mipsel_size / 10000 % 10 + 48);
HIDDEN(blink_mipsel_size_b5 = blink_mipsel_size < 100000 ? 32 : blink_mipsel_size / 100000 % 10 + 48);
HIDDEN(blink_mipsel_size_b6 = blink_mipsel_size < 1000000 ? 32 : blink_mipsel_size / 1000000 % 10 + 48);
HIDDEN(blink_mipsel_size_b7 = blink_mipsel_size < 10000000 ? 32 : blink_mipsel_size / 10000000 % 10 + 48);
HIDDEN(blink_mipsel_size_b8 = blink_mipsel_size < 100000000 ? 32 : blink_mipsel_size / 100000000 % 10 + 48);
HIDDEN(blink_mipsel_size_b9 = blink_mipsel_size < 1000000000 ? 32 : blink_mipsel_size / 1000000000 % 10 + 48);
HIDDEN(blink_powerpc64le_b0 = RVA(blink_powerpc64le) % 10 + 48);
HIDDEN(blink_powerpc64le_b1 = RVA(blink_powerpc64le) < 10 ? 32 : RVA(blink_powerpc64le) / 10 % 10 + 48);
HIDDEN(blink_powerpc64le_b2 = RVA(blink_powerpc64le) < 100 ? 32 : RVA(blink_powerpc64le) / 100 % 10 + 48);
HIDDEN(blink_powerpc64le_b3 = RVA(blink_powerpc64le) < 1000 ? 32 : RVA(blink_powerpc64le) / 1000 % 10 + 48);
HIDDEN(blink_powerpc64le_b4 = RVA(blink_powerpc64le) < 10000 ? 32 : RVA(blink_powerpc64le) / 10000 % 10 + 48);
HIDDEN(blink_powerpc64le_b5 = RVA(blink_powerpc64le) < 100000 ? 32 : RVA(blink_powerpc64le) / 100000 % 10 + 48);
HIDDEN(blink_powerpc64le_b6 = RVA(blink_powerpc64le) < 1000000 ? 32 : RVA(blink_powerpc64le) / 1000000 % 10 + 48);
HIDDEN(blink_powerpc64le_b7 = RVA(blink_powerpc64le) < 10000000 ? 32 : RVA(blink_powerpc64le) / 10000000 % 10 + 48);
HIDDEN(blink_powerpc64le_b8 = RVA(blink_powerpc64le) < 100000000 ? 32 : RVA(blink_powerpc64le) / 100000000 % 10 + 48);
HIDDEN(blink_powerpc64le_b9 = RVA(blink_powerpc64le) < 1000000000 ? 32 : RVA(blink_powerpc64le) / 1000000000 % 10 + 48);
HIDDEN(blink_powerpc64le_size_b0 = blink_powerpc64le_size % 10 + 48);
HIDDEN(blink_powerpc64le_size_b1 = blink_powerpc64le_size < 10 ? 32 : blink_powerpc64le_size / 10 % 10 + 48);
HIDDEN(blink_powerpc64le_size_b2 = blink_powerpc64le_size < 100 ? 32 : blink_powerpc64le_size / 100 % 10 + 48);
HIDDEN(blink_powerpc64le_size_b3 = blink_powerpc64le_size < 1000 ? 32 : blink_powerpc64le_size / 1000 % 10 + 48);
HIDDEN(blink_powerpc64le_size_b4 = blink_powerpc64le_size < 10000 ? 32 : blink_powerpc64le_size / 10000 % 10 + 48);
HIDDEN(blink_powerpc64le_size_b5 = blink_powerpc64le_size < 100000 ? 32 : blink_powerpc64le_size / 100000 % 10 + 48);
HIDDEN(blink_powerpc64le_size_b6 = blink_powerpc64le_size < 1000000 ? 32 : blink_powerpc64le_size / 1000000 % 10 + 48);
HIDDEN(blink_powerpc64le_size_b7 = blink_powerpc64le_size < 10000000 ? 32 : blink_powerpc64le_size / 10000000 % 10 + 48);
HIDDEN(blink_powerpc64le_size_b8 = blink_powerpc64le_size < 100000000 ? 32 : blink_powerpc64le_size / 100000000 % 10 + 48);
HIDDEN(blink_powerpc64le_size_b9 = blink_powerpc64le_size < 1000000000 ? 32 : blink_powerpc64le_size / 1000000000 % 10 + 48);
HIDDEN(blink_powerpc_b0 = RVA(blink_powerpc) % 10 + 48);
HIDDEN(blink_powerpc_b1 = RVA(blink_powerpc) < 10 ? 32 : RVA(blink_powerpc) / 10 % 10 + 48);
HIDDEN(blink_powerpc_b2 = RVA(blink_powerpc) < 100 ? 32 : RVA(blink_powerpc) / 100 % 10 + 48);
HIDDEN(blink_powerpc_b3 = RVA(blink_powerpc) < 1000 ? 32 : RVA(blink_powerpc) / 1000 % 10 + 48);
HIDDEN(blink_powerpc_b4 = RVA(blink_powerpc) < 10000 ? 32 : RVA(blink_powerpc) / 10000 % 10 + 48);
HIDDEN(blink_powerpc_b5 = RVA(blink_powerpc) < 100000 ? 32 : RVA(blink_powerpc) / 100000 % 10 + 48);
HIDDEN(blink_powerpc_b6 = RVA(blink_powerpc) < 1000000 ? 32 : RVA(blink_powerpc) / 1000000 % 10 + 48);
HIDDEN(blink_powerpc_b7 = RVA(blink_powerpc) < 10000000 ? 32 : RVA(blink_powerpc) / 10000000 % 10 + 48);
HIDDEN(blink_powerpc_b8 = RVA(blink_powerpc) < 100000000 ? 32 : RVA(blink_powerpc) / 100000000 % 10 + 48);
HIDDEN(blink_powerpc_b9 = RVA(blink_powerpc) < 1000000000 ? 32 : RVA(blink_powerpc) / 1000000000 % 10 + 48);
HIDDEN(blink_powerpc_size_b0 = blink_powerpc_size % 10 + 48);
HIDDEN(blink_powerpc_size_b1 = blink_powerpc_size < 10 ? 32 : blink_powerpc_size / 10 % 10 + 48);
HIDDEN(blink_powerpc_size_b2 = blink_powerpc_size < 100 ? 32 : blink_powerpc_size / 100 % 10 + 48);
HIDDEN(blink_powerpc_size_b3 = blink_powerpc_size < 1000 ? 32 : blink_powerpc_size / 1000 % 10 + 48);
HIDDEN(blink_powerpc_size_b4 = blink_powerpc_size < 10000 ? 32 : blink_powerpc_size / 10000 % 10 + 48);
HIDDEN(blink_powerpc_size_b5 = blink_powerpc_size < 100000 ? 32 : blink_powerpc_size / 100000 % 10 + 48);
HIDDEN(blink_powerpc_size_b6 = blink_powerpc_size < 1000000 ? 32 : blink_powerpc_size / 1000000 % 10 + 48);
HIDDEN(blink_powerpc_size_b7 = blink_powerpc_size < 10000000 ? 32 : blink_powerpc_size / 10000000 % 10 + 48);
HIDDEN(blink_powerpc_size_b8 = blink_powerpc_size < 100000000 ? 32 : blink_powerpc_size / 100000000 % 10 + 48);
HIDDEN(blink_powerpc_size_b9 = blink_powerpc_size < 1000000000 ? 32 : blink_powerpc_size / 1000000000 % 10 + 48);
HIDDEN(blink_s390x_b0 = RVA(blink_s390x) % 10 + 48);
HIDDEN(blink_s390x_b1 = RVA(blink_s390x) < 10 ? 32 : RVA(blink_s390x) / 10 % 10 + 48);
HIDDEN(blink_s390x_b2 = RVA(blink_s390x) < 100 ? 32 : RVA(blink_s390x) / 100 % 10 + 48);
HIDDEN(blink_s390x_b3 = RVA(blink_s390x) < 1000 ? 32 : RVA(blink_s390x) / 1000 % 10 + 48);
HIDDEN(blink_s390x_b4 = RVA(blink_s390x) < 10000 ? 32 : RVA(blink_s390x) / 10000 % 10 + 48);
HIDDEN(blink_s390x_b5 = RVA(blink_s390x) < 100000 ? 32 : RVA(blink_s390x) / 100000 % 10 + 48);
HIDDEN(blink_s390x_b6 = RVA(blink_s390x) < 1000000 ? 32 : RVA(blink_s390x) / 1000000 % 10 + 48);
HIDDEN(blink_s390x_b7 = RVA(blink_s390x) < 10000000 ? 32 : RVA(blink_s390x) / 10000000 % 10 + 48);
HIDDEN(blink_s390x_b8 = RVA(blink_s390x) < 100000000 ? 32 : RVA(blink_s390x) / 100000000 % 10 + 48);
HIDDEN(blink_s390x_b9 = RVA(blink_s390x) < 1000000000 ? 32 : RVA(blink_s390x) / 1000000000 % 10 + 48);
HIDDEN(blink_s390x_size_b0 = blink_s390x_size % 10 + 48);
HIDDEN(blink_s390x_size_b1 = blink_s390x_size < 10 ? 32 : blink_s390x_size / 10 % 10 + 48);
HIDDEN(blink_s390x_size_b2 = blink_s390x_size < 100 ? 32 : blink_s390x_size / 100 % 10 + 48);
HIDDEN(blink_s390x_size_b3 = blink_s390x_size < 1000 ? 32 : blink_s390x_size / 1000 % 10 + 48);
HIDDEN(blink_s390x_size_b4 = blink_s390x_size < 10000 ? 32 : blink_s390x_size / 10000 % 10 + 48);
HIDDEN(blink_s390x_size_b5 = blink_s390x_size < 100000 ? 32 : blink_s390x_size / 100000 % 10 + 48);
HIDDEN(blink_s390x_size_b6 = blink_s390x_size < 1000000 ? 32 : blink_s390x_size / 1000000 % 10 + 48);
HIDDEN(blink_s390x_size_b7 = blink_s390x_size < 10000000 ? 32 : blink_s390x_size / 10000000 % 10 + 48);
HIDDEN(blink_s390x_size_b8 = blink_s390x_size < 100000000 ? 32 : blink_s390x_size / 100000000 % 10 + 48);
HIDDEN(blink_s390x_size_b9 = blink_s390x_size < 1000000000 ? 32 : blink_s390x_size / 1000000000 % 10 + 48);
#if SupportsMetal()
HIDDEN(v_ape_realsectors =
MIN(0x70000 - IMAGE_BASE_REAL, ROUNDUP(RVA(_ezip), 512)) / 512);
@@ -772,7 +618,7 @@ HIDDEN(v_ape_realbytes = v_ape_realsectors * 512);
HIDDEN(v_ape_realdwords = v_ape_realsectors * (512 / 4));
HIDDEN(v_ape_allsectors = ROUNDUP(RVA(_ezip), 512) / 512);
HIDDEN(v_ape_allbytes = v_ape_allsectors * 512);
HIDDEN(v_ape_highsectors = v_ape_allsectors - v_ape_realsectors);
HIDDEN(v_ape_highsectors = MIN(0xffff, v_ape_allsectors - v_ape_realsectors));
TSSDESCSTUB2(_tss, _tss, _tss_end ? _tss_end - _tss - 1 : 0);
#endif
+2 -23
View File
@@ -98,14 +98,7 @@ o/ape/idata.inc: \
o/$(MODE)/ape/ape.o: \
ape/blink-aarch64.gz \
ape/blink-arm.gz \
ape/blink-darwin-arm64.gz \
ape/blink-i486.gz \
ape/blink-mipsel.gz \
ape/blink-powerpc.gz \
ape/blink-powerpc64le.gz \
ape/blink-riscv64.gz \
ape/blink-s390x.gz
ape/blink-darwin-arm64.gz
o/$(MODE)/ape/ape-no-modify-self.o: \
ape/ape.S \
@@ -127,14 +120,7 @@ o/$(MODE)/ape/ape-no-modify-self.o: \
libc/runtime/symbolic.h \
libc/sysv/consts/prot.h \
ape/blink-aarch64.gz \
ape/blink-arm.gz \
ape/blink-darwin-arm64.gz \
ape/blink-i486.gz \
ape/blink-mipsel.gz \
ape/blink-powerpc.gz \
ape/blink-powerpc64le.gz \
ape/blink-riscv64.gz \
ape/blink-s390x.gz \
o/$(MODE)/ape/ape.elf
@$(COMPILE) \
-AOBJECTIFY.S \
@@ -163,14 +149,7 @@ o/$(MODE)/ape/ape-copy-self.o: \
libc/runtime/symbolic.h \
libc/sysv/consts/prot.h \
ape/blink-aarch64.gz \
ape/blink-arm.gz \
ape/blink-darwin-arm64.gz \
ape/blink-i486.gz \
ape/blink-mipsel.gz \
ape/blink-powerpc.gz \
ape/blink-powerpc64le.gz \
ape/blink-riscv64.gz \
ape/blink-s390x.gz
ape/blink-darwin-arm64.gz
@$(COMPILE) \
-AOBJECTIFY.S \
$(OBJECTIFY.S) \
Binary file not shown.
BIN
View File
Binary file not shown.
View File
Whitespace-only changes.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+21
View File
@@ -0,0 +1,21 @@
#if 0
/*─────────────────────────────────────────────────────────────────╗
│ To the extent possible under law, Justine Tunney has waived │
│ all copyright and related or neighboring rights to this file, │
│ as it is written in the following disclaimers: │
│ • http://unlicense.org/ │
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/calls/calls.h"
#include "libc/stdio/stdio.h"
int main(int argc, char *argv[]) {
char buf[256];
if (!getdomainname(buf, sizeof(buf))) {
printf("%s\n", buf);
return 0;
} else {
return 1;
}
}
+3 -3
View File
@@ -27,13 +27,13 @@ dontinline void ShowIt(const char *path) {
"optimal transfer block size");
sizefmt(ibuf, sf.f_frsize, 1024);
printf("f_frsize = %,zu (%sb %s)\n", sf.f_frsize, ibuf, "fragment size");
sizefmt(ibuf, sf.f_blocks * sf.f_bsize, 1024);
sizefmt(ibuf, sf.f_blocks * sf.f_frsize, 1024);
printf("f_blocks = %,zu (%sb %s)\n", sf.f_blocks, ibuf,
"total data blocks in filesystem");
sizefmt(ibuf, sf.f_bfree * sf.f_bsize, 1024);
sizefmt(ibuf, sf.f_bfree * sf.f_frsize, 1024);
printf("f_bfree = %,zu (%sb %s)\n", sf.f_bfree, ibuf,
"free blocks in filesystem");
sizefmt(ibuf, sf.f_bavail * sf.f_bsize, 1024);
sizefmt(ibuf, sf.f_bavail * sf.f_frsize, 1024);
printf("f_bavail = %,zu (%sb %s)\n", sf.f_bavail, ibuf,
"free blocks available to use");
printf("f_files = %,zu (%s)\n", sf.f_files,
+16 -16
View File
@@ -46,31 +46,31 @@ int main(int argc, char *argv[]) {
1. / 65536 * si.loads[1], //
1. / 65536 * si.loads[2]); //
sizefmt(ibuf, si.totalram, 1024);
printf("%-16s %s\n", "totalram", ibuf);
sizefmt(ibuf, si.totalram * si.mem_unit, 1024);
printf("%-16s %ld (%s)\n", "totalram", si.totalram, ibuf);
sizefmt(ibuf, si.freeram, 1024);
printf("%-16s %s\n", "freeram", ibuf);
sizefmt(ibuf, si.freeram * si.mem_unit, 1024);
printf("%-16s %ld (%s)\n", "freeram", si.freeram, ibuf);
sizefmt(ibuf, si.sharedram, 1024);
printf("%-16s %s\n", "sharedram", ibuf);
sizefmt(ibuf, si.sharedram * si.mem_unit, 1024);
printf("%-16s %ld (%s)\n", "sharedram", si.sharedram, ibuf);
sizefmt(ibuf, si.bufferram, 1024);
printf("%-16s %s\n", "bufferram", ibuf);
sizefmt(ibuf, si.bufferram * si.mem_unit, 1024);
printf("%-16s %ld (%s)\n", "bufferram", si.bufferram, ibuf);
sizefmt(ibuf, si.totalswap, 1024);
printf("%-16s %s\n", "totalswap", ibuf);
sizefmt(ibuf, si.totalswap * si.mem_unit, 1024);
printf("%-16s %ld (%s)\n", "totalswap", si.totalswap, ibuf);
sizefmt(ibuf, si.freeswap, 1024);
printf("%-16s %s\n", "freeswap", ibuf);
sizefmt(ibuf, si.freeswap * si.mem_unit, 1024);
printf("%-16s %ld (%s)\n", "freeswap", si.freeswap, ibuf);
printf("%-16s %lu\n", "processes", si.procs);
sizefmt(ibuf, si.totalhigh, 1024);
printf("%-16s %s\n", "totalhigh", ibuf);
sizefmt(ibuf, si.totalhigh * si.mem_unit, 1024);
printf("%-16s %ld (%s)\n", "totalhigh", si.totalhigh, ibuf);
sizefmt(ibuf, si.freehigh, 1024);
printf("%-16s %s\n", "freehigh", ibuf);
sizefmt(ibuf, si.freehigh * si.mem_unit, 1024);
printf("%-16s %ld (%s)\n", "freehigh", si.freehigh, ibuf);
sizefmt(ibuf, si.mem_unit, 1024);
printf("%-16s %s\n", "mem_unit", ibuf);
+19
View File
@@ -5,6 +5,25 @@
#define _POSIX2_VERSION _POSIX_VERSION
#define _XOPEN_VERSION 700
#define _POSIX_MAPPED_FILES _POSIX_VERSION
#define _POSIX_FSYNC _POSIX_VERSION
#define _POSIX_IPV6 _POSIX_VERSION
#define _POSIX_THREADS _POSIX_VERSION
#define _POSIX_THREAD_PROCESS_SHARED _POSIX_VERSION
#define _POSIX_THREAD_SAFE_FUNCTIONS _POSIX_VERSION
#define _POSIX_THREAD_ATTR_STACKADDR _POSIX_VERSION
#define _POSIX_THREAD_ATTR_STACKSIZE _POSIX_VERSION
#define _POSIX_THREAD_PRIORITY_SCHEDULING _POSIX_VERSION
#define _POSIX_THREAD_CPUTIME _POSIX_VERSION
#define _POSIX_TIMEOUTS _POSIX_VERSION
#define _POSIX_MONOTONIC_CLOCK _POSIX_VERSION
#define _POSIX_CPUTIME _POSIX_VERSION
#define _POSIX_BARRIERS _POSIX_VERSION
#define _POSIX_SPIN_LOCKS _POSIX_VERSION
#define _POSIX_READER_WRITER_LOCKS _POSIX_VERSION
#define _POSIX_SEMAPHORES _POSIX_VERSION
#define _POSIX_SHARED_MEMORY_OBJECTS _POSIX_VERSION
#define EOF -1 /* end of file */
#define WEOF -1u /* end of file (multibyte) */
#define _IOFBF 0 /* fully buffered */
+1 -1
View File
@@ -212,7 +212,7 @@ static bool ShouldUseSpinNanosleep(int clock, int flags,
* while (clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &abs, 0));
*
* will accurately spin on `EINTR` errors. That way you're not impeding
* signal delivery and you're not losing precision on your wait timeout.
* signal delivery and you're not loosing precision on the wait timeout.
* This function has first-class support on Linux, FreeBSD, and NetBSD;
* on OpenBSD it's good; on XNU it's bad; and on Windows it's ugly.
*
+18 -4
View File
@@ -16,16 +16,18 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/intrin/bits.h"
#include "libc/intrin/safemacros.internal.h"
#include "libc/calls/calls.h"
#include "libc/intrin/strace.internal.h"
#include "libc/calls/struct/stat.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/bits.h"
#include "libc/intrin/safemacros.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/log/libfatal.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/ok.h"
#include "libc/sysv/consts/s.h"
#include "libc/sysv/errfuns.h"
static bool IsExePath(const char *s, size_t n) {
@@ -48,6 +50,9 @@ static bool AccessCommand(const char *name, char *path, size_t pathsz,
size_t pathlen) {
size_t suffixlen;
suffixlen = strlen(suffix);
if (IsWindows() && suffixlen == 0 && !IsExePath(name, namelen) &&
!IsComPath(name, namelen))
return false;
if (pathlen + 1 + namelen + suffixlen + 1 > pathsz) return false;
if (pathlen && (path[pathlen - 1] != '/' && path[pathlen - 1] != '\\')) {
path[pathlen] = !IsWindows() ? '/'
@@ -57,7 +62,16 @@ static bool AccessCommand(const char *name, char *path, size_t pathsz,
}
memcpy(path + pathlen, name, namelen);
memcpy(path + pathlen + namelen, suffix, suffixlen + 1);
if (!access(path, X_OK)) return true;
if (!access(path, X_OK)) {
struct stat st;
if (!stat(path, &st)) {
if (S_ISREG(st.st_mode)) {
return true;
} else {
errno = EACCES;
}
}
}
if (errno == EACCES || *err != EACCES) *err = errno;
return false;
}
+7 -5
View File
@@ -19,6 +19,7 @@
#include "libc/calls/blockcancel.internal.h"
#include "libc/calls/blocksigs.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/execve-sysv.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
@@ -37,6 +38,11 @@ static bool CanExecute(const char *path) {
return !sys_faccessat(AT_FDCWD, path, X_OK, 0);
}
bool IsAPEMagic(char buf[8]) {
return READ64LE(buf) == READ64LE("MZqFpD='") ||
READ64LE(buf) == READ64LE("JTqFpD='");
}
static bool IsApeBinary(const char *path) {
int fd;
char buf[8];
@@ -44,11 +50,7 @@ static bool IsApeBinary(const char *path) {
// TODO(jart): Should we block signals too?
BLOCK_CANCELLATIONS;
if ((fd = sys_open(path, O_RDONLY, 0)) != -1) {
if (sys_read(fd, buf, 8) == 8 && //
(READ64LE(buf) == READ64LE("MZqFpD='") ||
READ64LE(buf) == READ64LE("JTqFpD='"))) {
res = true;
}
res = sys_read(fd, buf, 8) == 8 && IsAPEMagic(buf);
sys_close(fd);
}
ALLOW_CANCELLATIONS;
+10
View File
@@ -0,0 +1,10 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_EXECVE_SYSV_H_
#define COSMOPOLITAN_LIBC_CALLS_EXECVE_SYSV_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
bool IsAPEMagic(char[8]) _Hide;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_EXECVE_SYSV_H_ */
+20 -8
View File
@@ -32,6 +32,7 @@
#include "libc/log/libfatal.internal.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/errfuns.h"
#include "libc/zipos/zipos.internal.h"
/**
* Replaces current process with program.
@@ -51,6 +52,7 @@
* @vforksafe
*/
int execve(const char *prog, char *const argv[], char *const envp[]) {
struct ZiposUri uri;
int rc;
size_t i;
if (!prog || !argv || !envp ||
@@ -61,16 +63,26 @@ int execve(const char *prog, char *const argv[], char *const envp[]) {
} else {
STRACE("execve(%#s, %s, %s) → ...", prog, DescribeStringList(argv),
DescribeStringList(envp));
if (!IsWindows()) {
rc = 0;
if (IsLinux() && __execpromises && _weaken(sys_pledge_linux)) {
rc = _weaken(sys_pledge_linux)(__execpromises, __pledge_mode);
}
if (!rc) {
rc = 0;
if (IsLinux() && __execpromises && _weaken(sys_pledge_linux)) {
rc = _weaken(sys_pledge_linux)(__execpromises, __pledge_mode);
}
if (!rc) {
if (_weaken(__zipos_parseuri) &&
(_weaken(__zipos_parseuri)(prog, &uri) != -1)) {
rc = _weaken(__zipos_open)(&uri, O_RDONLY | O_CLOEXEC, 0);
if (rc != -1) {
const int zipFD = rc;
strace_enabled(-1);
rc = fexecve(zipFD, argv, envp);
close(zipFD);
strace_enabled(+1);
}
} else if (!IsWindows()) {
rc = sys_execve(prog, argv, envp);
} else {
rc = sys_execve_nt(prog, argv, envp);
}
} else {
rc = sys_execve_nt(prog, argv, envp);
}
}
STRACE("execve(%#s) failed %d% m", prog, rc);
+209 -12
View File
@@ -16,21 +16,167 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/assert.h"
#include "libc/calls/blockcancel.internal.h"
#include "libc/calls/blocksigs.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/cp.internal.h"
#include "libc/calls/execve-sysv.internal.h"
#include "libc/calls/internal.h"
#include "libc/calls/struct/stat.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/fmt/itoa.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/safemacros.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/intrin/weaken.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/f.h"
#include "libc/sysv/consts/fd.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/mfd.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/prot.h"
#include "libc/sysv/consts/shm.h"
#include "libc/sysv/errfuns.h"
static bool IsAPEFd(const int fd) {
char buf[8];
bool res;
return (sys_pread(fd, buf, 8, 0, 0) == 8) && IsAPEMagic(buf);
}
static int fexecve_impl(const int fd, char *const argv[], char *const envp[]) {
int rc;
if (IsLinux()) {
char path[14 + 12];
FormatInt32(stpcpy(path, "/proc/self/fd/"), fd);
rc = __sys_execve(path, argv, envp);
} else if (IsFreebsd()) {
rc = sys_fexecve(fd, argv, envp);
} else {
rc = enosys();
}
return rc;
}
typedef enum {
PTF_NUM = 1 << 0,
PTF_NUM2 = 1 << 1,
PTF_NUM3 = 1 << 2,
PTF_ANY = 1 << 3
} PTF_PARSE;
static bool ape_to_elf(void *ape, const size_t apesize) {
static const char printftok[] = "printf '";
static const size_t printftoklen = sizeof(printftok) - 1;
const char *tok = memmem(ape, apesize, printftok, printftoklen);
if (tok) {
tok += printftoklen;
uint8_t *dest = ape;
PTF_PARSE state = PTF_ANY;
uint8_t value = 0;
for (; tok < (const char *)(dest + apesize); tok++) {
if ((state & (PTF_NUM | PTF_NUM2 | PTF_NUM3)) &&
(*tok >= '0' && *tok <= '7')) {
value = (value << 3) | (*tok - '0');
state <<= 1;
if (state & PTF_ANY) {
*dest++ = value;
}
} else if (state & PTF_NUM) {
break;
} else {
if (state & (PTF_NUM2 | PTF_NUM3)) {
*dest++ = value;
}
if (*tok == '\\') {
state = PTF_NUM;
value = 0;
} else if (*tok == '\'') {
return true;
} else {
*dest++ = *tok;
state = PTF_ANY;
}
}
}
}
errno = ENOEXEC;
return false;
}
/**
* Creates a memfd and copies fd to it.
*
* This does an inplace conversion of APE to ELF when detected!!!!
*/
static int fd_to_mem_fd(const int infd, char *path) {
if (!IsLinux() && !IsFreebsd() || !_weaken(mmap) || !_weaken(munmap)) {
return enosys();
}
struct stat st;
if (fstat(infd, &st) == -1) {
return -1;
}
int fd;
if (IsLinux()) {
fd = sys_memfd_create(__func__, MFD_CLOEXEC);
} else if (IsFreebsd()) {
fd = sys_shm_open(SHM_ANON, O_CREAT | O_RDWR, 0);
} else {
return enosys();
}
if (fd == -1) {
return -1;
}
void *space;
if ((sys_ftruncate(fd, st.st_size, st.st_size) != -1) &&
((space = _weaken(mmap)(0, st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED,
fd, 0)) != MAP_FAILED)) {
ssize_t readRc;
readRc = pread(infd, space, st.st_size, 0);
bool success = readRc != -1;
if (success && (st.st_size > 8) && IsAPEMagic(space)) {
int flags = fcntl(fd, F_GETFD);
if (success = (flags != -1) &&
(fcntl(fd, F_SETFD, flags & (~FD_CLOEXEC)) != -1) &&
ape_to_elf(space, st.st_size)) {
const int newfd = fcntl(fd, F_DUPFD, 9001);
if (newfd != -1) {
close(fd);
fd = newfd;
}
}
}
const int e = errno;
if ((_weaken(munmap)(space, st.st_size) != -1) && success) {
if (path) {
FormatInt32(stpcpy(path, "COSMOPOLITAN_INIT_ZIPOS="), fd);
}
_unassert(readRc == st.st_size);
return fd;
} else if (!success) {
errno = e;
}
}
const int e = errno;
close(fd);
errno = e;
return -1;
}
/**
* Executes binary executable at file descriptor.
*
* This is only supported on Linux and FreeBSD. APE binaries currently
* aren't supported.
* This is only supported on Linux and FreeBSD. APE binaries are
* supported. Zipos is supported. Zipos fds or FD_CLOEXEC APE fds or
* fds that fail fexecve with ENOEXEC are copied to a new memfd (with
* in-memory APE to ELF conversion) and fexecve is (re)attempted.
*
* @param fd is opened executable and current file position is ignored
* @return doesn't return on success, otherwise -1 w/ errno
@@ -38,8 +184,7 @@
* @raise ENOSYS on Windows, XNU, OpenBSD, NetBSD, and Metal
*/
int fexecve(int fd, char *const argv[], char *const envp[]) {
int rc;
size_t i;
int rc = 0;
if (!argv || !envp ||
(IsAsan() &&
(!__asan_is_valid_strlist(argv) || !__asan_is_valid_strlist(envp)))) {
@@ -47,15 +192,67 @@ int fexecve(int fd, char *const argv[], char *const envp[]) {
} else {
STRACE("fexecve(%d, %s, %s) → ...", fd, DescribeStringList(argv),
DescribeStringList(envp));
if (IsLinux()) {
char path[14 + 12];
FormatInt32(stpcpy(path, "/proc/self/fd/"), fd);
rc = __sys_execve(path, argv, envp);
} else if (IsFreebsd()) {
rc = sys_fexecve(fd, argv, envp);
} else {
rc = enosys();
int savedErr = 0;
do {
if (!IsLinux() && !IsFreebsd()) {
rc = enosys();
break;
}
if (!__isfdkind(fd, kFdZip)) {
bool memfdReq;
BEGIN_CANCELLATION_POINT;
BLOCK_SIGNALS;
strace_enabled(-1);
memfdReq = ((rc = fcntl(fd, F_GETFD)) != -1) && (rc & FD_CLOEXEC) &&
IsAPEFd(fd);
strace_enabled(+1);
ALLOW_SIGNALS;
END_CANCELLATION_POINT;
if (rc == -1) {
break;
} else if (!memfdReq) {
fexecve_impl(fd, argv, envp);
if (errno != ENOEXEC) {
break;
}
savedErr = ENOEXEC;
}
}
int newfd;
char *path = alloca(PATH_MAX);
BEGIN_CANCELLATION_POINT;
BLOCK_SIGNALS;
strace_enabled(-1);
newfd = fd_to_mem_fd(fd, path);
strace_enabled(+1);
ALLOW_SIGNALS;
END_CANCELLATION_POINT;
if (newfd == -1) {
break;
}
size_t numenvs;
for (numenvs = 0; envp[numenvs];) ++numenvs;
const size_t desenvs = min(500, max(numenvs + 1, 2));
static _Thread_local char *envs[500];
memcpy(envs, envp, numenvs * sizeof(char *));
envs[numenvs] = path;
envs[numenvs + 1] = NULL;
fexecve_impl(newfd, argv, envs);
if (!savedErr) {
savedErr = errno;
}
BEGIN_CANCELLATION_POINT;
BLOCK_SIGNALS;
strace_enabled(-1);
close(newfd);
strace_enabled(+1);
ALLOW_SIGNALS;
END_CANCELLATION_POINT;
} while (0);
if (savedErr) {
errno = savedErr;
}
rc = -1;
}
STRACE("fexecve(%d) failed %d% m", fd, rc);
return rc;
+1 -1
View File
@@ -47,7 +47,7 @@ int fsync(int fd) {
rc = sys_fdatasync_nt(fd);
}
END_CANCELLATION_POINT;
STRACE("fysnc(%d) → %d% m", fd, rc);
STRACE("fsync(%d) → %d% m", fd, rc);
} else {
rc = fstat(fd, &st);
STRACE("fsync_fake(%d) → %d% m", fd, rc);
-21
View File
@@ -1,21 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_GETCONSOLECTRLEVENT_H_
#define COSMOPOLITAN_LIBC_CALLS_GETCONSOLECTRLEVENT_H_
#include "libc/nt/enum/ctrlevent.h"
#include "libc/sysv/consts/sig.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
static inline int GetConsoleCtrlEvent(int sig) {
switch (sig) {
case SIGINT:
return kNtCtrlCEvent;
case SIGQUIT:
return kNtCtrlBreakEvent;
default:
return -1;
}
}
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_GETCONSOLECTRLEVENT_H_ */
+19 -4
View File
@@ -17,7 +17,6 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/calls/getconsolectrlevent.internal.h"
#include "libc/calls/internal.h"
#include "libc/dce.h"
#include "libc/macros.internal.h"
@@ -29,8 +28,20 @@
#include "libc/nt/process.h"
#include "libc/nt/runtime.h"
#include "libc/nt/struct/processentry32.h"
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/errfuns.h"
static inline int GetConsoleCtrlEvent(int sig) {
switch (sig) {
case SIGINT:
return kNtCtrlCEvent;
case SIGQUIT:
return kNtCtrlBreakEvent;
default:
return -1;
}
}
textwindows int sys_kill_nt(int pid, int sig) {
bool32 ok;
int64_t h;
@@ -46,6 +57,7 @@ textwindows int sys_kill_nt(int pid, int sig) {
// If we're targeting current process group then just call raise().
if (!pid || pid == getpid()) {
if (!sig) return 0; // ability check passes
return raise(sig);
}
@@ -72,6 +84,7 @@ textwindows int sys_kill_nt(int pid, int sig) {
// is this a cosmo pid that was returned by fork?
if (__isfdkind(pid, kFdProcess)) {
if (!sig) return 0; // ability check passes
// since windows can't execve we need to kill the grandchildren
// TODO(jart): should we just kill the whole tree too? there's
// no obvious way to tell if it's the execve shell
@@ -96,9 +109,11 @@ textwindows int sys_kill_nt(int pid, int sig) {
// XXX: Is this a raw new technology pid? Because that's messy.
if ((h = OpenProcess(kNtProcessTerminate, false, pid))) {
ok = TerminateProcess(h, 128 + sig);
if (!ok && GetLastError() == kNtErrorAccessDenied) {
ok = true; // cargo culting other codebases here
if (sig) {
ok = TerminateProcess(h, 128 + sig);
if (!ok && GetLastError() == kNtErrorAccessDenied) {
ok = true; // cargo culting other codebases here
}
}
CloseHandle(h);
return 0;
+9
View File
@@ -26,6 +26,15 @@
*/
#define LANDLOCK_ACCESS_FS_REFER 0x2000ul
/**
* Control file truncation.
*
* @see https://lore.kernel.org/all/[email protected]/
* @see https://docs.kernel.org/userspace-api/landlock.html
* @note ABI 3+
*/
#define LANDLOCK_ACCESS_FS_TRUNCATE 0x4000ul
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
+2 -2
View File
@@ -79,7 +79,7 @@ textwindows int __mkntpath2(const char *path,
* 1. Need +1 for NUL-terminator
* 2. Need +1 for UTF-16 overflow
* 3. Need ≥2 for SetCurrentDirectory trailing slash requirement
* 5. Need ≥13 for mkdir() i.e. 1+8+3+1, e.g. "\\ffffffff.xxx\0"
* 4. Need ≥13 for mkdir() i.e. 1+8+3+1, e.g. "\\ffffffff.xxx\0"
* which is an "8.3 filename" from the DOS days
*/
const char *q;
@@ -119,7 +119,7 @@ textwindows int __mkntpath2(const char *path,
q += 2;
z -= 7;
x = 7;
} else if (IsSlash(q[0]) && IsAlpha(q[1]) && IsSlash(q[2])) {
} else if (IsAlpha(q[0]) && q[1] == ':' && IsSlash(q[2])) {
z = MIN(32767, PATH_MAX);
// turn "c:\foo" into "\\?\c:\foo"
p[0] = '\\';
+1 -1
View File
@@ -48,7 +48,7 @@
*
* @param flags can have R_OK, W_OK, X_OK, etc.
* @return 0 if authorized, or -1 w/ errno
* @kudos Aaron Ballman for teaching this
* @see https://blog.aaronballman.com/2011/08/how-to-check-access-rights/
* @see libc/sysv/consts.sh
*/
textwindows int ntaccesscheck(const char16_t *pathname, uint32_t flags) {
+4 -2
View File
@@ -292,6 +292,7 @@ static const struct thatispacked SyscallName {
{__NR_linux_epoll_wait, "epoll_wait"}, //
{__NR_linux_epoll_ctl, "epoll_ctl"}, //
{__NR_linux_getdents, "getdents"}, //
{__NR_linux_oldgetdents, "oldgetdents"}, //
{__NR_linux_set_tid_address, "set_tid_address"}, //
{__NR_linux_restart_syscall, "restart_syscall"}, //
{__NR_linux_semtimedop, "semtimedop"}, //
@@ -582,6 +583,7 @@ static const uint16_t kPledgeRpath[] = {
__NR_linux_statfs, //
__NR_linux_fstatfs, //
__NR_linux_getdents, //
__NR_linux_oldgetdents, //
};
static const uint16_t kPledgeWpath[] = {
@@ -975,13 +977,13 @@ static privileged void OnSigSys(int sig, siginfo_t *si, void *vctx) {
if (HasSyscall(kPledge + i, si->si_syscall)) {
Log("error: pledge ", kPledge[i].name, " for ",
GetSyscallName(si->si_syscall), " (ord=", ord, " rip=", rip, ")\n",
0);
NULL);
found = true;
}
}
if (!found) {
Log("error: bad syscall (", GetSyscallName(si->si_syscall), " ord=", ord,
" rip=", rip, ")\n", 0);
" rip=", rip, ")\n", NULL);
}
switch (mode & PLEDGE_PENALTY_MASK) {
case PLEDGE_PENALTY_KILL_PROCESS:
+9 -5
View File
@@ -184,6 +184,10 @@ static const char *DescribeStatfsTypeLinux(int64_t x) {
return "xfs";
case 0x012fd16d:
return "_xiafs";
case 0x2fc12fc1:
return "zfs";
case 0x4253584e:
return "apfs";
default:
return "unknown";
}
@@ -222,7 +226,7 @@ void statfs2cosmo(struct statfs *f, const union statfs_meta *m) {
} else if (IsFreebsd()) {
f_type = m->freebsd.f_type;
f_bsize = m->freebsd.f_bsize;
f_bsize = m->freebsd.f_iosize;
f_blocks = m->freebsd.f_blocks;
f_bfree = m->freebsd.f_bfree;
f_bavail = m->freebsd.f_bavail;
@@ -237,14 +241,14 @@ void statfs2cosmo(struct statfs *f, const union statfs_meta *m) {
} else if (IsXnu()) {
f_type = m->xnu.f_type;
f_bsize = m->xnu.f_bsize;
f_bsize = m->xnu.f_iosize;
f_blocks = m->xnu.f_blocks;
f_bfree = m->xnu.f_bfree;
f_bavail = m->xnu.f_bavail;
f_files = m->xnu.f_files;
f_ffree = m->xnu.f_ffree;
f_fsid = m->xnu.f_fsid;
f_namelen = 4096;
f_namelen = 255;
f_frsize = m->xnu.f_bsize;
f_flags = m->xnu.f_flags;
f_owner = m->xnu.f_owner;
@@ -252,7 +256,7 @@ void statfs2cosmo(struct statfs *f, const union statfs_meta *m) {
} else if (IsOpenbsd()) {
f_type = f->f_type;
f_bsize = m->openbsd.f_bsize;
f_bsize = m->openbsd.f_iosize;
f_blocks = m->openbsd.f_blocks;
f_bfree = m->openbsd.f_bfree;
f_bavail = m->openbsd.f_bavail;
@@ -267,7 +271,7 @@ void statfs2cosmo(struct statfs *f, const union statfs_meta *m) {
} else if (IsNetbsd()) {
f_type = m->netbsd.f_type;
f_bsize = m->netbsd.f_bsize;
f_bsize = m->netbsd.f_iosize;
f_blocks = m->netbsd.f_blocks;
f_bfree = m->netbsd.f_bfree;
f_bavail = m->netbsd.f_bavail;
+1 -1
View File
@@ -9,7 +9,7 @@ struct statfs_linux {
int64_t f_bsize; /* optimal transfer block size */
int64_t f_blocks; /* total data blocks in filesystem */
int64_t f_bfree; /* free blocks in filesystem */
int64_t f_bavail; /* free blocks available to */
int64_t f_bavail; /* free blocks available to unprivileged user */
int64_t f_files; /* total file nodes in filesystem */
int64_t f_ffree; /* free file nodes in filesystem */
fsid_t f_fsid; /* filesystem id */
+1
View File
@@ -105,6 +105,7 @@ i32 sys_setresuid(u32, u32, u32) _Hide;
i32 sys_setreuid(u32, u32) _Hide;
i32 sys_setsid(void) _Hide;
i32 sys_setuid(i32) _Hide;
i32 sys_shm_open(const char *, i32, u32) _Hide;
i32 sys_sigaction(i32, const void *, void *, i64, i64) _Hide;
i32 sys_sigaltstack(const void *, void *) _Hide;
i32 sys_symlinkat(const char *, i32, const char *) _Hide;
-3
View File
@@ -81,9 +81,6 @@ int sysinfo(struct sysinfo *info) {
rc = sys_sysinfo_nt(&x);
}
if (rc != -1) {
x.procs = MAX(1, x.procs);
x.mem_unit = MAX(1, x.mem_unit);
x.totalram = MAX((8 * 1024 * 1024) / x.mem_unit, x.totalram);
memcpy(info, &x, sizeof(x));
}
STRACE("sysinfo(%p) → %d% m", info, rc);
+16
View File
@@ -17,13 +17,16 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/calls/struct/stat.h"
#include "libc/calls/syscall-nt.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/intrin/weaken.h"
#include "libc/sysv/consts/s.h"
#include "libc/sysv/errfuns.h"
#include "libc/zipos/zipos.internal.h"
@@ -40,6 +43,7 @@
*/
int unlinkat(int dirfd, const char *path, int flags) {
int rc;
if (IsAsan() && !__asan_is_valid_str(path)) {
rc = efault();
} else if (_weaken(__zipos_notat) &&
@@ -50,6 +54,18 @@ int unlinkat(int dirfd, const char *path, int flags) {
} else {
rc = sys_unlinkat_nt(dirfd, path, flags);
}
// POSIX.1 says unlink(directory) raises EPERM but on Linux
// it always raises EISDIR, which is so much less ambiguous
if (!IsLinux() && rc == -1 && !flags && errno == EPERM) {
struct stat st;
if (!fstatat(dirfd, path, &st, 0) && S_ISDIR(st.st_mode)) {
errno = EISDIR;
} else {
errno = EPERM;
}
}
STRACE("unlinkat(%s, %#s, %#b) → %d% m", DescribeDirfd(dirfd), path, flags,
rc);
return rc;
+47 -17
View File
@@ -53,7 +53,7 @@
#define UNVEIL_READ \
(LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_READ_DIR | \
LANDLOCK_ACCESS_FS_REFER)
#define UNVEIL_WRITE (LANDLOCK_ACCESS_FS_WRITE_FILE)
#define UNVEIL_WRITE (LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_TRUNCATE)
#define UNVEIL_EXEC (LANDLOCK_ACCESS_FS_EXECUTE)
#define UNVEIL_CREATE \
(LANDLOCK_ACCESS_FS_MAKE_CHAR | LANDLOCK_ACCESS_FS_MAKE_DIR | \
@@ -65,7 +65,7 @@
(LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_WRITE_FILE | \
LANDLOCK_ACCESS_FS_EXECUTE)
static const struct sock_filter kUnveilBlacklist[] = {
static const struct sock_filter kUnveilBlacklistAbiVersionBelow3[] = {
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(arch)),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, AUDIT_ARCH_X86_64, 1, 0),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL_PROCESS),
@@ -76,13 +76,29 @@ static const struct sock_filter kUnveilBlacklist[] = {
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
};
static const struct sock_filter kUnveilBlacklistLatestAbi[] = {
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(arch)),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, AUDIT_ARCH_X86_64, 1, 0),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL_PROCESS),
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_setxattr, 0, 1),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | (1 & SECCOMP_RET_DATA)),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
};
static int landlock_abi_version;
__attribute__((__constructor__)) void init_landlock_version() {
landlock_abi_version = landlock_create_ruleset(0, 0, LANDLOCK_CREATE_RULESET_VERSION);
}
/**
* Long living state for landlock calls.
* fs_mask is set to use all the access rights from the latest landlock ABI.
* On init, the current supported abi is checked and unavailable rights are
* masked off.
*
* As of 5.19, the latest abi is v2.
* As of 6.2, the latest abi is v3.
*
* TODO:
* - Integrate with pledge and remove the file access?
@@ -96,9 +112,15 @@ _Thread_local static struct {
static int unveil_final(void) {
int e, rc;
struct sock_fprog sandbox = {
.filter = kUnveilBlacklist,
.len = ARRAYLEN(kUnveilBlacklist),
.filter = kUnveilBlacklistLatestAbi,
.len = ARRAYLEN(kUnveilBlacklistLatestAbi),
};
if (landlock_abi_version < 3) {
sandbox = (struct sock_fprog){
.filter = kUnveilBlacklistAbiVersionBelow3,
.len = ARRAYLEN(kUnveilBlacklistAbiVersionBelow3),
};
}
e = errno;
prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
errno = e;
@@ -120,16 +142,18 @@ static int err_close(int rc, int fd) {
static int unveil_init(void) {
int rc, fd;
State.fs_mask = UNVEIL_READ | UNVEIL_WRITE | UNVEIL_EXEC | UNVEIL_CREATE;
if ((rc = landlock_create_ruleset(0, 0, LANDLOCK_CREATE_RULESET_VERSION)) ==
-1) {
if (landlock_abi_version == -1) {
if (errno == EOPNOTSUPP) {
errno = ENOSYS;
}
return -1;
}
if (rc < 2) {
if (landlock_abi_version < 2) {
State.fs_mask &= ~LANDLOCK_ACCESS_FS_REFER;
}
if (landlock_abi_version < 3) {
State.fs_mask &= ~LANDLOCK_ACCESS_FS_TRUNCATE;
}
const struct landlock_ruleset_attr attr = {
.handled_access_fs = State.fs_mask,
};
@@ -301,14 +325,19 @@ int sys_unveil_linux(const char *path, const char *permissions) {
* possible to use opendir() and go fishing for paths which weren't
* previously known.
*
* 5. Use ftruncate() rather than truncate(). One issue Landlock hasn't
* addressed yet is restrictions over truncate() and setxattr() which
* could permit certain kinds of modifications to files outside the
* sandbox. When your policy is committed, we install a SECCOMP BPF
* filter to disable those calls, however similar trickery may be
* possible through other unaddressed calls like ioctl(). Using the
* pledge() function in addition to unveil() will solve this, since
* it installs a strong system call access policy.
* 5. Use ftruncate() rather than truncate() if you wish for portability to
* Linux kernels versions released before February 2022. One issue
* Landlock hadn't addressed as of ABI version 2 was restrictions over
* truncate() and setxattr() which could permit certain kinds of
* modifications to files outside the sandbox. When your policy is
* committed, we install a SECCOMP BPF filter to disable those calls,
* however similar trickery may be possible through other unaddressed
* calls like ioctl(). Using the pledge() function in addition to
* unveil() will solve this, since it installs a strong system call
* access policy. Linux 6.2 has improved this situation with Landlock
* ABI v3, which added the ability to control truncation operations -
* this means the SECCOMP BPF filter will only disable
* truncate() on Linux 6.1 or older
*
* 6. Set your process-wide policy at startup from the main thread. On
* OpenBSD unveil() will apply process-wide even when called from a
@@ -347,7 +376,8 @@ int sys_unveil_linux(const char *path, const char *permissions) {
* @raise EINVAL if one argument is set and the other is not
* @raise EINVAL if an invalid character in `permissions` was found
* @raise EPERM if unveil() is called after locking
* @note on Linux this function requires Linux Kernel 5.13+
* @note on Linux this function requires Linux Kernel 5.13+ and version 6.2+
* to properly support truncation operations
* @see [1] https://docs.kernel.org/userspace-api/landlock.html
* @threadsafe
*/
+9 -1
View File
@@ -16,10 +16,11 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/fmt/fmt.h"
#include "libc/assert.h"
#include "libc/errno.h"
#include "libc/fmt/conv.h"
#include "libc/fmt/fmt.h"
#include "libc/fmt/fmt.internal.h"
#include "libc/fmt/internal.h"
#include "libc/fmt/itoa.h"
@@ -255,6 +256,7 @@ _Hide int __fmt(void *fn, void *arg, const char *format, va_list va) {
}
if (prec < 0) {
prec = 0;
flags &= ~FLAGS_PRECISION;
}
// evaluate length field
@@ -317,6 +319,7 @@ _Hide int __fmt(void *fn, void *arg, const char *format, va_list va) {
goto FormatNumber;
case 'b':
log2base = 1;
alphabet = "0123456789abcdefpb";
goto FormatNumber;
case 'o':
log2base = 3;
@@ -359,10 +362,15 @@ _Hide int __fmt(void *fn, void *arg, const char *format, va_list va) {
p = "\r\e[K";
goto FormatString;
}
case 'S':
// Specified by POSIX to be equivalent to %ls
signbit = 63;
goto FormatStringPNotFetchedYet;
case 'q':
flags |= FLAGS_QUOTE;
// fallthrough
case 's':
FormatStringPNotFetchedYet:
p = va_arg(va, void *);
FormatString:
if (__fmt_stoa(out, arg, p, flags, prec, width, signbit, qchar) == -1) {
+70 -39
View File
@@ -31,47 +31,67 @@ uint128_t __udivmodti4(uint128_t, uint128_t, uint128_t *);
static int __fmt_ntoa_format(int out(const char *, void *, size_t), void *arg,
char *buf, unsigned len, bool negative,
unsigned log2base, unsigned prec, unsigned width,
unsigned char flags) {
unsigned i;
unsigned char flags, const char *alphabet) {
unsigned i, prec_width_zeros;
char alternate_form_middle_char, sign_character;
unsigned actual_buf_len;
actual_buf_len = len;
prec_width_zeros = 0;
/* pad leading zeros */
if (!(flags & FLAGS_LEFT)) {
if (width && (flags & FLAGS_ZEROPAD) &&
(negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
width--;
}
while ((len < prec) && (len < BUFFER_SIZE)) {
buf[len++] = '0';
}
while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < BUFFER_SIZE)) {
buf[len++] = '0';
}
if (width && (flags & FLAGS_ZEROPAD) &&
(negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
width--;
}
if (len < prec) {
prec_width_zeros += (prec - len);
len = prec;
}
if ((flags & FLAGS_ZEROPAD) && (len < width)) {
prec_width_zeros += (width - len);
len = width;
}
/* handle hash */
if (flags & FLAGS_HASH) {
if (!(flags & FLAGS_PRECISION) && len &&
((len == prec) || (len == width)) && buf[len - 1] == '0') {
len--;
if (len && (log2base == 4 || log2base == 1) && buf[len - 1] == '0') {
len--;
if ((!(flags & FLAGS_PRECISION) || log2base == 3) && len &&
((len >= prec) || (len >= width)) &&
(prec_width_zeros || buf[len - 1] == '0')) {
if (prec_width_zeros) {
--prec_width_zeros;
}
--len;
if (len < actual_buf_len) {
actual_buf_len = len;
}
if (len && (log2base == 4 || log2base == 1) &&
(prec_width_zeros || buf[len - 1] == '0')) {
if (prec_width_zeros) {
--prec_width_zeros;
}
--len;
if (len < actual_buf_len) {
actual_buf_len = len;
}
}
}
if (log2base == 4 && len < BUFFER_SIZE) {
buf[len++] = 'x';
} else if (log2base == 1 && len < BUFFER_SIZE) {
buf[len++] = 'b';
}
if (len < BUFFER_SIZE) {
buf[len++] = '0';
alternate_form_middle_char = '\0';
if ((log2base == 4 || log2base == 1)) {
++len;
alternate_form_middle_char =
alphabet[17]; // x, X or b (for the corresponding conversion
// specifiers)
}
++len;
}
if (len < BUFFER_SIZE) {
if (negative) {
buf[len++] = '-';
} else if (flags & FLAGS_PLUS) {
buf[len++] = '+'; /* ignore the space if the '+' exists */
} else if (flags & FLAGS_SPACE) {
buf[len++] = ' ';
}
sign_character = '\0';
if (negative) {
++len;
sign_character = '-';
} else if (flags & FLAGS_PLUS) {
++len;
sign_character = '+'; /* ignore the space if the '+' exists */
} else if (flags & FLAGS_SPACE) {
++len;
sign_character = ' ';
}
/* pad spaces up to given width */
if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) {
@@ -79,8 +99,17 @@ static int __fmt_ntoa_format(int out(const char *, void *, size_t), void *arg,
if (__fmt_pad(out, arg, width - len) == -1) return -1;
}
}
reverse(buf, len);
if (out(buf, arg, len) == -1) return -1;
if (sign_character != '\0' && out(&sign_character, arg, 1) == -1) return -1;
if (flags & FLAGS_HASH) {
if (out("0", arg, 1) == -1) return -1;
if (alternate_form_middle_char != '\0' &&
out(&alternate_form_middle_char, arg, 1) == -1)
return -1;
}
for (i = 0; i < prec_width_zeros; ++i)
if (out("0", arg, 1) == -1) return -1;
reverse(buf, actual_buf_len);
if (out(buf, arg, actual_buf_len) == -1) return -1;
/* append pad spaces up to given width */
if (flags & FLAGS_LEFT) {
if (len < width) {
@@ -97,7 +126,9 @@ int __fmt_ntoa2(int out(const char *, void *, size_t), void *arg,
unsigned len, count, digit;
char buf[BUFFER_SIZE];
len = 0;
if (!value) flags &= ~FLAGS_HASH;
/* we check for log2base != 3 because otherwise we'll print nothing for a
* value of 0 with precision 0 when # mandates that one be printed */
if (!value && log2base != 3) flags &= ~FLAGS_HASH;
if (value || !(flags & FLAGS_PRECISION)) {
count = 0;
do {
@@ -124,7 +155,7 @@ int __fmt_ntoa2(int out(const char *, void *, size_t), void *arg,
_npassert(count <= BUFFER_SIZE);
}
return __fmt_ntoa_format(out, arg, buf, len, neg, log2base, prec, width,
flags);
flags, alphabet);
}
int __fmt_ntoa(int out(const char *, void *, size_t), void *arg, va_list va,
@@ -134,8 +165,8 @@ int __fmt_ntoa(int out(const char *, void *, size_t), void *arg, va_list va,
bool neg;
uint128_t value, sign;
/* ignore '0' flag when prec is given */
if (flags & FLAGS_PRECISION) {
/* ignore '0' flag when prec or minus flag is given */
if (flags & (FLAGS_PRECISION | FLAGS_LEFT)) {
flags &= ~FLAGS_ZEROPAD;
}
+13 -13
View File
@@ -12,19 +12,19 @@
*/
#define PFLINK(...) _PFLINK(__VA_ARGS__)
#define _PFLINK(FMT, ...) \
({ \
if (___PFLINK(FMT, strpbrk, "faAeg")) STATIC_YOINK("__fmt_dtoa"); \
if (___PFLINK(FMT, strpbrk, "cmrqs")) { \
if (___PFLINK(FMT, strstr, "%m")) STATIC_YOINK("strerror"); \
if (___PFLINK(FMT, strstr, "%*") || \
___PFLINK(FMT, strpbrk, "0123456789")) { \
STATIC_YOINK("strnwidth"); \
STATIC_YOINK("strnwidth16"); \
STATIC_YOINK("wcsnwidth"); \
} \
} \
FMT; \
#define _PFLINK(FMT, ...) \
({ \
if (___PFLINK(FMT, strpbrk, "fFaAeEgG")) STATIC_YOINK("__fmt_dtoa"); \
if (___PFLINK(FMT, strpbrk, "cmrqs")) { \
if (___PFLINK(FMT, strstr, "%m")) STATIC_YOINK("strerror"); \
if (___PFLINK(FMT, strstr, "%*") || \
___PFLINK(FMT, strpbrk, "0123456789")) { \
STATIC_YOINK("strnwidth"); \
STATIC_YOINK("strnwidth16"); \
STATIC_YOINK("wcsnwidth"); \
} \
} \
FMT; \
})
#define SFLINK(...) _SFLINK(__VA_ARGS__)
+2
View File
@@ -174,6 +174,8 @@ int vcscanf(int callback(void *), int unget(int, void *), void *arg,
c = callback(arg);
if (c == prefix || c == prefix + ('a' - 'A')) {
c = callback(arg);
} else if (c == -1) {
c = '0';
}
}
DecodeNumber:
+9 -7
View File
@@ -30,14 +30,16 @@ struct SprintfStr {
};
static int vsnprintfputchar(const char *s, struct SprintfStr *t, size_t n) {
if (n == 1 && t->i < t->n) {
t->p[t->i] = s[0];
} else if (t->i + n <= t->n) {
memcpy(t->p + t->i, s, n);
} else if (t->i < t->n) {
memcpy(t->p + t->i, s, t->n - t->i);
if (n) {
if (n == 1 && t->i < t->n) {
t->p[t->i] = s[0];
} else if (t->i + n <= t->n) {
memcpy(t->p + t->i, s, n);
} else if (t->i < t->n) {
memcpy(t->p + t->i, s, t->n - t->i);
}
t->i += n;
}
t->i += n;
return 0;
}
+10 -7
View File
@@ -13,13 +13,16 @@
* @see libc/atomic.h
*/
#define memory_order int
#define memory_order_relaxed 0
#define memory_order_consume 1
#define memory_order_acquire 2
#define memory_order_release 3
#define memory_order_acq_rel 4
#define memory_order_seq_cst 5
typedef int memory_order;
enum {
memory_order_relaxed,
memory_order_consume,
memory_order_acquire,
memory_order_release,
memory_order_acq_rel,
memory_order_seq_cst,
};
#define ATOMIC_VAR_INIT(...) __VA_ARGS__
#define atomic_is_lock_free(obj) ((void)(obj), sizeof(obj) <= sizeof(void *))
+3 -3
View File
@@ -38,10 +38,10 @@ textwindows struct DirectMap sys_mmap_nt(void *addr, size_t size, int prot,
struct ProtectNt fl;
const struct NtSecurityAttributes *sec;
if (fd != -1) {
handle = g_fds.p[fd].handle;
} else {
if (flags & MAP_ANONYMOUS) {
handle = kNtInvalidHandleValue;
} else {
handle = g_fds.p[fd].handle;
}
if ((flags & MAP_TYPE) != MAP_SHARED) {
+2 -2
View File
@@ -26,7 +26,7 @@
*/
void(shufpd)(double c[2], const double b[2], const double a[2], uint8_t m) {
double t[2];
t[0] = a[(m & 0b0000001) >> 0];
t[1] = b[(m & 0b0000010) >> 1];
t[0] = b[(m & 0b0000001) >> 0];
t[1] = a[(m & 0b0000010) >> 1];
__builtin_memcpy(c, t, 16);
}
+31
View File
@@ -5,6 +5,37 @@ COSMOPOLITAN_C_START_
void shufpd(double[2], const double[2], const double[2], uint8_t);
#if !defined(__STRICT_ANSI__) && !defined(__chibicc__)
typedef double shufpd_t _Vector_size(16) forcealign(16) mayalias;
shufpd_t shufpdjt(shufpd_t, shufpd_t);
#define shufpd(C, B, A, I) \
do { \
if (__builtin_expect(X86_NEED(SSE) && X86_HAVE(SSSE3), 1)) { \
shufpd_t *Xmm0 = (void *)(C); \
const shufpd_t *Xmm1 = (const shufpd_t *)(B); \
const shufpd_t *Xmm2 = (const shufpd_t *)(A); \
if (__builtin_constant_p(I)) { \
if (!X86_NEED(AVX)) { \
asm("shufpd\t%2,%1,%0" \
: "=x"(*Xmm0) \
: "x"(*Xmm2), "i"(I), "0"(*Xmm1)); \
} else { \
asm("vshufpd\t%3,%2,%1,%0" \
: "=x"(*Xmm0) \
: "x"(*Xmm1), "x"(*Xmm2), "i"(I)); \
} \
} else { \
uint8_t Vimm = (I); \
typeof(shufpdjt) *Fn; \
Fn = (typeof(shufpdjt) *)((uintptr_t)&shufpdjt + Vimm * 8); \
*Xmm0 = Fn(*Xmm1, *Xmm2); \
} \
} else { \
shufpd(C, B, A, I); \
} \
} while (0)
#endif
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_INTRIN_SHUFPD_H_ */
+30
View File
@@ -0,0 +1,30 @@
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2023 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or distribute this software for │
│ any purpose with or without fee is hereby granted, provided that the │
│ above copyright notice and this permission notice appear in all copies. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/macros.internal.h"
.align 8
shufpdjt:
i=0
.rept 256
shufpd $i,%xmm1,%xmm0
ret
.align 8
i=i+1
.endr
.endfn shufpdjt,globl
+31
View File
@@ -5,6 +5,37 @@ COSMOPOLITAN_C_START_
void shufps(float[4], const float[4], const float[4], uint8_t);
#if !defined(__STRICT_ANSI__) && !defined(__chibicc__)
typedef float shufps_t _Vector_size(16) forcealign(16) mayalias;
shufps_t shufpsjt(shufps_t, shufps_t);
#define shufps(C, B, A, I) \
do { \
if (__builtin_expect(X86_NEED(SSE) && X86_HAVE(SSSE3), 1)) { \
shufps_t *Xmm0 = (void *)(C); \
const shufps_t *Xmm1 = (const shufps_t *)(B); \
const shufps_t *Xmm2 = (const shufps_t *)(A); \
if (__builtin_constant_p(I)) { \
if (!X86_NEED(AVX)) { \
asm("shufps\t%2,%1,%0" \
: "=x"(*Xmm0) \
: "x"(*Xmm2), "i"(I), "0"(*Xmm1)); \
} else { \
asm("vshufps\t%3,%2,%1,%0" \
: "=x"(*Xmm0) \
: "x"(*Xmm1), "x"(*Xmm2), "i"(I)); \
} \
} else { \
uint8_t Vimm = (I); \
typeof(shufpsjt) *Fn; \
Fn = (typeof(shufpsjt) *)((uintptr_t)&shufpsjt + Vimm * 8); \
*Xmm0 = Fn(*Xmm1, *Xmm2); \
} \
} else { \
shufps(C, B, A, I); \
} \
} while (0)
#endif
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_INTRIN_SHUFPS_H_ */
+30
View File
@@ -0,0 +1,30 @@
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2023 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or distribute this software for │
│ any purpose with or without fee is hereby granted, provided that the │
│ above copyright notice and this permission notice appear in all copies. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/macros.internal.h"
.align 8
shufpsjt:
i=0
.rept 256
shufps $i,%xmm1,%xmm0
ret
.align 8
i=i+1
.endr
.endfn shufpsjt,globl
+14 -14
View File
@@ -86,7 +86,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t;
#define PRIdLEAST128 __PRI128 "d"
#define PRIdFAST8 __PRI8 "d"
#define PRIdFAST16 __PRI16 "d"
#define PRIdFAST16 __PRI32 "d"
#define PRIdFAST32 __PRI32 "d"
#define PRIdFAST64 __PRI64 "d"
#define PRIdFAST128 __PRI128 "d"
@@ -108,7 +108,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t;
#define PRIuLEAST128 __PRI128 "u"
#define PRIuFAST8 __PRI8 "u"
#define PRIuFAST16 __PRI16 "u"
#define PRIuFAST16 __PRI32 "u"
#define PRIuFAST32 __PRI32 "u"
#define PRIuFAST64 __PRI64 "u"
#define PRIuFAST128 __PRI128 "u"
@@ -130,7 +130,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t;
#define PRIiLEAST128 __PRI128 "i"
#define PRIiFAST8 __PRI8 "i"
#define PRIiFAST16 __PRI16 "i"
#define PRIiFAST16 __PRI32 "i"
#define PRIiFAST32 __PRI32 "i"
#define PRIiFAST64 __PRI64 "i"
#define PRIiFAST128 __PRI128 "i"
@@ -152,7 +152,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t;
#define PRIoLEAST128 __PRI128 "o"
#define PRIoFAST8 __PRI8 "o"
#define PRIoFAST16 __PRI16 "o"
#define PRIoFAST16 __PRI32 "o"
#define PRIoFAST32 __PRI32 "o"
#define PRIoFAST64 __PRI64 "o"
#define PRIoFAST128 __PRI128 "o"
@@ -174,7 +174,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t;
#define PRIxLEAST128 __PRI128 "x"
#define PRIxFAST8 __PRI8 "x"
#define PRIxFAST16 __PRI16 "x"
#define PRIxFAST16 __PRI32 "x"
#define PRIxFAST32 __PRI32 "x"
#define PRIxFAST64 __PRI64 "x"
#define PRIxFAST128 __PRI128 "x"
@@ -192,7 +192,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t;
#define PRIXLEAST128 __PRI128 "X"
#define PRIXFAST8 __PRI8 "X"
#define PRIXFAST16 __PRI16 "X"
#define PRIXFAST16 __PRI32 "X"
#define PRIXFAST32 __PRI32 "X"
#define PRIXFAST64 __PRI64 "X"
#define PRIXFAST128 __PRI128 "X"
@@ -214,7 +214,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t;
#define PRIbLEAST128 __PRI128 "b"
#define PRIbFAST8 __PRI8 "b"
#define PRIbFAST16 __PRI16 "b"
#define PRIbFAST16 __PRI32 "b"
#define PRIbFAST32 __PRI32 "b"
#define PRIbFAST64 __PRI64 "b"
#define PRIbFAST128 __PRI128 "b"
@@ -232,7 +232,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t;
#define PRIBLEAST128 __PRI128 "B"
#define PRIBFAST8 __PRI8 "B"
#define PRIBFAST16 __PRI16 "B"
#define PRIBFAST16 __PRI32 "B"
#define PRIBFAST32 __PRI32 "B"
#define PRIBFAST64 __PRI64 "B"
#define PRIBFAST128 __PRI128 "B"
@@ -272,7 +272,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t;
#define SCNdLEAST128 __PRI128 "d"
#define SCNdFAST8 __PRI8 "d"
#define SCNdFAST16 __PRI16 "d"
#define SCNdFAST16 __PRI32 "d"
#define SCNdFAST32 __PRI32 "d"
#define SCNdFAST64 __PRI64 "d"
#define SCNdFAST128 __PRI128 "d"
@@ -294,7 +294,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t;
#define SCNiLEAST128 __PRI128 "i"
#define SCNiFAST8 __PRI8 "i"
#define SCNiFAST16 __PRI16 "i"
#define SCNiFAST16 __PRI32 "i"
#define SCNiFAST32 __PRI32 "i"
#define SCNiFAST64 __PRI64 "i"
#define SCNiFAST128 __PRI128 "i"
@@ -316,7 +316,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t;
#define SCNuLEAST128 __PRI128 "u"
#define SCNuFAST8 __PRI8 "u"
#define SCNuFAST16 __PRI16 "u"
#define SCNuFAST16 __PRI32 "u"
#define SCNuFAST32 __PRI32 "u"
#define SCNuFAST64 __PRI64 "u"
#define SCNuFAST128 __PRI128 "u"
@@ -338,7 +338,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t;
#define SCNoLEAST128 __PRI128 "o"
#define SCNoFAST8 __PRI8 "o"
#define SCNoFAST16 __PRI16 "o"
#define SCNoFAST16 __PRI32 "o"
#define SCNoFAST32 __PRI32 "o"
#define SCNoFAST64 __PRI64 "o"
#define SCNoFAST128 __PRI128 "o"
@@ -360,7 +360,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t;
#define SCNxLEAST128 __PRI128 "x"
#define SCNxFAST8 __PRI8 "x"
#define SCNxFAST16 __PRI16 "x"
#define SCNxFAST16 __PRI32 "x"
#define SCNxFAST32 __PRI32 "x"
#define SCNxFAST64 __PRI64 "x"
#define SCNxFAST128 __PRI128 "x"
@@ -382,7 +382,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t;
#define SCNbLEAST128 __PRI128 "b"
#define SCNbFAST8 __PRI8 "b"
#define SCNbFAST16 __PRI16 "b"
#define SCNbFAST16 __PRI32 "b"
#define SCNbFAST32 __PRI32 "b"
#define SCNbFAST64 __PRI64 "b"
#define SCNbFAST128 __PRI128 "b"
+1
View File
@@ -1,5 +1,6 @@
#ifndef COSMOPOLITAN_LIBC_ISYSTEM_STRINGS_H_
#define COSMOPOLITAN_LIBC_ISYSTEM_STRINGS_H_
#include "libc/nexgen32e/ffs.h"
#include "libc/str/locale.h"
#include "libc/str/str.h"
+4
View File
@@ -0,0 +1,4 @@
#ifndef COSMOPOLITAN_LIBC_ISYSTEM_SYS_VFS_H_
#define COSMOPOLITAN_LIBC_ISYSTEM_SYS_VFS_H_
#include "libc/calls/struct/statfs.h"
#endif /* COSMOPOLITAN_LIBC_ISYSTEM_SYS_VFS_H_ */
-4
View File
@@ -1,4 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_ISYSTEM_ZLIB_H_
#define COSMOPOLITAN_LIBC_ISYSTEM_ZLIB_H_
#include "third_party/zlib/zlib.h"
#endif /* COSMOPOLITAN_LIBC_ISYSTEM_ZLIB_H_ */
File renamed without changes.
+1 -1
View File
@@ -25,7 +25,7 @@
#include "libc/intrin/bits.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/nexgen32e/msr.h"
#include "libc/nexgen32e/msr.internal.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/runtime/pc.internal.h"
#include "libc/sysv/consts/sig.h"
+32 -6
View File
@@ -36,6 +36,7 @@
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/consts/timer.h"
#include "third_party/awk/cmd.h"
#include "third_party/musl/glob.h"
#include "third_party/sed/cmd.h"
#include "third_party/tr/cmd.h"
#include "tool/curl/cmd.h"
@@ -398,7 +399,7 @@ static int Fake(int main(int, char **)) {
}
static int TryBuiltin(void) {
if (!n) return 0;
if (!n) return exitstatus;
if (!strcmp(args[0], "exit")) Exit();
if (!strcmp(args[0], "cd")) return Cd();
if (!strcmp(args[0], "rm")) return Rm();
@@ -569,9 +570,14 @@ static char *Tokenize(void) {
if (q > r) {
return Finish();
} else {
Run();
exitstatus = Run();
t = STATE_WHITESPACE;
}
} else if (*p == '>') {
Append(*p);
if (p[1] == '&') {
Append(*++p);
}
} else if (*p == '&') {
if (q > r) {
return Finish();
@@ -662,6 +668,9 @@ static const char *GetRedirectArg(const char *prog, const char *arg, int n) {
int _cocmd(int argc, char **argv, char **envp) {
char *arg;
size_t i, j;
size_t globCount = 0;
int globFlags = 0;
glob_t globTheBuilder;
prog = argc > 0 ? argv[0] : "cocmd.com";
for (i = 1; i < 32; ++i) {
@@ -673,12 +682,15 @@ int _cocmd(int argc, char **argv, char **envp) {
unsupported['~'] = true;
unsupported['`'] = true;
unsupported['#'] = true;
unsupported['*'] = true;
unsupported['('] = true;
unsupported[')'] = true;
unsupported['{'] = true;
unsupported['}'] = true;
unsupported['?'] = true;
unsupported['}'] = false; // Perl t/op/exec.t depends on unpaired } being
// passed from the shell to Perl
if (!_weaken(glob)) {
unsupported['*'] = true;
unsupported['?'] = true;
}
if (argc != 3) {
Wexit(10, prog, ": error: wrong number of args\n", 0);
@@ -727,7 +739,21 @@ int _cocmd(int argc, char **argv, char **envp) {
} else if (arg[0] == '<') {
Open(GetRedirectArg(prog, arg, 1), 0, O_RDONLY);
} else {
args[n++] = arg;
int globrc = GLOB_NOMATCH;
if (_weaken(glob)) {
globrc = _weaken(glob)(arg, globFlags, NULL, &globTheBuilder);
if (globrc == 0) {
for (; globCount < globTheBuilder.gl_pathc; globCount++) {
args[n++] = globTheBuilder.gl_pathv[globCount];
}
} else if (globrc != GLOB_NOMATCH) {
Wexit(16, prog, ": error: with glob\n", 0);
}
globFlags |= GLOB_APPEND;
}
if (globrc == GLOB_NOMATCH) {
args[n++] = arg;
}
args[n] = 0;
}
} else {
+2 -2
View File
@@ -26,12 +26,12 @@
/**
* Returns maximum number of open files.
*/
long GetMaxFd(void) {
long _GetMaxFd(void) {
int rc;
if (IsNetbsd()) {
if ((rc = __sys_fcntl(0, F_MAXFD, 0)) != -1) {
return rc;
}
}
return GetResourceLimit(RLIMIT_NOFILE);
return _GetResourceLimit(RLIMIT_NOFILE);
}
+1 -1
View File
@@ -21,7 +21,7 @@
#include "libc/macros.internal.h"
#include "libc/sysv/consts/rlim.h"
long GetResourceLimit(int resource) {
long _GetResourceLimit(int resource) {
struct rlimit rl;
getrlimit(resource, &rl);
if (rl.rlim_cur == RLIM_INFINITY) return -1;
+1 -1
View File
@@ -30,7 +30,7 @@
#include "libc/x/x.h"
#include "libc/zip.h"
#include "libc/zipos/zipos.internal.h"
#include "third_party/zlib/puff.h"
#include "third_party/puff/puff.h"
static pthread_spinlock_t g_lock;
_Hide struct SymbolTable *__symtab; // for kprintf
+2 -2
View File
@@ -20,7 +20,7 @@
#include "libc/intrin/weaken.h"
#include "libc/macros.internal.h"
#include "libc/runtime/runtime.h"
#include "third_party/zlib/puff.h"
#include "third_party/puff/puff.h"
#include "third_party/zlib/zlib.h"
/**
@@ -54,7 +54,7 @@ int __inflate(void *out, size_t outsize, const void *in, size_t insize) {
rc = rc;
}
} else {
rc = puff(out, &outsize, in, &insize);
rc = _puff(out, &outsize, in, &insize);
}
STRACE("inflate([%#.*hhs%s], %'zu, %#.*hhs%s, %'zu) → %d", MIN(40, outsize),
out, outsize > 40 ? "..." : "", outsize, MIN(40, insize), in,
+3
View File
@@ -44,6 +44,9 @@ int GetDosEnviron(const char16_t *, char *, size_t, char **, size_t);
bool __intercept_flag(int *, char *[], const char *);
int sys_mprotect_nt(void *, size_t, int) _Hide;
int __inflate(void *, size_t, const void *, size_t);
noasan void *_Mmap(void *addr, size_t size, int prot, int flags, int fd,
int64_t off) _Hide;
noasan int _Munmap(char *, size_t) _Hide;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
+1 -1
View File
@@ -33,7 +33,7 @@
/**
* Returns true if ELF executable uses dynamic loading magic.
*/
bool IsDynamicExecutable(const char *prog) {
bool _IsDynamicExecutable(const char *prog) {
bool res;
Elf64_Ehdr *e;
Elf64_Phdr *p;
+10 -9
View File
@@ -238,8 +238,8 @@ static textwindows dontinline noasan void *MapMemories(char *addr, size_t size,
return addr;
}
static noasan inline void *Mmap(void *addr, size_t size, int prot, int flags,
int fd, int64_t off) {
noasan inline void *_Mmap(void *addr, size_t size, int prot, int flags, int fd,
int64_t off) {
char *p = addr;
struct DirectMap dm;
int a, b, i, f, m, n, x;
@@ -485,12 +485,7 @@ static noasan inline void *Mmap(void *addr, size_t size, int prot, int flags,
*/
void *mmap(void *addr, size_t size, int prot, int flags, int fd, int64_t off) {
void *res;
size_t toto;
if (__isfdkind(fd, kFdZip)) {
return _weaken(__zipos_mmap)(
addr, size, prot, flags,
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, off);
}
size_t toto = 0;
#if defined(SYSDEBUG) && (_KERNTRACE || _NTTRACE)
if (IsWindows()) {
STRACE("mmap(%p, %'zu, %s, %s, %d, %'ld) → ...", addr, size,
@@ -498,7 +493,13 @@ void *mmap(void *addr, size_t size, int prot, int flags, int fd, int64_t off) {
}
#endif
__mmi_lock();
res = Mmap(addr, size, prot, flags, fd, off);
if (!__isfdkind(fd, kFdZip)) {
res = _Mmap(addr, size, prot, flags, fd, off);
} else {
res = _weaken(__zipos_Mmap)(
addr, size, prot, flags,
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, off);
}
#if SYSDEBUG
toto = __strace > 0 ? GetMemtrackSize(&_mmi) : 0;
#endif
+3 -5
View File
@@ -40,8 +40,6 @@
#define ADDR(x) ((int64_t)((uint64_t)(x) << 32) >> 16)
#define FRAME(x) ((int)((intptr_t)(x) >> 16))
static noasan int Munmap(char *, size_t);
static noasan void MunmapShadow(char *p, size_t n) {
intptr_t a, b, x, y;
KERNTRACE("MunmapShadow(%p, %'zu)", p, n);
@@ -55,7 +53,7 @@ static noasan void MunmapShadow(char *p, size_t n) {
// to be >1mb since we can only unmap it if it's aligned, and
// as such we poison the edges if there are any.
__repstosb((void *)a, kAsanUnmapped, x - a);
Munmap((void *)x, y - x);
_Munmap((void *)x, y - x);
__repstosb((void *)y, kAsanUnmapped, b - y);
} else {
// otherwise just poison and assume reuse
@@ -115,7 +113,7 @@ static noasan void MunmapImpl(char *p, size_t n) {
}
}
static noasan int Munmap(char *p, size_t n) {
noasan int _Munmap(char *p, size_t n) {
unsigned i;
char poison;
intptr_t a, b, x, y;
@@ -159,7 +157,7 @@ int munmap(void *p, size_t n) {
int rc;
size_t toto;
__mmi_lock();
rc = Munmap(p, n);
rc = _Munmap(p, n);
#if SYSDEBUG
toto = __strace > 0 ? GetMemtrackSize(&_mmi) : 0;
#endif
+2 -2
View File
@@ -30,7 +30,7 @@
// @return file descriptor
// @note only works on .com binary (not .com.dbg)
// @note only supports linux, freebsd, openbsd, and netbsd
OpenExecutable:
_OpenExecutable:
push %rbp
mov %rsp,%rbp
pushq __NR_open(%rip) # -0x08(%rbp)
@@ -198,7 +198,7 @@ OpenExecutable:
pop %rbx
leave
ret
9: .endfn OpenExecutable,globl
9: .endfn _OpenExecutable,globl
.weak ape_rom_vaddr
.weak ape_rom_filesz
+6 -7
View File
@@ -141,8 +141,8 @@
│ Page-level Cache Disable - PCD┐││││
│ Set if has been read - Accessed┐│││││
│ Set if has been written - Dirty┐││││││
│ IsPage (if PDPTE/PDE) or PAT (if PT)┐│││││││
│ (If this maps 2MB/1GB page and CR4.PGE) Global┐││││││││
│ IsPage 2MB/1GB (if PDPTE/PDE) or PAT (if PT)┐│││││││
│ (If this maps page and CR4.PGE) Global┐││││││││
│ (If IsPage 2MB/1GB, see Intel V3A § 11.12) PAT │││││││││
│ │ │││││││││
│ ┌─────────────────────────────────────┤ │││││││││
@@ -159,9 +159,8 @@
#define PAGE_V /* */ 0b000000000001
#define PAGE_RW /* */ 0b000000000010
#define PAGE_U /* */ 0b000000000100
#define PAGE_4KB /* */ 0b000010000000
#define PAGE_2MB /* */ 0b000110000000
#define PAGE_1GB /* */ 0b000110000000
#define PAGE_PS /* */ 0b000010000000
#define PAGE_G /* */ 0b000100000000
#define PAGE_IGN1 /* */ 0b111000000000
#define PAGE_RSRV /* blinkenlights/libc reservation */ 0b001000000000
#define PAGE_GROD /* blinkenlights MAP_GROWSDOWN */ 0b010000000000
@@ -189,8 +188,8 @@ struct IdtDescriptor {
uint64_t *__get_virtual(struct mman *, uint64_t *, int64_t, bool);
uint64_t __clear_page(uint64_t);
uint64_t __new_page(struct mman *);
uint64_t * __invert_memory_area(struct mman *, uint64_t *, uint64_t, uint64_t,
uint64_t);
uint64_t *__invert_memory_area(struct mman *, uint64_t *, uint64_t, uint64_t,
uint64_t);
void __map_phdrs(struct mman *, uint64_t *, uint64_t, uint64_t);
void __reclaim_boot_pages(struct mman *, uint64_t, uint64_t);
void __ref_page(struct mman *, uint64_t *, uint64_t);
+33 -3
View File
@@ -19,6 +19,7 @@
#include "libc/calls/calls.h"
#include "libc/calls/struct/rlimit.h"
#include "libc/calls/struct/sched_param.h"
#include "libc/calls/struct/sigaction.h"
#include "libc/calls/struct/sigset.h"
#include "libc/calls/struct/termios.h"
#include "libc/calls/struct/utsname.h"
@@ -166,6 +167,7 @@ textstartup void __printargs(const char *prologue) {
uintptr_t *auxp;
struct rlimit rlim;
struct utsname uts;
struct sigaction sa;
struct sched_param sp;
struct termios termios;
struct AuxiliaryValue *auxinfo;
@@ -288,7 +290,7 @@ textstartup void __printargs(const char *prologue) {
if (!sigprocmask(SIG_BLOCK, 0, &ss)) {
PRINT("");
PRINT("SIGNALS {%#lx, %#lx}", ss.__bits[0], ss.__bits[1]);
PRINT("SIGNAL MASK {%#lx, %#lx}", ss.__bits[0], ss.__bits[1]);
if (ss.__bits[0] || ss.__bits[1]) {
for (i = 0; i < 32; ++i) {
if (ss.__bits[0] & (1u << i)) {
@@ -304,6 +306,23 @@ textstartup void __printargs(const char *prologue) {
PRINT(" error: sigprocmask() failed %m");
}
PRINT("");
PRINT("SIGNALS");
for (gotsome = 0, i = 1; i <= 64; ++i) {
if (!sigaction(i, 0, &sa)) {
if (sa.sa_handler == SIG_IGN) {
PRINT(" ☼ %G is SIG_IGN", i);
gotsome = 1;
} else if (sa.sa_handler != SIG_DFL) {
PRINT(" ☼ %G is %p", i, sa.sa_handler);
gotsome = 1;
}
}
}
if (!gotsome) {
PRINT(" ☼ SIG_DFL");
}
if (PLEDGED(PROC)) {
PRINT("");
PRINT("SCHEDULER");
@@ -419,10 +438,21 @@ textstartup void __printargs(const char *prologue) {
PRINT("");
PRINT("TERMIOS");
for (i = 0; i < 2; ++i) {
for (i = 0; i <= 2; ++i) {
if (!tcgetattr(i, &termios)) {
PRINT(" - stdin");
struct winsize ws;
if (i == 0) {
PRINT(" - stdin");
} else if (i == 1) {
PRINT(" - stdout");
} else {
PRINT(" - stderr");
}
kprintf(prologue);
if (!tcgetwinsize(i, &ws)) {
kprintf(" ws_row = %d\n", ws.ws_row);
kprintf(" ws_col = %d\n", ws.ws_col);
}
kprintf(" c_iflag =");
if (termios.c_iflag & IGNBRK) kprintf(" IGNBRK");
if (termios.c_iflag & BRKINT) kprintf(" BRKINT");
+4 -4
View File
@@ -94,12 +94,12 @@ void _peekall(void);
void _savexmm(void *);
void _weakfree(void *);
void free_s(void *) paramsnonnull() libcesque;
int OpenExecutable(void);
int _OpenExecutable(void);
int ftrace_install(void);
int ftrace_enabled(int);
int strace_enabled(int);
long GetResourceLimit(int);
long GetMaxFd(void);
long _GetResourceLimit(int);
long _GetMaxFd(void);
char *GetProgramExecutableName(void);
char *GetInterpreterExecutableName(char *, size_t);
void __printargs(const char *);
@@ -108,7 +108,7 @@ int __arg_max(void);
void __print_maps(void);
void __warn_if_powersave(void);
const char *__describe_os(void);
bool IsDynamicExecutable(const char *);
bool _IsDynamicExecutable(const char *);
void _restorewintty(void);
const char *GetCpuidOs(void);
const char *GetCpuidEmulator(void);
+1 -1
View File
@@ -45,7 +45,7 @@ LIBC_RUNTIME_A_DIRECTDEPS = \
LIBC_STUBS \
LIBC_SYSV \
LIBC_SYSV_CALLS \
THIRD_PARTY_ZLIB \
THIRD_PARTY_PUFF \
THIRD_PARTY_XED
LIBC_RUNTIME_A_DEPS := \
+1 -1
View File
@@ -20,7 +20,7 @@
#include "libc/calls/calls.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/nexgen32e/msr.h"
#include "libc/nexgen32e/msr.internal.h"
#include "libc/nt/thread.h"
#include "libc/thread/tls.h"
+2 -2
View File
@@ -41,11 +41,11 @@ long sysconf(int name) {
case _SC_ARG_MAX:
return _ARG_MAX;
case _SC_CHILD_MAX:
return GetResourceLimit(RLIMIT_NPROC);
return _GetResourceLimit(RLIMIT_NPROC);
case _SC_CLK_TCK:
return CLK_TCK;
case _SC_OPEN_MAX:
return GetMaxFd();
return _GetMaxFd();
case _SC_PAGESIZE:
return FRAMESIZE;
case _SC_NPROCESSORS_ONLN:
+16 -5
View File
@@ -43,26 +43,37 @@
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct timeval *timeout) {
int rc;
struct timeval tv, *tvp;
POLLTRACE("select(%d, %p, %p, %p, %s) → ...", nfds, readfds, writefds,
exceptfds, DescribeTimeval(0, timeout));
// the linux kernel modifies timeout
if (timeout) {
if (IsAsan() && !__asan_is_valid(timeout, sizeof(*timeout))) {
return efault();
}
tv = *timeout;
tvp = &tv;
} else {
tvp = 0;
}
BEGIN_CANCELLATION_POINT;
if (nfds < 0) {
rc = einval();
} else if (IsAsan() &&
((readfds && !__asan_is_valid(readfds, FD_SIZE(nfds))) ||
(writefds && !__asan_is_valid(writefds, FD_SIZE(nfds))) ||
(exceptfds && !__asan_is_valid(exceptfds, FD_SIZE(nfds))) ||
(timeout && !__asan_is_valid(timeout, sizeof(*timeout))))) {
(exceptfds && !__asan_is_valid(exceptfds, FD_SIZE(nfds))))) {
rc = efault();
} else if (!IsWindows()) {
rc = sys_select(nfds, readfds, writefds, exceptfds, timeout);
rc = sys_select(nfds, readfds, writefds, exceptfds, tvp);
} else {
rc = sys_select_nt(nfds, readfds, writefds, exceptfds, timeout, 0);
rc = sys_select_nt(nfds, readfds, writefds, exceptfds, tvp, 0);
}
END_CANCELLATION_POINT;
POLLTRACE("select(%d, %p, %p, %p, [%s]) → %d% m", nfds, readfds, writefds,
exceptfds, DescribeTimeval(rc, timeout), rc);
exceptfds, DescribeTimeval(rc, tvp), rc);
return rc;
}
+2 -1
View File
@@ -11,7 +11,8 @@ COSMOPOLITAN_C_START_
* must know all networks accessible).
*/
struct ifconf {
uint64_t ifc_len; /* size of buffer */
int32_t ifc_len; /* size of buffer */
int32_t padding;
union {
char *ifcu_buf;
struct ifreq *ifcu_req;
+1 -1
View File
@@ -44,7 +44,7 @@ static int vfprintfputchar(const char *s, struct state *t, size_t n) {
} else {
rc = 0;
}
return 0;
return rc;
}
/**
+7 -6
View File
@@ -55,11 +55,12 @@ void *GetZipCdir(const uint8_t *p, size_t n) {
continue;
}
}
while (magic = READ32LE(p + i),
magic != kZipCdir64LocatorMagic && magic != kZipCdirHdrMagic &&
i + 0x10000 + 0x1000 >= n) --i;
if (magic == kZipCdir64LocatorMagic &&
i + kZipCdir64LocatorSize <= n &&
while (magic = READ32LE(p + i), magic != kZipCdir64LocatorMagic &&
magic != kZipCdirHdrMagic &&
i + 0x10000 + 0x1000 >= n && i > 0) {
--i;
}
if (magic == kZipCdir64LocatorMagic && i + kZipCdir64LocatorSize <= n &&
IsZipCdir64(p, n, ZIP_LOCATE64_OFFSET(p + i))) {
return p + ZIP_LOCATE64_OFFSET(p + i);
} else if (magic == kZipCdirHdrMagic && IsZipCdir32(p, n, i)) {
@@ -73,6 +74,6 @@ void *GetZipCdir(const uint8_t *p, size_t n) {
} while (j-- && i - j < 128);
return p + i;
}
} while (i-- + 0x10000 + 0x1000 >= n);
} while (i > 0 && i-- + 0x10000 + 0x1000 >= n);
return 0;
}
+29 -13
View File
@@ -19,20 +19,36 @@
#include "libc/intrin/strace.internal.h"
#include "libc/runtime/runtime.h"
static void _intsorter(int *A, size_t n) {
int t, p;
size_t i, j;
if (n < 2) return;
for (p = A[n / 2], i = 0, j = n - 1;; i++, j--) {
while (A[i] < p) i++;
while (A[j] > p) j--;
if (i >= j) break;
static inline void InsertionSort(int *A, long n) {
long i, j, t;
for (i = 1; i < n; i++) {
t = A[i];
A[i] = A[j];
A[j] = t;
j = i - 1;
while (j >= 0 && A[j] > t) {
A[j + 1] = A[j];
j = j - 1;
}
A[j + 1] = t;
}
}
static void IntSort(int *A, long n) {
int t, p;
long i, j;
if (n <= 32) {
InsertionSort(A, n);
} else {
for (p = A[n >> 1], i = 0, j = n - 1;; i++, j--) {
while (A[i] < p) i++;
while (A[j] > p) j--;
if (i >= j) break;
t = A[i];
A[i] = A[j];
A[j] = t;
}
IntSort(A, i);
IntSort(A + i, n - i);
}
_intsorter(A, i);
_intsorter(A + i, n - i);
}
/**
@@ -40,7 +56,7 @@ static void _intsorter(int *A, size_t n) {
* @see djbsort
*/
void _intsort(int *A, size_t n) {
_intsorter(A, n);
IntSort(A, n);
if (n > 1000) {
STRACE("_intsort(%p, %'zu)", A, n);
}
+28 -13
View File
@@ -19,20 +19,35 @@
#include "libc/intrin/strace.internal.h"
#include "libc/runtime/runtime.h"
static void _longsorter(long *A, size_t n) {
long t, p;
size_t i, j;
if (n < 2) return;
for (p = A[n / 2], i = 0, j = n - 1;; i++, j--) {
while (A[i] < p) i++;
while (A[j] > p) j--;
if (i >= j) break;
static inline void InsertionSort(long *A, long n) {
long i, j, t;
for (i = 1; i < n; i++) {
t = A[i];
A[i] = A[j];
A[j] = t;
j = i - 1;
while (j >= 0 && A[j] > t) {
A[j + 1] = A[j];
j = j - 1;
}
A[j + 1] = t;
}
}
static void LongSort(long *A, long n) {
long t, p, i, j;
if (n <= 32) {
InsertionSort(A, n);
} else {
for (p = A[n >> 1], i = 0, j = n - 1;; i++, j--) {
while (A[i] < p) i++;
while (A[j] > p) j--;
if (i >= j) break;
t = A[i];
A[i] = A[j];
A[j] = t;
}
LongSort(A, i);
LongSort(A + i, n - i);
}
_longsorter(A, i);
_longsorter(A + i, n - i);
}
/**
@@ -43,7 +58,7 @@ static void _longsorter(long *A, size_t n) {
*
*/
void _longsort(long *A, size_t n) {
_longsorter(A, n);
LongSort(A, n);
if (n > 1000) {
STRACE("_longsort(%p, %'zu)", A, n);
}
+1 -1
View File
@@ -30,5 +30,5 @@ int wcscmp(const wchar_t *a, const wchar_t *b) {
size_t i = 0;
if (a == b) return 0;
while (a[i] == b[i] && b[i]) ++i;
return (unsigned)a[i] - (unsigned)b[i];
return (a[i] > b[i]) - (a[i] < b[i]);
}
+1 -1
View File
@@ -30,5 +30,5 @@ int wcsncmp(const wchar_t *a, const wchar_t *b, size_t n) {
size_t i = 0;
if (!n-- || a == b) return 0;
while (i < n && a[i] == b[i] && b[i]) ++i;
return (unsigned)a[i] - (unsigned)b[i];
return (a[i] > b[i]) - (a[i] < b[i]);
}
+1
View File
@@ -1620,6 +1620,7 @@ syscon shm SHM_HUGETLB 0x0800 0 0 0 0 0
syscon shm SHM_LOCKED 0x0400 0 0 0 0 0
syscon shm SHM_NORESERVE 0x1000 0 0 0 0 0
syscon shm SHM_REMAP 0x4000 0 0 0 0 0
syscon shm SHM_ANON 0 0 1 0 0 0
syscon lock LOCK_UNLOCK_CACHE 54 0 0 0 0 0 # wut
+2
View File
@@ -0,0 +1,2 @@
.include "o/libc/sysv/consts/syscon.internal.inc"
.syscon shm,SHM_ANON,0,0,1,0,0,0
+1
View File
@@ -209,6 +209,7 @@
#define __NR_linux_epoll_wait 0x00e8
#define __NR_linux_epoll_ctl 0x00e9
#define __NR_linux_getdents 0x00d9
#define __NR_linux_oldgetdents 0x004e
#define __NR_linux_set_tid_address 0x00da
#define __NR_linux_restart_syscall 0x00db
#define __NR_linux_semtimedop 0x00dc
+15 -13
View File
@@ -2,24 +2,26 @@
#define COSMOPOLITAN_LIBC_SYSV_CONSTS_SHM_H_
#include "libc/runtime/symbolic.h"
#define SHM_DEST SYMBOLIC(SHM_DEST)
#define SHM_EXEC SYMBOLIC(SHM_EXEC)
#define SHM_HUGETLB SYMBOLIC(SHM_HUGETLB)
#define SHM_INFO SYMBOLIC(SHM_INFO)
#define SHM_LOCK SYMBOLIC(SHM_LOCK)
#define SHM_LOCKED SYMBOLIC(SHM_LOCKED)
#define SHM_ANON SYMBOLIC(SHM_ANON)
#define SHM_DEST SYMBOLIC(SHM_DEST)
#define SHM_EXEC SYMBOLIC(SHM_EXEC)
#define SHM_HUGETLB SYMBOLIC(SHM_HUGETLB)
#define SHM_INFO SYMBOLIC(SHM_INFO)
#define SHM_LOCK SYMBOLIC(SHM_LOCK)
#define SHM_LOCKED SYMBOLIC(SHM_LOCKED)
#define SHM_NORESERVE SYMBOLIC(SHM_NORESERVE)
#define SHM_R SYMBOLIC(SHM_R)
#define SHM_RDONLY SYMBOLIC(SHM_RDONLY)
#define SHM_REMAP SYMBOLIC(SHM_REMAP)
#define SHM_RND SYMBOLIC(SHM_RND)
#define SHM_STAT SYMBOLIC(SHM_STAT)
#define SHM_UNLOCK SYMBOLIC(SHM_UNLOCK)
#define SHM_W SYMBOLIC(SHM_W)
#define SHM_R SYMBOLIC(SHM_R)
#define SHM_RDONLY SYMBOLIC(SHM_RDONLY)
#define SHM_REMAP SYMBOLIC(SHM_REMAP)
#define SHM_RND SYMBOLIC(SHM_RND)
#define SHM_STAT SYMBOLIC(SHM_STAT)
#define SHM_UNLOCK SYMBOLIC(SHM_UNLOCK)
#define SHM_W SYMBOLIC(SHM_W)
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
extern const char *SHM_ANON;
extern const int SHM_DEST;
extern const int SHM_EXEC;
extern const int SHM_HUGETLB;
+19 -19
View File
@@ -64,9 +64,9 @@ scall sys_sched_yield 0x15e12a14bf25d018 globl hidden # select() on XNU (previo
scall __sys_mremap 0x19bffffffffff019 globl hidden
scall sys_mincore 0x04e04e04e204e01b globl hidden
scall sys_madvise 0x04b04b04b204b01c globl hidden
scall sys_shmget 0x0e71210e7210901d globl # no wrapper; consider mmap
scall sys_shmat 0x0e40e40e4210601e globl # no wrapper; consider mmap
scall sys_shmctl 0x1bb128200210701f globl # no wrapper; consider mmap
scall sys_shmget 0x0e71210e7210901d globl # no wrapper
scall sys_shmat 0x0e40e40e4210601e globl # no wrapper
scall sys_shmctl 0x1bb128200210701f globl # no wrapper
scall sys_dup 0x0290290292029020 globl hidden
scall sys_dup2 0x05a05a05a205a021 globl hidden
scall sys_pause 0xfffffffffffff022 globl hidden
@@ -107,14 +107,14 @@ scall sys_futex_cp 0x8a68539c6ffff8ca globl hidden # intended for futex wait op
scall sys_set_robust_list 0x0a7ffffffffff111 globl # no wrapper
scall sys_get_robust_list 0x0a8ffffffffff112 globl # no wrapper
scall sys_uname 0x0a4fff0a4ffff03f globl hidden
scall sys_semget 0x0dd0dd0dd20ff040 globl # no wrapper; won't polyfill for windows
scall sys_semop 0x0de1220de2100041 globl # no wrapper; won't polyfill for windows
scall sys_semctl 0xfff1271fe20fe042 globl # no wrapper; won't polyfill for windows
scall sys_shmdt 0x0e60e60e62108043 globl # no wrapper; won't polyfill for windows
scall sys_msgget 0x0e10e10e12103044 globl # no wrapper; won't polyfill for windows
scall sys_msgsnd 0x8e28e28e22904845 globl # no wrapper; won't polyfill for windows
scall sys_msgrcv 0x8e38e38e32905846 globl # no wrapper; won't polyfill for windows
scall sys_msgctl 0x1bc1291ff2102047 globl # no wrapper; won't polyfill for windows
scall sys_semget 0x0dd0dd0dd20ff040 globl # no wrapper
scall sys_semop 0x0de1220de2100041 globl # no wrapper
scall sys_semctl 0xfff1271fe20fe042 globl # no wrapper
scall sys_shmdt 0x0e60e60e62108043 globl # no wrapper
scall sys_msgget 0x0e10e10e12103044 globl # no wrapper
scall sys_msgsnd 0x8e28e28e22904845 globl # no wrapper
scall sys_msgrcv 0x8e38e38e32905846 globl # no wrapper
scall sys_msgctl 0x1bc1291ff2102047 globl # no wrapper
scall __sys_fcntl 0x05c05c05c205c048 globl hidden
scall __sys_fcntl_cp 0x85c85c85c285c848 globl hidden # intended for F_SETLKW and F_OFD_SETLKW
scall sys_flock 0x8838838832883849 globl hidden
@@ -282,7 +282,7 @@ scall sys_request_key 0xfffffffffffff0f9 globl # no wrapper
scall sys_keyctl 0xfffffffffffff0fa globl # no wrapper
scall ioprio_set 0xfffffffffffff0fb globl
scall ioprio_get 0xfffffffffffff0fc globl
scall sys_inotify_init 0xfffffffffffff0fd globl # wicked # no wrapper
scall sys_inotify_init 0xfffffffffffff0fd globl # no wrapper
scall sys_inotify_add_watch 0xfffffffffffff0fe globl # no wrapper
scall sys_inotify_rm_watch 0xfffffffffffff0ff globl # no wrapper
scall __sys_openat 0x9d49419f329cf901 globl hidden # Linux 2.6.16+ (c. 2007)
@@ -323,13 +323,13 @@ scall sys_epoll_create1 0xfffffffffffff123 globl hidden
scall sys_perf_event_open 0xfffffffffffff12a globl # no wrapper
scall sys_inotify_init1 0xfffffffffffff126 globl # no wrapper
scall sys_rt_tgsigqueueinfo 0xfffffffffffff129 globl # no wrapper
scall sys_signalfd 0xfffffffffffff11a globl # won't polyfill; see INTON/INTOFF tutorial in examples/unbourne.c
scall sys_signalfd4 0xfffffffffffff121 globl # won't polyfill; see INTON/INTOFF tutorial in examples/unbourne.c
scall sys_eventfd 0xfffffffffffff11c globl # won't polyfill; see INTON/INTOFF tutorial in examples/unbourne.c
scall sys_eventfd2 0xfffffffffffff122 globl # won't polyfill; see INTON/INTOFF tutorial in examples/unbourne.c
scall sys_timerfd_create 0xfffffffffffff11b globl # won't polyfill; see INTON/INTOFF tutorial in examples/unbourne.c
scall sys_timerfd_settime 0xfffffffffffff11e globl # won't polyfill; see INTON/INTOFF tutorial in examples/unbourne.c
scall sys_timerfd_gettime 0xfffffffffffff11f globl # won't polyfill; see INTON/INTOFF tutorial in examples/unbourne.c
scall sys_signalfd 0xfffffffffffff11a globl # no wrapper
scall sys_signalfd4 0xfffffffffffff121 globl # no wrapper
scall sys_eventfd 0xfffffffffffff11c globl # no wrapper
scall sys_eventfd2 0xfffffffffffff122 globl # no wrapper
scall sys_timerfd_create 0xfffffffffffff11b globl # no wrapper
scall sys_timerfd_settime 0xfffffffffffff11e globl # no wrapper
scall sys_timerfd_gettime 0xfffffffffffff11f globl # no wrapper
#──────────────────────RHEL 6.0 LIMIT──────────────────────── # ←┬─ modern glibc needs rhel6+ c. 2011
scall sys_recvmmsg 0x1dbffffffffff12b globl # ├─ end of life 2024-06-30 (extended)
scall sys_fanotify_init 0xfffffffffffff12c globl # ├─ last distro with the original gnome desktop
+12
View File
@@ -23,7 +23,9 @@
#include "libc/log/log.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/runtime/runtime.h"
#include "libc/sysv/consts/f.h"
#include "libc/sysv/consts/mlock.h"
#include "libc/sysv/consts/o.h"
#include "libc/testlib/testlib.h"
double g_avx2_juiceup_doubles_[4] forcealign(32);
@@ -47,6 +49,15 @@ void testlib_benchwarmup(void) {
}
}
void EnableCruiseControlForCool(void) {
int fd, micros = 10;
if ((fd = open("/dev/cpu_dma_latency", O_WRONLY)) != -1) {
write(fd, &micros, sizeof(micros));
fcntl(fd, F_DUPFD_CLOEXEC, 123);
close(fd);
}
}
/**
* Runs all benchmark functions in sorted order.
*
@@ -55,5 +66,6 @@ void testlib_benchwarmup(void) {
void testlib_runallbenchmarks(void) {
int e;
__log_level = kLogWarn;
EnableCruiseControlForCool();
testlib_runtestcases(__bench_start, __bench_end, testlib_benchwarmup);
}
-1
View File
@@ -29,7 +29,6 @@
* @return 0 on success, or -1 w/ errno
*/
int sem_getvalue(sem_t *sem, int *sval) {
_unassert(sem->sem_pshared || sem->sem_pid == getpid());
*sval = atomic_load_explicit(&sem->sem_value, memory_order_relaxed);
return 0;
}
+4 -1
View File
@@ -16,6 +16,7 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/dce.h"
#include "libc/str/blake2.h"
#include "libc/str/path.h"
@@ -38,7 +39,9 @@ const char *sem_path_np(const char *name, char *buf, size_t size) {
const char *path, *a;
uint8_t digest[BLAKE2B256_DIGEST_LENGTH];
a = "/tmp/", n = 5;
if (IsLinux()) a = "/dev/shm/", n = 9;
if (IsLinux() && isdirectory("/dev/shm")) {
a = "/dev/shm/", n = 9;
}
if (n + BLAKE2B256_DIGEST_LENGTH * 2 + 4 < size) {
BLAKE2B256(name, strlen(name), digest);
p = mempcpy(buf, a, n);
+1 -2
View File
@@ -33,11 +33,10 @@
*/
int sem_post(sem_t *sem) {
int rc, old, wakeups;
_unassert(sem->sem_pshared || sem->sem_pid == getpid());
old = atomic_fetch_add_explicit(&sem->sem_value, 1, memory_order_acq_rel);
_unassert(old > INT_MIN);
if (old >= 0) {
wakeups = nsync_futex_wake_(&sem->sem_value, 1, sem->sem_pshared);
wakeups = nsync_futex_wake_(&sem->sem_value, 1, true);
_npassert(wakeups >= 0);
rc = 0;
} else {
+1 -1
View File
@@ -75,7 +75,7 @@ int sem_timedwait(sem_t *sem, const struct timespec *abstime) {
do {
if (!(v = atomic_load_explicit(&sem->sem_value, memory_order_relaxed))) {
rc = nsync_futex_wait_(&sem->sem_value, v, sem->sem_pshared, abstime);
rc = nsync_futex_wait_(&sem->sem_value, v, true, abstime);
if (rc == -EINTR || rc == -ECANCELED) {
errno = -rc;
rc = -1;
-1
View File
@@ -34,7 +34,6 @@
*/
int sem_trywait(sem_t *sem) {
int v;
_unassert(sem->sem_pshared || sem->sem_pid == getpid());
v = atomic_load_explicit(&sem->sem_value, memory_order_relaxed);
do {
_unassert(v > INT_MIN);
+1 -1
View File
@@ -30,7 +30,7 @@ char *xstrndup(const char *, size_t) paramsnonnull()
returnspointerwithnoaliases dontthrow nocallback dontdiscard returnsnonnull;
char *xstrcat(const char *, ...) paramsnonnull((1)) nullterminated()
returnspointerwithnoaliases dontthrow nocallback dontdiscard returnsnonnull;
#define xstrcat(...) (xstrcat)(__VA_ARGS__, 0)
#define xstrcat(...) (xstrcat)(__VA_ARGS__, NULL)
char *xstrmul(const char *, size_t) paramsnonnull((1))
returnspointerwithnoaliases dontthrow nocallback dontdiscard returnsnonnull;
char *xinet_ntop(int, const void *) paramsnonnull()
+1 -1
View File
@@ -43,6 +43,6 @@ char *xjoinpaths(const char *path, const char *other) {
} else if (_endswith(path, "/")) {
return xstrcat(path, other);
} else {
return xstrcat(path, '/', other);
return xstrcat(path, (uintptr_t)'/', other);
}
}
+2
View File
@@ -21,6 +21,7 @@
#include "libc/intrin/asancodes.h"
#include "libc/intrin/cmpxchg.h"
#include "libc/str/str.h"
#include "libc/thread/thread.h"
#include "libc/zipos/zipos.internal.h"
void __zipos_free(struct Zipos *z, struct ZiposHandle *h) {
@@ -28,6 +29,7 @@ void __zipos_free(struct Zipos *z, struct ZiposHandle *h) {
__asan_poison((char *)h + sizeof(struct ZiposHandle),
h->mapsize - sizeof(struct ZiposHandle), kAsanHeapFree);
}
pthread_mutex_destroy(&h->lock);
__zipos_lock();
do h->next = z->freelist;
while (!_cmpxchg(&z->freelist, h->next, h));
+12 -4
View File
@@ -18,6 +18,7 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/calls/metalfile.internal.h"
#include "libc/fmt/conv.h"
#include "libc/intrin/cmpxchg.h"
#include "libc/intrin/promises.internal.h"
#include "libc/intrin/strace.internal.h"
@@ -59,7 +60,7 @@ static void __zipos_munmap_unneeded(const uint8_t *base, const uint8_t *cdir,
* @threadsafe
*/
struct Zipos *__zipos_get(void) {
int fd;
int fd = -1;
ssize_t size;
const char *msg;
static bool once;
@@ -67,10 +68,17 @@ struct Zipos *__zipos_get(void) {
const char *progpath;
static struct Zipos zipos;
uint8_t *map, *base, *cdir;
if (!once && PLEDGED(RPATH)) {
progpath = getenv("COSMOPOLITAN_INIT_ZIPOS");
if (progpath) {
fd = atoi(progpath);
}
if (!once && ((fd != -1) || PLEDGED(RPATH))) {
__zipos_lock();
progpath = GetProgramExecutableName();
if ((fd = open(progpath, O_RDONLY)) != -1) {
if (fd == -1) {
progpath = GetProgramExecutableName();
fd = open(progpath, O_RDONLY);
}
if (fd != -1) {
if ((size = getfiledescriptorsize(fd)) != -1ul &&
(map = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0)) != MAP_FAILED) {
if ((base = FindEmbeddedApe(map, size))) {
+3
View File
@@ -18,6 +18,7 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/sysv/errfuns.h"
#include "libc/thread/thread.h"
#include "libc/zip.h"
#include "libc/zipos/zipos.internal.h"
@@ -31,6 +32,7 @@
*/
int64_t __zipos_lseek(struct ZiposHandle *h, int64_t offset, unsigned whence) {
int64_t rc;
pthread_mutex_lock(&h->lock);
switch (whence) {
case SEEK_SET:
rc = offset;
@@ -50,5 +52,6 @@ int64_t __zipos_lseek(struct ZiposHandle *h, int64_t offset, unsigned whence) {
} else {
rc = einval();
}
pthread_mutex_unlock(&h->lock);
return rc;
}
+27 -14
View File
@@ -22,6 +22,7 @@
#include "libc/errno.h"
#include "libc/intrin/likely.h"
#include "libc/intrin/strace.internal.h"
#include "libc/runtime/internal.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/prot.h"
#include "libc/sysv/errfuns.h"
@@ -46,8 +47,8 @@
* it does not need to be 64kb aligned.
* @return virtual base address of new mapping, or MAP_FAILED w/ errno
*/
void *__zipos_mmap(void *addr, size_t size, int prot, int flags,
struct ZiposHandle *h, int64_t off) {
noasan void *__zipos_Mmap(void *addr, size_t size, int prot, int flags,
struct ZiposHandle *h, int64_t off) {
if (!(flags & MAP_PRIVATE) ||
(flags & ~(MAP_PRIVATE | MAP_FILE | MAP_FIXED | MAP_FIXED_NOREPLACE)) ||
(!!(flags & MAP_FIXED) ^ !!(flags & MAP_FIXED_NOREPLACE))) {
@@ -56,21 +57,33 @@ void *__zipos_mmap(void *addr, size_t size, int prot, int flags,
return VIP(einval());
}
if (VERY_UNLIKELY(off < 0)) {
STRACE("neg off");
return VIP(einval());
}
const int tempProt = !IsXnu() ? prot | PROT_WRITE : PROT_WRITE;
void *outAddr =
mmap(addr, size, tempProt, (flags & (~MAP_FILE)) | MAP_ANONYMOUS, -1, 0);
_Mmap(addr, size, tempProt, (flags & (~MAP_FILE)) | MAP_ANONYMOUS, -1, 0);
if (outAddr == MAP_FAILED) {
return MAP_FAILED;
}
const int64_t beforeOffset = __zipos_lseek(h, 0, SEEK_CUR);
if ((beforeOffset == -1) ||
(__zipos_read(h, &(struct iovec){outAddr, size}, 1, off) == -1) ||
(__zipos_lseek(h, beforeOffset, SEEK_SET) == -1) ||
((prot != tempProt) && (mprotect(outAddr, size, prot) == -1))) {
const int e = errno;
munmap(outAddr, size);
errno = e;
return MAP_FAILED;
}
return outAddr;
do {
if (__zipos_read(h, &(struct iovec){outAddr, size}, 1, off) == -1) {
strace_enabled(-1);
break;
} else if (prot != tempProt) {
strace_enabled(-1);
if (mprotect(outAddr, size, prot) == -1) {
break;
}
strace_enabled(+1);
}
return outAddr;
} while (0);
const int e = errno;
_Munmap(outAddr, size);
errno = e;
strace_enabled(+1);
return MAP_FAILED;
}
+1
View File
@@ -90,6 +90,7 @@ StartOver:
if (h) {
h->size = size;
h->mapsize = mapsize;
pthread_mutex_init(&h->lock, 0);
}
return h;
}
Loaded 100 of 184 files, more files were not shown because too many files have changed in this diff. Show more