Compare commits

...
168 Commits
Author SHA1 Message Date
Justine Tunney 83341a4269 Remove hints from Windows imports 2023-07-27 14:09:07 -07:00
Justine Tunney 7e0a09feec Mint APE Loader v1.5
This change ports APE Loader to Linux AARCH64, so that Raspberry Pi
users can run programs like redbean, without the executable needing
to modify itself. Progress has also slipped into this change on the
issue of making progress better conforming to user expectations and
industry standards regarding which symbols we're allowed to declare
2023-07-26 13:54:49 -07:00
Justine Tunney 6843150e0c Mint APE Loader v1.4
This change also incorporates more bug fixes and improvements to a wide
variety of small things. For example this fixes #860 so Windows console
doesn't get corrupted after exit. An system stack memory map issue with
aarch64 has been fixed. We no longer use O_NONBLOCK on AF_UNIX sockets.
Crash reports on Arm64 will now demangle C++ symbols, even when c++filt
isn't available. Most importantly the Apple M1 version of APE Loader is
brought up to date by this change. A prebuilt unsigned binary for it is
being included in build/bootstrap/. One more thing: retrieving the term
dimensions under --strace was causing the stack to become corrupted and
now that's been solved too. PSS: We're now including an ELF PT_NOTE for
APE in the binaries we build, that has the APE Loader version.
2023-07-25 05:48:08 -07:00
Michael Lenaghan 53d3f9d9c5 Change the default TZ value from GST to GMT #861 (#867)
With this change, `unix.localtime()` will match `unix.gmtime()`
when `TZ` hasn't been defined.
2023-07-24 20:40:15 -07:00
Andy George 9c79c5682c Add sh code tagging (#855) 2023-07-24 20:15:18 -07:00
Justine Tunney e0c2b91b3e Remove _Hide keyword
It never did anything and isn't worthwhile as documentation.
2023-07-24 08:34:58 -07:00
Justine Tunney 4fb6cbc1fe Revert "Polyfill ENOTSOCK in getsockname() and getpeername()"
This reverts commit 925219bdf3.
2023-07-24 03:09:43 -07:00
Justine Tunney 925219bdf3 Polyfill ENOTSOCK in getsockname() and getpeername() 2023-07-24 02:11:25 -07:00
Justine Tunney eb84a25994 Check for interrupts more eagerly on Windows 2023-07-24 02:03:29 -07:00
Justine Tunney 94ea34367a Tune the page sizes 2023-07-24 00:49:06 -07:00
Justine Tunney ff198e7577 Introduce GetElfSegmentAddress() function 2023-07-23 17:36:18 -07:00
Justine Tunney 3d172c99fe Mint APE Loader v1.3
This version has better error messages and safety checks. It supports
loading static position-independent executables. It correctly handles
more kinds of weird ELF program header layouts. A force flag has been
added to avoid system execve(). Finally the longstanding misalignment
with our ELF PT_NOTE section has been addressed.
2023-07-23 17:08:14 -07:00
Justine Tunney 82b1e61443 Fix Landlock Make build config issue 2023-07-23 16:43:22 -07:00
Justine Tunney 0ba3199915 Fix some more socket bugs
- The functions that return a sockaddr now do so the same way the Linux
  Kernel does across platforms, e.g. getpeername(), accept4()

- Socket system calls on Windows will now only check for interrupts when
  a blocking operation needs to be performed.

- Write tests for recvfrom() system call
2023-07-23 16:31:10 -07:00
Danny Robinson ac92f25296 Update definitions.lua with latest progress (#852)
* Update definitions.lua with latest progress

* Remove duplicate definition
2023-07-23 11:14:55 -07:00
tkchiaandtkchia 0ffc0dd461 Let lz4toasm accept LZ4 files that lack extracted-size field (#858)
lz4toasm should now more easily accept LZ4 files output by
compressor programs that do not support the extracted-size
field, such as Stephan Brumme's smallz4.

This patch also proposes to add a new lz4len() function to
the libc: it parses an LZ4 compressed block to compute the
unpacked content size, without really unpacking the block.

Co-authored-by: tkchia <[email protected]>
2023-07-23 11:12:22 -07:00
Gautham 3eec69f9c3 Simplify cosmocc builds (#863)
- tcgetpgrp(STDIN_FILENO) should be equal to getpgrp() on Windows also,
  found while reading wget source code which uses this check to decide
  whether to print to stderr or to a file
- IN6_ADDR_ARE_EQUAL is a comparison macro used when IPV6 is allowed,
  found while reading CPython3.11 source code
- the changes in signal.h and addition of ucontext.h are because
  CPython3.11 source code expect sigaltstack to be available
- the sqlite3.mk change is because CPython3.11 requires sqlite3 to be
  built with -DOMIT_SHARED_CACHE
- unistd.h has getopt.h now, because some libraries like it there
2023-07-23 11:11:08 -07:00
Justine Tunney f83eb440f7 Incorporate more small improvements 2023-07-23 10:57:18 -07:00
Justine Tunney 1d4eb08fa1 Support non-blocking i/o across platforms
This change introduces new tests for `O_NONBLOCK` and `SOCK_NONBLOCK` to
confirm that non-blocking i/o is now working on all supported platforms,
including Windows. For example, you can now say on Windows, MacOS, etc.:

    socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);

To create a non-blocking IPv4 TCP socket. Or you can enable non-blocking
i/o on an existing socket / pipe / etc. file descriptor by calling fcntl

    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);

This functionality is polyfilled on older Linux kernels too, e.g. RHEL5.
Now that fcntl() support is much better the FIOCLEX / FIONCLEX polyfills
for ioctl() have been removed since they're ugly non-POSIX diameond APIs

This change fixes a weakness in kprintf() that was causing Windows trace
tools to frequently crash.
2023-07-23 02:56:47 -07:00
Justine Tunney 5c9e03e3e0 Temporarily turn down redbean StoreAsset() feature 2023-07-22 15:51:44 -07:00
Justine Tunney 18536950b3 Fix the build 2023-07-11 05:48:39 -07:00
Justine Tunney 1ee2e89326 Make improvements
- This commit mints a new release of APE Loader v1.2 which supports
  loading ELF programs with a non-contiguous virtual address layout
  even though we've never been able to take advantage of it, due to
  how `objcopy -SO binary` fills any holes left by PT_LOAD. This'll
  change soon, since we'll have a new way of creating APE binaries.

- The undiamonding trick with our ioctl() implementation is removed
  since POSIX has been killing ioctl() for years and they've done a
  much better job. One problem it resolves, is that ioctl(FIONREAD)
  wasn't working earlier and that caused issues when building Emacs
2023-07-11 04:41:50 -07:00
Justine Tunney a1b1fdd1a4 Reconfigure GitHub Actions 2023-07-10 12:17:18 -07:00
Justine Tunney a2d269dc38 Brush up some more code 2023-07-10 10:17:26 -07:00
Justine Tunney ee6566a152 Further improve usability of cosmocc
- Support -s flag in cosmocc
- Support posix_spawn() setsid() feature
- Disable monorepo debug path prefix stripping
2023-07-10 05:55:00 -07:00
Justine Tunney f7ae50462a Make improvements
- Fix unused local variable errors
- Remove yoinks from sigaction() header
- Add nox87 and aarch64 to github actions
- Fix cosmocc -fportcosmo in linking mode
- It's now possible to build `make m=llvm o/llvm/libc`
2023-07-10 04:35:14 -07:00
Justine Tunney 3dc86ce154 Fix breakages in Linux-only build modes
- compile.com now polyfills -march=native which gcc/clang removed
- Guarantee zero Windows code is linked into non-Windows binaries
- MODE=tinylinux binaries are now back to being as tiny as ~4kb
- Improve the runtime's stack allocation / alignment hack
- GitHub Actions now tests Linux modes for assurance
2023-07-09 19:51:44 -07:00
Justine Tunney 0e4c828a8e Fix alignment of ftrace hook 2023-07-09 16:52:08 -07:00
Justine Tunney e1316d6565 Fix chibicc build breakage 2023-07-09 15:00:33 -07:00
Justine Tunney d3cf9d4ef1 Use long as implicit type in chibicc
This makes it possible to write 64-bit C without headers and prototypes.
2023-07-09 10:11:06 -07:00
Justine Tunney 42ba9901e4 Fix some behavioral issues on Windows 2023-07-09 09:59:22 -07:00
Justine Tunney 41396ff48a Make fixes and improvements
- Fix handling of precision in hex float formatting
- Enhance the cocmd interpreter for system() and popen()
- Manually ran the Lua unit tests, which are now passing
- Let stdio i/o operations happen when file is in error state
- We're now saving and restoring xmm in ftrace out of paranoia
2023-07-09 05:21:11 -07:00
Justine Tunney 95fbdb4f76 Have function tracer save all registers 2023-07-08 12:04:44 -07:00
Justine Tunney 1cc8ff6a55 Fix some aarch64 build issues 2023-07-08 10:47:45 -07:00
Justine Tunney 9ae230afad Fix more build configuration errors 2023-07-08 09:08:13 -07:00
Justine Tunney a75175fe94 Make build hermetically sealed again
It turned out that Landlock Make hasn't been applying sandboxing for a
while, due to a mistyped if statement for `$(USE_SYSTEM_TOOLCHAIN)` it
should have had the opposite meaning. Regressions in the build configs
have been fixed. The rmrf() function works better now. The rm.com tool
works according to POSIX with the exception of supporting prompts.
2023-07-08 07:06:25 -07:00
Justine Tunney 0c43c98de1 Add libcxx filesystem modules 2023-07-08 02:40:17 -07:00
Justine Tunney a092fda388 Make some fixes for libcxx
This change figures out some of the build configuration issues we've
been having with libcxx. The c++ span header is added. Per a Discord
discussion we're now turning off `-g` for the default build mode, so
consider using `make MODE=dbg` or `make MODE=zero` for GDB debugging
which works much better than `MODE=` ever has. Note that the default
build mode has always had very good function call / system call logs
plus you can still use ShowCrashReports() for backtrace. Making this
change ensures cosmocc will better conform to FOSS norms. Lastly the
LoadZipArgs() API has been added to cosmopolitan.a and <cosmo.h>.
2023-07-07 19:35:58 -07:00
Justine Tunney 3a8579252d Move demangling utility to stdio
Closes #848
2023-07-07 10:47:50 -07:00
Farid Zakaria a1dd777f22 add support for __cxa_demangle
This adds support for __cxa_demangle through the cxxabi.h file.

At the moment it is the only symbol included.
The source was taken from FreeBSD
contrib/libcxxrt/libelftc_dem_gnu3.c
2176c9ab71c85efd90a6c7af4a9e04fe8e3d49ca

FreeBSD does say this is also almost verbatim from ELFToolkit
2023-07-07 10:29:03 -07:00
Justine Tunney 0d3c1c8b1a Do work on curl/mbedtls/zstd
This change fixes stderr to be unbuffered. Added hardware AES on ARM64
to help safeguard against timing attacks. The curl.com command will be
somewhat more pleasant to use.
2023-07-07 10:13:35 -07:00
Justine Tunney a186143f62 Add EncodeHex() and DecodeHex() to Redbean 2023-07-06 15:38:08 -07:00
Justine Tunney 00acd81b2f Delete more dead code 2023-07-06 09:12:28 -07:00
Justine Tunney 0a24b4fc3c Clean up more code
The *NSYNC linked list API is good enough that it deserves to be part of
the C libray, so this change writes an improved version of it which uses
that offsetof() trick from the Linux Kernel. We vendor all of the *NSYNC
tests in third_party which helped confirm the needed refactoring is safe

This change also deletes more old code that didn't pan out. My goal here
is to work towards a vision where the Cosmopolitan core libraries become
less experimental and more focused on curation. This better reflects the
current level of quality we've managed to achieve.
2023-07-06 08:03:24 -07:00
Justine Tunney 88612a2cd7 Restore original redbean build linking 2023-07-05 20:04:43 -07:00
Justine Tunney 97b7116953 Hunt down more bugs
After going through the MODE=dbg and MODE=zero build modes, a bunch of
little issues were identified, which have been addressed. Fixing those
issues created even more troubles for the project, because it improved
our ability to detect latent problems which are getting fixed so fast.
2023-07-03 18:43:29 -07:00
Justine Tunney 73c0faa1b5 Remove some dead code 2023-07-03 02:48:29 -07:00
Justine Tunney 168d1c157e Fix build breakage under special strace config 2023-07-03 00:05:51 -07:00
Justine Tunney fe044e22cc Switch public headers to getopt_long() entirely
Cosmopolitan's getopt() is now redefined as __getopt().
2023-07-02 19:57:43 -07:00
Justine Tunney 0c630d95b5 Rewrite Cosmopolitan Ar
The build/bootstrap/ar.com program is now tinier. This change reduces
its size from 140kb to 53kb. Nothing was traded away. Cosmopolitan Ar
performance is now 2x better than llvm-ar largely thanks to using the
copy_file_range() system call. This change homebrews a new allocation
API that addresses the shortcomings of the C standard library design.
Using these new balloc() and reballoc() functions I managed to reduce
memory consumption so much that Cosmpolitan Ar should now use roughly
100x fewer bytes of peak resident memory compared to llvm-ar. Correct
behavior with better compatibility has been assured. Binary output is
now pretty much bit-identical to llvm-ar, as of this change. This can
and should be the living proof we need to show that a better world is
possible for software.
2023-07-02 10:19:16 -07:00
Justine Tunney 197aa0d465 Implement swapcontext() and makecontext()
This change introduces support for Linux-style uc_context manipulation
that's fast and works well on all supported OSes and architectures. It
also integrates with the Cosmpolitan runtime which can show backtraces
comprised of multiple stacks and fibers. See the test and example code
for further details. This will be used by Mold once it's been vendored
2023-07-02 09:01:44 -07:00
Justine Tunney 7ec84655b4 Get setcontext() and getcontext() working on Aarch64
This change also adds the missing code for getting and restoring the
thread's signal mask, since that's explicitly listed by the man page
2023-07-01 22:53:23 -07:00
Farid Zakaria 8b62bff364 Introduce xxhash into third_party (#837) 2023-07-01 20:56:53 -07:00
Farid Zakaria 5f1e129222 Introduce zstd into cosmopolitan (#843) 2023-07-01 20:30:38 -07:00
Paul Kulchenko c0348330a5 Add path information in logged error messages (#832) 2023-07-01 19:47:59 -07:00
Paul Kulchenko dc8fbf38ad Update Windows IP_MULTICAST constants to use Ws2tcpip.h values (#839) (#842) 2023-07-01 19:44:27 -07:00
Justine Tunney ce0a3065f3 Update build/bootstrap/make.com
This is important, because the execve() workflow has been upgraded for
launching APE binaries. Programs that call execve() need to be remade,
otherwise they might attempt to use ~/.ape rather than ~/ape-1.1.
2023-07-01 18:37:19 -07:00
Justine Tunney 40eb3b9d5d Fully support OpenBSD 7.3
This change (1) upgrades to OpenBSD's newer kernel ABIs, and (2)
modifies APE to have a read-only data segment. Doing this required
creating APE Loader v1.1, which is backwards and forwards compatible
with the previous version.

If you've run the following commands in the past to install your APE
Loader systemwide, then you need to run them again. Ad-hoc installations
shouldn't be impacted. It's also recommended that APE binaries be remade
after upgrading, since they embed old versions of the APE Loader.

    ape/apeuninstall.sh
    ape/apeinstall.sh

This change does more than just fix OpenBSD. The new loader is smarter
and more reliable. We're now able create much tinier ELF and Mach-O data
structures than we could before. Both APE Loader and execvpe() will now
normalize ambiguous argv[0] resolution the same way as the UNIX shell.
Badness with TLS linkage has been solved.

Fixes #826
2023-07-01 18:14:27 -07:00
Justine Tunney 963e10b9bf Introduce new tinyprint() api 2023-07-01 05:09:32 -07:00
Justine Tunney 053681cb97 Fix BSD regressions
The recent change to crt.S that aggressively aligns the system-provided
stack has been rolled back on non-Linux until we can find a better way,
since it can cause a segfault early in execution on several platforms.

This change fixes a regression in tcgetattr() and tcsetattr() on OpenBSD
and NetBSD caused by 4778cd4d27.

This change has been tested across the runitd test fleet which is green.
2023-07-01 00:17:33 -07:00
Paul Kulchenko 5a77db2cd5 Fix recvfrom on Windows (closes #841) (#844) 2023-06-30 23:39:55 -07:00
Justine Tunney 48b2afb192 Address weakness with new pledge("anet") promise
The intent with pledge("anet") has been to prevent outbound connections.
However we were only doing that for TCP sockets, and outbound UDP could
still get through, by using socket() plus sendto(). This change fixed
that by preventing UDP sockets from being created.

Credit goes to chc4 on Hacker News for finding this.
2023-06-18 18:06:47 -07:00
Justine Tunney fb2bd313ae Fix redbean unix.poll() with -1 timeout 2023-06-18 18:05:26 -07:00
Justine Tunney f10845ab9f Add blackhole support to Python tokenbucket module 2023-06-18 07:50:11 -07:00
Justine Tunney 461c835784 Remove removed GCC symlinks 2023-06-18 05:41:55 -07:00
Justine Tunney 226375933a Implement more toolchain fixes 2023-06-18 05:39:31 -07:00
Justine Tunney 0409096658 Get us closer to building busybox
This change undefines __linux__ and adds APIs like clock_settime(). The
gosh darned getopt_long() API has been reintroduced, thanks to OpenBSD.
2023-06-18 04:13:45 -07:00
Justine Tunney 5ac522f0de Add make clean build rule 2023-06-18 01:23:54 -07:00
Justine Tunney 8514933b60 Delete itoa() prototype 2023-06-18 01:17:15 -07:00
Justine Tunney d7c79f43ef Clean up more code
- Found some bugs in LLVM compiler-rt library
- The useless LIBC_STUBS package is now deleted
- Improve the overflow checking story even further
- Get chibicc tests working in MODE=dbg mode again
- The libc/isystem/ headers now have correctly named guards
2023-06-18 01:00:05 -07:00
Justine Tunney afc58a8b41 Upgrade cosmopolitan gcc and binutils to 2.35.2
This change upgrades to the latest portcosmo gcc patch
6728fe1a25185560603ca312a8d4352af2a4e515 which lets us avoid needing to
define __tmpcosmo_FOO constants. We're now using an appropriate binutils
version for GCC 11. The older binutils sometimes wasn't able to print
backtraces, due to not being able to find a .debug_ranges section.

This is breaking change for /opt/cosmos libraries :'( due to this weird
"error: need linked-to section for --gc-sections" that pops up.

Please run `make clean` in the monorepo before rebuilding.
2023-06-18 00:54:14 -07:00
Justine Tunney 2c0f0bab0b Fix mkfifo() on Linux 2023-06-17 16:04:08 -07:00
Justine Tunney 12452976bd Remove getopt_long() from headers
We removed this API a long time ago and it was breaking the GNU make
open source build.
2023-06-17 16:03:16 -07:00
Justine Tunney b881c0ec9e Remove printf() linking hack 2023-06-17 10:13:50 -07:00
Justine Tunney ba03cd95c5 Modernize the README file 2023-06-17 07:55:48 -07:00
Justine Tunney 562a1384cd Make blink support conditionally linkable into APE 2023-06-17 07:55:35 -07:00
Justine Tunney 52d28966f7 Remove old zip base skew hack
Since 8ff48201ca we no longer need the
hack where, when running .com.dbg files, we scanned for the embedded
.com file offset, and then computed zip offsets realtive to that. It
wasn't very reliable in the first place, and was causing issues with
running our new .com.dbg executables, which are true zip files.
2023-06-17 04:20:16 -07:00
Justine Tunney 207e18a060 Unbreak the x86-64 build 2023-06-16 20:05:24 -07:00
Justine Tunney 7bc20bff3e Resolve argv[0] based on path search in ape-m1 2023-06-16 16:58:30 -07:00
Justine Tunney 1353db7d3f Fix rwx .rodata in python.com on aarch64 2023-06-16 16:25:04 -07:00
Justine Tunney 4eebd6b9dc Improve new C23 checked arithmetic feature 2023-06-16 15:32:18 -07:00
Justine Tunney 2a1c588826 Add tokenbucket module to python.com 2023-06-16 15:32:09 -07:00
Justine Tunney e6b7c16a53 Make changes needed for new demo 2023-06-15 23:22:49 -07:00
Justine Tunney c3440d040c Make improvements
- More timspec_*() and timeval_*() APIs have been introduced.
- The copyfd() function is now simplified thanks to POSIX rules.
- More Cosmo-specific APIs have been moved behind the COSMO define.
- The setitimer() polyfill for Windows NT is now much higher quality.
- Fixed build error for MODE=aarch64 due to -mstringop-strategy=loop.
- This change introduces `make MODE=nox87 toolchain` which makes it
  possible to build programs using your cosmocc toolchain that don't
  have legacy fpu instructions. This is useful, for example, if you
  want to have a ~22kb tinier blink virtual machine.
2023-06-15 14:50:53 -07:00
Justine Tunney 8dc11afcf6 Upgrade portcosmo patch and GCC third party docs 2023-06-14 19:53:06 -07:00
Justine Tunney 4778cd4d27 Fix bugs in termios library and cleanup code
This change fixes an issue with the tcflow() magic numbers that was
causing bash to freeze up on Linux. While auditing termios polyfills,
several other issues were identified with XNU/BSD compatibility.

Out of an abundance of caution this change undefines as much surface
area from libc/calls/struct/termios.h as possible, so that autoconf
scripts are less likely to detect non-POSIX teletypewriter APIs that
haven't been polyfilled by Cosmopolitan.

This is a *breaking change* for your static archives in /opt/cosmos if
you use the cosmocc toolchain. That's because this change disables the
ioctl() undiamonding trick for code outside the monorepo, specifically
because it'll lead to brittle ABI breakages like this. If you're using
the cosmocc toolchain, you'll need to rebuild libraries like ncurses,
readline, etc. Yes diamonds cause bloat. To work around that, consider
using tcgetwinsize() instead of ioctl(TIOCGWINSZ) since it'll help you
avoid pulling every single ioctl-related polyfill into the linkage.

The cosmocc script was specifying -DNDEBUG for some reason. It's fixed.
2023-06-14 19:30:52 -07:00
Justine Tunney 06b749ae03 Remove blinkenlights
New home: https://github.com/jart/blink
2023-06-14 19:30:52 -07:00
Gabriel Ravier 50d8d953ce Fix syscall(2) returning -errno instead of using POSIX errno scheme (#830)
As of now, the syscall function is implemented as alike to how the
linux kernel sycall ABI works, returning -errno upon errors without
setting the value of errno. However, this does not conform to the
expectations of most software, which expect it to return -1 and set
errno, which is how it works on other libcs, which document it
accordingly:

> The return value is defined by the system call being invoked.  In
> general, a 0 return value indicates success.  A -1 return value
> indicates an error, and an error number is stored in errno.
- Linux man-pages, syscall(2)

> The return value is the return value from the system call, unless
> the system call failed.  In that case, ‘syscall’ returns ‘-1’ and
> sets ‘errno’ to an error code that the system call returned.
- glibc manual, (libc)System Calls

> When the C-bit is set, syscall returns -1 and sets the external
> variable errno (see intro(2)).
- 4BSD manual, syscall(2)

> A -1 return value indicates an error, and an error code is stored in
> errno.
- 4.4BSD, FreeBSD, OpenBSD and NetBSD manuals (same quote is found in
  all of them), syscall(2)

This patch corrects the syscall function to work in the same way as in
other libcs.
2023-06-11 10:33:28 -07:00
tkchiaandtkchia e47c0cc929 [metal] Clean up code for getting pointer to struct mman (#828)
Co-authored-by: tkchia <[email protected]>
2023-06-11 10:32:39 -07:00
Justine Tunney 5a6a4819d4 Fix -iquote in cosmocc toolchain 2023-06-10 16:35:53 -07:00
Justine Tunney 2676ec55de Make improvements to cosmocc toolchain 2023-06-10 15:50:01 -07:00
Justine Tunney 8ff48201ca Rewrite .zip.o file linker
This change takes an entirely new approach to the incremental linking of
pkzip executables. The assets created by zipobj.com are now treated like
debug data. After a .com.dbg is compiled, fixupobj.com should be run, so
it can apply fixups to the offsets and move the zip directory to the end
of the file. Since debug data doesn't get objcopy'd, a new tool has been
introduced called zipcopy.com which should be run after objcopy whenever
a .com file is created. This is all automated by the `cosmocc` toolchain
which is rapidly becoming the new recommended approach.

This change also introduces the new C23 checked arithmetic macros.
2023-06-10 09:29:44 -07:00
Justine Tunney f6407d5f7c Fix missing includes 2023-06-09 18:11:53 -07:00
Justine Tunney 4a59210008 Introduce #include <cosmo.h> to toolchain users
This change improves the way internal APIs are being hidden behind the
`COSMO` define. The cosmo.h header will take care of defining that, so
that a separate define statement isn't needed. This change also does a
lot more to define which APIs are standard, and which belong to Cosmo.
2023-06-09 18:03:05 -07:00
Justine Tunney 9b55dbe417 Get GCC to mostly build with Cosmo 2023-06-09 06:41:34 -07:00
Justine Tunney 2eb7148474 Create a fake syscall() function due to Python 2023-06-09 05:18:38 -07:00
Justine Tunney 4b2023ffab Disable linker map generation and improve tinyness 2023-06-09 03:29:26 -07:00
Justine Tunney 23e235b7a5 Fix bugs in cosmocc toolchain
This change integrates e58abc1110b335a3341e8ad5821ad8e3880d9bb2 from
https://github.com/ahgamut/musl-cross-make/ which fixes the issues we
were having with our C language extension for symbolic constants. This
change also performs some code cleanup and bug fixes to getaddrinfo().
It's now possible to compile projects like ncurses, readline and python
without needing to patch anything upstream, except maybe a line or two.
Pretty soon it should be possible to build a Linux distro on Cosmo.
2023-06-08 23:44:03 -07:00
Justine Tunney 22f81a8d50 Improve cosmocc / cosmoc++ toolchain scripts
- Get out of the red zone
- Generate --ftrace nops unless -Os is passed
- Intercept -o path to generate .com / .com.dbg appropriately
2023-06-08 14:29:22 -07:00
Justine Tunney 25678db2a0 Fix remaining regressions in ASAN support
See #829
2023-06-08 08:00:50 -07:00
Justine Tunney 4d629fd424 Fix stack abuse in llama.cc
This change also incorporates improvements for MODE=asan. It's been
confirmed that o/asan/third_party/ggml/llama.com will work.

Fixes #829
2023-06-08 07:12:26 -07:00
Justine Tunney 32682f0ce7 Remove some problematic APIs
In order to improve our chances of success building other open source
projects we shouldn't define APIs that'll lead any ./configure script
astray. For example:

- brk() and sbrk() can break mac/windows support
- syscall() is a superb way to break portability
- arch_prctl() is the greatest of all horror shows
2023-06-08 06:12:26 -07:00
Justine Tunney 7512318a2a Fix MODE=aarch64 build 2023-06-08 05:17:37 -07:00
Justine Tunney 8767e9ad6a Fix --ftrace regression 2023-06-08 04:46:11 -07:00
Justine Tunney daf4454a06 Validate privileged code relationships
- Work towards improving non-optimized build support
- Introduce MODE=zero which is -O0 without ASAN/UBSAN
- Use system GCC when ~/.cosmo.mk has USE_SYSTEM_TOOLCHAIN=1
- Have package.com check .privileged code doesn't call non-privileged
2023-06-08 04:38:06 -07:00
Justine Tunney 01fd655097 Get garbage collector working on aarch64
Garbage collection will now happen on arm64 when a function returns,
rather than kicking the can down the road to when the process exits.
This change also does some code cleanup and incorporates suggestions
2023-06-07 03:34:45 -07:00
Justine Tunney 9793d3524f Remove superfluous RET instructions 2023-06-06 19:46:56 -07:00
Justine Tunney b6182db813 Simplify ftrace_hook()
We now have a test to prove that its transitive closure doesn't perform
floating point computations.
2023-06-06 11:10:38 -07:00
Justine Tunney 61b9677c05 Make improvements
- Get mprotect_test working on aarch64
- Get completion working on python.com repl again
- Improve quality of printvideo.com and printimage.com
- Fix bug in openpty() so examples/script.c works again
2023-06-06 09:12:30 -07:00
Justine Tunney b94b29d79c Prevent ftrace from misaligning functions 2023-06-06 06:00:31 -07:00
Justine Tunney b8a6a989c0 Create ELF aliases for identical symbols
This change greatly reduces the number of modules that need to be
compiled. The only issue right now is that sometimes when viewing
symbol table entries, the aliased symbol is chosen.
2023-06-06 03:33:49 -07:00
Justine Tunney e1b83399bd Fix memmove() alias on aarch64 with --ftrace 2023-06-06 00:39:55 -07:00
Justine Tunney e9e8bbe6da Avoid /etc/services in whois command
Apparently IANA has abolished the WHOIS protocol and no longer lists it
as a service. Therefore distros which naively create /etc/services from
IANA's braindead recommendation will inadvertently break any tools that
rely on /etc/services to determine this well-known Internet port.
2023-06-06 00:11:41 -07:00
Justine Tunney eb40cb371d Get --ftrace working on aarch64
This change implements a new approach to function call logging, that's
based on the GCC flag: -fpatchable-function-entry. Read the commentary
in build/config.mk to learn how it works.
2023-06-05 23:35:31 -07:00
Justine Tunney 5b908bc756 Fix some build errors 2023-06-05 15:53:44 -07:00
Justine Tunney 7558549d44 Test m=aarch64 on GitHub Actions 2023-06-05 15:23:00 -07:00
Justine Tunney 42b9b75749 Fix aarch64 build 2023-06-05 05:57:44 -07:00
Justine Tunney f554dd800e Make it possible to log kprintf() to file
It's now possible to compile Emacs using cosmocc. However we need to
troubleshoot why it's event loop isn't working correctly at runtime.
2023-06-05 04:16:15 -07:00
Justine Tunney 9cc3e37263 Upgrade to Cosmopolitan GCC 11.2.0 for aarch64 2023-06-05 02:07:28 -07:00
Justine Tunney 39f20dbb13 Upgrade to Cosmopolitan GCC 11.2.0 for x86_64 2023-06-05 02:06:18 -07:00
Justine Tunney 682b74ed88 Incorporate Blink 1.0.0 release 2023-06-04 11:07:31 -07:00
Justine Tunney 35dcaca53c Fix test fleet errors 2023-06-04 10:57:11 -07:00
Justine Tunney a91a945b88 Fix build breakage 2023-06-04 09:33:48 -07:00
Justine Tunney 4aa1d09b9e Improve aarch64 native support some more
This change introduces partial support for automating remote testing of
aarch64 binaries on Raspberry Pi and Apple Silicon.
2023-06-04 08:58:47 -07:00
Justine Tunney fc34ba2596 Fix Linenoise REPL on AARCH64 2023-06-04 02:57:17 -07:00
Justine Tunney bcf9af94bf Get threads working well on MacOS Arm64
- Now using 10x better GCD semaphores
- We now generate Linux-like thread ids
- We now use fast system clock / sleep libraries
- The APE M1 loader now generates Linux-like stacks
2023-06-04 01:57:10 -07:00
Justine Tunney b5eab2b0b7 Get POSIX threads working on Apple Silicon
It's now possible to run a working

    ape-m1 o/aarch64/third_party/ggml/llama.com

on Apple M1 hardware running XNU!
2023-06-03 18:33:01 -07:00
Justine Tunney 8fdb31681a Introduce support for GGJT v3 file format
llama.com can now load weights that use the new file format which was
introduced a few weeks ago. Note that, unlike llama.cpp, we will keep
support for old file formats in our tool so you don't need to convert
your weights when the upstream project makes breaking changes. Please
note that using ggjt v3 does make avx2 inference go 5% faster for me.
2023-06-03 15:46:21 -07:00
Justine Tunney 6ae18a10ba Fix MODE=tiny build 2023-06-03 10:30:48 -07:00
Justine Tunney 1904a3cae8 Sync llama.cpp to 6986c7835adc13ba3f9d933b95671bb1f3984dc6 2023-06-03 10:29:12 -07:00
Justine Tunney 8f522cb702 Make improvements
This change progresses our AARCH64 support:

- The AARCH64 build and tests are now passing
- Add 128-bit floating-point support to printf()
- Fix clone() so it initializes cosmo's x28 TLS register
- Fix TLS memory layout issue with aarch64 _Alignas vars
- Revamp microbenchmarking tools so they work on aarch64
- Make some subtle improvements to aarch64 crash reporting
- Make kisdangerous() memory checks more accurate on aarch64
- Remove sys_open() since it's not available on Linux AARCH64

This change makes general improvements to Cosmo and Redbean:

- Introduce GetHostIsa() function in Redbean
- You can now feature check using pledge(0, 0)
- You can now feature check using unveil("",0)
- Refactor some more x86-specific asm comments
- Refactor and write docs for some libm functions
- Make the mmap() API behave more similar to Linux
- Fix WIFSIGNALED() which wrongly returned true for zero
- Rename some obscure cosmo keywords from noFOO to dontFOO
2023-06-03 08:12:22 -07:00
Paul Kulchenko 5655c9a4e7 Extend Pledge with anet (same as inet, but with no connect) (#827)
* Add `anet` pledge for `inet` without connect

This is useful for configurations where it's desirable to start redbean
under these restrictions, but not to allow `connect` socket calls.

* Update message on protected/unpledged syscalls for clarity

* Update redbean to add reporting for unpledged sigaction

Previously it would abort without indicating what signal it failed to
install when sigaction is not pledged (although it fails all of them).

* Move GetHostIps before processing command line options

This allows using unix.pledge as part of the options without affecting
retrieving host IP addresses (which requires `connect`). It may still
fail under external `pledge` command as expected; in this case IPs
would need to be passed manually.

* Update tests for pledge anet promise
2023-06-03 07:50:29 -07:00
Justine Tunney 72f8bd10b7 Perform some code cleanup 2023-05-28 19:42:00 -07:00
Connor 992a4638ae Fix rgbtoxterm tool to output the proper colors (#819) 2023-05-26 18:30:24 -07:00
tkchiaandtkchia 90645f4dac [metal] Fix some issues that were breaking UEFI boot (#822)
Co-authored-by: tkchia <[email protected]>
2023-05-26 18:29:25 -07:00
Paul Kulchenko 5c40800d69 Update redbean ProgramDirectory to update package.path (#823) 2023-05-26 18:29:00 -07:00
Justine Tunney 1422e96b4e Introduce native support for MacOS ARM64
There's a new program named ape/ape-m1.c which will be used to build an
embeddable binary that can load ape and elf executables. The support is
mostly working so far, but still chasing down ABI issues.
2023-05-20 04:17:03 -07:00
Justine Tunney b852650c08 Fiddle around with Mach-O 2023-05-20 04:13:49 -07:00
Paul Kulchenko 6881a2ecea Extend redbean Fetch to add option to keeping connection open (#818) 2023-05-17 20:49:26 -07:00
Paul Kulchenko 021c71b651 Fix redbean to avoid compressing the first yielded chunk. (#813)
This may happen if no Status or Content-Type is set and if the written
content is longer than 100B, the compression is going to be applied
after coroutine.yield, even though it shouldn't be.
2023-05-17 20:46:27 -07:00
Justine Tunney e7eb0b3070 Make more ML improvements
- Fix UX issues with llama.com
- Do housekeeping on libm code
- Add more vectorization to GGML
- Get GGJT quantizer programs working well
- Have the quantizer keep the output layer as f16c
- Prefetching improves performance 15% if you use fewer threads
2023-05-16 08:07:23 -07:00
Justine Tunney 80db9de173 Make the intrinsics more readable 2023-05-15 23:12:11 -07:00
Justine Tunney 210187cf77 Perform some code cleanup 2023-05-15 16:32:10 -07:00
Justine Tunney cc1732bc42 Make AARCH64 harder, better, faster, stronger
- Perform some housekeeping on scalar math function code
- Import ARM's Optimized Routines for SIMD string processing
- Upgrade to latest Chromium zlib and enable more SIMD optimizations
2023-05-15 02:15:34 -07:00
Justine Tunney 550b52abf6 Port a lot more code to AARCH64
- Introduce epoll_pwait()
- Rewrite -ftrapv and ffs() libraries in C code
- Use more FreeBSD code in math function library
- Get significantly more tests passing on qemu-aarch64
- Fix many Musl long double functions that were broken on AARCH64
2023-05-14 09:37:26 -07:00
Ariel Núñez 91791e9f38 Started removing features from RedPajama to make it easier to understand for beginners (#817) 2023-05-14 09:16:22 -07:00
Justine Tunney 89d1fad7ee Enable crash reports for radpajama executables 2023-05-13 21:16:03 -07:00
Justine Tunney 296ee3ec58 Make some other fixes to radpajama build config 2023-05-13 21:09:28 -07:00
Justine Tunney 282dd8e7b7 Get radpajama to build
make -j8 o//third_party/radpajama/radpajama.com
    make -j8 o//third_party/radpajama/radpajama-chat.com

This change gets the radpajama.mk config working. This package depends
on THIRD_PARTY_GGML but it's configured to call ggjt_v1(), so that the
library will provide the old quantizers. The ggml_quantize_chunk() API
will now dispatch to older quantizers based on the configured version.
2023-05-13 20:44:36 -07:00
Justine Tunney 410c8785c9 Fix the AARCH64 build 2023-05-13 08:19:44 -07:00
Justine Tunney 5a4cf9560f Add support for new GGJT v2 quantizers
This change makes quantized models (e.g. q4_0) go 10% faster on Macs
however doesn't offer much improvement for Intel PC hardware.

This change syncs llama.cpp 699b1ad7fe6f7b9e41d3cb41e61a8cc3ea5fc6b5
which recently made a breaking change to nearly all its file formats
without any migration. Since that'll break hundreds upon hundreds of
models on websites like HuggingFace llama.com will support both file
formats because llama.com will never ever break the GGJT file format
2023-05-13 08:08:32 -07:00
Justine Tunney ba49e86e20 Get TEST_LIBC_CALLS passing on AARCH64 2023-05-13 02:41:41 -07:00
Justine Tunney 802e7eb4ef Mop up more test regressions 2023-05-13 01:09:44 -07:00
Justine Tunney 4a8a81eb9f Fix llama.com interactive mode regressions 2023-05-13 00:09:38 -07:00
Justine Tunney fd34ef732d Make considerably more progress on AARCH64
- Utilities like pledge.com now build
- kprintf() will no longer balk at 48-bit addresses
- There's a new aarch64-dbg build mode that should work
- gc() and defer() are mostly pacified; avoid using them on aarch64
- THIRD_PART_STB now has Arm Neon intrinsics for fast image handling
2023-05-12 22:42:57 -07:00
Justine Tunney 1bfb3aab1b Make Arm Neon intrinsics work with make tags 2023-05-12 18:32:53 -07:00
Justine Tunney 414667b1c9 Get TEST_LIBC_STR passing on AARCH64
It's now possible to run commands like:

    make -j8 m=aarch64 o/aarch64/test/libc/str

Which will cross-compile and run the test suites in a qemu-aarch64
binary that's vendored in the third_party/qemu/ folder within your
x86_64 build environment.
2023-05-12 18:09:23 -07:00
Justine Tunney 45186c74ac Introduce -q (quiet flag) and improve ctrl-c ux 2023-05-12 09:46:07 -07:00
Justine Tunney e8de1e4766 Fix subtoken antiprompt scanning 2023-05-12 08:55:40 -07:00
Justine Tunney 80c174d494 Clean up llama.com anti/stop/reverse-prompt code
Example use case for JSON completion:

    $ m=opt
    $ make -j16 m=$m o/$m/third_party/ggml/llama.com
    $ o/$m/third_party/ggml/llama.com -m llama.bin -p '{"key": "life", "val": ' -r '}'
    42}

This provides better control. More sophisticated facilities for
controlling text generation will be provided soon enough.
2023-05-12 08:20:58 -07:00
Justine Tunney bbfe4fbd11 Make llama.com n_predict be -1 by default 2023-05-12 08:20:34 -07:00
Justine Tunney ca19ecf49c Fine tune crash reports for llama.com 2023-05-12 06:24:26 -07:00
Justine Tunney 1f2a5a8fc1 Implement crash reporting for AARCH64
The ShowCrashReports() feature for aarch64 should work even better than
the x86 crash reports. Thanks to the benefit of hindsight these reports
should be rock solid reliable and beautiful to read.

This change also improves the syscall polyfills for aarch64. Some of the
sys_foo() functions have been removed, usually because they're legacy or
downright footguns not worth building.
2023-05-12 05:47:54 -07:00
Justine Tunney 285e8a2348 Get backtraces working on AARCH64 2023-05-11 22:12:41 -07:00
Justine Tunney 4edbc98811 Get MbedTLS and its unit tests passing AARCH64 2023-05-11 21:53:15 -07:00
Justine Tunney 5e2f7f7ced Get LIBC_TESTLIB building on AARCH64 2023-05-11 19:57:09 -07:00
Justine Tunney 95fab334e4 Use yield on aarch in spin locks 2023-05-11 19:57:09 -07:00
Ariel Núñez b3e3359d22 Import radpajama (a redpajama.cpp fork) (#814)
This is the relevant commit: https://github.com/togethercomputer/redpajama.cpp/commit/bfa6466199b8ef92185ecb72e2a550e12baf6602

Model download links:
https://huggingface.co/ceonlabs/radpajama/tree/main
2023-05-11 07:12:08 -07:00
8891 changed files with 295103 additions and 157493 deletions

No files matched your search

+1 -1
View File
@@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
mode: ["", tiny, opt, rel]
mode: ["", tiny, rel, tinylinux, optlinux]
steps:
- uses: actions/checkout@v3
+3 -4
View File
@@ -36,13 +36,13 @@
"textwindows=",
"privileged=",
"compatfn=",
"noinstrument=",
"dontinstrument=",
"nodebuginfo=",
"interruptfn=",
"optimizespeed=",
"forcealignargpointer=",
"noasan=",
"noubsan=",
"dontasan=",
"dontubsan=",
"donothing=",
"nosideeffect=",
"unreachable=",,
@@ -78,7 +78,6 @@
"-Wa,-W",
"-Wa,-I.",
"-Wa,--noexecstack",
"-Wa,--nocompress-debug-sections",
"-Og",
"-g",
"-gdescribe-dies",
+52 -22
View File
@@ -60,13 +60,12 @@
# build/config.mk
SHELL = build/bootstrap/cocmd.com
HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 xnu win10
MAKEFLAGS += --no-builtin-rules
.SUFFIXES:
.DELETE_ON_ERROR:
.FEATURES: output-sync
.PHONY: all o bins check test depend tags
.PHONY: all o bins check test depend tags aarch64 clean
ifneq ($(m),)
ifeq ($(MODE),)
@@ -87,7 +86,15 @@ o/$(MODE): \
o/$(MODE)/examples \
o/$(MODE)/third_party
ifneq ($(LANDLOCKMAKE_VERSION),)
ifeq ($(wildcard /usr/bin/ape),)
$(error please run ape/apeinstall.sh if you intend to use landlock make)
endif
ifeq ($(USE_SYSTEM_TOOLCHAIN),)
.STRICT = 1
endif
endif
.PLEDGE = stdio rpath wpath cpath fattr proc
.UNVEIL = \
libc/integral \
@@ -95,8 +102,10 @@ o/$(MODE): \
rwc:/dev/shm \
rx:build/bootstrap \
rx:o/third_party/gcc \
r:build/portcosmo.h \
/proc/stat \
rw:/dev/null \
rw:/dev/full \
w:o/stack.log \
/etc/hosts \
~/.runit.psk \
@@ -110,15 +119,13 @@ include build/functions.mk #─┐
include build/definitions.mk # ├──META
include build/config.mk # │ You can build
include build/rules.mk # │ You can topologically order
include build/online.mk # │
include libc/stubs/stubs.mk #─┘
include build/online.mk #─┘
include libc/nexgen32e/nexgen32e.mk #─┐
include libc/sysv/sysv.mk # ├──SYSTEM SUPPORT
include libc/nt/nt.mk # │ You can do math
include libc/intrin/intrin.mk # │ You can use the stack
include libc/linux/linux.mk # │ You can manipulate arrays
include third_party/compiler_rt/compiler_rt.mk # │ You can issue raw system calls
include libc/tinymath/tinymath.mk # │
include third_party/compiler_rt/compiler_rt.mk # │ You can manipulate arrays
include libc/tinymath/tinymath.mk # │ You can issue raw system calls
include libc/str/str.mk # │
include third_party/xed/xed.mk # │
include third_party/puff/puff.mk # │
@@ -129,7 +136,6 @@ include ape/ape.mk # │
include libc/fmt/fmt.mk # │
include libc/vga/vga.mk #─┘
include libc/calls/calls.mk #─┐
include third_party/getopt/getopt.mk # │
include libc/runtime/runtime.mk # ├──SYSTEMS RUNTIME
include libc/crt/crt.mk # │ You can issue system calls
include tool/hello/hello.mk # │
@@ -140,22 +146,21 @@ 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 libc/time/time.mk # │
include net/net.mk # │
include third_party/vqsort/vqsort.mk # │
include libc/log/log.mk # │
include third_party/ggml/ggml.mk # │
include third_party/getopt/getopt.mk # │
include third_party/bzip2/bzip2.mk # │
include dsp/core/core.mk # │
include third_party/musl/musl.mk # │
include libc/x/x.mk # │
include third_party/stb/stb.mk # │
include dsp/scale/scale.mk # │
include dsp/mpeg/mpeg.mk # │
include dsp/dsp.mk # │
include third_party/zlib/gz/gz.mk # │
include third_party/musl/musl.mk # │
include third_party/intel/intel.mk # │
include third_party/aarch64/aarch64.mk # │
include libc/libc.mk #─┘
@@ -164,6 +169,9 @@ include dsp/tty/tty.mk # ├──ONLINE RUNTIME
include libc/dns/dns.mk # │ You can communicate with the network
include net/http/http.mk # │
include third_party/mbedtls/mbedtls.mk # │
include third_party/libcxx/libcxx.mk # │
include third_party/ggml/ggml.mk # │
include third_party/radpajama/radpajama.mk # │
include net/https/https.mk # │
include third_party/regex/regex.mk #─┘
include third_party/tidy/tidy.mk
@@ -178,6 +186,7 @@ include third_party/maxmind/maxmind.mk
include net/finger/finger.mk
include third_party/double-conversion/test/test.mk
include third_party/lua/lua.mk
include third_party/zstd/zstd.mk
include third_party/tr/tr.mk
include third_party/sed/sed.mk
include third_party/awk/awk.mk
@@ -192,15 +201,15 @@ include third_party/mbedtls/test/test.mk
include third_party/quickjs/quickjs.mk
include third_party/lz4cli/lz4cli.mk
include third_party/zip/zip.mk
include third_party/xxhash/xxhash.mk
include third_party/unzip/unzip.mk
include tool/build/lib/buildlib.mk
include third_party/chibicc/chibicc.mk
include third_party/chibicc/test/test.mk
include third_party/python/python.mk
include tool/build/emucrt/emucrt.mk
include tool/build/emubin/emubin.mk
include tool/build/build.mk
include tool/curl/curl.mk
include tool/ape/ape.mk
include third_party/qemu/qemu.mk
include examples/examples.mk
include examples/pyapp/pyapp.mk
@@ -212,7 +221,6 @@ include tool/lambda/lambda.mk
include tool/plinko/lib/lib.mk
include tool/plinko/plinko.mk
include test/tool/plinko/test.mk
include tool/hash/hash.mk
include tool/net/net.mk
include tool/viz/viz.mk
include tool/tool.mk
@@ -273,14 +281,14 @@ tags: TAGS HTAGS
o/$(MODE)/.x:
@$(COMPILE) -AMKDIR -tT$@ $(MKDIR) $(@D)
o/$(MODE)/srcs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(SRCS),$(dir $(x))))
o/$(MODE)/srcs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(SRCS),$(dir $(x)))) $(SRCS)
$(file >$@,$(SRCS))
o/$(MODE)/hdrs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(HDRS) $(INCS),$(dir $(x))))
o/$(MODE)/hdrs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(HDRS) $(INCS),$(dir $(x)))) $(HDRS) $(INCS)
$(file >$@,$(HDRS) $(INCS))
o/$(MODE)/incs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(INCS) $(INCS),$(dir $(x))))
o/$(MODE)/incs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(INCS) $(INCS),$(dir $(x)))) $(INCS) $(INCS)
$(file >$@,$(INCS))
o/$(MODE)/depend: o/$(MODE)/.x o/$(MODE)/srcs.txt o/$(MODE)/hdrs.txt o/$(MODE)/incs.txt $(SRCS) $(HDRS) $(INCS)
@$(COMPILE) -AMKDEPS -L320 $(MKDEPS) -o $@ -r o/$(MODE)/ @o/$(MODE)/srcs.txt @o/$(MODE)/hdrs.txt @o/$(MODE)/incs.txt
$(COMPILE) -AMKDEPS -L320 $(MKDEPS) -o $@ -r o/$(MODE)/ @o/$(MODE)/srcs.txt @o/$(MODE)/hdrs.txt @o/$(MODE)/incs.txt
o/$(MODE)/srcs-old.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(SRCS),$(dir $(x))))
$(file >$@) $(foreach x,$(SRCS),$(file >>$@,$(x)))
@@ -293,7 +301,7 @@ TAGS: o/$(MODE)/srcs-old.txt $(SRCS) #o/$(MODE)/third_party/ctags/ctags.com
@o/$(MODE)/third_party/ctags/ctags.com $(TAGSFLAGS) -L $< -o $@
HTAGS: private .UNSANDBOXED = 1
HTAGS: o/$(MODE)/hdrs-old.txt $(HDRS) #o/$(MODE)/third_party/ctags/ctags.com
HTAGS: o/$(MODE)/hdrs-old.txt $(filter-out third_party/libcxx/%,$(HDRS)) #o/$(MODE)/third_party/ctags/ctags.com
@$(RM) $@
@build/htags o/$(MODE)/third_party/ctags/ctags.com -L $< -o $@
@@ -305,6 +313,7 @@ loc: o/$(MODE)/tool/build/summy.com
# PLEASE: MAINTAIN TOPOLOGICAL ORDER
# FROM HIGHEST LEVEL TO LOWEST LEVEL
COSMOPOLITAN_OBJECTS = \
TOOL_ARGS \
NET_HTTP \
LIBC_DNS \
LIBC_SOCK \
@@ -377,6 +386,7 @@ COSMOPOLITAN_HEADERS = \
LIBC_ZIPOS \
LIBC_VGA \
NET_HTTP \
TOOL_ARGS \
THIRD_PARTY_DLMALLOC \
THIRD_PARTY_GDTOA \
THIRD_PARTY_GETOPT \
@@ -392,7 +402,8 @@ o/cosmopolitan.h: \
$(foreach x,$(COSMOPOLITAN_HEADERS),$($(x)_HDRS)) \
$(foreach x,$(COSMOPOLITAN_HEADERS),$($(x)_INCS))
$(file >$(TMPDIR)/$(subst /,_,$@),libc/integral/normalize.inc $(foreach x,$(COSMOPOLITAN_HEADERS),$($(x)_HDRS)))
@$(COMPILE) -AROLLUP -T$@ o/$(MODE)/tool/build/rollup.com @$(TMPDIR)/$(subst /,_,$@) >$@
@$(ECHO) '#define COSMO' >$@
@$(COMPILE) -AROLLUP -T$@ o/$(MODE)/tool/build/rollup.com @$(TMPDIR)/$(subst /,_,$@) >>$@
o/cosmopolitan.html: private .UNSANDBOXED = 1
o/cosmopolitan.html: \
@@ -414,6 +425,7 @@ $(SRCS): \
libc/integral/lp64.inc
.PHONY: toolchain
ifeq ($(ARCH), x86_64)
toolchain: o/cosmopolitan.h \
o/$(MODE)/ape/public/ape.lds \
o/$(MODE)/libc/crt/crt.o \
@@ -421,7 +433,25 @@ toolchain: o/cosmopolitan.h \
o/$(MODE)/ape/ape-copy-self.o \
o/$(MODE)/ape/ape-no-modify-self.o \
o/$(MODE)/cosmopolitan.a \
o/$(MODE)/third_party/libcxx/libcxx.a
o/$(MODE)/third_party/libcxx/libcxx.a \
o/$(MODE)/tool/build/fixupobj.com \
o/$(MODE)/tool/build/zipcopy.com
else
toolchain: o/$(MODE)/ape/aarch64.lds \
o/$(MODE)/libc/crt/crt.o \
o/$(MODE)/cosmopolitan.a \
o/$(MODE)/third_party/libcxx/libcxx.a \
o/$(MODE)/tool/build/fixupobj.com \
o/$(MODE)/tool/build/zipcopy.com
endif
aarch64: private .INTERNET = true
aarch64: private .UNSANDBOXED = true
aarch64:
$(MAKE) m=aarch64
clean:
$(RM) -r o
# UNSPECIFIED PREREQUISITES TUTORIAL
#
+275 -104
View File
@@ -19,8 +19,243 @@ libc](https://justine.lol/cosmopolitan/index.html) website. We also have
## Getting Started
If you're doing your development work on Linux or BSD then you need just
five files to get started. Here's what you do on Linux:
It's recommended that Cosmopolitan be installed to `/opt/cosmo` and
`/opt/cosmos` on your computer. The first has the monorepo. The second
contains your non-monorepo artifacts.
```sh
sudo mkdir -p /opt
sudo chmod 1777 /opt
git clone https://github.com/jart/cosmopolitan /opt/cosmo
cd /opt/cosmo
make -j8 toolchain
ape/apeinstall.sh # optional
mkdir -p /opt/cosmos/bin
export PATH="/opt/cosmos/bin:$PATH"
echo 'PATH="/opt/cosmos/bin:$PATH"' >>~/.profile
sudo ln -sf /opt/cosmo/tool/scripts/cosmocc /opt/cosmos/bin/cosmocc
sudo ln -sf /opt/cosmo/tool/scripts/cosmoc++ /opt/cosmos/bin/cosmoc++
```
You've now successfully installed your very own cosmos. Now let's build
an example program, which demonstrates the crash reporting feature:
```c
// hello.c
#include <stdio.h>
#include <cosmo.h>
int main() {
ShowCrashReports();
printf("hello world\n");
__builtin_trap();
}
```
To compile the program, you can run the `cosmocc` command. It's
important to give it an output path that ends with `.com` so the output
format will be Actually Portable Executable. When this happens, a
concomitant debug binary is created automatically too.
```sh
cosmocc -o hello.com hello.c
./hello.com
./hello.com.dbg
```
You can use the `cosmocc` toolchain to build conventional open source
projects which use autotools. This strategy normally works:
```sh
export CC=cosmocc
export CXX=cosmoc++
./configure --prefix=/opt/cosmos
make -j
make install
```
The Cosmopolitan Libc runtime links some heavyweight troubleshooting
features by default, which are very useful for developers and admins.
Here's how you can log system calls:
```sh
./hello.com --strace
```
Here's how you can get a much more verbose log of function calls:
```sh
./hello.com --ftrace
```
If you want to cut out the bloat and instead make your executables as
tiny as possible, then the monorepo supports numerous build modes. You
can select one of the predefined ones by looking at
[build/config.mk](build/config.mk). One of the most popular modes is
`MODE=tiny`. It can be used with the `cosmocc` toolchain as follows:
```sh
cd /opt/cosmo
make -j8 MODE=tiny toolchain
```
Now that we have our toolchain, let's write a program that links less
surface area than the program above. The executable that this program
produces will run on platforms like Linux, Windows, MacOS, etc., even
though it's directly using POSIX APIs, which Cosmopolitan polyfills.
```c
// hello2.c
#include <unistd.h>
int main() {
write(1, "hello world\n", 12);
}
```
Now let's compile our tiny actually portable executable, which should be
on the order of 20kb in size.
```sh
export MODE=tiny
cosmocc -Os -o hello2.com hello2.c
./hello2.com
```
Let's say you only care about Linux and would rather have simpler tinier
binaries, similar to what Musl Libc would produce. In that case, try
using the `MODE=tinylinux` build mode, which can produce binaries more
on the order of 4kb.
```sh
export MODE=tinylinux
(cd /opt/cosmo; make -j8 toolchain)
cosmocc -Os -o hello2.com hello2.c
./hello2.com # <-- actually an ELF executable
```
## ARM
Cosmo supports cross-compiling binaries for machines with ARM
microprocessors. There are two options available for doing this.
The first option is to embed the [blink virtual
machine](https://github.com/jart/blink) by adding the following to the
top of your main.c file:
```c
__static_yoink("blink_linux_aarch64"); // for raspberry pi
__static_yoink("blink_xnu_aarch64"); // is apple silicon
```
The benefit is you'll have single file executables that'll run on both
x86_64 and arm64 platforms. The tradeoff is Blink's JIT is slower than
running natively, but tends to go fast enough, unless you're doing
scientific computing (e.g. running LLMs with
`o//third_party/ggml/llama.com`).
Therefore, the second option is to cross compile aarch64 executables,
by using build modes like the following:
```sh
make -j8 m=aarch64 o/aarch64/third_party/ggml/llama.com
make -j8 m=aarch64-tiny o/aarch64-tiny/third_party/ggml/llama.com
```
That'll produce ELF executables that run natively on two operating
systems: Linux Arm64 (e.g. Raspberry Pi) and MacOS Arm64 (i.e. Apple
Silicon), thus giving you full performance. The catch is you have to
compile these executables on an x86_64-linux machine. The second catch
is that MacOS needs a little bit of help understanding the ELF format.
To solve that, we provide a tiny APE loader you can use on M1 machines.
```sh
scp ape/ape-m1.c macintosh:
scp o/aarch64/third_party/ggml/llama.com macintosh:
ssh macintosh
xcode-install
cc -o ape ape-m1.c
sudo cp ape /usr/local/bin/ape
```
You can run your ELF AARCH64 executable on Apple Silicon as follows:
```sh
ape ./llama.com
```
## Source Builds
Cosmopolitan can be compiled from source on any Linux distro. First, you
need to download or clone the repository.
```sh
wget https://justine.lol/cosmopolitan/cosmopolitan.tar.gz
tar xf cosmopolitan.tar.gz # see releases page
cd cosmopolitan
```
This will build the entire repository and run all the tests:
```sh
build/bootstrap/make.com
o//examples/hello.com
find o -name \*.com | xargs ls -rShal | less
```
If you get an error running make.com then it's probably because you have
WINE installed to `binfmt_misc`. You can fix that by installing the the
APE loader as an interpreter. It'll improve build performance too!
```sh
ape/apeinstall.sh
```
Since the Cosmopolitan repository is very large, you might only want to
build a particular thing. Cosmopolitan's build config does a good job at
having minimal deterministic builds. For example, if you wanted to build
only hello.com then you could do that as follows:
```sh
build/bootstrap/make.com o//examples/hello.com
```
Sometimes it's desirable to build a subset of targets, without having to
list out each individual one. You can do that by asking make to build a
directory name. For example, if you wanted to build only the targets and
subtargets of the chibicc package including its tests, you would say:
```sh
build/bootstrap/make.com o//third_party/chibicc
o//third_party/chibicc/chibicc.com --help
```
Cosmopolitan provides a variety of build modes. For example, if you want
really tiny binaries (as small as 12kb in size) then you'd say:
```sh
build/bootstrap/make.com m=tiny
```
Here's some other build modes you can try:
```sh
build/bootstrap/make.com m=dbg # asan + ubsan + debug
build/bootstrap/make.com m=asan # production memory safety
build/bootstrap/make.com m=opt # -march=native optimizations
build/bootstrap/make.com m=rel # traditional release binaries
build/bootstrap/make.com m=optlinux # optimal linux-only performance
build/bootstrap/make.com m=fastbuild # build 28% faster w/o debugging
build/bootstrap/make.com m=tinylinux # tiniest linux-only 4kb binaries
```
For further details, see [//build/config.mk](build/config.mk).
## Cosmopolitan Amalgamation
Another way to use Cosmopolitan is via our amalgamated release, where
we've combined everything into a single static archive and a single
header file. If you're doing your development work on Linux or BSD then
you need just five files to get started. Here's what you do on Linux:
```sh
wget https://justine.lol/cosmopolitan/cosmopolitan-amalgamation-2.2.zip
@@ -29,6 +264,7 @@ printf 'main() { printf("hello world\\n"); }\n' >hello.c
gcc -g -Os -static -nostdlib -nostdinc -fno-pie -no-pie -mno-red-zone \
-fno-omit-frame-pointer -pg -mnop-mcount -mno-tls-direct-seg-refs -gdwarf-4 \
-o hello.com.dbg hello.c -fuse-ld=bfd -Wl,-T,ape.lds -Wl,--gc-sections \
-Wl,-z,common-page-size=0x1000 -Wl,-z,max-page-size=0x1000 \
-include cosmopolitan.h crt.o ape-no-modify-self.o cosmopolitan.a
objcopy -S -O binary hello.com.dbg hello.com
```
@@ -112,106 +348,6 @@ from 60kb in size to about 16kb. There's also a prebuilt amalgamation
online <https://justine.lol/cosmopolitan/cosmopolitan-tiny.zip> hosted
on our download page <https://justine.lol/cosmopolitan/download.html>.
### MacOS
If you're developing on MacOS you can install the GNU compiler
collection for x86_64-elf via homebrew:
```sh
brew install x86_64-elf-gcc
```
Then in the above scripts just replace `gcc` and `objcopy` with
`x86_64-elf-gcc` and `x86_64-elf-objcopy` to compile your APE binary.
### Windows
If you're developing on Windows then you need to download an
x86_64-pc-linux-gnu toolchain beforehand. See the [Compiling on
Windows](https://justine.lol/cosmopolitan/windows-compiling.html)
tutorial. It's needed because the ELF object format is what makes
universal binaries possible.
Cosmopolitan officially only builds on Linux. However, one highly
experimental (and currently broken) thing you could try, is building the
entire cosmo repository from source using the cross9 toolchain.
```
mkdir -p o/third_party
rm -rf o/third_party/gcc
wget https://justine.lol/linux-compiler-on-windows/cross9.zip
unzip cross9.zip
mv cross9 o/third_party/gcc
build/bootstrap/make.com
```
## Source Builds
Cosmopolitan can be compiled from source on any Linux distro. First, you
need to download or clone the repository.
```sh
wget https://justine.lol/cosmopolitan/cosmopolitan.tar.gz
tar xf cosmopolitan.tar.gz # see releases page
cd cosmopolitan
```
This will build the entire repository and run all the tests:
```sh
build/bootstrap/make.com
o//examples/hello.com
find o -name \*.com | xargs ls -rShal | less
```
If you get an error running make.com then it's probably because you have
WINE installed to `binfmt_misc`. You can fix that by installing the the
APE loader as an interpreter. It'll improve build performance too!
```sh
ape/apeinstall.sh
```
Since the Cosmopolitan repository is very large, you might only want to
build a particular thing. Cosmopolitan's build config does a good job at
having minimal deterministic builds. For example, if you wanted to build
only hello.com then you could do that as follows:
```sh
build/bootstrap/make.com o//examples/hello.com
```
Sometimes it's desirable to build a subset of targets, without having to
list out each individual one. You can do that by asking make to build a
directory name. For example, if you wanted to build only the targets and
subtargets of the chibicc package including its tests, you would say:
```sh
build/bootstrap/make.com o//third_party/chibicc
o//third_party/chibicc/chibicc.com --help
```
Cosmopolitan provides a variety of build modes. For example, if you want
really tiny binaries (as small as 12kb in size) then you'd say:
```sh
build/bootstrap/make.com m=tiny
```
Here's some other build modes you can try:
```sh
build/bootstrap/make.com m=dbg # asan + ubsan + debug
build/bootstrap/make.com m=asan # production memory safety
build/bootstrap/make.com m=opt # -march=native optimizations
build/bootstrap/make.com m=rel # traditional release binaries
build/bootstrap/make.com m=optlinux # optimal linux-only performance
build/bootstrap/make.com m=fastbuild # build 28% faster w/o debugging
build/bootstrap/make.com m=tinylinux # tiniest linux-only 4kb binaries
```
For further details, see [//build/config.mk](build/config.mk).
## GDB
Here's the recommended `~/.gdbinit` config:
@@ -239,10 +375,45 @@ src
You normally run the `.com.dbg` file under gdb. If you need to debug the
`.com` file itself, then you can load the debug symbols independently as
```
```sh
gdb foo.com -ex 'add-symbol-file foo.com.dbg 0x401000'
```
## Alternative Development Environments
### MacOS
If you're developing on MacOS you can install the GNU compiler
collection for x86_64-elf via homebrew:
```sh
brew install x86_64-elf-gcc
```
Then in the above scripts just replace `gcc` and `objcopy` with
`x86_64-elf-gcc` and `x86_64-elf-objcopy` to compile your APE binary.
### Windows
If you're developing on Windows then you need to download an
x86_64-pc-linux-gnu toolchain beforehand. See the [Compiling on
Windows](https://justine.lol/cosmopolitan/windows-compiling.html)
tutorial. It's needed because the ELF object format is what makes
universal binaries possible.
Cosmopolitan officially only builds on Linux. However, one highly
experimental (and currently broken) thing you could try, is building the
entire cosmo repository from source using the cross9 toolchain.
```sh
mkdir -p o/third_party
rm -rf o/third_party/gcc
wget https://justine.lol/linux-compiler-on-windows/cross9.zip
unzip cross9.zip
mv cross9 o/third_party/gcc
build/bootstrap/make.com
```
## Discord Chatroom
The Cosmopolitan development team collaborates on the Redbean Discord
@@ -257,7 +428,7 @@ server. You're welcome to join us! <https://discord.gg/FwAVVu7eJ4>
| Linux | 2.6.18 | 2007 |
| Windows | 8 [1] | 2012 |
| Mac OS X | 15.6 | 2018 |
| OpenBSD | 6.4 | 2018 |
| OpenBSD | 7 | 2021 |
| FreeBSD | 13 | 2020 |
| NetBSD | 9.2 | 2021 |
+290
View File
@@ -0,0 +1,290 @@
/*-*- mode: ld-script; indent-tabs-mode: nil; tab-width: 2; coding: utf-8 -*-│
│vi: set et sts=2 tw=2 fenc=utf-8 :vi│
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/thread/tls.h"
ENTRY(_start)
OUTPUT_ARCH(aarch64)
OUTPUT_FORMAT("elf64-littleaarch64",
"elf64-bigaarch64",
"elf64-littleaarch64")
SECTIONS {
. = SEGMENT_START("text-segment", IMAGE_BASE_VIRTUAL);
__executable_start = .;
. += SIZEOF_HEADERS;
.interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rela.init : { *(.rela.init) }
.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
.rela.fini : { *(.rela.fini) }
.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
.rela.data.rel.ro : { *(.rela.data.rel.ro .rela.data.rel.ro.* .rela.gnu.linkonce.d.rel.ro.*) }
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
.rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
.rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
.rela.ctors : { *(.rela.ctors) }
.rela.dtors : { *(.rela.dtors) }
.rela.got : { *(.rela.got) }
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
.rela.ifunc : { *(.rela.ifunc) }
.rela.plt : {
*(.rela.plt)
__rela_iplt_start = .;
*(.rela.iplt)
__rela_iplt_end = .;
}
.init : {
*(.start)
KEEP(*(.initprologue))
KEEP(*(SORT_NONE(.init)))
KEEP(*(.initepilogue))
} =0x1f2003d5
.plt : ALIGN(16) {
*(.plt)
*(.iplt)
}
.text : {
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.antiquity .text.antiquity.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(.text.modernity .text.modernity.*)
*(.text .stub .text.* .gnu.linkonce.t.*)
*(.gnu.warning)
} =0x1f2003d5
.fini : {
KEEP(*(SORT_NONE(.fini)))
} =0x1f2003d5
. += CONSTANT(COMMONPAGESIZE);
.privileged : {
__privileged_start = .;
*(.privileged*)
} =0x1f2003d6
.rodata : {
KEEP(*(.rodata.pytab.0));
KEEP(*(.rodata.pytab.1));
KEEP(*(.rodata.pytab.2));
KEEP(*(SORT_BY_NAME(.sort.rodata.*)))
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.ubsan.types)
*(.ubsan.data)
}
.comment : {
__comment_start = .;
KEEP(*(.comment))
BYTE(0);
}
.eh_frame_hdr : {
*(.eh_frame_hdr)
*(.eh_frame_entry .eh_frame_entry.*)
}
.eh_frame : ONLY_IF_RO {
KEEP(*(.eh_frame))
*(.eh_frame.*)
}
.gcc_except_table : ONLY_IF_RO {
*(.gcc_except_table .gcc_except_table.*)
}
.gnu_extab : ONLY_IF_RO {
*(.gnu_extab*)
}
.exception_ranges : ONLY_IF_RO {
*(.exception_ranges*)
}
__etext = .;
_etext = .;
PROVIDE(etext = .);
. += CONSTANT(COMMONPAGESIZE);
. = DATA_SEGMENT_ALIGN(CONSTANT(COMMONPAGESIZE), CONSTANT(COMMONPAGESIZE));
.eh_frame : ONLY_IF_RW {
KEEP(*(.eh_frame))
*(.eh_frame.*)
}
.gnu_extab : ONLY_IF_RW {
*(.gnu_extab)
}
.gcc_except_table : ONLY_IF_RW {
*(.gcc_except_table .gcc_except_table.*)
}
.exception_ranges : ONLY_IF_RW {
*(.exception_ranges*)
}
.tdata : {
_tdata_start = .;
__tdata_start = .;
*(.tdata .tdata.* .gnu.linkonce.td.*)
_tdata_end = .;
}
.tbss : {
_tbss_start = .;
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)
_tbss_end = .;
}
.init_array : {
__init_array_start = .;
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP(*(.init_array EXCLUDE_FILE(*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
__init_array_end = .;
}
.fini_array : {
__fini_array_start = .;
KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP(*(.fini_array EXCLUDE_FILE(*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
__fini_array_end = .;
}
.data.rel.ro : {
KEEP(*(SORT_BY_NAME(.piro.relo.sort.*)))
*(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*)
*(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*)
}
.dynamic : {
*(.dynamic)
}
.got : {
*(.got)
*(.igot)
}
. = DATA_SEGMENT_RELRO_END(24, .);
.got.plt : {
*(.got.plt)
*(.igot.plt)
}
.data : {
__data_start = .;
KEEP(*(SORT_BY_NAME(.piro.data.sort.*)))
*(.data .data.* .gnu.linkonce.d.*)
KEEP(*(SORT_BY_NAME(.sort.data.*)))
SORT(CONSTRUCTORS)
}
_edata = .;
PROVIDE(edata = .);
. = .;
__bss_start = .;
__bss_start__ = .;
.bss : {
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
KEEP(*(SORT_BY_NAME(.piro.bss.sort.*)))
*(COMMON)
. = ALIGN(CONSTANT(COMMONPAGESIZE));
}
_bss_end__ = .;
__bss_end__ = .;
. = ALIGN(64 / 8);
. = SEGMENT_START("ldata-segment", .);
. = ALIGN(64 / 8);
__end__ = .;
_end = .;
PROVIDE(end = .);
. = DATA_SEGMENT_END(.);
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
.debug_macro 0 : { *(.debug_macro) }
.debug_addr 0 : { *(.debug_addr) }
.ARM.attributes 0 : { KEEP(*(.ARM.attributes)) KEEP(*(.gnu.attributes)) }
.note.gnu.arm.ident 0 : { KEEP(*(.note.gnu.arm.ident)) }
.zip 0 : {
KEEP(*(.zip.file))
__zip_cdir_start = .;
KEEP(*(.zip.cdir))
__zip_cdir_size = . - __zip_cdir_start;
KEEP(*(.zip.eocd))
}
/DISCARD/ : {
*(__patchable_function_entries)
*(.GCC.command.line)
*(.note.GNU-stack)
*(.gnu_debuglink)
*(.text.windows)
*(.gnu.lto_*)
*(.eh_frame)
*(.idata.*)
*(.head)
}
}
ape_stack_memsz = DEFINED(ape_stack_memsz) ? ape_stack_memsz : APE_STACKSIZE;
ape_stack_memsz2 = ape_stack_memsz * 2;
_tls_size = _tbss_end - _tdata_start;
_tdata_size = _tdata_end - _tdata_start;
_tbss_size = _tbss_end - _tbss_start;
_tbss_offset = _tbss_start - _tdata_start;
_tls_content = (_tdata_end - _tdata_start) + (_tbss_end - _tbss_start);
_tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss));
ASSERT(ALIGNOF(.tdata) <= TLS_ALIGNMENT && ALIGNOF(.tbss) <= TLS_ALIGNMENT,
"_Thread_local _Alignof can't exceed TLS_ALIGNMENT");
+944
View File
@@ -0,0 +1,944 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2021 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 <dispatch/dispatch.h>
#include <errno.h>
#include <fcntl.h>
#include <libkern/OSCacheControl.h>
#include <limits.h>
#include <pthread.h>
#include <signal.h>
#include <stdarg.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/random.h>
#include <sys/uio.h>
#include <time.h>
#include <unistd.h>
#define pagesz 16384
#define SYSLIB_MAGIC ('s' | 'l' << 8 | 'i' << 16 | 'b' << 24)
#define SYSLIB_VERSION 1
struct Syslib {
int magic;
int version;
long (*fork)(void);
long (*pipe)(int[2]);
long (*clock_gettime)(int, struct timespec *);
long (*nanosleep)(const struct timespec *, struct timespec *);
long (*mmap)(void *, size_t, int, int, int, off_t);
int (*pthread_jit_write_protect_supported_np)(void);
void (*pthread_jit_write_protect_np)(int);
void (*sys_icache_invalidate)(void *, size_t);
int (*pthread_create)(pthread_t *, const pthread_attr_t *, void *(*)(void *),
void *);
void (*pthread_exit)(void *);
int (*pthread_kill)(pthread_t, int);
int (*pthread_sigmask)(int, const sigset_t *restrict, sigset_t *restrict);
int (*pthread_setname_np)(const char *);
dispatch_semaphore_t (*dispatch_semaphore_create)(long);
long (*dispatch_semaphore_signal)(dispatch_semaphore_t);
long (*dispatch_semaphore_wait)(dispatch_semaphore_t, dispatch_time_t);
dispatch_time_t (*dispatch_walltime)(const struct timespec *, int64_t);
};
#define ELFCLASS32 1
#define ELFDATA2LSB 1
#define EM_AARCH64 183
#define ET_EXEC 2
#define ET_DYN 3
#define PT_LOAD 1
#define PT_DYNAMIC 2
#define PT_INTERP 3
#define EI_CLASS 4
#define EI_DATA 5
#define PF_X 1
#define PF_W 2
#define PF_R 4
#define AT_PHDR 3
#define AT_PHENT 4
#define AT_PHNUM 5
#define AT_PAGESZ 6
#define AT_BASE 7
#define AT_ENTRY 9
#define AT_UID 11
#define AT_EUID 12
#define AT_GID 13
#define AT_EGID 14
#define AT_HWCAP 16
#define AT_HWCAP2 16
#define AT_SECURE 23
#define AT_RANDOM 25
#define AT_EXECFN 31
#define STACK_SIZE (8ul * 1024 * 1024)
#define STACK_ALIGN (sizeof(long) * 2)
#define AUXV_BYTES (sizeof(long) * 2 * 15)
// from the xnu codebase
#define _COMM_PAGE_START_ADDRESS 0x0000000FFFFFC000ul
#define _COMM_PAGE_APRR_SUPPORT (_COMM_PAGE_START_ADDRESS + 0x10C)
#define _COMM_PAGE_APRR_WRITE_ENABLE (_COMM_PAGE_START_ADDRESS + 0x110)
#define _COMM_PAGE_APRR_WRITE_DISABLE (_COMM_PAGE_START_ADDRESS + 0x118)
#define MIN(X, Y) ((Y) > (X) ? (X) : (Y))
#define MAX(X, Y) ((Y) < (X) ? (X) : (Y))
#define READ32(S) \
((unsigned)(255 & (S)[3]) << 030 | (unsigned)(255 & (S)[2]) << 020 | \
(unsigned)(255 & (S)[1]) << 010 | (unsigned)(255 & (S)[0]) << 000)
#define READ64(S) \
((unsigned long)(255 & (S)[7]) << 070 | \
(unsigned long)(255 & (S)[6]) << 060 | \
(unsigned long)(255 & (S)[5]) << 050 | \
(unsigned long)(255 & (S)[4]) << 040 | \
(unsigned long)(255 & (S)[3]) << 030 | \
(unsigned long)(255 & (S)[2]) << 020 | \
(unsigned long)(255 & (S)[1]) << 010 | \
(unsigned long)(255 & (S)[0]) << 000)
struct ElfEhdr {
unsigned char e_ident[16];
unsigned short e_type;
unsigned short e_machine;
unsigned e_version;
unsigned long e_entry;
unsigned long e_phoff;
unsigned long e_shoff;
unsigned e_flags;
unsigned short e_ehsize;
unsigned short e_phentsize;
unsigned short e_phnum;
unsigned short e_shentsize;
unsigned short e_shnum;
unsigned short e_shstrndx;
};
struct ElfPhdr {
unsigned p_type;
unsigned p_flags;
unsigned long p_offset;
unsigned long p_vaddr;
unsigned long p_paddr;
unsigned long p_filesz;
unsigned long p_memsz;
unsigned long p_align;
};
union ElfEhdrBuf {
struct ElfEhdr ehdr;
char buf[8192];
};
union ElfPhdrBuf {
struct ElfPhdr phdr;
char buf[4096];
};
struct PathSearcher {
unsigned long namelen;
const char *name;
const char *syspath;
char path[1024];
};
struct ApeLoader {
union ElfEhdrBuf ehdr;
struct PathSearcher ps;
// this memory shall be discarded by the guest
//////////////////////////////////////////////
// this memory shall be known to guest program
union {
char argblock[ARG_MAX];
long numblock[ARG_MAX / sizeof(long)];
};
union ElfPhdrBuf phdr;
struct Syslib lib;
char rando[16];
};
static int ToLower(int c) {
return 'A' <= c && c <= 'Z' ? c + ('a' - 'A') : c;
}
static unsigned long StrLen(const char *s) {
unsigned long n = 0;
while (*s++) ++n;
return n;
}
static int StrCmp(const char *l, const char *r) {
unsigned long i = 0;
while (l[i] == r[i] && r[i]) ++i;
return (l[i] & 255) - (r[i] & 255);
}
static const char *BaseName(const char *s) {
int c;
const char *b = "";
if (s) {
while ((c = *s++)) {
if (c == '/') {
b = s;
}
}
}
return b;
}
static void Bzero(void *a, unsigned long n) {
long z;
char *p, *e;
p = (char *)a;
e = p + n;
z = 0;
while (p + sizeof(z) <= e) {
__builtin_memcpy(p, &z, sizeof(z));
p += sizeof(z);
}
while (p < e) {
*p++ = 0;
}
}
static const char *MemChr(const char *s, unsigned char c, unsigned long n) {
for (; n; --n, ++s) {
if ((*s & 255) == c) {
return s;
}
}
return 0;
}
static void *MemMove(void *a, const void *b, unsigned long n) {
long w;
char *d;
const char *s;
unsigned long i;
d = (char *)a;
s = (const char *)b;
if (d > s) {
while (n >= sizeof(w)) {
n -= sizeof(w);
__builtin_memcpy(&w, s + n, sizeof(n));
__builtin_memcpy(d + n, &w, sizeof(n));
}
while (n--) {
d[n] = s[n];
}
} else {
i = 0;
while (i + sizeof(w) <= n) {
__builtin_memcpy(&w, s + i, sizeof(i));
__builtin_memcpy(d + i, &w, sizeof(i));
i += sizeof(w);
}
for (; i < n; ++i) {
d[i] = s[i];
}
}
return d;
}
static char *GetEnv(char **p, const char *s) {
unsigned long i, j;
if (p) {
for (i = 0; p[i]; ++i) {
for (j = 0;; ++j) {
if (!s[j]) {
if (p[i][j] == '=') {
return p[i] + j + 1;
}
break;
}
if (s[j] != p[i][j]) {
break;
}
}
}
}
return 0;
}
static char *Utoa(char p[21], unsigned long x) {
char t;
unsigned long i, a, b;
i = 0;
do {
p[i++] = x % 10 + '0';
x = x / 10;
} while (x > 0);
p[i] = '\0';
if (i) {
for (a = 0, b = i - 1; a < b; ++a, --b) {
t = p[a];
p[a] = p[b];
p[b] = t;
}
}
return p + i;
}
static char *Itoa(char p[21], long x) {
if (x < 0) *p++ = '-', x = -(unsigned long)x;
return Utoa(p, x);
}
static void Emit(const char *s) {
write(2, s, StrLen(s));
}
static long Print(int fd, const char *s, ...) {
int c;
unsigned n;
char b[512];
__builtin_va_list va;
__builtin_va_start(va, s);
for (n = 0; s; s = __builtin_va_arg(va, const char *)) {
while ((c = *s++)) {
if (n < sizeof(b)) {
b[n++] = c;
}
}
}
__builtin_va_end(va);
return write(fd, b, n);
}
static void Perror(const char *thing, long rc, const char *reason) {
char ibuf[21];
ibuf[0] = 0;
if (rc) Itoa(ibuf, -rc);
Print(2, "ape error: ", thing, ": ", reason, rc ? " failed w/ errno " : "",
ibuf, "\n", 0l);
}
__attribute__((__noreturn__)) static void Pexit(const char *c, int failed,
const char *s) {
Perror(c, failed, s);
_exit(127);
}
static char EndsWithIgnoreCase(const char *p, unsigned long n, const char *s) {
unsigned long i, m;
if (n >= (m = StrLen(s))) {
for (i = n - m; i < n; ++i) {
if (ToLower(p[i]) != *s++) {
return 0;
}
}
return 1;
} else {
return 0;
}
}
static char IsComPath(struct PathSearcher *ps) {
return EndsWithIgnoreCase(ps->name, ps->namelen, ".com") ||
EndsWithIgnoreCase(ps->name, ps->namelen, ".exe") ||
EndsWithIgnoreCase(ps->name, ps->namelen, ".com.dbg");
}
static char AccessCommand(struct PathSearcher *ps, const char *suffix,
unsigned long pathlen) {
unsigned long suffixlen;
suffixlen = StrLen(suffix);
if (pathlen + 1 + ps->namelen + suffixlen + 1 > sizeof(ps->path)) return 0;
if (pathlen && ps->path[pathlen - 1] != '/') ps->path[pathlen++] = '/';
MemMove(ps->path + pathlen, ps->name, ps->namelen);
MemMove(ps->path + pathlen + ps->namelen, suffix, suffixlen + 1);
return !access(ps->path, X_OK);
}
static char SearchPath(struct PathSearcher *ps, const char *suffix) {
const char *p;
unsigned long i;
for (p = ps->syspath;;) {
for (i = 0; p[i] && p[i] != ':'; ++i) {
if (i < sizeof(ps->path)) {
ps->path[i] = p[i];
}
}
if (AccessCommand(ps, suffix, i)) {
return 1;
} else if (p[i] == ':') {
p += i + 1;
} else {
return 0;
}
}
}
static char FindCommand(struct PathSearcher *ps, const char *suffix) {
if (MemChr(ps->name, '/', ps->namelen)) {
ps->path[0] = 0;
return AccessCommand(ps, suffix, 0);
}
return SearchPath(ps, suffix);
}
static char *Commandv(struct PathSearcher *ps, const char *name,
const char *syspath) {
ps->syspath = syspath ? syspath : "/bin:/usr/local/bin:/usr/bin";
if (!(ps->namelen = StrLen((ps->name = name)))) return 0;
if (ps->namelen + 1 > sizeof(ps->path)) return 0;
if (FindCommand(ps, "") || (!IsComPath(ps) && FindCommand(ps, ".com"))) {
return ps->path;
} else {
return 0;
}
}
static void pthread_jit_write_protect_np_workaround(int enabled) {
int count_start = 8192;
volatile int count = count_start;
unsigned long *addr, *other, val, val2, reread = -1;
addr = (unsigned long *)(!enabled ? _COMM_PAGE_APRR_WRITE_ENABLE
: _COMM_PAGE_APRR_WRITE_DISABLE);
other = (unsigned long *)(enabled ? _COMM_PAGE_APRR_WRITE_ENABLE
: _COMM_PAGE_APRR_WRITE_DISABLE);
switch (*(volatile unsigned char *)_COMM_PAGE_APRR_SUPPORT) {
case 1:
do {
val = *addr;
reread = -1;
asm volatile("msr\tS3_4_c15_c2_7,%0\n"
"isb\tsy\n"
: /* no outputs */
: "r"(val)
: "memory");
val2 = *addr;
asm volatile("mrs\t%0,S3_4_c15_c2_7\n"
: "=r"(reread)
: /* no inputs */
: "memory");
if (val2 == reread) {
return;
}
usleep(10);
} while (count-- > 0);
break;
case 3:
do {
val = *addr;
reread = -1;
asm volatile("msr\tS3_6_c15_c1_5,%0\n"
"isb\tsy\n"
: /* no outputs */
: "r"(val)
: "memory");
val2 = *addr;
asm volatile("mrs\t%0,S3_6_c15_c1_5\n"
: "=r"(reread)
: /* no inputs */
: "memory");
if (val2 == reread) {
return;
}
usleep(10);
} while (count-- > 0);
break;
default:
pthread_jit_write_protect_np(enabled);
return;
}
Pexit("ape", 0, "failed to set jit write protection");
}
__attribute__((__noreturn__)) static void Spawn(const char *exe, int fd,
long *sp, struct ElfEhdr *e,
struct ElfPhdr *p,
struct Syslib *lib) {
long rc;
int prot;
int flags;
int found_entry;
unsigned long dynbase;
unsigned long virtmin, virtmax;
unsigned long a, b, c, d, i, j;
/* validate elf */
found_entry = 0;
virtmin = virtmax = 0;
for (i = 0; i < e->e_phnum; ++i) {
if (p[i].p_type != PT_LOAD) {
continue;
}
if (p[i].p_filesz > p[i].p_memsz) {
Pexit(exe, 0, "ELF p_filesz exceeds p_memsz");
}
if ((p[i].p_flags & (PF_W | PF_X)) == (PF_W | PF_X)) {
Pexit(exe, 0, "Apple Silicon doesn't allow RWX memory");
}
if ((p[i].p_vaddr & (pagesz - 1)) != (p[i].p_offset & (pagesz - 1))) {
Pexit(exe, 0, "ELF p_vaddr incongruent w/ p_offset modulo 16384");
}
if (p[i].p_vaddr + p[i].p_memsz < p[i].p_vaddr ||
p[i].p_vaddr + p[i].p_memsz + (pagesz - 1) < p[i].p_vaddr) {
Pexit(exe, 0, "ELF p_vaddr + p_memsz overflow");
}
if (p[i].p_offset + p[i].p_filesz < p[i].p_offset ||
p[i].p_offset + p[i].p_filesz + (pagesz - 1) < p[i].p_offset) {
Pexit(exe, 0, "ELF p_offset + p_filesz overflow");
}
a = p[i].p_vaddr & -pagesz;
b = (p[i].p_vaddr + p[i].p_memsz + (pagesz - 1)) & -pagesz;
for (j = i + 1; j < e->e_phnum; ++j) {
if (p[j].p_type != PT_LOAD) continue;
c = p[j].p_vaddr & -pagesz;
d = (p[j].p_vaddr + p[j].p_memsz + (pagesz - 1)) & -pagesz;
if (MAX(a, c) < MIN(b, d)) {
Pexit(exe, 0, "ELF segments overlap each others virtual memory");
}
}
if (p[i].p_flags & PF_X) {
if (p[i].p_vaddr <= e->e_entry &&
e->e_entry < p[i].p_vaddr + p[i].p_memsz) {
found_entry = 1;
}
}
if (p[i].p_vaddr < virtmin) {
virtmin = p[i].p_vaddr;
}
if (p[i].p_vaddr + p[i].p_memsz > virtmax) {
virtmax = p[i].p_vaddr + p[i].p_memsz;
}
}
if (!found_entry) {
Pexit(exe, 0, "ELF entrypoint not found in PT_LOAD with PF_X");
}
/* choose loading address for dynamic elf executables
that maintains relative distances between segments */
if (e->e_type == ET_DYN) {
rc = (long)mmap(0, virtmax - virtmin, PROT_NONE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (rc < 0) Pexit(exe, rc, "pie mmap");
dynbase = rc;
if (dynbase & (pagesz - 1)) {
Pexit(exe, 0, "OS mmap incongruent w/ AT_PAGESZ");
}
if (dynbase + virtmin < dynbase) {
Pexit(exe, 0, "ELF dynamic base overflow");
}
} else {
dynbase = 0;
}
/* load elf */
for (i = 0; i < e->e_phnum; ++i) {
if (p[i].p_type != PT_LOAD) continue;
if (!p[i].p_memsz) continue;
/* configure mapping */
prot = 0;
flags = MAP_FIXED | MAP_PRIVATE;
if (p[i].p_flags & PF_R) prot |= PROT_READ;
if (p[i].p_flags & PF_W) prot |= PROT_WRITE;
if (p[i].p_flags & PF_X) prot |= PROT_EXEC;
/* load from file */
if (p[i].p_filesz) {
void *addr;
int prot1, prot2;
unsigned long size;
prot1 = prot;
prot2 = prot;
a = p[i].p_vaddr + p[i].p_filesz; /* end of file content */
b = (a + (pagesz - 1)) & -pagesz; /* first pure bss page */
c = p[i].p_vaddr + p[i].p_memsz; /* end of segment data */
if (b > c) b = c;
if (c > b && (~prot1 & PROT_WRITE)) {
prot1 = PROT_READ | PROT_WRITE;
}
addr = (void *)(dynbase + (p[i].p_vaddr & -pagesz));
size = (p[i].p_vaddr & (pagesz - 1)) + p[i].p_filesz;
rc = (long)mmap(addr, size, prot1, flags, fd, p[i].p_offset & -pagesz);
if (rc < 0) Pexit(exe, rc, "prog mmap");
if (c > b) Bzero((void *)(dynbase + a), b - a);
if (prot2 != prot1) {
rc = mprotect(addr, size, prot2);
if (rc < 0) Pexit(exe, rc, "prog mprotect");
}
}
/* allocate extra bss */
a = p[i].p_vaddr + p[i].p_filesz;
a = (a + (pagesz - 1)) & -pagesz;
b = p[i].p_vaddr + p[i].p_memsz;
if (b > a) {
flags |= MAP_ANONYMOUS;
rc = (long)mmap((void *)(dynbase + a), b - a, prot, flags, -1, 0);
if (rc < 0) Pexit(exe, rc, "bss mmap");
}
}
/* finish up */
close(fd);
register long *x0 asm("x0") = sp;
register struct Syslib *x15 asm("x15") = lib;
register long x16 asm("x16") = e->e_entry;
asm volatile("mov\tx1,#0\n\t"
"mov\tx2,#0\n\t"
"mov\tx3,#0\n\t"
"mov\tx4,#0\n\t"
"mov\tx5,#0\n\t"
"mov\tx6,#0\n\t"
"mov\tx7,#0\n\t"
"mov\tx8,#0\n\t"
"mov\tx9,#0\n\t"
"mov\tx10,#0\n\t"
"mov\tx11,#0\n\t"
"mov\tx12,#0\n\t"
"mov\tx13,#0\n\t"
"mov\tx14,#0\n\t"
"mov\tx17,#0\n\t"
"mov\tx19,#0\n\t"
"mov\tx20,#0\n\t"
"mov\tx21,#0\n\t"
"mov\tx22,#0\n\t"
"mov\tx23,#0\n\t"
"mov\tx24,#0\n\t"
"mov\tx25,#0\n\t"
"mov\tx26,#0\n\t"
"mov\tx27,#0\n\t"
"mov\tx28,#0\n\t"
"mov\tx29,#0\n\t"
"mov\tx30,#0\n\t"
"mov\tsp,x0\n\t"
"mov\tx0,#0\n\t"
"br\tx16"
: /* no outputs */
: "r"(x0), "r"(x15), "r"(x16)
: "memory");
__builtin_unreachable();
}
static const char *TryElf(struct ApeLoader *M, const char *exe, int fd,
long *sp, long *bp, char *execfn) {
long i, rc;
unsigned size;
struct ElfEhdr *e;
struct ElfPhdr *p;
/* validate elf header */
e = &M->ehdr.ehdr;
if (READ32(M->ehdr.buf) != READ32("\177ELF")) {
return "didn't embed ELF magic";
}
if (e->e_ident[EI_CLASS] == ELFCLASS32) {
return "32-bit ELF isn't supported";
}
if (e->e_type != ET_EXEC && e->e_type != ET_DYN) {
return "ELF not ET_EXEC or ET_DYN";
}
if (e->e_machine != EM_AARCH64) {
return "couldn't find ELF header with ARM64 machine type";
}
if (e->e_phentsize != sizeof(struct ElfPhdr)) {
Pexit(exe, 0, "e_phentsize is wrong");
}
size = e->e_phnum;
if ((size *= sizeof(struct ElfPhdr)) > sizeof(M->phdr.buf)) {
Pexit(exe, 0, "too many ELF program headers");
}
/* read program headers */
rc = pread(fd, M->phdr.buf, size, M->ehdr.ehdr.e_phoff);
if (rc < 0) return "failed to read ELF program headers";
if (rc != size) return "truncated read of ELF program headers";
/* bail on recoverable program header errors */
p = &M->phdr.phdr;
for (i = 0; i < e->e_phnum; ++i) {
if (p[i].p_type == PT_INTERP) {
return "ELF has PT_INTERP which isn't supported";
}
if (p[i].p_type == PT_DYNAMIC) {
return "ELF has PT_DYNAMIC which isn't supported";
}
}
/* remove empty program headers */
for (i = 0; i < e->e_phnum;) {
if (p[i].p_type == PT_LOAD && !p[i].p_memsz) {
if (i + 1 < e->e_phnum) {
MemMove(p + i, p + i + 1,
(e->e_phnum - (i + 1)) * sizeof(struct ElfPhdr));
}
--e->e_phnum;
} else {
++i;
}
}
/*
* merge adjacent loads that are contiguous with equal protection,
* which prevents our program header overlap check from needlessly
* failing later on; it also shaves away a microsecond of latency,
* since every program header requires invoking at least 1 syscall
*/
for (i = 0; i + 1 < e->e_phnum;) {
if (p[i].p_type == PT_LOAD && p[i + 1].p_type == PT_LOAD &&
((p[i].p_flags & (PF_R | PF_W | PF_X)) ==
(p[i + 1].p_flags & (PF_R | PF_W | PF_X))) &&
((p[i].p_offset + p[i].p_filesz + (pagesz - 1)) & -pagesz) -
(p[i + 1].p_offset & -pagesz) <=
pagesz &&
((p[i].p_vaddr + p[i].p_memsz + (pagesz - 1)) & -pagesz) -
(p[i + 1].p_vaddr & -pagesz) <=
pagesz) {
p[i].p_memsz = (p[i + 1].p_vaddr + p[i + 1].p_memsz) - p[i].p_vaddr;
p[i].p_filesz = (p[i + 1].p_offset + p[i + 1].p_filesz) - p[i].p_offset;
if (i + 2 < e->e_phnum) {
MemMove(p + i + 1, p + i + 2,
(e->e_phnum - (i + 2)) * sizeof(struct ElfPhdr));
}
--e->e_phnum;
} else {
++i;
}
}
/* simulate linux auxiliary values */
long auxv[][2] = {
{AT_PHDR, (long)&M->phdr.phdr}, //
{AT_PHENT, M->ehdr.ehdr.e_phentsize}, //
{AT_PHNUM, M->ehdr.ehdr.e_phnum}, //
{AT_ENTRY, M->ehdr.ehdr.e_entry}, //
{AT_PAGESZ, pagesz}, //
{AT_UID, getuid()}, //
{AT_EUID, geteuid()}, //
{AT_GID, getgid()}, //
{AT_EGID, getegid()}, //
{AT_HWCAP, 0xffb3ffffu}, //
{AT_HWCAP2, 0x181}, //
{AT_SECURE, issetugid()}, //
{AT_RANDOM, (long)M->rando}, //
{AT_EXECFN, (long)execfn}, //
{0, 0}, //
};
_Static_assert(sizeof(auxv) == AUXV_BYTES,
"Please update the AUXV_BYTES constant");
MemMove(bp, auxv, sizeof(auxv));
/* we're now ready to load */
Spawn(exe, fd, sp, e, p, &M->lib);
}
__attribute__((__noinline__)) static long sysret(long rc) {
return rc == -1 ? -errno : rc;
}
static long sys_fork(void) {
return sysret(fork());
}
static long sys_pipe(int pfds[2]) {
return sysret(pipe(pfds));
}
static long sys_clock_gettime(int clock, struct timespec *ts) {
return sysret(clock_gettime(clock, ts));
}
static long sys_nanosleep(const struct timespec *req, struct timespec *rem) {
return sysret(nanosleep(req, rem));
}
static long sys_mmap(void *addr, size_t size, int prot, int flags, int fd,
off_t off) {
return sysret((long)mmap(addr, size, prot, flags, fd, off));
}
int main(int argc, char **argv, char **envp) {
long z;
void *map;
long *sp, *bp, *ip;
int c, i, n, fd, rc;
struct ApeLoader *M;
unsigned char rando[24];
char *p, *pe, *tp, *exe, *prog, *execfn;
// generate some hard random data
if (getentropy(rando, sizeof(rando))) {
Pexit(argv[0], -1, "getentropy");
}
// make the stack look like a linux one
map = mmap((void *)(0x7f0000000000 | (long)rando[23] << 32), STACK_SIZE,
PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
if (map == MAP_FAILED) {
Pexit(argv[0], -1, "stack mmap");
}
// put argument block at top of allocated stack
z = (long)map;
z += STACK_SIZE - sizeof(struct ApeLoader);
z &= -_Alignof(struct ApeLoader);
M = (struct ApeLoader *)z;
// expose screwy apple libs
M->lib.magic = SYSLIB_MAGIC;
M->lib.version = SYSLIB_VERSION;
M->lib.fork = sys_fork;
M->lib.pipe = sys_pipe;
M->lib.clock_gettime = sys_clock_gettime;
M->lib.nanosleep = sys_nanosleep;
M->lib.mmap = sys_mmap;
M->lib.pthread_jit_write_protect_supported_np =
pthread_jit_write_protect_supported_np;
M->lib.pthread_jit_write_protect_np = pthread_jit_write_protect_np_workaround;
M->lib.pthread_create = pthread_create;
M->lib.pthread_exit = pthread_exit;
M->lib.pthread_kill = pthread_kill;
M->lib.pthread_sigmask = pthread_sigmask;
M->lib.pthread_setname_np = pthread_setname_np;
M->lib.dispatch_semaphore_create = dispatch_semaphore_create;
M->lib.dispatch_semaphore_signal = dispatch_semaphore_signal;
M->lib.dispatch_semaphore_wait = dispatch_semaphore_wait;
M->lib.dispatch_walltime = dispatch_walltime;
// copy system provided argument block
bp = M->numblock;
tp = M->argblock + sizeof(M->argblock);
*bp++ = argc;
for (i = 0; i < argc; ++i) {
tp -= (n = StrLen(argv[i]) + 1);
MemMove(tp, argv[i], n);
*bp++ = (long)tp;
}
*bp++ = 0;
for (i = 0; envp[i]; ++i) {
tp -= (n = StrLen(envp[i]) + 1);
MemMove(tp, envp[i], n);
*bp++ = (long)tp;
}
*bp++ = 0;
// get arguments that point into our block
sp = M->numblock;
argc = *sp;
argv = (char **)(sp + 1);
envp = (char **)(sp + 1 + argc + 1);
// xnu stores getauxval(at_execfn) in getenv("_")
execfn = argc > 0 ? argv[0] : 0;
for (i = 0; envp[i]; ++i) {
if (envp[i][0] == '_' && envp[i][1] == '=') {
execfn = envp[i] + 2;
break;
}
}
// interpret command line arguments
if (argc >= 3 && !StrCmp(argv[1], "-")) {
// if the first argument is a hyphen then we give the user the
// power to change argv[0] or omit it entirely. most operating
// systems don't permit the omission of argv[0] but we do, b/c
// it's specified by ANSI X3.159-1988.
prog = (char *)sp[3];
argc = sp[3] = sp[0] - 3;
argv = (char **)((sp += 3) + 1);
} else if (argc < 2) {
Emit("usage: ape PROG [ARGV1,ARGV2,...]\n"
" ape - PROG [ARGV0,ARGV1,...]\n"
"actually portable executable loader silicon 1.5\n"
"copyright 2023 justine alexandra roberts tunney\n"
"https://justine.lol/ape.html\n");
_exit(1);
} else {
prog = (char *)sp[2];
argc = sp[1] = sp[0] - 1;
argv = (char **)((sp += 1) + 1);
}
// search for executable
if (!(exe = Commandv(&M->ps, prog, GetEnv(envp, "PATH")))) {
Pexit(prog, 0, "not found (maybe chmod +x)");
} else if ((fd = openat(AT_FDCWD, exe, O_RDONLY)) < 0) {
Pexit(exe, -1, "open");
} else if ((rc = read(fd, M->ehdr.buf, sizeof(M->ehdr.buf))) < 0) {
Pexit(exe, -1, "read");
} else if ((unsigned long)rc < sizeof(M->ehdr.ehdr)) {
Pexit(exe, 0, "too small");
}
pe = M->ehdr.buf + rc;
// resolve argv[0] to reflect path search
if ((argc > 0 && *prog != '/' && *exe == '/' && !StrCmp(prog, argv[0])) ||
!StrCmp(BaseName(prog), argv[0])) {
tp -= (n = StrLen(exe) + 1);
MemMove(tp, exe, n);
argv[0] = tp;
}
// squeeze and align the argument block
ip = (long *)(((long)tp - AUXV_BYTES) & -sizeof(long));
ip -= (n = bp - sp);
ip = (long *)((long)ip & -STACK_ALIGN);
MemMove(ip, sp, n * sizeof(long));
bp = ip + n;
sp = ip;
// relocate the guest's random numbers
MemMove(M->rando, rando, sizeof(M->rando));
Bzero(rando, sizeof(rando));
// ape intended behavior
// 1. if file is an elf executable, it'll be used as-is
// 2. if ape, will scan shell script for elf printf statements
// 3. shell script may have multiple lines producing elf headers
// 4. all elf printf lines must exist in the first 8192 bytes of file
// 5. elf program headers may appear anywhere in the binary
if (READ64(M->ehdr.buf) == READ64("MZqFpD='") ||
READ64(M->ehdr.buf) == READ64("jartsr='") ||
READ64(M->ehdr.buf) == READ64("APEDBG='")) {
for (p = M->ehdr.buf; p < pe; ++p) {
if (READ64(p) != READ64("printf '")) {
continue;
}
for (i = 0, p += 8; p + 3 < pe && (c = *p++) != '\'';) {
if (c == '\\') {
if ('0' <= *p && *p <= '7') {
c = *p++ - '0';
if ('0' <= *p && *p <= '7') {
c *= 8;
c += *p++ - '0';
if ('0' <= *p && *p <= '7') {
c *= 8;
c += *p++ - '0';
}
}
}
}
M->ehdr.buf[i++] = c;
if (i >= sizeof(M->ehdr.buf)) {
break;
}
}
if (i >= sizeof(M->ehdr.ehdr)) {
TryElf(M, exe, fd, sp, bp, execfn);
}
}
}
Pexit(exe, 0, TryElf(M, exe, fd, sp, bp, execfn));
}
+159 -257
View File
@@ -43,6 +43,7 @@
#include "libc/nt/pedef.internal.h"
#include "libc/runtime/pc.internal.h"
#include "ape/ape.internal.h"
#include "libc/thread/tls.h"
#include "libc/sysv/consts/prot.h"
#define USE_SYMBOL_HACK 1
@@ -223,7 +224,7 @@ stub: mov $0x40,%dl // *literally* dos
3: .byte 0xbd,0,0 // a.k.a. mov imm,%bp
jmp pc // real mode, is real
jmp _start // surprise it's unix
.endfn stub
.endfn stub,globl
/*─────────────────────────────────────────────────────────────────────────────╗
│ αcτµαlly pδrταblε εxεcµταblε § ibm personal computer │
@@ -598,40 +599,40 @@ apesh: .ascii "\n@\n#'\"\n" // sixth edition shebang
// modify the binary to follow the local system's convention.
// There isn't a one-size-fits-all approach for this, thus we
// present two choices.
.ascii "o=\"$(command -v \"$0\")\"\n"
// Try to use a system-wide APE loader.
.ascii "[ x\"$1\" != x--assimilate ] && "
.ascii "type ape >/dev/null 2>&1 && "
.ascii "exec ape \"$o\" \"$@\"\n"
.ascii "o=\"$(command -v \"$0\")\"\n"
// Try to use system-wide APE loader.
.ascii "[ x\"$1\" != x--assimilate ] && "
.ascii "type ape >/dev/null 2>&1 && "
.ascii "exec ape \"$o\" \"$@\"\n"
#ifdef APE_LOADER
// There is no system-wide APE loader, but there is one
// embedded inside the APE. So if the system is not MacOs,
// extract the loader into a temp folder, and use it to
// load the APE without modifying it.
.ascii "[ x\"$1\" != x--assimilate ] && {\n"
.ascii "t=\"${TMPDIR:-${HOME:-.}}/.ape\"\n"
.ascii "[ -x \"$t\" ] || {\n"
.ascii "mkdir -p \"${t%/*}\" &&\n"
.ascii "dd if=\"$o\" of=\"$t.$$\" skip="
.shstub ape_loader_dd_skip,2
.ascii " count="
.shstub ape_loader_dd_count,2
.ascii " bs=64 2>/dev/null\n"
.ascii "[ x\"$1\" != x--assimilate ] && {\n"
.ascii "t=\"${TMPDIR:-${HOME:-.}}/.ape-1.5\"\n"
.ascii "[ -x \"$t\" ] || {\n"
.ascii "mkdir -p \"${t%/*}\" &&\n"
.ascii "dd if=\"$o\" of=\"$t.$$\" skip="
.shstub ape_loader_dd_skip,2
.ascii " count="
.shstub ape_loader_dd_count,2
.ascii " bs=64 2>/dev/null\n"
#if SupportsXnu()
.ascii "[ -d /Applications ] && "
.ascii "dd if=\"$t.$$\""
.ascii " of=\"$t.$$\""
.ascii " skip=6"
.ascii " count=10"
.ascii " bs=64"
.ascii " conv=notrunc"
.ascii " 2>/dev/null\n"
.ascii "[ -d /Applications ] && "
.ascii "dd if=\"$t.$$\""
.ascii " of=\"$t.$$\""
.ascii " skip=5"
.ascii " count=8"
.ascii " bs=64"
.ascii " conv=notrunc"
.ascii " 2>/dev/null\n"
#endif /* SupportsXnu() */
.ascii "chmod 755 \"$t.$$\"\n"
.ascii "mv -f \"$t.$$\" \"$t\"\n"
.ascii "chmod 755 \"$t.$$\"\n"
.ascii "mv -f \"$t.$$\" \"$t\"\n"
.ascii "}\n"
.ascii "exec \"$t\" \"$o\" \"$@\"\n"
.ascii "}\n"
.ascii "exec \"$t\" \"$o\" \"$@\"\n"
.ascii "}\n"
#endif /* APE_LOADER */
#ifndef APE_NO_MODIFY_SELF
// The default behavior is: to overwrite the header in place.
@@ -641,155 +642,91 @@ apesh: .ascii "\n@\n#'\"\n" // sixth edition shebang
// The alternative behavior is to copy to $TMPDIR or $HOME or
// the current directory. We like TMPDIR because it's part of
// the IEEE POSIX standard whereas alternatives (XDG) aren't.
.ascii "t=\"${TMPDIR:-${HOME:-.}}/$0\"\n"
.ascii "[ x\"$1\" != x--assimilate ] || [ ! -e \"$t\" ] && {\n"
.ascii "[ x\"$1\" != x--assimilate ] && {\n"
.ascii "mkdir -p \"${t%/*}\" 2>/dev/null\n"
.ascii "cp -f \"$o\" \"$t.$$\" &&\n"
.ascii "mv -f \"$t.$$\" \"$t\" || exit 120\n"
.ascii "o=\"$t\"\n"
.ascii "}\n"
.ascii "t=\"${TMPDIR:-${HOME:-.}}/$0\"\n"
.ascii "[ x\"$1\" != x--assimilate ] || [ ! -e \"$t\" ] && {\n"
.ascii "[ x\"$1\" != x--assimilate ] && {\n"
.ascii "mkdir -p \"${t%/*}\" 2>/dev/null\n"
.ascii "cp -f \"$o\" \"$t.$$\" &&\n"
.ascii "mv -f \"$t.$$\" \"$t\" || exit 120\n"
.ascii "o=\"$t\"\n"
.ascii "}\n"
#endif /* APE_NO_MODIFY_SELF */
.ascii "exec 7<> \"$o\" || exit 121\n"
.ascii "printf '"
.ascii "\\177ELF" // 0x0: ⌂ELF
.ascii "\\2" // 4: long mode
.ascii "\\1" // 5: little endian
.ascii "\\1" // 6: elf v1.o
.ascii "\\011" // 7: FreeBSD
.ascii "\\0" // 8: os/abi ver.
.ascii "\\0\\0\\0" // 9: padding 3/7
.ascii "\\0\\0\\0\\0" // padding 4/7
.ascii "\\2\\0" // 10: εxεcµταblε
.ascii "\\076\\0" // 12: NexGen32e
.ascii "\\1\\0\\0\\0" // 14: elf v1.o
.shstub ape_elf_entry,8 // 18: e_entry
.shstub ape_elf_phoff,8 // 20: e_phoff
.shstub ape_elf_shoff,8 // 28: e_shoff
.ascii "\\0\\0\\0\\0" // 30: e_flags
.ascii "\\100\\0" // 34: e_ehsize
.ascii "\\070\\0" // 36: e_phentsize
.shstub ape_elf_phnum,2 // 38: e_phnum
.ascii "\\0\\0" // 3a: e_shentsize
.shstub ape_elf_shnum,2 // 3c: e_shnum
.shstub ape_elf_shstrndx,2 // 3e: e_shstrndx
.ascii "' >&7\n"
.ascii "exec 7<&-\n"
.ascii "exec 7<> \"$o\" || exit 121\n"
.ascii "printf '"
.ascii "\\177ELF" // 0x0: ⌂ELF
.ascii "\\2" // 4: long mode
.ascii "\\1" // 5: little endian
.ascii "\\1" // 6: elf v1.o
.ascii "\\011" // 7: FreeBSD
.ascii "\\0" // 8: os/abi ver.
.ascii "\\0\\0\\0" // 9: padding 3/7
.ascii "\\0\\0\\0\\0" // padding 4/7
.ascii "\\2\\0" // 10: εxεcµταblε
.ascii "\\076\\0" // 12: NexGen32e
.ascii "\\1\\0\\0\\0" // 14: elf v1.o
.shstub ape_elf_entry,8 // 18: e_entry
.shstub ape_elf_phoff,8 // 20: e_phoff
.shstub ape_elf_shoff,8 // 28: e_shoff
.ascii "\\0\\0\\0\\0" // 30: e_flags
.ascii "\\100\\0" // 34: e_ehsize
.ascii "\\070\\0" // 36: e_phentsize
.shstub ape_elf_phnum,2 // 38: e_phnum
.ascii "\\0\\0" // 3a: e_shentsize
.shstub ape_elf_shnum,2 // 3c: e_shnum
.shstub ape_elf_shstrndx,2 // 3e: e_shstrndx
.ascii "' >&7\n"
.ascii "exec 7<&-\n"
#if SupportsXnu()
.ascii "[ -d /Applications ] && "
.ascii "dd if=\"$o\""
.ascii " of=\"$o\""
.ascii " bs=8"
.ascii " skip="
.shstub ape_macho_dd_skip,2
.ascii " count="
.shstub ape_macho_dd_count,2
.ascii " conv=notrunc 2>/dev/null\n"
.ascii "[ -d /Applications ] && "
.ascii "dd if=\"$o\""
.ascii " of=\"$o\""
.ascii " bs=8"
.ascii " skip="
.shstub ape_macho_dd_skip,2
.ascii " count="
.shstub ape_macho_dd_count,2
.ascii " conv=notrunc 2>/dev/null\n"
#endif /* XNU */
.ascii "[ x\"$1\" = x--assimilate ] && exit 0\n"
.ascii "[ x\"$1\" = x--assimilate ] && exit 0\n"
#ifndef APE_NO_MODIFY_SELF
.ascii "exec \"$0\" \"$@\"\n" // try to preserve argv[0]
.ascii "exec \"$0\" \"$@\"\n" // try to preserve argv[0]
#else
.ascii "}\n"
.ascii "o=\"$t\"\n"
.ascii "exec \"$o\" \"$@\"\n"
.ascii "}\n"
.ascii "o=\"$t\"\n"
.ascii "exec \"$o\" \"$@\"\n"
#endif /* APE_NO_MODIFY_SELF */
.ascii "exit $?\n"
.ascii "fi\n"
.ascii "exit $?\n"
.ascii "fi\n" // x86_64
// ...
// decentralized section (.apesh)
// ...
.ascii "PHDRS='' <<'@'\n"
.endobj apesh
#if !IsTiny()
// elf program headers get inserted here
// because they need to be in the first 4096 bytes
.section .emush,"a",@progbits
.section .emushprologue,"a",@progbits
emush: .ascii "\n@\n#'\"\n"
.ascii "s=\"$(uname -s)\"\n"
// our script is running on a non-x86_64 architecture
// 1. `dd` out the appropriate blink vm blob
// 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-0.9.2\"\n"
// Blink for Apple Silicon, e.g. M1 Macbook
.ascii "if [ \"$s\" = Darwin ] && [ \"$m\" = arm64 ]; then\n"
.ascii "if ! [ -x \"$e\" ]; then\n"
.ascii "echo \"extracting blink-darwin-arm64 to ${e}\" >&2\n"
.ascii "dd if=\"$o\" bs=1 skip=$(("
.byte blink_darwin_arm64_b9
.byte blink_darwin_arm64_b8
.byte blink_darwin_arm64_b7
.byte blink_darwin_arm64_b6
.byte blink_darwin_arm64_b5
.byte blink_darwin_arm64_b4
.byte blink_darwin_arm64_b3
.byte blink_darwin_arm64_b2
.byte blink_darwin_arm64_b1
.byte blink_darwin_arm64_b0
.ascii ")) count=$(("
.byte blink_darwin_arm64_size_b9
.byte blink_darwin_arm64_size_b8
.byte blink_darwin_arm64_size_b7
.byte blink_darwin_arm64_size_b6
.byte blink_darwin_arm64_size_b5
.byte blink_darwin_arm64_size_b4
.byte blink_darwin_arm64_size_b3
.byte blink_darwin_arm64_size_b2
.byte blink_darwin_arm64_size_b1
.byte blink_darwin_arm64_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 Aarch64 Linux, e.g. Raspberry Pi
.ascii "if [ \"$s\" = Linux ]; then\n"
.ascii "if [ \"$m\" = aarch64 ] || [ \"$m\" = arm64 ]; then\n"
.ascii "if ! [ -x \"$e\" ]; then\n"
.ascii "echo \"extracting blink-aarch64 to ${e}\" >&2\n"
.ascii "dd if=\"$o\" bs=1 skip=$(("
.byte blink_aarch64_b9
.byte blink_aarch64_b8
.byte blink_aarch64_b7
.byte blink_aarch64_b6
.byte blink_aarch64_b5
.byte blink_aarch64_b4
.byte blink_aarch64_b3
.byte blink_aarch64_b2
.byte blink_aarch64_b1
.byte blink_aarch64_b0
.ascii ")) count=$(("
.byte blink_aarch64_size_b9
.byte blink_aarch64_size_b8
.byte blink_aarch64_size_b7
.byte blink_aarch64_size_b6
.byte blink_aarch64_size_b5
.byte blink_aarch64_size_b4
.byte blink_aarch64_size_b3
.byte blink_aarch64_size_b2
.byte blink_aarch64_size_b1
.byte blink_aarch64_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"
.ascii "echo unsupported architecture >&2\n"
.ascii "e=\"${TMPDIR:-${HOME:-.}}/.ape-blink-1.0.0\"\n"
.previous
// ...
// decentralized section (.emush)
// - __static_yoink("blink_linux_aarch64"); // for raspberry pi
// - __static_yoink("blink_xnu_aarch64"); // is apple silicon
// ...
.section .emushepilogue,"a",@progbits
.ascii "echo \"$0: this ape binary lacks $m support\" >&2\n"
.rept 16
.ascii "exit 127\n"
.endr
.ascii "exit 1\n"
.endobj emush
#endif /* !IsTiny() */
.previous
#ifdef APE_LOADER
.section .ape.loader,"a",@progbits
@@ -810,6 +747,15 @@ ape_loader_end:
.long PT_LOAD
.long PF_R|PF_X
.stub ape_cod_offset,quad
.stub ape_cod_vaddr,quad
.stub ape_cod_paddr,quad
.stub ape_cod_filesz,quad
.stub ape_cod_memsz,quad
.stub ape_cod_align,quad
.long PT_LOAD
.long PF_R
.stub ape_rom_offset,quad
.stub ape_rom_vaddr,quad
.stub ape_rom_paddr,quad
@@ -848,24 +794,38 @@ ape_loader_end:
.stub ape_stack_vaddr,quad // is mmap()'d with MAP_FIXED
.stub ape_stack_paddr,quad // ignored
.stub ape_stack_filesz,quad // ignored
.stub ape_stack_memsz,quad // is mmap(size) argument
.stub ape_stack_memsz2,quad // is mmap(size) argument
.stub ape_stack_align,quad // must be 16+
#if SupportsOpenbsd() || SupportsNetbsd()
.long PT_NOTE
.long PF_R
.stub ape_note_offset,quad
.stub ape_note_vaddr,quad
.stub ape_note_paddr,quad
.quad 0
.quad 0
.stub ape_note_filesz,quad
.stub ape_note_memsz,quad
.stub ape_note_align,quad
.quad 4
#endif
.previous
#endif /* SupportsSystemv() || SupportsMetal() */
.section .note.ape.ident,"a",@progbits
.balign 4
ape.ident:
.long 2f-1f
.long 4f-3f
.long 1
1: .asciz "APE"
2: .balign 4
3: .long 105000000
4: .size ape.ident,.-ape.ident
.type ape.ident,@object
.previous
#if SupportsOpenbsd()
.section .note.openbsd.ident,"a",@progbits
.balign 4
openbsd.ident:
.long 2f-1f
.long 4f-3f
@@ -880,6 +840,7 @@ openbsd.ident:
#if SupportsNetbsd()
.section .note.netbsd.ident,"a",@progbits
.balign 4
netbsd.ident:
.long 2f-1f
.long 4f-3f
@@ -932,8 +893,8 @@ ape_macho:
.long MAC_CPU_NEXGEN32E
.long MAC_CPU_NEXGEN32E_ALL
.long MAC_EXECUTE
.long 5 // number of load commands
.long 60f-10f // size of all load commands
.long 6 // number of load commands
.long 70f-10f // size of all load commands
.long MAC_NOUNDEFS // flags
.long 0 // reserved
10: .long MAC_LC_SEGMENT_64
@@ -944,26 +905,27 @@ ape_macho:
20: .long MAC_LC_SEGMENT_64
.long 30f-20b
.ascin "__TEXT",16
.stub ape_cod_vaddr,quad
.stub ape_cod_memsz,quad
.stub ape_cod_offset,quad
.stub ape_cod_filesz,quad
.long PROT_EXEC|PROT_READ|PROT_WRITE // maxprot
.long PROT_EXEC|PROT_READ // initprot
.long 0 // segment section count
.long 0 // flags
30: .long MAC_LC_SEGMENT_64
.long 40f-30b
.ascin "__RODATA",16
.stub ape_rom_vaddr,quad
.stub ape_rom_memsz,quad
.stub ape_rom_offset,quad
.stub ape_rom_filesz,quad
.long PROT_EXEC|PROT_READ|PROT_WRITE // maxprot
.long PROT_EXEC|PROT_READ // initprot
.long 1 // segment section count
.long PROT_READ // initprot
.long 0 // segment section count
.long 0 // flags
210: .ascin "__text",16 // section name (.text)
.ascin "__TEXT",16
.stub ape_text_vaddr,quad
.stub ape_text_memsz,quad
.stub ape_text_offset,long
.long 12 // align 2**12 = 4096
.long 0 // reloc table offset
.long 0 // relocation count
.long MAC_S_ATTR_SOME_INSTRUCTIONS // section type & attributes
.long 0,0,0 // reserved
30: .long MAC_LC_SEGMENT_64
.long 40f-30b
40: .long MAC_LC_SEGMENT_64
.long 50f-40b
.ascin "__DATA",16
.stub ape_ram_vaddr,quad
.stub ape_ram_memsz,quad
@@ -971,39 +933,19 @@ ape_macho:
.stub ape_ram_filesz,quad
.long PROT_EXEC|PROT_READ|PROT_WRITE // maxprot
.long PROT_READ|PROT_WRITE // initprot
.long 2 // segment section count
.long 0 // segment section count
.long 0 // flags
310: .ascin "__data",16 // section name (.data)
.ascin "__DATA",16
.stub ape_data_vaddr,quad
.stub ape_data_memsz,quad
.stub ape_data_offset,long
.long 12 // align 2**12 = 4096
.long 0 // reloc table offset
.long 0 // relocation count
.long 0 // section type & attributes
.long 0,0,0 // reserved
320: .ascin "__bss",16 // section name (.bss)
.ascin "__DATA",16
.stub ape_bss_vaddr,quad // virtual address
.stub ape_bss_memsz,quad // memory size
.long 0 // file offset
.long 12 // align 2**12 = 4096
.long 0 // reloc table offset
.long 0 // relocation count
.long MAC_S_ZEROFILL // section type & attributes
.long 0,0,0 // reserved
40: .long MAC_LC_UUID
.long 50f-40b
50: .long MAC_LC_UUID
.long 60f-50b
.stub ape_uuid1,quad
.stub ape_uuid2,quad
50: .long MAC_LC_UNIXTHREAD
.long 60f-50b // cmdsize
60: .long MAC_LC_UNIXTHREAD
.long 70f-60b // cmdsize
.long MAC_THREAD_NEXGEN32E // flavaflav
.long (520f-510f)/4 // count
510: .quad 0 // rax
.quad IMAGE_BASE_VIRTUAL // rbx
.quad _HOSTXNU // rcx
.long (620f-610f)/4 // count
610: .quad 0 // rax
.quad 0 // rbx
.quad 0 // rcx
.quad 0 // rdx
.quad 0 // rdi
.quad 0 // rsi
@@ -1017,13 +959,13 @@ ape_macho:
.quad 0 // r13
.quad 0 // r14
.quad 0 // r15
.quad _start // rip
.quad _apple // rip
.quad 0 // rflags
.quad 0 // cs
.quad 0 // fs
.quad 0 // gs
520:
60:
620:
70:
.endobj ape_macho,globl,hidden
.previous /* .macho */
@@ -1125,8 +1067,8 @@ ape_pe: .ascin "PE",4
.long RVA(ape_pe_entry) // EntryPoint
.long 0 // BaseOfCode
.quad ape_pe_base // ImageBase
.long 4096 // SectionAlignment
.long 4096 // FileAlignment
.long ape_pe_sectionalignment // SectionAlignment
.long ape_pe_filealignment // FileAlignment
.short v_ntversion // MajorOperatingSystemVersion
.short 0 // MinorOperatingSystemVersion
.short 0 // MajorImageVersion
@@ -1135,7 +1077,7 @@ ape_pe: .ascin "PE",4
.short 0 // MinorSubsystemVersion
.long 0 // Win32VersionValue
.long RVA(_end) // SizeOfImage
.long RVA(_ehead) // SizeOfHeaders
.long ape_pe_sizeofheaders // SizeOfHeaders
.long 0 // Checksum
.short v_ntsubsystem // Subsystem: 0=Neutral,2=GUI,3=Console
.stub v_ntdllchar,short // DllCharacteristics
@@ -1144,25 +1086,10 @@ ape_pe: .ascin "PE",4
.quad 0 // HeapReserve
.quad 0 // HeapCommit
.long 0 // LoaderFlags
.long 16 // NumberOfDirectoryEntries
.long 2 // NumberOfDirectoryEntries
.long 0,0 // ExportsDirectory
.stub ape_idata,long // ImportsDirectory
.stub ape_idata_idtsize,long // ImportsDirectorySize
.long 0,0 // ResourcesDirectory
.long 0,0 // ExceptionsDirectory
.long 0,0 // SecurityDirectory
.long 0,0 // BaseRelocationTable
.long 0,0 // DebugDirectory
.long 0,0 // DescriptionString
.long 0,0 // MachineSpecific
.long 0,0 // ThreadLocalStorage
.long 0,0 // LoadConfigurationDirectory
.long 0,0 // BoundImportDirectory
.stub ape_idata,long // ImportAddressDirectory
.stub ape_idata_iatsize,long // ImportAddressDirectorySize
.long 0,0 // DelayImportDescriptor
.long 0,0 // ComPlusRuntimeHeader
.long 0,0 // Reserved
.endobj ape_pe,globl
.previous
@@ -1791,7 +1718,7 @@ ape_grub_entry:
│ αcτµαlly pδrταblε εxεcµταblε § cosmopolitan libc runtime runtime ─╬─│┼
╚────────────────────────────────────────────────────────────────────────────│*/
kernel: movabs $ape_stack_vaddr,%rsp
add $ape_stack_memsz,%rsp
add $ape_stack_memsz2,%rsp
movl $0,0x7b000 // unmap null 2mb
#if USE_SYMBOL_HACK
.byte 0x0f,0x1f,0207 // nop rdi binbase
@@ -1849,7 +1776,6 @@ kernel: movabs $ape_stack_vaddr,%rsp
.ldsvar v_ape_realbytes
.ldsvar v_ape_highsectors
.ldsvar ape_idata_ro
.ldsvar ape_pad_rodata
.ldsvar ape_piro
.ldsvar ape_piro_end
.type ape_macho_end,@object
@@ -1863,10 +1789,10 @@ kernel: movabs $ape_stack_vaddr,%rsp
.type __test_end,@object
.section .commentprologue,"a",@progbits
.globl kLegalNotices
.type kLegalNotices,@object
.hidden kLegalNotices
kLegalNotices:/*
.globl __comment_start
.type __comment_start,@object
.hidden __comment_start
__comment_start:/*
...
decentralized content
...
@@ -1893,12 +1819,6 @@ ape_pad_text:
ape_pad_privileged:
.previous
.section .ape.pad.rodata,"a",@progbits
.type ape_pad_rodata,@object
.hidden ape_pad_rodata
ape_pad_rodata:
.previous
.section .ape.pad.data,"a",@progbits
.type ape_pad_data,@object
.hidden ape_pad_data
@@ -1941,27 +1861,9 @@ __bss_start:
__bss_end:
.previous
#if !IsTiny()
#ifdef APE_IS_SHELL_SCRIPT
.section .blink,"a",@progbits
.globl blink_aarch64_size
blink_aarch64:
.incbin "ape/blink-aarch64.gz"
.endobj blink_aarch64,globl
blink_aarch64_size = . - blink_aarch64
.section .fstls,"awT",@nobits
.align TLS_ALIGNMENT
.previous
.section .blink,"a",@progbits
.globl blink_darwin_arm64_size
blink_darwin_arm64:
.incbin "ape/blink-darwin-arm64.gz"
.endobj blink_darwin_arm64,globl
blink_darwin_arm64_size = . - blink_darwin_arm64
.previous
#endif /* APE_IS_SHELL_SCRIPT */
#endif /* !IsTiny() */
.end

+197 -204
View File
@@ -182,7 +182,9 @@
#include "libc/nt/pedef.internal.h"
#include "libc/thread/tls.h"
#include "ape/ape.internal.h"
#include "libc/zip.h"
/* uncomment if .com.dbg won't execute on your kernel (will break .com file) */
/* #define APE_FIX_COM_DBG */
#ifdef __x86__
#define CODE_GRANULE 1
@@ -190,14 +192,24 @@
#define CODE_GRANULE 4
#endif
#ifdef APE_FIX_COM_DBG
#define SKEW SIZEOF_HEADERS
#else
#define SKEW 0
#endif
#if IMAGE_BASE_VIRTUAL > 0xffffffff
#error "please use 32-bit addresses for image data"
#endif
ENTRY(_start)
PHDRS {
Head PT_LOAD FLAGS(PF_X|PF_R);
Rom PT_LOAD FLAGS(PF_X|PF_R);
Ram PT_LOAD FLAGS(PF_W|PF_R);
Cod PT_LOAD FLAGS(PF_X|PF_R);
Rom PT_LOAD FLAGS(PF_R);
Tls PT_TLS FLAGS(PF_W|PF_R);
Bss PT_LOAD FLAGS(PF_W|PF_R);
Ram PT_LOAD FLAGS(PF_W|PF_R);
stack PT_GNU_STACK FLAGS(PF_W|PF_R);
}
@@ -208,44 +220,49 @@ SECTIONS {
/*BEGIN: linux addressability guarantee */
/*BEGIN: bsd addressability guarantee */
.head SEGMENT_START("text-segment", IMAGE_BASE_VIRTUAL) : AT(IMAGE_BASE_REAL) {
HIDDEN(_base = .);
.head SEGMENT_START("text-segment", IMAGE_BASE_VIRTUAL) + SKEW : AT(IMAGE_BASE_REAL) {
__executable_start = .;
/* Real Mode */
KEEP(*(.head))
KEEP(*(.apesh))
KEEP(*(.head2))
KEEP(*(.text.head))
/* Executable & Linkable Format */
. = ALIGN(__SIZEOF_POINTER__);
HIDDEN(ape_phdrs = .);
ape_phdrs = .;
KEEP(*(.elf.phdrs))
HIDDEN(ape_phdrs_end = .);
ape_phdrs_end = .;
KEEP(*(.emushprologue))
KEEP(*(.emush))
KEEP(*(.emushepilogue))
/* OpenBSD */
. = ALIGN(__SIZEOF_POINTER__);
HIDDEN(ape_note = .);
ape_note = .;
KEEP(*(.note.openbsd.ident))
KEEP(*(.note.netbsd.ident))
HIDDEN(ape_note_end = .);
ape_note_end = .;
/* Portable Executable */
KEEP(*(.pe.header))
HIDDEN(ape_pe_sections = .);
ape_pe_sections = .;
KEEP(*(.pe.sections))
HIDDEN(ape_pe_sections_end = .);
ape_pe_sections_end = .;
/* Mach-O */
KEEP(*(.macho))
. = ALIGN(__SIZEOF_POINTER__);
HIDDEN(ape_macho_end = .);
ape_macho_end = .;
/* APE loader */
KEEP(*(.ape.loader))
. = ALIGN(CODE_GRANULE);
KEEP(*(.ape.pad.head))
. = ALIGN(SupportsWindows() || SupportsMetal() ? PAGESIZE : 16);
HIDDEN(_ehead = .);
. = ALIGN(SupportsWindows() || SupportsMetal() ? CONSTANT(COMMONPAGESIZE) : 16);
_ehead = .;
} :Head
/*BEGIN: nt addressability guarantee */
@@ -255,10 +272,7 @@ SECTIONS {
/* Code that needs to be addressable in Real Mode */
*(.text.real)
KEEP(*(SORT_BY_NAME(.sort.text.real.*)))
/* Code we want earlier in the binary w/o modifications */
KEEP(*(.ape.loader))
. = ALIGN(CODE_GRANULE);
HIDDEN(_ereal = .);
_ereal = .;
/*END: realmode addressability guarantee */
/*BEGIN: morphable code */
. += CODE_GRANULE;
@@ -291,7 +305,6 @@ SECTIONS {
KEEP(*(.keep.text))
*(.text .stub .text.*)
KEEP(*(SORT_BY_NAME(.sort.text.*)))
*(.subrs)
KEEP(*(.ape.pad.test));
*(.test.unlikely)
@@ -299,16 +312,20 @@ SECTIONS {
/* Privileged code invulnerable to magic */
KEEP(*(.ape.pad.privileged));
. = ALIGN(__privileged_end > __privileged_start ? PAGESIZE : 1);
. = ALIGN(__privileged_end > __privileged_start ? CONSTANT(COMMONPAGESIZE) : 1);
/*END: morphable code */
HIDDEN(__privileged_start = .);
__privileged_start = .;
*(.privileged)
HIDDEN(__privileged_end = .);
. += . > 0 ? CODE_GRANULE : 0;
__privileged_end = .;
KEEP(*(.ape.pad.text))
. = ALIGN(CONSTANT(COMMONPAGESIZE));
/*END: Read Only Data (only needed for initialization) */
} :Cod
/*BEGIN: Read Only Data */
KEEP(*(.ape.pad.rodata));
.rodata . : {
KEEP(*(.rodata.pytab.0));
KEEP(*(.rodata.pytab.1));
KEEP(*(.rodata.pytab.2));
@@ -317,10 +334,6 @@ SECTIONS {
*(.ubsan.types)
*(.ubsan.data)
/* Unit Test & Fixture Registry */
/*BEGIN: Read only data that needn't be mapped after initialization */
/* Legal Notices */
#if !defined(IM_FEELING_NAUGHTY) || defined(EMBED_NOTICES)
KEEP(*(.commentprologue))
@@ -328,25 +341,30 @@ SECTIONS {
KEEP(*(.commentepilogue))
#endif
/*BEGIN: read-only data that's only needed for initialization */
#if SupportsWindows()
/* Windows DLL Import Directory */
KEEP(*(.idata.ro));
KEEP(*(SORT_BY_NAME(.idata.ro.*)))
#endif
. = ALIGN(__SIZEOF_POINTER__);
PROVIDE_HIDDEN(__init_array_start = .);
__init_array_start = .;
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*)
SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP(*(.ctors))
KEEP(*(.init_array))
KEEP(*(.preinit_array))
PROVIDE_HIDDEN(__init_array_end = .);
__init_array_end = .;
. = ALIGN(__SIZEOF_POINTER__);
PROVIDE_HIDDEN(__fini_array_start = .);
__fini_array_start = .;
KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*)
SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP(*(.fini_array))
KEEP(*(.dtors))
PROVIDE_HIDDEN(__fini_array_end = .);
__fini_array_end = .;
/* Encoded Data Structures w/ Linear Initialization Order */
KEEP(*(.initroprologue))
@@ -354,11 +372,8 @@ SECTIONS {
KEEP(*(.initroepilogue))
KEEP(*(SORT_BY_NAME(.sort.rodata.*)))
KEEP(*(.ape.pad.text))
. = ALIGN(PAGESIZE);
HIDDEN(_etext = .);
PROVIDE_HIDDEN(etext = .);
/*END: Read Only Data (only needed for initialization) */
/*END: read-only data that's only needed for initialization */
} :Rom
/* initialization image for thread-local storage, this is copied */
@@ -368,27 +383,37 @@ SECTIONS {
*(SORT_BY_ALIGNMENT(.tdata))
*(SORT_BY_ALIGNMENT(.tdata.*))
_tdata_end = .;
. = ALIGN(PAGESIZE);
KEEP(*(.ape.pad.rodata))
. = ALIGN(CONSTANT(COMMONPAGESIZE));
_etext = .;
PROVIDE(etext = .);
} :Tls :Rom
/*END: Read Only Data */
. = DATA_SEGMENT_ALIGN(CONSTANT(COMMONPAGESIZE), CONSTANT(COMMONPAGESIZE));
. = DATA_SEGMENT_RELRO_END(0, .);
/* this only tells the linker about the layout of uninitialized */
/* TLS data, and does not advance the linker's location counter */
.tbss . : {
.tbss : {
_tbss_start = .;
*(SORT_BY_ALIGNMENT(.tbss))
*(SORT_BY_ALIGNMENT(.tbss.*))
. = ALIGN(TLS_ALIGNMENT);
KEEP(*(.fstls))
/* the %fs register is based on this location */
_tbss_end = .;
} :Tls
.data ALIGN(PAGESIZE) : {
.data . : {
/*BEGIN: Read/Write Data */
#if SupportsWindows()
KEEP(*(SORT_BY_NAME(.piro.data.sort.iat.*)))
#endif
/*BEGIN: NT FORK COPYING */
KEEP(*(.dataprologue))
*(.data .data.*)
*(.PyRuntime) /* for python */
*(.subrs) /* for emacs */
KEEP(*(SORT_BY_NAME(.sort.data.*)))
. += . > 0 ? CODE_GRANULE : 0;
@@ -403,30 +428,28 @@ SECTIONS {
/*BEGIN: Post-Initialization Read-Only */
. = ALIGN(__SIZEOF_POINTER__);
KEEP(*(SORT_BY_NAME(.piro.relo.sort.*)))
PROVIDE_HIDDEN(__relo_end = .);
. = ALIGN(__SIZEOF_POINTER__);
KEEP(*(SORT_BY_NAME(.piro.data.sort.*)))
KEEP(*(.piro.pad.data))
KEEP(*(.dataepilogue))
. = ALIGN(512);
/*END: NT FORK COPYING */
HIDDEN(_edata = .);
PROVIDE_HIDDEN(edata = .);
KEEP(*(SORT_BY_NAME(.zip.*)))
HIDDEN(_ezip = .);
. = ALIGN(PAGESIZE);
_edata = .;
PROVIDE(edata = .);
_ezip = .; /* <-- very deprecated */
} :Ram
/*END: file content that's loaded by o/s */
/*END: file content */
/*BEGIN: bss memory that's addressable */
.bss ALIGN(64) : {
.bss : {
/*BEGIN: NT FORK COPYING */
KEEP(*(.bssprologue))
KEEP(*(SORT_BY_NAME(.piro.bss.init.*)))
*(.piro.bss)
KEEP(*(SORT_BY_NAME(.piro.bss.sort.*)))
HIDDEN(__piro_end = .);
__piro_end = .;
. += . > 0 ? CODE_GRANULE : 0;
/*END: Post-Initialization Read-Only */
@@ -438,11 +461,15 @@ SECTIONS {
KEEP(*(SORT_BY_NAME(.sort.bss.*)))
KEEP(*(.bssepilogue))
. = ALIGN(CONSTANT(COMMONPAGESIZE));
/*END: NT FORK COPYING */
. = ALIGN(PAGESIZE);
HIDDEN(_end = .);
PROVIDE_HIDDEN(end = .);
} :Bss
_end = .;
PROVIDE(end = .);
} :Ram
. = DATA_SEGMENT_END(.);
/*END: nt addressability guarantee */
/*END: bsd addressability guarantee */
@@ -485,14 +512,32 @@ SECTIONS {
.gnu.attributes 0 : { KEEP(*(.gnu.attributes)) }
.GCC.command.line 0 : { *(.GCC.command.line) }
.zip 0 : {
KEEP(*(.zip.file))
__zip_cdir_start = .;
KEEP(*(.zip.cdir))
__zip_cdir_size = . - __zip_cdir_start;
KEEP(*(.zip.eocd))
}
/DISCARD/ : {
#if !SupportsWindows()
*(.idata.ro);
*(.idata.ro.*)
*(.piro.data.sort.iat.*)
#endif
*(__patchable_function_entries)
*(__mcount_loc)
*(.discard)
*(.yoink)
*(.*)
}
}
ape_pe_filealignment = 512;
ape_pe_sectionalignment = 4096;
ape_pe_sizeofheaders = SIZEOF(.head);
ape_pe_sizeofimage = ROUNDUP(_end - __executable_start, ape_pe_sectionalignment);
PFSTUB8(ape_elf_entry, _start);
PFSTUB8(ape_elf_phoff, RVA(ape_phdrs));
PFSTUB8(ape_elf_shoff, 0);
@@ -500,70 +545,58 @@ PFSTUB4(ape_elf_phnum, (ape_phdrs_end - ape_phdrs) / 56);
PFSTUB4(ape_elf_shnum, 0);
PFSTUB4(ape_elf_shstrndx, 0);
HIDDEN(_tls_size = _tbss_end - _tdata_start);
HIDDEN(_tdata_size = _tdata_end - _tdata_start);
HIDDEN(_tbss_size = _tbss_end - _tbss_start);
HIDDEN(_tbss_offset = _tbss_start - _tdata_start);
HIDDEN(_tls_content = (_tdata_end - _tdata_start) + (_tbss_end - _tbss_start));
_tls_size = _tbss_end - _tdata_start;
_tdata_size = _tdata_end - _tdata_start;
_tbss_size = _tbss_end - _tbss_start;
_tbss_offset = _tbss_start - _tdata_start;
_tls_content = (_tdata_end - _tdata_start) + (_tbss_end - _tbss_start);
_tls_align = 1;
HIDDEN(__privileged_addr = ROUNDDOWN(__privileged_start, PAGESIZE));
HIDDEN(__privileged_size = (ROUNDUP(__privileged_end, PAGESIZE) -
ROUNDDOWN(__privileged_start, PAGESIZE)));
ape_cod_offset = 0;
ape_cod_vaddr = ADDR(.head);
ape_cod_paddr = LOADADDR(.head);
ape_cod_filesz = SIZEOF(.head) + SIZEOF(.text);
ape_cod_memsz = ape_cod_filesz;
ape_cod_align = CONSTANT(COMMONPAGESIZE);
ape_cod_rva = RVA(ape_cod_vaddr);
HIDDEN(ape_rom_offset = 0);
HIDDEN(ape_rom_vaddr = ADDR(.head));
HIDDEN(ape_rom_paddr = LOADADDR(.head));
HIDDEN(ape_rom_filesz = LOADADDR(.data) - ape_rom_paddr);
HIDDEN(ape_rom_memsz = ADDR(.data) - ADDR(.head));
HIDDEN(ape_rom_align = PAGESIZE);
HIDDEN(ape_rom_rva = RVA(ape_rom_vaddr));
ape_rom_offset = ape_cod_offset + ape_cod_filesz;
ape_rom_vaddr = ADDR(.rodata);
ape_rom_paddr = LOADADDR(.rodata);
ape_rom_filesz = SIZEOF(.rodata) + SIZEOF(.tdata);
ape_rom_memsz = ape_rom_filesz;
ape_rom_align = CONSTANT(COMMONPAGESIZE);
ape_rom_rva = RVA(ape_rom_vaddr);
HIDDEN(ape_ram_offset = ape_rom_offset + ape_rom_filesz);
HIDDEN(ape_ram_vaddr = ADDR(.data));
HIDDEN(ape_ram_paddr = LOADADDR(.data));
HIDDEN(ape_ram_filesz = SIZEOF(.data));
HIDDEN(ape_ram_memsz = ADDR(.bss) + SIZEOF(.bss) - ape_ram_vaddr);
HIDDEN(ape_ram_align = PAGESIZE);
HIDDEN(ape_ram_rva = RVA(ape_ram_vaddr));
ape_ram_offset = ape_rom_offset + ape_rom_filesz;
ape_ram_vaddr = ADDR(.data);
ape_ram_paddr = LOADADDR(.data);
ape_ram_filesz = SIZEOF(.data);
ape_ram_memsz = SIZEOF(.data) + SIZEOF(.bss);
ape_ram_align = CONSTANT(COMMONPAGESIZE);
ape_ram_rva = RVA(ape_ram_vaddr);
HIDDEN(ape_stack_pf = DEFINED(ape_stack_pf) ? ape_stack_pf : PF_R | PF_W);
HIDDEN(ape_stack_prot = _PF2PROT(ape_stack_pf));
HIDDEN(ape_stack_offset = ape_ram_offset + ape_ram_filesz);
HIDDEN(ape_stack_vaddr = DEFINED(ape_stack_vaddr) ? ape_stack_vaddr : 0x700000000000);
HIDDEN(ape_stack_paddr = ape_ram_paddr + ape_ram_filesz);
HIDDEN(ape_stack_filesz = 0);
HIDDEN(ape_stack_memsz = DEFINED(ape_stack_memsz) ? ape_stack_memsz : STACKSIZE);
HIDDEN(ape_stack_align = 16);
ape_stack_pf = DEFINED(ape_stack_pf) ? ape_stack_pf : PF_R | PF_W;
ape_stack_prot = _PF2PROT(ape_stack_pf);
ape_stack_offset = 0;
ape_stack_vaddr = DEFINED(ape_stack_vaddr) ? ape_stack_vaddr : 0x700000000000;
ape_stack_paddr = ape_ram_paddr + ape_ram_filesz;
ape_stack_filesz = 0;
ape_stack_memsz = DEFINED(ape_stack_memsz) ? ape_stack_memsz : APE_STACKSIZE;
ape_stack_memsz2 = ape_stack_memsz * 2;
ape_stack_align = 16;
HIDDEN(ape_note_offset = ape_rom_offset + (ape_note - ape_rom_vaddr));
HIDDEN(ape_note_vaddr = ape_note);
HIDDEN(ape_note_paddr = ape_rom_paddr + ape_note_offset);
HIDDEN(ape_note_filesz = ape_note_end - ape_note);
HIDDEN(ape_note_memsz = ape_note_filesz);
HIDDEN(ape_note_align = __SIZEOF_POINTER__);
ape_note_offset = ape_cod_offset + (ape_note - ape_cod_vaddr);
ape_note_filesz = ape_note_end - ape_note;
ape_note_memsz = ape_note_filesz;
HIDDEN(ape_text_offset = ape_rom_offset + LOADADDR(.text) - ape_rom_paddr);
HIDDEN(ape_text_paddr = LOADADDR(.text));
HIDDEN(ape_text_vaddr = ADDR(.text));
HIDDEN(ape_text_filesz = SIZEOF(.text) + SIZEOF(.tdata));
HIDDEN(ape_text_memsz = SIZEOF(.text) + SIZEOF(.tdata));
HIDDEN(ape_text_align = PAGESIZE);
HIDDEN(ape_text_rva = RVA(ape_text_vaddr));
HIDDEN(ape_data_offset = ape_ram_offset + LOADADDR(.data) - ape_ram_paddr);
HIDDEN(ape_data_paddr = LOADADDR(.data));
HIDDEN(ape_data_vaddr = ADDR(.data));
HIDDEN(ape_data_filesz = SIZEOF(.data));
HIDDEN(ape_data_memsz = SIZEOF(.data));
HIDDEN(ape_data_align = PAGESIZE);
HIDDEN(ape_data_rva = RVA(ape_data_vaddr));
HIDDEN(ape_bss_offset = ape_ram_offset + LOADADDR(.bss) - ape_ram_paddr);
HIDDEN(ape_bss_paddr = LOADADDR(.bss));
HIDDEN(ape_bss_vaddr = ADDR(.bss));
HIDDEN(ape_bss_filesz = 0);
HIDDEN(ape_bss_memsz = SIZEOF(.bss));
HIDDEN(ape_bss_align = PAGESIZE);
ape_text_offset = ape_cod_offset + LOADADDR(.text) - ape_cod_paddr;
ape_text_paddr = LOADADDR(.text);
ape_text_vaddr = ADDR(.text);
ape_text_filesz = SIZEOF(.text) + SIZEOF(.rodata) + SIZEOF(.tdata);
ape_text_memsz = ape_text_filesz;
ape_text_align = CONSTANT(COMMONPAGESIZE);
ape_text_rva = RVA(ape_text_vaddr);
/* we roundup here because xnu wants the file load segments page-aligned */
/* but we don't want to add the nop padding to the ape program, so we'll */
@@ -571,76 +604,42 @@ HIDDEN(ape_bss_align = PAGESIZE);
SHSTUB2(ape_loader_dd_skip, DEFINED(ape_loader) ? RVA(ape_loader) / 64 : 0);
SHSTUB2(ape_loader_dd_count,
DEFINED(ape_loader_end)
? ROUNDUP(ape_loader_end - ape_loader, PAGESIZE) / 64
? ROUNDUP(ape_loader_end - ape_loader, CONSTANT(COMMONPAGESIZE)) / 64
: 0);
#if defined(APE_IS_SHELL_SCRIPT) && !IsTiny()
HIDDEN(blink_aarch64_b0 = RVA(blink_aarch64) % 10 + 48);
HIDDEN(blink_aarch64_b1 = RVA(blink_aarch64) < 10 ? 32 : RVA(blink_aarch64) / 10 % 10 + 48);
HIDDEN(blink_aarch64_b2 = RVA(blink_aarch64) < 100 ? 32 : RVA(blink_aarch64) / 100 % 10 + 48);
HIDDEN(blink_aarch64_b3 = RVA(blink_aarch64) < 1000 ? 32 : RVA(blink_aarch64) / 1000 % 10 + 48);
HIDDEN(blink_aarch64_b4 = RVA(blink_aarch64) < 10000 ? 32 : RVA(blink_aarch64) / 10000 % 10 + 48);
HIDDEN(blink_aarch64_b5 = RVA(blink_aarch64) < 100000 ? 32 : RVA(blink_aarch64) / 100000 % 10 + 48);
HIDDEN(blink_aarch64_b6 = RVA(blink_aarch64) < 1000000 ? 32 : RVA(blink_aarch64) / 1000000 % 10 + 48);
HIDDEN(blink_aarch64_b7 = RVA(blink_aarch64) < 10000000 ? 32 : RVA(blink_aarch64) / 10000000 % 10 + 48);
HIDDEN(blink_aarch64_b8 = RVA(blink_aarch64) < 100000000 ? 32 : RVA(blink_aarch64) / 100000000 % 10 + 48);
HIDDEN(blink_aarch64_b9 = RVA(blink_aarch64) < 1000000000 ? 32 : RVA(blink_aarch64) / 1000000000 % 10 + 48);
#define IDENTITY(X) X
HIDDEN(blink_aarch64_size_b0 = blink_aarch64_size % 10 + 48);
HIDDEN(blink_aarch64_size_b1 = blink_aarch64_size < 10 ? 32 : blink_aarch64_size / 10 % 10 + 48);
HIDDEN(blink_aarch64_size_b2 = blink_aarch64_size < 100 ? 32 : blink_aarch64_size / 100 % 10 + 48);
HIDDEN(blink_aarch64_size_b3 = blink_aarch64_size < 1000 ? 32 : blink_aarch64_size / 1000 % 10 + 48);
HIDDEN(blink_aarch64_size_b4 = blink_aarch64_size < 10000 ? 32 : blink_aarch64_size / 10000 % 10 + 48);
HIDDEN(blink_aarch64_size_b5 = blink_aarch64_size < 100000 ? 32 : blink_aarch64_size / 100000 % 10 + 48);
HIDDEN(blink_aarch64_size_b6 = blink_aarch64_size < 1000000 ? 32 : blink_aarch64_size / 1000000 % 10 + 48);
HIDDEN(blink_aarch64_size_b7 = blink_aarch64_size < 10000000 ? 32 : blink_aarch64_size / 10000000 % 10 + 48);
HIDDEN(blink_aarch64_size_b8 = blink_aarch64_size < 100000000 ? 32 : blink_aarch64_size / 100000000 % 10 + 48);
HIDDEN(blink_aarch64_size_b9 = blink_aarch64_size < 1000000000 ? 32 : blink_aarch64_size / 1000000000 % 10 + 48);
#define APE_DECLARE_FIXED_DECIMAL(F, X) \
X##_quad = DEFINED(X) ? ((F(X) < 1000000000 ? 32 : F(X) / 1000000000 % 10 + 48) << 000 | \
(F(X) < 100000000 ? 32 : F(X) / 100000000 % 10 + 48) << 010 | \
(F(X) < 10000000 ? 32 : F(X) / 10000000 % 10 + 48) << 020 | \
(F(X) < 1000000 ? 32 : F(X) / 1000000 % 10 + 48) << 030 | \
(F(X) < 100000 ? 32 : F(X) / 100000 % 10 + 48) << 040 | \
(F(X) < 10000 ? 32 : F(X) / 10000 % 10 + 48) << 050 | \
(F(X) < 1000 ? 32 : F(X) / 1000 % 10 + 48) << 060 | \
(F(X) < 100 ? 32 : F(X) / 100 % 10 + 48) << 070) : 0; \
X##_short = DEFINED(X) ? ((F(X) < 10 ? 32 : F(X) / 10 % 10 + 48) << 000 | \
(F(X) % 10 + 48) << 010) : 0
HIDDEN(blink_darwin_arm64_b0 = RVA(blink_darwin_arm64) % 10 + 48);
HIDDEN(blink_darwin_arm64_b1 = RVA(blink_darwin_arm64) < 10 ? 32 : RVA(blink_darwin_arm64) / 10 % 10 + 48);
HIDDEN(blink_darwin_arm64_b2 = RVA(blink_darwin_arm64) < 100 ? 32 : RVA(blink_darwin_arm64) / 100 % 10 + 48);
HIDDEN(blink_darwin_arm64_b3 = RVA(blink_darwin_arm64) < 1000 ? 32 : RVA(blink_darwin_arm64) / 1000 % 10 + 48);
HIDDEN(blink_darwin_arm64_b4 = RVA(blink_darwin_arm64) < 10000 ? 32 : RVA(blink_darwin_arm64) / 10000 % 10 + 48);
HIDDEN(blink_darwin_arm64_b5 = RVA(blink_darwin_arm64) < 100000 ? 32 : RVA(blink_darwin_arm64) / 100000 % 10 + 48);
HIDDEN(blink_darwin_arm64_b6 = RVA(blink_darwin_arm64) < 1000000 ? 32 : RVA(blink_darwin_arm64) / 1000000 % 10 + 48);
HIDDEN(blink_darwin_arm64_b7 = RVA(blink_darwin_arm64) < 10000000 ? 32 : RVA(blink_darwin_arm64) / 10000000 % 10 + 48);
HIDDEN(blink_darwin_arm64_b8 = RVA(blink_darwin_arm64) < 100000000 ? 32 : RVA(blink_darwin_arm64) / 100000000 % 10 + 48);
HIDDEN(blink_darwin_arm64_b9 = RVA(blink_darwin_arm64) < 1000000000 ? 32 : RVA(blink_darwin_arm64) / 1000000000 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b0 = blink_darwin_arm64_size % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b1 = blink_darwin_arm64_size < 10 ? 32 : blink_darwin_arm64_size / 10 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b2 = blink_darwin_arm64_size < 100 ? 32 : blink_darwin_arm64_size / 100 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b3 = blink_darwin_arm64_size < 1000 ? 32 : blink_darwin_arm64_size / 1000 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b4 = blink_darwin_arm64_size < 10000 ? 32 : blink_darwin_arm64_size / 10000 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b5 = blink_darwin_arm64_size < 100000 ? 32 : blink_darwin_arm64_size / 100000 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b6 = blink_darwin_arm64_size < 1000000 ? 32 : blink_darwin_arm64_size / 1000000 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b7 = blink_darwin_arm64_size < 10000000 ? 32 : blink_darwin_arm64_size / 10000000 % 10 + 48);
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);
APE_DECLARE_FIXED_DECIMAL(RVA, blink_linux_aarch64);
APE_DECLARE_FIXED_DECIMAL(IDENTITY, blink_linux_aarch64_size);
APE_DECLARE_FIXED_DECIMAL(RVA, blink_xnu_aarch64);
APE_DECLARE_FIXED_DECIMAL(IDENTITY, blink_xnu_aarch64_size);
#endif /* APE_IS_SHELL_SCRIPT */
#if SupportsMetal()
HIDDEN(v_ape_realsectors =
MIN(0x70000 - IMAGE_BASE_REAL, ROUNDUP(RVA(_ezip), 512)) / 512);
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 = MIN(0xffff, v_ape_allsectors - v_ape_realsectors));
v_ape_realsectors = MIN(0x70000 - IMAGE_BASE_REAL, ROUNDUP(RVA(_ezip), 512)) / 512;
v_ape_realbytes = v_ape_realsectors * 512;
v_ape_realdwords = v_ape_realsectors * (512 / 4);
v_ape_allsectors = ROUNDUP(RVA(_ezip), 512) / 512;
v_ape_allbytes = v_ape_allsectors * 512;
v_ape_highsectors = MIN(0xffff, v_ape_allsectors - v_ape_realsectors);
TSSDESCSTUB2(_tss, _tss, _tss_end ? _tss_end - _tss - 1 : 0);
#endif
/* ZIP End of Central Directory header */
#define ZIPCONST(NAME, VAL) HIDDEN(NAME = DEFINED(__zip_start) ? VAL : 0);
ZIPCONST(v_zip_cdoffset, __zip_start - IMAGE_BASE_VIRTUAL);
ZIPCONST(v_zip_cdirsize, __zip_end - __zip_start);
ASSERT(v_zip_cdirsize % kZipCdirHdrLinkableSize == 0, "bad zip cdir");
ZIPCONST(v_zip_records, v_zip_cdirsize / kZipCdirHdrLinkableSize);
ZIPCONST(v_zip_commentsize, _ezip - __zip_end - kZipCdirHdrMinSize);
#if SupportsXnu()
/* Generates deterministic ID. */
#define PHI 0x9e3779b9925d4c17
@@ -659,19 +658,8 @@ ZIPCONST(v_zip_commentsize, _ezip - __zip_end - kZipCdirHdrMinSize);
KMH(ape_uuid1, X); \
XORSHIFT(ape_uuid2, X); \
KMH(ape_uuid2, X)
HIDDEN(ape_uuid1 = 88172645463325252);
HIDDEN(ape_uuid2 = 88172645463325252);
CHURN(ape_bss_align);
CHURN(ape_bss_filesz);
CHURN(ape_bss_memsz);
CHURN(ape_bss_offset);
CHURN(ape_bss_paddr);
CHURN(ape_data_filesz);
CHURN(ape_data_memsz);
CHURN(ape_data_offset);
CHURN(ape_data_paddr);
CHURN(ape_data_rva);
CHURN(ape_data_vaddr);
ape_uuid1 = 88172645463325252;
ape_uuid2 = 88172645463325252;
CHURN(ape_elf_entry);
CHURN(ape_elf_phnum);
CHURN(ape_elf_phoff);
@@ -680,13 +668,10 @@ CHURN(ape_elf_shoff);
CHURN(ape_elf_shstrndx);
CHURN(ape_macho_end);
CHURN(ape_note);
CHURN(ape_note_align);
CHURN(ape_note_end);
CHURN(ape_note_filesz);
CHURN(ape_note_memsz);
CHURN(ape_note_offset);
CHURN(ape_note_paddr);
CHURN(ape_note_vaddr);
CHURN(ape_ram_align);
CHURN(ape_ram_filesz);
CHURN(ape_ram_memsz);
@@ -700,7 +685,14 @@ CHURN(ape_rom_memsz);
CHURN(ape_rom_offset);
CHURN(ape_rom_paddr);
CHURN(ape_rom_rva);
CHURN(ape_rom_vaddr);
CHURN(ape_cod_vaddr);
CHURN(ape_cod_align);
CHURN(ape_cod_filesz);
CHURN(ape_cod_memsz);
CHURN(ape_cod_offset);
CHURN(ape_cod_paddr);
CHURN(ape_cod_rva);
CHURN(ape_cod_vaddr);
CHURN(ape_text_align);
CHURN(ape_text_filesz);
CHURN(ape_text_memsz);
@@ -733,22 +725,23 @@ CHURN(WinMain);
#if SupportsWindows() || SupportsMetal()
#define LINK_WINDOWS (SupportsWindows() && !DEFINED(EfiMain))
PFSTUB4(ape_pe_offset, ape_pe - ape_mz);
HIDDEN(ape_pe_optsz = ape_pe_sections - (ape_pe + 24));
HIDDEN(ape_pe_shnum = (ape_pe_sections_end - ape_pe_sections) / 40);
HIDDEN(ape_pe_base = IMAGE_BASE_VIRTUAL);
HIDDEN(ape_idata = LINK_WINDOWS ? RVA(ape_idata_iat) : 0);
HIDDEN(ape_idata_iatsize = LINK_WINDOWS ? ape_idata_iatend - ape_idata_iat : 0);
HIDDEN(ape_idata = LINK_WINDOWS ? RVA(ape_idata_idt) : 0);
HIDDEN(ape_idata_idtsize = LINK_WINDOWS ? ape_idata_idtend - ape_idata_idt : 0);
HIDDEN(v_ntversion = LINK_WINDOWS ? 6 : 1);
HIDDEN(v_ntdllchar = LINK_WINDOWS ? 288 : 0);
HIDDEN(v_ntsubversion = LINK_WINDOWS ? 6 : 5);
HIDDEN(v_ntsubsystem = (LINK_WINDOWS
? (DEFINED(GetMessage)
? kNtImageSubsystemWindowsGui
: kNtImageSubsystemWindowsCui)
: kNtImageSubsystemEfiApplication));
HIDDEN(ape_pe_entry = LINK_WINDOWS ? WinMain : EfiMain);
ape_pe_optsz = ape_pe_sections - (ape_pe + 24);
ASSERT(ape_pe_optsz % 8 == 0, "SizeOfOptionalHeader must be multiple of 8");
ape_pe_shnum = (ape_pe_sections_end - ape_pe_sections) / 40;
ape_pe_base = IMAGE_BASE_VIRTUAL;
ape_idataz = LINK_WINDOWS ? RVA(ape_idata_iat) : 0;
ape_idata_iatsize = LINK_WINDOWS ? ape_idata_iatend - ape_idata_iat : 0;
ape_idata = LINK_WINDOWS ? RVA(ape_idata_idt) : 0;
ape_idata_idtsize = LINK_WINDOWS ? ape_idata_idtend - ape_idata_idt : 0;
v_ntversion = LINK_WINDOWS ? 6 : 1;
v_ntdllchar = LINK_WINDOWS ? 288 : 0;
v_ntsubversion = LINK_WINDOWS ? 6 : 5;
v_ntsubsystem = (LINK_WINDOWS
? (DEFINED(GetMessage)
? kNtImageSubsystemWindowsGui
: kNtImageSubsystemWindowsCui)
: kNtImageSubsystemEfiApplication);
ape_pe_entry = LINK_WINDOWS ? WinMain : EfiMain;
#endif
#if SupportsXnu()
+127 -43
View File
@@ -19,6 +19,89 @@ APE_FILES := $(wildcard ape/*.*)
APE_HDRS = $(filter %.h,$(APE_FILES))
APE_INCS = $(filter %.inc,$(APE_FILES))
ifeq ($(ARCH), aarch64)
APE = o/$(MODE)/ape/aarch64.lds
APELINK = \
$(COMPILE) \
-ALINK.ape \
$(LINK) \
$(LINKARGS) \
$(OUTPUT_OPTION) && \
$(COMPILE) \
-AFIXUP.ape \
-wT$@ \
$(FIXUPOBJ) \
$@
APE_SRCS = ape/ape.S ape/start.S ape/launch.S ape/systemcall.S
APE_OBJS = o/$(MODE)/ape/ape.o
APE_NO_MODIFY_SELF = $(APE)
APE_COPY_SELF = $(APE)
.PHONY: o/$(MODE)/ape
o/$(MODE)/ape: $(APE)
o/$(MODE)/ape/aarch64.lds: \
ape/aarch64.lds \
libc/zip.internal.h \
libc/intrin/bits.h \
libc/thread/tls.h \
libc/calls/struct/timespec.h \
libc/macros.internal.h \
libc/str/str.h
APE_LOADER_LDFLAGS = \
-pie \
-static \
-nostdlib \
--no-dynamic-linker \
-z norelro \
-z common-page-size=0x4000 \
-z max-page-size=0x4000
APE_LOADER_FLAGS = \
-DNDEBUG \
-iquote. \
-Wall \
-Wextra \
-fpie \
-Os \
-ffreestanding \
-mgeneral-regs-only \
-fno-asynchronous-unwind-tables \
-fno-stack-protector \
-fno-ident \
-fno-gnu-unique \
-c \
$(OUTPUT_OPTION) \
$<
o/$(MODE)/ape/ape.elf: o/$(MODE)/ape/ape.elf.dbg
$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -g $< $@
o/$(MODE)/ape/ape.elf.dbg: \
o/$(MODE)/ape/start.o \
o/$(MODE)/ape/loader.o \
o/$(MODE)/ape/launch.o \
o/$(MODE)/ape/systemcall.o
@$(COMPILE) -ALINK.elf $(LD) $(APE_LOADER_LDFLAGS) -o $@ $(patsubst %.lds,-T %.lds,$^)
o/$(MODE)/ape/loader.o: ape/loader.c
@$(COMPILE) -AOBJECTIFY.c $(CC) -DSUPPORT_VECTOR=1 -g $(APE_LOADER_FLAGS)
o/$(MODE)/ape/start.o: ape/start.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/ape/launch.o: ape/launch.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/ape/systemcall.o: ape/systemcall.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
.PHONY: o/$(MODE)/ape
o/$(MODE)/ape: o/$(MODE)/ape/ape.elf
else
APE = o/$(MODE)/ape/ape.o \
o/$(MODE)/ape/ape.lds
@@ -27,19 +110,12 @@ APELINK = \
-ALINK.ape \
$(LINK) \
$(LINKARGS) \
$(OUTPUT_OPTION)
ifeq ($(ARCH), aarch64)
APE_SRCS = ape/ape.S
APE_OBJS = o/$(MODE)/ape/ape.o
APE_NO_MODIFY_SELF = $(APE)
APE_COPY_SELF = $(APE)
.PHONY: o/$(MODE)/ape
o/$(MODE)/ape: $(APE)
else
$(OUTPUT_OPTION) && \
$(COMPILE) \
-AFIXUP.ape \
-wT$@ \
$(FIXUPOBJ) \
$@
APE_NO_MODIFY_SELF = \
o/$(MODE)/ape/ape.lds \
@@ -58,7 +134,7 @@ APE_LOADER_FLAGS = \
-Os \
-ffreestanding \
-mgeneral-regs-only \
-mno-red-zone \
-fno-stack-protector \
-fno-ident \
-fno-gnu-unique \
-c \
@@ -71,7 +147,7 @@ APE_SRCS = $(APE_SRCS_C) $(APE_SRCS_S)
APE_OBJS = $(APE_SRCS_S:%.S=o/$(MODE)/%.o)
APE_CHECKS = $(APE_HDRS:%=o/%.ok)
o/$(MODE)/ape/public/ape.lds: OVERRIDE_CPPFLAGS += -UCOSMO
o/$(MODE)/ape/public/ape.lds: CPPFLAGS += -UCOSMO
o/$(MODE)/ape/public/ape.lds: \
ape/public/ape.lds \
ape/ape.lds \
@@ -88,7 +164,7 @@ o/$(MODE)/ape/public/ape.lds: \
libc/macros.internal.h \
libc/nt/pedef.internal.h \
libc/str/str.h \
libc/zip.h
libc/zip.internal.h
o/ape/idata.inc: \
ape/idata.internal.h \
@@ -102,6 +178,7 @@ o/$(MODE)/ape/ape-no-modify-self.o: \
ape/ape.internal.h \
libc/dce.h \
libc/elf/def.h \
libc/thread/tls.h \
libc/intrin/asancodes.h \
libc/macho.internal.h \
libc/macros.internal.h \
@@ -112,10 +189,9 @@ o/$(MODE)/ape/ape-no-modify-self.o: \
libc/runtime/e820.internal.h \
libc/runtime/mman.internal.h \
libc/runtime/pc.internal.h \
libc/runtime/symbolic.h \
libc/sysv/consts/prot.h \
ape/blink-aarch64.gz \
ape/blink-darwin-arm64.gz \
ape/blink-linux-aarch64.gz \
ape/blink-xnu-aarch64.gz \
o/$(MODE)/ape/ape.elf
@$(COMPILE) \
-AOBJECTIFY.S \
@@ -132,6 +208,7 @@ o/$(MODE)/ape/ape-copy-self.o: \
ape/ape.internal.h \
libc/dce.h \
libc/elf/def.h \
libc/thread/tls.h \
libc/intrin/asancodes.h \
libc/macho.internal.h \
libc/macros.internal.h \
@@ -142,44 +219,51 @@ o/$(MODE)/ape/ape-copy-self.o: \
libc/runtime/e820.internal.h \
libc/runtime/mman.internal.h \
libc/runtime/pc.internal.h \
libc/runtime/symbolic.h \
libc/sysv/consts/prot.h \
ape/blink-aarch64.gz \
ape/blink-darwin-arm64.gz
ape/blink-linux-aarch64.gz \
ape/blink-xnu-aarch64.gz
@$(COMPILE) \
-AOBJECTIFY.S \
$(OBJECTIFY.S) \
$(OUTPUT_OPTION) \
-DAPE_NO_MODIFY_SELF $<
o/$(MODE)/ape/loader.o: ape/loader.c ape/loader.h
@$(COMPILE) -AOBJECTIFY.c $(CC) -DSUPPORT_VECTOR=0b01111001 -g $(APE_LOADER_FLAGS)
o/$(MODE)/ape/loader.o: ape/loader.c
@$(COMPILE) -AOBJECTIFY.c $(CC) -DSUPPORT_VECTOR=121 -g $(APE_LOADER_FLAGS)
o/$(MODE)/ape/loader-gcc.asm: ape/loader.c
@$(COMPILE) -AOBJECTIFY.c $(CC) -DSUPPORT_VECTOR=0b01111001 -S -g0 $(APE_LOADER_FLAGS)
@$(COMPILE) -AOBJECTIFY.c $(CC) -DSUPPORT_VECTOR=121 -S -g0 $(APE_LOADER_FLAGS)
o/$(MODE)/ape/loader-clang.asm: ape/loader.c
@$(COMPILE) -AOBJECTIFY.c $(CLANG) -DSUPPORT_VECTOR=0b01111001 -S -g0 $(APE_LOADER_FLAGS)
@$(COMPILE) -AOBJECTIFY.c $(CLANG) -DSUPPORT_VECTOR=121 -S -g0 $(APE_LOADER_FLAGS)
o/$(MODE)/ape/loader-xnu.o: ape/loader.c ape/loader.h
@$(COMPILE) -AOBJECTIFY.c $(CC) -DSUPPORT_VECTOR=0b00001000 -g $(APE_LOADER_FLAGS)
o/$(MODE)/ape/loader-xnu.o: ape/loader.c
@$(COMPILE) -AOBJECTIFY.c $(CC) -DSUPPORT_VECTOR=8 -g $(APE_LOADER_FLAGS)
o/$(MODE)/ape/loader-xnu-gcc.asm: ape/loader.c
@$(COMPILE) -AOBJECTIFY.c $(CC) -DSUPPORT_VECTOR=0b00001000 -S -g0 $(APE_LOADER_FLAGS)
@$(COMPILE) -AOBJECTIFY.c $(CC) -DSUPPORT_VECTOR=8 -S -g0 $(APE_LOADER_FLAGS)
o/$(MODE)/ape/loader-xnu-clang.asm: ape/loader.c
@$(COMPILE) -AOBJECTIFY.c $(CLANG) -DSUPPORT_VECTOR=0b00001000 -S -g0 $(APE_LOADER_FLAGS)
@$(COMPILE) -AOBJECTIFY.c $(CLANG) -DSUPPORT_VECTOR=8 -S -g0 $(APE_LOADER_FLAGS)
o/$(MODE)/ape/ape.elf: o/$(MODE)/ape/ape.elf.dbg
o/$(MODE)/ape/ape.macho: o/$(MODE)/ape/ape.macho.dbg
@$(COMPILE) -AOBJBINCOPY -w build/bootstrap/objbincopy.com -f -o $@ $<
o/$(MODE)/ape/ape.macho: o/$(MODE)/ape/ape.elf.dbg
@$(COMPILE) -AOBJBINCOPY -w build/bootstrap/objbincopy.com -fm -o $@ $<
APE_LOADER_LDFLAGS = \
-static \
-nostdlib \
--no-dynamic-linker \
-z separate-code \
-z common-page-size=0x1000 \
-z max-page-size=0x10000
o/$(MODE)/ape/ape.elf.dbg: \
o/$(MODE)/ape/loader.o \
o/$(MODE)/ape/loader-elf.o \
ape/loader.lds
@$(ELFLINK) -z max-page-size=0x10
o/$(MODE)/ape/ape.macho.dbg: \
o/$(MODE)/ape/loader-xnu.o \
o/$(MODE)/ape/loader-macho.o \
ape/loader-macho.lds
@$(ELFLINK) -z max-page-size=0x10
o/$(MODE)/ape/start.o \
o/$(MODE)/ape/loader.o \
o/$(MODE)/ape/launch.o \
o/$(MODE)/ape/systemcall.o \
ape/loader.lds
@$(COMPILE) -ALINK.elf $(LD) $(APE_LOADER_LDFLAGS) -o $@ $(patsubst %.lds,-T %.lds,$^)
.PHONY: o/$(MODE)/ape
o/$(MODE)/ape: $(APE_CHECKS) \
@@ -198,8 +282,8 @@ o/$(MODE)/ape/ape.o: ape/ape.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/ape/ape.o: \
ape/blink-aarch64.gz \
ape/blink-darwin-arm64.gz
ape/blink-linux-aarch64.gz \
ape/blink-xnu-aarch64.gz
o/$(MODE)/ape/ape.lds: \
ape/ape.lds \
@@ -216,4 +300,4 @@ o/$(MODE)/ape/ape.lds: \
libc/macros.internal.h \
libc/nt/pedef.internal.h \
libc/str/str.h \
libc/zip.h
libc/zip.internal.h
+2 -7
View File
@@ -12,13 +12,8 @@ echo "Author: Justine Tunney <[email protected]>" >&2
################################################################################
# INSTALL APE LOADER SYSTEMWIDE
if [ -f o/depend ]; then
# mkdeps.com build was successfully run so assume we can build
echo >&2
echo "recompiling ape loader" >&2
echo "running: make -j8 o//ape" >&2
make -j8 o//ape || exit
echo "done" >&2
if [ -f o/depend ] && make -j8 o//ape; then
echo "successfully recompiled ape loader" >&2
elif [ -d build/bootstrap ]; then
# if make isn't being used then it's unlikely the user changed the sources
# in that case the prebuilt binaries should be completely up-to-date
+24 -2
View File
@@ -11,7 +11,7 @@ fi
echo "APE Uninstaller intends to run (in pseudo-shell)"
echo
echo " sudo echo -1 into /proc/sys/fs/binfmt_misc/APE*"
echo " sudo rm -f /usr/bin/ape ~/.ape o/tmp/.ape /tmp/.ape"
echo " sudo rm -f /usr/bin/ape ~/.ape /tmp/.ape # etc."
echo
echo "You may then use ape/apeinstall.sh to reinstall it"
echo
@@ -23,4 +23,26 @@ for f in /proc/sys/fs/binfmt_misc/APE*; do
$SUDO sh -c "echo -1 >$f" || exit
fi
done
$SUDO rm -f /usr/bin/ape ~/.ape o/tmp/.ape o/tmp/ape /tmp/.ape /tmp/ape || exit
# system installation
if [ -f /usr/bin/ape ]; then
$SUDO rm -f /usr/bin/ape
fi
# legacy installations
rm -f o/tmp/ape /tmp/ape "${TMPDIR:-/tmp}/ape"
# ad-hoc installations
for x in .ape \
.ape-1.1 \
.ape-1.3 \
.ape-1.4 \
.ape-1.5 \
.ape-blink-0.9.2 \
.ape-blink-1.0.0; do
rm -f \
~/$x \
/tmp/$x \
o/tmp/$x \
"${TMPDIR:-/tmp}/$x"
done
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
-10
View File
@@ -1,10 +0,0 @@
#ifndef COSMOPOLITAN_APE_CONFIG_H_
#define COSMOPOLITAN_APE_CONFIG_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
#define STATIC_SYMBOL(NAME, VALUE) \
asm(".equ\t" NAME "," VALUE "\n\t" \
".globl\t" NAME)
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_APE_CONFIG_H_ */
+71 -3
View File
@@ -1,7 +1,7 @@
/*-*- 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 2022 Justine Alexandra Roberts Tunney │
│ 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 │
@@ -18,7 +18,75 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/macros.internal.h"
endutent:
// Calls _start() function of loaded program.
//
// When the program entrypoint is called, all registers shall be
// cleared, with the exception of (1) %rdi will be equal to %rsp
// on FreeBSD and (2) %cl will contain the detected host OS code
//
// We clear all the general registers we can to have some wiggle
// room, to extend the behavior of this loader in the future. We
// don't need to clear the XMM registers because your APE loader
// should be compiled using gcc/clang's -mgeneral-regs-only flag
//
// @param rdi is passed through as-is
// @param rsi is address of entrypoint (becomes zero)
// @param rdx is stack pointer (becomes zero)
// @param rcx is passed through as-is
// @noreturn
Launch:
#ifdef __aarch64__
mov x16,x1
mov sp,x2
mov x1,0
mov x2,0
mov x3,0
mov x4,0
mov x5,0
mov x6,0
mov x7,0
mov x8,0
mov x9,0
mov x10,0
mov x11,0
mov x12,0
mov x13,0
mov x14,0
mov x15,0
mov x17,0
mov x19,0
mov x20,0
mov x21,0
mov x22,0
mov x23,0
mov x24,0
mov x25,0
mov x26,0
mov x27,0
mov x28,0
mov x29,0
mov x30,0
br x16
#else
xor %r8d,%r8d
xor %r9d,%r9d
xor %r10d,%r10d
xor %r11d,%r11d
xor %r12d,%r12d
xor %r13d,%r13d
xor %r14d,%r14d
xor %r15d,%r15d
mov %rdx,%rsp
xor %edx,%edx
push %rsi
xor %esi,%esi
xor %ebp,%ebp
xor %ebx,%ebx
xor %eax,%eax
ret
.endfn endutent,globl
#endif
.endfn Launch,globl
-249
View File
@@ -1,249 +0,0 @@
/*-*- 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 2021 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/elf/def.h"
#include "libc/sysv/consts/prot.h"
#include "libc/macho.internal.h"
#include "libc/dce.h"
#include "libc/macros.internal.h"
// APE Loader Executable Structure
// Linux, FreeBSD, NetBSD, OpenBSD
.balign 8
ehdr: .ascii "\177ELF"
.byte ELFCLASS64
.byte ELFDATA2LSB
.byte 1
.byte ELFOSABI_FREEBSD
.quad 0
.word ET_EXEC # e_type
.word EM_NEXGEN32E # e_machine
.long 1 # e_version
.quad _start # e_entry
.quad phdrs - ehdr # e_phoff
.quad 0 # e_shoff
.long 0 # e_flags
.word 64 # e_ehsize
.word 56 # e_phentsize
.word 4 # e_phnum
.word 0 # e_shentsize
.word 0 # e_shnum
.word 0 # e_shstrndx
.endobj ehdr,globl
.balign 8
phdrs: .long PT_LOAD # p_type
.long PF_R|PF_X # p_flags
.quad 0 # p_offset
.quad ehdr # p_vaddr
.quad ehdr # p_paddr
.quad filesz # p_filesz
.quad filesz # p_memsz
.quad PAGESIZE # p_align
.long PT_LOAD # p_type
.long PF_R|PF_W # p_flags
.quad 0 # p_offset
.quad bss # p_vaddr
.quad bss # p_paddr
.quad 0 # p_filesz
.quad bsssize # p_memsz
.quad PAGESIZE # p_align
.long PT_GNU_STACK # p_type
.long PF_R|PF_W # p_flags
.quad 0 # p_offset
.quad 0 # p_vaddr
.quad 0 # p_paddr
.quad 0 # p_filesz
.quad 0 # p_memsz
.quad 16 # p_align
.long PT_NOTE # p_type
.long PF_R # p_flags
.quad note - ehdr # p_offset
.quad note # p_vaddr
.quad note # p_paddr
.quad notesize # p_filesz
.quad notesize # p_memsz
.quad 8 # p_align
.endobj phdrs
note: .long 2f-1f
.long 4f-3f
.long 1
1: .asciz "OpenBSD"
2: .balign 4
3: .long 0
4: .long 2f-1f
.long 4f-3f
.long 1
1: .asciz "NetBSD"
2: .balign 4
3: .long 901000000
4: .endobj note
notesize = . - note
.balign 64,0 # for ape.S dd
.org 0x180 # for ape.S dd
// APE Loader XNU Header
//
// This header is dd'd backwards by the APE shell script when
// running on Mac OS X.
//
// @see ape/ape.S
macho: .long 0xFEEDFACE+1
.long MAC_CPU_NEXGEN32E
.long MAC_CPU_NEXGEN32E_ALL
.long MAC_EXECUTE
.long 5 # number of load commands
.long 60f-10f # size of all load commands
.long MAC_NOUNDEFS # flags
.long 0 # reserved
10: .long MAC_LC_SEGMENT_64
.long 20f-10b # unmaps first page dir
.ascin "__PAGEZERO",16 # consistent with linux
.quad 0,0x200000,0,0 # which forbids mem <2m
.long 0,0,0,0
20: .long MAC_LC_SEGMENT_64
.long 30f-20b
.ascin "__TEXT",16
.quad ehdr # vaddr
.quad 4096 # memsz
.quad 0 # file offset
.quad filesz # file size
.long PROT_EXEC|PROT_READ|PROT_WRITE # maxprot
.long PROT_EXEC|PROT_READ # initprot
.long 1 # segment section count
.long 0 # flags
210: .ascin "__text",16 # section name (.text)
.ascin "__TEXT",16
.quad _start # vaddr
.quad textsz # memsz
.long textoff # offset
.long 6 # align 2**6 = 64
.long 0 # reloc table offset
.long 0 # relocation count
.long MAC_S_ATTR_SOME_INSTRUCTIONS # section type & attributes
.long 0,0,0 # reserved
30: .long MAC_LC_SEGMENT_64
.long 40f-30b
.ascin "__DATA",16
.quad bss # vaddr
.quad bsssize # memsz
.quad 0 # offset
.quad 0 # file size
.long PROT_EXEC|PROT_READ|PROT_WRITE # maxprot
.long PROT_READ|PROT_WRITE # initprot
.long 1 # segment section count
.long 0 # flags
310: .ascin "__bss",16 # section name (.bss)
.ascin "__DATA",16
.quad bss # vaddr
.quad bsssize # memsz
.long 0 # offset
.long 12 # align 2**12 = 4096
.long 0 # reloc table offset
.long 0 # relocation count
.long MAC_S_ZEROFILL # section type & attributes
.long 0,0,0 # reserved
40: .long MAC_LC_UUID
.long 50f-40b
.quad 0x3fb29ee4ac6c87aa # uuid1
.quad 0xdd2c9bb866d9eef8 # uuid2
50: .long MAC_LC_UNIXTHREAD
.long 60f-50b # cmdsize
.long MAC_THREAD_NEXGEN32E # flavaflav
.long (520f-510f)/4 # count
510: .quad 0 # rax
.quad 0 # rbx
.quad 0 # rcx
.quad _HOSTXNU # rdx
.quad 0 # rdi
.quad 0 # rsi
.quad 0 # rbp
.quad 0 # rsp
.quad 0 # r8
.quad 0 # r9
.quad 0 # r10
.quad 0 # r11
.quad 0 # r12
.quad 0 # r13
.quad 0 # r14
.quad 0 # r15
.quad _start # rip
.quad 0 # rflags
.quad 0 # cs
.quad 0 # fs
.quad 0 # gs
520:
60:
.endobj macho
.balign 64,0 # for ape.S dd
.org 0x400 # for ape.S dd
// Ape Loader Entrpoint
//
// This is normally called by the operating system. However it may
// be called by the Actually Portable Executables themselves, when
// re-executing a program. Just do this:
//
// memcpy(0x200000, loader)
// lea handoff(%rip),%rcx
// lea argblock(%rip),%rsp
// jmp 0x200400
//
// @see APE_LOADER_ENTRY
// @see ape/loader.h
_start:
// Hack for detecting M1 Rosetta environment.
// https://github.com/jart/cosmopolitan/issues/429#issuecomment-1166704377
cmp $-1,%ebx
jne 0f
cmp $+1,%edx
jne 0f
mov $_HOSTXNU,%dl
xor %ecx,%ecx
0: mov %rsp,%rsi
jmp ApeLoader
.endfn _start,globl
// System Call Entrpoint
//
// This function is used by the APE loader to make system calls.
// We also pass a reference to this function to the APE binary's
// _start() function. It's needed because on OpenBSD, msyscall()
// restricts which pages can issue system calls, and it can only
// be called once. Therefore if we want to be load and re-load a
// binary multiple times without calling the system execve(), we
// need to be able to handover the SYSCALL function. We hardcode
// this to a fixed address, but that shouldn't be used, since we
// would ideally want to move it to a random page in the future.
__syscall_loader:
clc
syscall
jc 1f
ret
1: neg %rax
ret
.endfn __syscall_loader,globl
+56 -99
View File
@@ -21,118 +21,75 @@
#include "libc/dce.h"
#include "libc/macros.internal.h"
// APE Loader Executable Structure for XNU
// Apple Mach-O Executable Headers
// Fixups are applied by objbincopy.com
// There must exist a MAC_LC_SEGMENT_64 for every PT_LOAD
.balign 4096
macho: .long 0xFEEDFACE+1
.section .macho,"a",@progbits
.balign 64
.long 0xFEEDFACE+1
.long MAC_CPU_NEXGEN32E
.long MAC_CPU_NEXGEN32E_ALL
.long MAC_EXECUTE
.long 5 # number of load commands
.long 60f-10f # size of all load commands
.long MAC_NOUNDEFS # flags
.long 0 # reserved
.long 5 // number of load commands
.long 60f-10f // size of all load commands
.long MAC_NOUNDEFS|MAC_SPLIT_SEGS // flags
.long 0 // reserved
10: .long MAC_LC_SEGMENT_64
.long 20f-10b # unmaps first page dir
.ascin "__PAGEZERO",16 # consistent with linux
.quad 0,0x200000,0,0 # which forbids mem <2m
.long 20f-10b // unmaps first page dir
.ascin "__PAGEZERO",16 // consistent with linux
.quad 0,0x200000,0,0 // which forbids mem <2m
.long 0,0,0,0
20: .long MAC_LC_SEGMENT_64
.long 30f-20b
.ascin "__TEXT",16
.quad macho # vaddr
.quad 4096 # memsz
.quad 0 # file offset
.quad filesz # file size
.long PROT_EXEC|PROT_READ|PROT_WRITE # maxprot
.long PROT_EXEC|PROT_READ # initprot
.long 1 # segment section count
.long 0 # flags
210: .ascin "__text",16 # section name (.text)
.ascin "__TEXT",16
.quad _start # vaddr
.quad textsz # memsz
.long textoff # offset
.long 6 # align 2**3 = 64
.long 0 # reloc table offset
.long 0 # relocation count
.long MAC_S_ATTR_SOME_INSTRUCTIONS # section type & attributes
.long 0,0,0 # reserved
.quad 0 // vaddr
.quad 0 // memsz
.quad 0 // file offset
.quad 0 // file size
.long 0 // maxprot
.long 0 // initprot
.long 0 // segment section count
.long 0 // flags
30: .long MAC_LC_SEGMENT_64
.long 40f-30b
.ascin "__DATA",16
.quad bss # vaddr
.quad bsssize # memsz
.quad 0 # offset
.quad 0 # file size
.long PROT_EXEC|PROT_READ|PROT_WRITE # maxprot
.long PROT_READ|PROT_WRITE # initprot
.long 1 # segment section count
.long 0 # flags
310: .ascin "__bss",16 # section name (.bss)
.ascin "__DATA",16
.quad bss # vaddr
.quad bsssize # memsz
.long 0 # offset
.long 12 # align 2**12 = 4096
.long 0 # reloc table offset
.long 0 # relocation count
.long MAC_S_ZEROFILL # section type & attributes
.long 0,0,0 # reserved
.ascin "__RODATA",16
.quad 0 // vaddr
.quad 0 // memsz
.quad 0 // file offset
.quad 0 // file size
.long 0 // maxprot
.long 0 // initprot
.long 0 // segment section count
.long 0 // flags
40: .long MAC_LC_UUID
.long 50f-40b
.quad 0x3fb29ee4ac6c87aa # uuid1
.quad 0xdd2c9bb866d9eef8 # uuid2
.quad 0x4527148ba7a513ef // uuid1
.quad 0x56fa865940665e8f // uuid2
50: .long MAC_LC_UNIXTHREAD
.long 60f-50b # cmdsize
.long MAC_THREAD_NEXGEN32E # flavaflav
.long (520f-510f)/4 # count
510: .quad 0 # rax
.quad 0 # rbx
.quad 0 # rcx
.quad _HOSTXNU # rdx
.quad 0 # rdi
.quad 0 # rsi
.quad 0 # rbp
.quad 0 # rsp
.quad 0 # r8
.quad 0 # r9
.quad 0 # r10
.quad 0 # r11
.quad 0 # r12
.quad 0 # r13
.quad 0 # r14
.quad 0 # r15
.quad _start # rip
.quad 0 # rflags
.quad 0 # cs
.quad 0 # fs
.quad 0 # gs
.long 60f-50b // cmdsize
.long MAC_THREAD_NEXGEN32E // flavaflav
.long (520f-510f)/4 // count
510: .quad 0 // rax
.quad 0 // rbx
.quad 0 // rcx
.quad 0 // rdx
.quad 0 // rdi
.quad 0 // rsi
.quad 0 // rbp
.quad 0 // rsp
.quad 0 // r8
.quad 0 // r9
.quad 0 // r10
.quad 0 // r11
.quad 0 // r12
.quad 0 // r13
.quad 0 // r14
.quad 0 // r15
.quad XnuEntrypoint // rip
.quad 0 // rflags
.quad 0 // cs
.quad 0 // fs
.quad 0 // gs
520:
60:
.endobj macho,globl
.balign 64
_start:
// Hack for detecting M1 Rosetta environment.
// https://github.com/jart/cosmopolitan/issues/429#issuecomment-1166704377
cmp $-1,%ebx
jne 0f
cmp $+1,%edx
jne 0f
mov $_HOSTXNU,%dl
xor %ecx,%ecx
0: mov %rsp,%rsi
jmp ApeLoader
.endfn _start,globl
__syscall_loader:
clc
syscall
jc 1f
ret
1: neg %rax
ret
.endfn __syscall_loader,globl
-42
View File
@@ -1,42 +0,0 @@
/*-*- mode: ld-script; indent-tabs-mode: nil; tab-width: 2; coding: utf-8 -*-│
│vi: set et sts=2 tw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2021 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. │
╚─────────────────────────────────────────────────────────────────────────────*/
ENTRY(_start)
SECTIONS {
. = 0x200000;
.text : {
*(.text)
*(.rodata .rodata.*)
. = ALIGN(4096);
}
filesz = . - macho;
textsz = . - _start;
.bss ALIGN(4096) : {
bss = .;
*(.bss)
. = ALIGN(4096);
}
memsz = . - macho;
/DISCARD/ : {
*(.*)
}
}
bsssize = SIZEOF(.bss);
textoff = _start - macho;
+667 -402
View File
File diff suppressed because it is too large. Load diff
-20
View File
@@ -1,20 +0,0 @@
#ifndef COSMOPOLITAN_APE_LOADER_H_
#define COSMOPOLITAN_APE_LOADER_H_
#define APE_LOADER_BASE 0x200000
#define APE_LOADER_SIZE 0x200000
#define APE_LOADER_ENTRY 0x200400
#define APE_LOADER_BSS (PAGESIZE * 2)
#define APE_LOADER_STACK 0x7f0000000000
#define APE_BLOCK_BASE 0x7e0000000000
#define APE_BLOCK_SIZE 0x000200000000
struct ApeLoader {
int fd;
int os;
char *prog;
char *page;
void *systemcall;
};
#endif /* COSMOPOLITAN_APE_LOADER_H_ */
+70 -18
View File
@@ -1,7 +1,7 @@
/*-*- mode: ld-script; indent-tabs-mode: nil; tab-width: 2; coding: utf-8 -*-│
│vi: set et sts=2 tw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2021 Justine Alexandra Roberts Tunney │
│ 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 │
@@ -16,28 +16,80 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
ENTRY(_start)
ENTRY(ElfEntrypoint)
PHDRS {
text PT_LOAD FLAGS(1) FILEHDR PHDRS; /* PF_X */
rodata PT_LOAD FLAGS(4); /* PF_R */
stack PT_GNU_STACK FLAGS(6); /* PF_W|PF_R */
note PT_NOTE FLAGS(4); /* PF_R */
}
SECTIONS {
. = 0x200000;
. = SEGMENT_START("text-segment", 0x7f000000);
__executable_start = .;
. += SIZEOF_HEADERS;
.macho : {
KEEP(*(.macho))
} :text
.note : {
KEEP(*(.note))
} :text :note
.text : {
*(.text)
*(.rodata .rodata.*)
. = ALIGN(64);
}
filesz = . - ehdr;
textsz = . - _start;
.bss ALIGN(4096) : {
bss = .;
*(.bss)
. = ALIGN(4096);
}
*(.text .text.* .gnu.linkonce.t.*)
} :text
.rodata ALIGN(CONSTANT(COMMONPAGESIZE)) : {
*(.rodata .rodata.* .gnu.linkonce.r.*)
} :rodata
.stack : {
*(.stack)
} :stack
_end = .;
memsz = _end - ehdr;
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
.debug_macro 0 : { *(.debug_macro) }
.debug_addr 0 : { *(.debug_addr) }
.debug_loclists 0 : { *(.debug_loclists) }
.debug_rnglists 0 : { *(.debug_rnglists) }
.debug_line_str 0 : { *(.debug_line_str) }
.debug_extra 0 : { *(.debug_line_str) }
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.gnu.attributes 0 : { KEEP(*(.gnu.attributes)) }
/DISCARD/ : {
*(.*)
}
}
bsssize = SIZEOF(.bss);
textoff = _start - ehdr;
+20 -25
View File
@@ -3,31 +3,26 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
extern unsigned char _base[];
extern unsigned char _ehead[];
extern unsigned char _etext[];
extern unsigned char _edata[];
extern unsigned char _ezip[];
extern unsigned char _end[];
extern unsigned char _ereal[];
extern unsigned char _tdata_start[];
extern unsigned char _tdata_end[];
extern unsigned char _tbss_start[];
extern unsigned char _tbss_end[];
extern unsigned char __privileged_start[];
extern unsigned char __privileged_addr[];
extern unsigned char __privileged_size[];
extern unsigned char __privileged_end[];
extern unsigned char __test_start[];
extern unsigned char __ro[];
extern unsigned char *__relo_start[];
extern unsigned char *__relo_end[];
extern uint8_t __zip_start[];
extern uint8_t __zip_end[];
extern uint8_t __data_start[];
extern uint8_t __data_end[];
extern uint8_t __bss_start[];
extern uint8_t __bss_end[];
extern const char __comment_start[] __attribute__((__weak__));
extern unsigned char __executable_start[] __attribute__((__weak__));
extern unsigned char __privileged_start[] __attribute__((__weak__));
extern unsigned char _ehead[] __attribute__((__weak__));
extern unsigned char _etext[] __attribute__((__weak__));
extern unsigned char _edata[] __attribute__((__weak__));
extern unsigned char _ezip[] __attribute__((__weak__));
extern unsigned char _end[] __attribute__((__weak__));
extern unsigned char _ereal[] __attribute__((__weak__));
extern unsigned char _tdata_start[] __attribute__((__weak__));
extern unsigned char _tdata_end[] __attribute__((__weak__));
extern unsigned char _tbss_start[] __attribute__((__weak__));
extern unsigned char _tbss_end[] __attribute__((__weak__));
extern unsigned char _tls_align[] __attribute__((__weak__));
extern unsigned char __test_start[] __attribute__((__weak__));
extern unsigned char __ro[] __attribute__((__weak__));
extern uint8_t __data_start[] __attribute__((__weak__));
extern uint8_t __data_end[] __attribute__((__weak__));
extern uint8_t __bss_start[] __attribute__((__weak__));
extern uint8_t __bss_end[] __attribute__((__weak__));
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
+52 -11
View File
@@ -1,7 +1,7 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney │
│ 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 │
@@ -16,16 +16,57 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/log/log.h"
#include "libc/dce.h"
#include "libc/macros.internal.h"
.bss
.balign 4
__log_level:
.long 0
.endobj __log_level,globl
.previous
#ifdef __aarch64__
.init.start 200,_init_log_level
movb $kLogInfo,__log_level(%rip)
.init.end 200,_init_log_level
_start: mov x1,sp
mov x29,0
bl ApeLoader
.endfn _start,globl
#else
XnuEntrypoint:
mov $_HOSTXNU,%dl // xnu's not unix!
ElfEntrypoint:
mov %rsp,%rsi // save real stack
sub $1024*1024,%rsp // room for allocs
call ApeLoader
.endfn ElfEntrypoint,globl
.endfn XnuEntrypoint,globl
.section .note,"a",@progbits
.balign 4
openbsd.ident:
.long 2f-1f
.long 4f-3f
.long 1
1: .asciz "OpenBSD"
2: .balign 4
3: .long 0
4: .size openbsd.ident,.-openbsd.ident
.type openbsd.ident,@object
.balign 4
netbsd.ident:
.long 2f-1f
.long 4f-3f
.long 1
1: .asciz "NetBSD"
2: .balign 4
3: .long 901000000
4: .size netbsd.ident,.-netbsd.ident
.type netbsd.ident,@object
.balign 4
ape.ident:
.long 2f-1f
.long 4f-3f
.long 1
1: .asciz "APE"
2: .balign 4
3: .long 105000000
4: .size ape.ident,.-ape.ident
.type ape.ident,@object
#endif
+28 -17
View File
@@ -1,7 +1,7 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney │
│ 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 │
@@ -17,22 +17,33 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/macros.internal.h"
.privileged
.alignfunc
// Returns -𝑥, aborting on overflow (two's complement bane).
// Invokes system call.
//
// @param rdi is int64 𝑥
// @return rax is -𝑥
// @see -ftrapv
__negvdi2:
mov %rdi,%rax
// This function has eight parameters. The first seven are for
// arguments passed along to the system call. The eight is for
// the magic number that indicates which system call is called
//
// The return value follows the Linux kernel convention, where
// errors are returned as `-errno`. BSD systems are normalized
// to follow this convention automatically.
SystemCall:
#ifdef __aarch64__
mov x8,x7
mov x9,0
adds x9,x9,0
svc 0
bcs 1f
ret
1: neg x0,x0
ret
#else
mov %rcx,%r10
mov 16(%rsp),%eax
clc
syscall
jnc 1f
neg %rax
jo 1f
ret
1: push %rbp
mov %rsp,%rbp
call __on_arithmetic_overflow
pop %rbp
ret
.endfn __negvdi2,globl
1: ret
#endif
.endfn SystemCall,globl
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
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.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
+145 -73
View File
@@ -6,19 +6,41 @@
# - `make`
# - Optimized
# - Backtraces
# - Debuggable
# - Syscall tracing
# - Function tracing
# - Reasonably small
#
ifeq ($(MODE),)
CONFIG_CCFLAGS += $(BACKTRACES) $(FTRACE) -O2
ENABLE_FTRACE = 1
CONFIG_OFLAGS ?= -g
CONFIG_CCFLAGS += -O2 $(BACKTRACES)
CONFIG_CPPFLAGS += -DSYSDEBUG
TARGET_ARCH ?= -msse3
endif
ifeq ($(MODE), aarch64)
CONFIG_CCFLAGS += -O2 $(BACKTRACES) #$(FTRACE)
ENABLE_FTRACE = 1
CONFIG_OFLAGS ?= -g
CONFIG_CCFLAGS += -O2 $(BACKTRACES)
CONFIG_CPPFLAGS += -DSYSDEBUG
endif
# Zero Optimization Mode
#
# - Goes 2x slower
# - Supports --strace
# - Unsupports --ftrace
# - Better GDB debugging
#
ifeq ($(MODE), zero)
ENABLE_FTRACE = 1
CONFIG_OFLAGS ?= -g
OVERRIDE_CFLAGS += -O0
OVERRIDE_CXXFLAGS += -O0
CONFIG_CPPFLAGS += -DSYSDEBUG
endif
ifeq ($(MODE), aarch64-zero)
CONFIG_OFLAGS ?= -g
OVERRIDE_CFLAGS += -O0
OVERRIDE_CXXFLAGS += -O0
CONFIG_CPPFLAGS += -DSYSDEBUG
endif
@@ -30,12 +52,11 @@ endif
# - Function tracing
# - Some optimizations
# - Limited Backtraces
# - Compiles 28% faster
#
ifeq ($(MODE), fastbuild)
CONFIG_CCFLAGS += $(BACKTRACES) $(FTRACE) -O
ENABLE_FTRACE = 1
CONFIG_CCFLAGS += $(BACKTRACES) -O
CONFIG_CPPFLAGS += -DSYSDEBUG -DDWARFLESS
CONFIG_OFLAGS += -g0
CONFIG_LDFLAGS += -S
TARGET_ARCH ?= -msse3
endif
@@ -53,12 +74,15 @@ endif
# - GCC 8+ hoists check fails into .text.cold, thus minimizing impact
#
ifeq ($(MODE), opt)
CONFIG_CPPFLAGS += -DNDEBUG -DSYSDEBUG -msse2avx -Wa,-msse2avx
CONFIG_CCFLAGS += $(BACKTRACES) $(FTRACE) -O3 -fmerge-all-constants
ENABLE_FTRACE = 1
CONFIG_OFLAGS ?= -g
CONFIG_CPPFLAGS += -DNDEBUG -DSYSDEBUG
CONFIG_CCFLAGS += $(BACKTRACES) -O3 -fmerge-all-constants
TARGET_ARCH ?= -march=native
endif
# Optimized Linux Mode
# The Fastest Mode of All
#
# - `make MODE=optlinux`
# - Turns on red zone
@@ -68,9 +92,10 @@ endif
# - Turns off support for other operating systems
#
ifeq ($(MODE), optlinux)
CONFIG_CPPFLAGS += -DNDEBUG -msse2avx -Wa,-msse2avx -DSUPPORT_VECTOR=1
CONFIG_OFLAGS ?= -g
CONFIG_CPPFLAGS += -DNDEBUG -DSYSDEBUG -DSUPPORT_VECTOR=1
CONFIG_CCFLAGS += -O3 -fmerge-all-constants
DEFAULT_COPTS += -mred-zone
CONFIG_COPTS += -mred-zone
TARGET_ARCH ?= -march=native
endif
@@ -82,6 +107,7 @@ endif
# - More optimized
# - Reasonably small
# - Numeric backtraces
# - No DWARF data bloat
# - Toilsome debuggability
# - assert() statements removed
# - DCHECK_xx() statements removed
@@ -89,7 +115,7 @@ endif
# - CHECK_xx() won't leak strings into binary
#
ifeq ($(MODE), rel)
CONFIG_CPPFLAGS += -DNDEBUG
CONFIG_CPPFLAGS += -DNDEBUG -DDWARFLESS
CONFIG_CCFLAGS += $(BACKTRACES) -O2
TARGET_ARCH ?= -msse3
PYFLAGS += -O1
@@ -107,9 +133,13 @@ endif
# - Larger binaries
#
ifeq ($(MODE), asan)
ENABLE_FTRACE = 1
CONFIG_OFLAGS ?= -g
CONFIG_CPPFLAGS += -D__SANITIZE_ADDRESS__
CONFIG_CCFLAGS += $(BACKTRACES) -O2 -DSYSDEBUG
CONFIG_COPTS += -fsanitize=address
TARGET_ARCH ?= -msse3
QUOTA ?= -C64 -L300
endif
# Debug Mode
@@ -117,17 +147,28 @@ endif
# - `make MODE=dbg`
# - Backtraces
# - Enables asan
# - Enables ubsan (TODO)
# - Enables ubsan
# - Stack canaries
# - No optimization (TODO)
# - No optimization
# - Enormous binaries
#
ifeq ($(MODE), dbg)
CONFIG_CPPFLAGS += -DMODE_DBG
CONFIG_CCFLAGS += $(BACKTRACES) $(FTRACE) -DSYSDEBUG -O -fno-inline
ENABLE_FTRACE = 1
CONFIG_OFLAGS ?= -g
CONFIG_CPPFLAGS += -DMODE_DBG -D__SANITIZE_ADDRESS__ -D__SANITIZE_UNDEFINED__
CONFIG_CCFLAGS += $(BACKTRACES) -DSYSDEBUG -O0 -fno-inline
CONFIG_COPTS += -fsanitize=address -fsanitize=undefined
TARGET_ARCH ?= -msse3
OVERRIDE_CCFLAGS += -fno-pie
QUOTA ?= -C64 -L300
endif
ifeq ($(MODE), aarch64-dbg)
ENABLE_FTRACE = 1
CONFIG_OFLAGS ?= -g
CONFIG_CPPFLAGS += -DMODE_DBG -D__SANITIZE_UNDEFINED__
CONFIG_CCFLAGS += $(BACKTRACES) -DSYSDEBUG -O0 -fno-inline
CONFIG_COPTS += -fsanitize=undefined
QUOTA ?= -C64 -L300
endif
# System Five Mode
@@ -141,7 +182,9 @@ endif
# - No Windows bloat!
#
ifeq ($(MODE), sysv)
CONFIG_CCFLAGS += $(BACKTRACES) $(FTRACE) -O2
ENABLE_FTRACE = 1
CONFIG_OFLAGS ?= -g
CONFIG_CCFLAGS += $(BACKTRACES) -O2
CONFIG_CPPFLAGS += -DSYSDEBUG -DSUPPORT_VECTOR=121
TARGET_ARCH ?= -msse3
endif
@@ -170,22 +213,17 @@ CONFIG_CCFLAGS += \
-fno-align-labels \
-fno-align-loops \
-fschedule-insns2 \
-fomit-frame-pointer \
-momit-leaf-frame-pointer \
-foptimize-sibling-calls \
-DDWARFLESS
CONFIG_OFLAGS += \
-g0
CONFIG_LDFLAGS += \
-S
TARGET_ARCH ?= \
-msse3
PYFLAGS += \
-O2 \
-B
endif
ifeq ($(MODE), aarch64-tiny)
# TODO(jart): -mcmodel=tiny
CONFIG_CPPFLAGS += \
-DTINY \
-DNDEBUG \
@@ -197,14 +235,9 @@ CONFIG_CCFLAGS += \
-fno-align-labels \
-fno-align-loops \
-fschedule-insns2 \
-fomit-frame-pointer \
-momit-leaf-frame-pointer \
-foptimize-sibling-calls \
-DDWARFLESS
CONFIG_OFLAGS += \
-g0
CONFIG_LDFLAGS += \
-S
PYFLAGS += \
-O2 \
-B
@@ -230,12 +263,6 @@ CONFIG_CPPFLAGS += \
-DTRUSTWORTHY \
-DSUPPORT_VECTOR=1 \
-DDWARFLESS
DEFAULT_COPTS += \
-mred-zone
CONFIG_OFLAGS += \
-g0
CONFIG_LDFLAGS += \
-S
CONFIG_CCFLAGS += \
-Os \
-fno-align-functions \
@@ -267,12 +294,6 @@ CONFIG_CPPFLAGS += \
-DTRUSTWORTHY \
-DSUPPORT_VECTOR=113 \
-DDWARFLESS
DEFAULT_COPTS += \
-mred-zone
CONFIG_OFLAGS += \
-g0
CONFIG_LDFLAGS += \
-S
CONFIG_CCFLAGS += \
-Os \
-fno-align-functions \
@@ -303,18 +324,12 @@ CONFIG_CPPFLAGS += \
-DTRUSTWORTHY \
-DSUPPORT_VECTOR=121 \
-DDWARFLESS
DEFAULT_COPTS += \
-mred-zone
CONFIG_CCFLAGS += \
-Os \
-fno-align-functions \
-fno-align-jumps \
-fno-align-labels \
-fno-align-loops
CONFIG_OFLAGS += \
-g0
CONFIG_LDFLAGS += \
-S
TARGET_ARCH ?= \
-msse3
endif
@@ -345,40 +360,44 @@ CONFIG_CCFLAGS += \
-fno-align-jumps \
-fno-align-labels \
-fno-align-loops
CONFIG_OFLAGS += \
-g0
CONFIG_LDFLAGS += \
-S
TARGET_ARCH ?= \
-msse3
endif
# GCC11 Mode
# https://justine.lol/compilers/x86_64-linux-musl__x86_64-linux-musl__g++-11.2.0.tar.xz
ifeq ($(MODE), gcc11)
.UNVEIL += rx:/opt/gcc11
CONFIG_CCFLAGS += $(BACKTRACES) $(FTRACE) -DSYSDEBUG -O2
AS = /opt/gcc11/bin/x86_64-linux-musl-as
CC = /opt/gcc11/bin/x86_64-linux-musl-gcc
CXX = /opt/gcc11/bin/x86_64-linux-musl-g++
CXXFILT = /opt/gcc11/bin/x86_64-linux-musl-c++filt
LD = /opt/gcc11/bin/x86_64-linux-musl-ld.bfd
NM = /opt/gcc11/bin/x86_64-linux-musl-nm
GCC = /opt/gcc11/bin/x86_64-linux-musl-gcc
STRIP = /opt/gcc11/bin/x86_64-linux-musl-strip
OBJCOPY = /opt/gcc11/bin/x86_64-linux-musl-objcopy
OBJDUMP = /opt/gcc11/bin/x86_64-linux-musl-objdump
ADDR2LINE = /opt/gcc11/bin/x86_64-linux-musl-addr2line
CONFIG_CCFLAGS += $(BACKTRACES) $(FTRACE) -O2 -Wno-stringop-overread
CONFIG_CFLAGS += -Wno-old-style-definition
CONFIG_CPPFLAGS += -DNDEBUG -DSYSDEBUG
# no x87 instructions mode
#
# export MODE=nox87
# make -j8 toolchain
# cosmocc -o /tmp/hello.com hello.c
#
# lets you shave ~23kb off blink
#
# git clone https://github.com/jart/blink
# cd blink
# ./configure --disable-x87
# make -j8
# o//blink/blink /tmp/hello.com
#
ifeq ($(MODE), nox87)
ENABLE_FTRACE = 1
CONFIG_COPTS += -mlong-double-64
CONFIG_CCFLAGS += $(BACKTRACES) -O2
CONFIG_CPPFLAGS += -DSYSDEBUG -DNOX87
TARGET_ARCH ?= -msse3
endif
# LLVM Mode
#
# We aim to support:
#
# make -j8 m=llvm o/llvm/libc
#
# The rest of the monorepo may not work with llvm.
#
ifeq ($(MODE), llvm)
.STRICT = 0
TARGET_ARCH ?= -msse3
CONFIG_CCFLAGS += $(BACKTRACES) $(FTRACE) -DSYSDEBUG -O2
CONFIG_CCFLAGS += $(BACKTRACES) -DSYSDEBUG -O2
AS = clang
CC = clang
CXX = clang++
@@ -416,12 +435,65 @@ endif
# such as MSVC or XCode. You can run your binary objects through a tool
# like objconv to convert them to COFF or MachO. Then use ANSI mode to
# rollup one header file that'll enable linkage with minimal issues.
ifeq ($(MODE), ansi)
CONFIG_CFLAGS += -std=c11
#CONFIG_CPPFLAGS += -ansi
CONFIG_CXXFLAGS += -std=c++11
TARGET_ARCH ?= -msse3
endif
ifneq ($(ENABLE_FTRACE),)
CONFIG_CPPFLAGS += -DFTRACE
FTRACE_CCFLAGS = -fno-inline-functions-called-once
OVERRIDE_CFLAGS += $(FTRACE_CCFLAGS)
OVERRIDE_CXXFLAGS += $(FTRACE_CCFLAGS)
# function prologue nops for --ftrace
ifeq ($(ARCH), x86_64)
# this flag causes gcc to generate functions like this
#
# nop nop nop nop nop nop nop nop nop
# func:
# nop nop
# ...
#
# which tool/build/fixupobj.c improves at build time like this
#
# nop nop nop nop nop nop nop nop nop
# func:
# xchg %ax,%ax
# ...
#
# which --ftrace morphs at runtime like this
#
# ud2 # 2 bytes
# call ftrace_hook # 5 bytes
# jmp +2 # 2 bytes
# func:
# jmp -7 # 2 bytes
# ...
#
CONFIG_CCFLAGS += -fpatchable-function-entry=18,16
endif
ifeq ($(ARCH), aarch64)
# this flag causes gcc to generate functions like this
#
# nop nop nop nop nop nop
# func:
# nop
# ...
#
# which --ftrace morphs at runtime like this
#
# brk #31337
# stp x29,x30,[sp,#-16]!
# mov x29,sp
# bl ftrace_hook
# ldp x29,x30,[sp],#16
# b +1
# func:
# b -5
# ...
#
CONFIG_CCFLAGS += -fpatchable-function-entry=7,6
endif
endif
+80 -47
View File
@@ -33,14 +33,25 @@
#
# VARIABLES
#
# CCFLAGS gcc frontend flags (.i, .c, .cc, .f, .S, .lds, etc.)
# Our configuration variables, ordered by increasing preference:
#
# CCFLAGS frontend flags (.i, .c, .cc, .f, .S, .lds, etc.)
# OFLAGS objectify flags (precludes -S and -E)
# CPPFLAGS preprocessor flags (.h, .c, .cc, .S, .inc, .lds, etc.)
# TARGET_ARCH microarchitecture flags (e.g. -march=native)
# COPTS c/c++ flags (.c, .cc)
# CFLAGS c flags (.c only)
# CXXFLAGS c++ flags (.cc only)
# COPTS c/c++ flags (.c, .cc)
# LDFLAGS linker flags (don't use -Wl, frontend prefix)
# ASFLAGS assembler flags (don't use -Wa, frontend prefix)
# TARGET_ARCH microarchitecture flags (e.g. -march=native)
#
# For each FOO above, there exists (by increasing preference)
#
# DEFAULT_FOO see build/definitions.mk
# CONFIG_FOO see build/config.mk
# FOO set ~/.cosmo.mk and target-specific
# OVERRIDE_FOO set ~/.cosmo.mk and target-specific (use rarely)
#
LC_ALL = C
SOURCE_DATE_EPOCH = 0
@@ -58,28 +69,33 @@ CP = build/bootstrap/cp.com
RM = build/bootstrap/rm.com -f
GZIP = build/bootstrap/gzip.com
ECHO = build/bootstrap/echo.com
CHMOD = build/bootstrap/chmod.com
TOUCH = build/bootstrap/touch.com
PKG = build/bootstrap/package.com
MKDEPS = build/bootstrap/mkdeps.com
ZIPOBJ = build/bootstrap/zipobj.com
ZIPCOPY = build/bootstrap/zipcopy.com
FIXUPOBJ = build/bootstrap/fixupobj.com
MKDIR = build/bootstrap/mkdir.com -p
COMPILE = build/bootstrap/compile.com -V9 -P4096 $(QUOTA)
COMMA := ,
PWD := $(shell build/bootstrap/pwd.com)
IMAGE_BASE_VIRTUAL ?= 0x400000
IGNORE := $(shell $(ECHO) -2 ♥cosmo)
IGNORE := $(shell $(MKDIR) o/tmp)
IGNORE := $(shell $(MKDIR) $(TMPDIR))
ifneq ($(findstring aarch64,$(MODE)),)
ARCH = aarch64
VM = o/third_party/qemu/qemu-aarch64
HOSTS ?= pi silicon
else
ARCH = x86_64
HOSTS ?= freebsd openbsd openbsd73 netbsd rhel7 rhel5 xnu win10
endif
ifeq ($(PREFIX),)
ifeq ($(USE_SYSTEM_TOOLCHAIN),)
ifneq ("$(wildcard o/third_party/gcc/bin/x86_64-pc-linux-gnu-*)","")
PREFIX = o/third_party/gcc/bin/x86_64-pc-linux-gnu-
else
@@ -89,6 +105,8 @@ endif
ifeq ($(ARCH), aarch64)
PREFIX = o/third_party/gcc/bin/aarch64-linux-musl-
endif
endif
endif
AS = $(PREFIX)as
CC = $(PREFIX)gcc
@@ -100,7 +118,11 @@ GCC = $(PREFIX)gcc
STRIP = $(PREFIX)strip
OBJCOPY = $(PREFIX)objcopy
OBJDUMP = $(PREFIX)objdump
ifneq ($(wildcard $(PWD)/$(PREFIX)addr2line), )
ADDR2LINE = $(PWD)/$(PREFIX)addr2line
else
ADDR2LINE = $(PREFIX)addr2line
endif
export ADDR2LINE
export LC_ALL
@@ -110,20 +132,18 @@ export SOURCE_DATE_EPOCH
export TMPDIR
ifeq ($(LANDLOCKMAKE_VERSION),)
TMPSAFE = $(TMPDIR)/$(subst /,_,$@).tmp
TMPSAFE = $(join $(TMPDIR),$(subst /,_,$@)).tmp
else
TMPSAFE = $(TMPDIR)/
endif
ifneq ($(ARCH), aarch64)
MNO_FENTRY = -mno-fentry
ifeq ($(ARCH), aarch64)
IMAGE_BASE_VIRTUAL ?= 0x010000000000
else
IMAGE_BASE_VIRTUAL ?= 0x400000
endif
FTRACE = \
-pg
BACKTRACES = \
-fno-omit-frame-pointer \
-fno-optimize-sibling-calls \
-mno-omit-leaf-frame-pointer
@@ -135,7 +155,6 @@ SANITIZER = \
-fsanitize=address
NO_MAGIC = \
$(MNO_FENTRY) \
-fno-stack-protector \
-fwrapv \
-fno-sanitize=all
@@ -149,38 +168,49 @@ TRADITIONAL = \
-Wno-return-type \
-Wno-pointer-sign
DEFAULT_CCFLAGS = \
DEFAULT_CCFLAGS += \
-Wall \
-Werror \
-fdebug-prefix-map='$(PWD)'= \
-fno-omit-frame-pointer \
-frecord-gcc-switches
DEFAULT_OFLAGS = \
-g \
-gdwarf-4 \
-gdescribe-dies
DEFAULT_COPTS = \
DEFAULT_COPTS ?= \
-fno-math-errno \
-fno-fp-int-builtin-inexact \
-fno-ident \
-fno-common \
-fno-gnu-unique \
-fstrict-aliasing \
-fstrict-overflow \
-fno-semantic-interposition
-fno-semantic-interposition \
-fno-dwarf2-cfi-asm \
-fno-unwind-tables \
-fno-asynchronous-unwind-tables
ifneq ($(ARCH), aarch64)
ifeq ($(ARCH), x86_64)
DEFAULT_COPTS += \
-mno-red-zone \
-mno-tls-direct-seg-refs
endif
ifeq ($(ARCH), aarch64)
#
# - Apple says in "Writing ARM64 code for Apple platforms" that we're
# not allowed to use the x18 register.
#
# - Cosmopolitan Libc uses x28 for thread-local storage because Apple
# forbids us from using tpidr_el0 too.
#
DEFAULT_COPTS += \
-ffixed-x18 \
-ffixed-x28 \
-mno-outline-atomics
endif
MATHEMATICAL = \
-O3 \
-fwrapv
DEFAULT_CPPFLAGS = \
DEFAULT_CPPFLAGS += \
-DCOSMO \
-DMODE='"$(MODE)"' \
-DIMAGE_BASE_VIRTUAL=$(IMAGE_BASE_VIRTUAL) \
@@ -202,27 +232,33 @@ DEFAULT_CXXFLAGS = \
DEFAULT_ASFLAGS = \
-W \
-I. \
--noexecstack \
--nocompress-debug-sections
--noexecstack
DEFAULT_LDFLAGS = \
-static \
-nostdlib \
-znorelro \
--gc-sections \
--build-id=none \
--no-dynamic-linker \
-zmax-page-size=0x1000 #--cref [email protected]
--no-dynamic-linker
ZIPOBJ_FLAGS = \
-b$(IMAGE_BASE_VIRTUAL)
# # generate linker report files
# DEFAULT_LDFLAGS += --cref [email protected]
PYFLAGS = \
-b$(IMAGE_BASE_VIRTUAL)
ifeq ($(ARCH), aarch64)
DEFAULT_LDFLAGS += \
-zmax-page-size=0x4000 \
-zcommon-page-size=0x4000 \
-znorelro
else
DEFAULT_LDFLAGS += \
-zmax-page-size=0x10000 \
-zcommon-page-size=0x1000
endif
ASONLYFLAGS = \
-c \
-g \
--debug-prefix-map='$(PWD)'=
-g
DEFAULT_LDLIBS =
@@ -296,19 +332,19 @@ LD.libs = \
$(CONFIG_LIBS) \
$(LIBS)
COMPILE.c.flags = $(cc.flags) $(cpp.flags) $(copt.flags) $(c.flags)
COMPILE.cxx.flags = $(cc.flags) $(cpp.flags) $(copt.flags) $(cxx.flags)
COMPILE.c.flags = $(cc.flags) $(copt.flags) $(cpp.flags) $(c.flags)
COMPILE.cxx.flags = $(cc.flags) $(copt.flags) $(cpp.flags) $(cxx.flags)
COMPILE.f.flags = $(cc.flags) $(copt.flags) $(f.flags)
COMPILE.F.flags = $(cc.flags) $(cpp.flags) $(copt.flags) $(f.flags)
COMPILE.F.flags = $(cc.flags) $(copt.flags) $(cpp.flags) $(f.flags)
COMPILE.i.flags = $(cc.flags) $(copt.flags) $(c.flags)
COMPILE.ii.flags = $(cc.flags) $(copt.flags) $(cxx.flags)
LINK.flags = $(DEFAULT_LDFLAGS) $(CONFIG_LDFLAGS) $(LDFLAGS)
OBJECTIFY.c.flags = $(OBJECTIFY.S.flags) $(copt.flags) $(c.flags)
OBJECTIFY.cxx.flags = $(OBJECTIFY.S.flags) $(copt.flags) $(cxx.flags)
OBJECTIFY.c.flags = $(cc.flags) $(o.flags) $(S.flags) $(cpp.flags) $(copt.flags) $(c.flags)
OBJECTIFY.cxx.flags = $(cc.flags) $(o.flags) $(S.flags) $(cpp.flags) $(copt.flags) $(cxx.flags)
OBJECTIFY.s.flags = $(ASONLYFLAGS) $(s.flags)
OBJECTIFY.S.flags = $(copt.flags) $(cc.flags) $(o.flags) $(cpp.flags) $(S.flags)
OBJECTIFY.f.flags = $(copt.flags) $(cc.flags) $(o.flags) $(copt.flags) $(S.flags) $(f.flags)
OBJECTIFY.F.flags = $(OBJECTIFY.f.flags) $(cpp.flags)
OBJECTIFY.S.flags = $(cc.flags) $(o.flags) $(S.flags) $(cpp.flags)
OBJECTIFY.f.flags = $(cc.flags) $(o.flags) $(S.flags) $(f.flags)
OBJECTIFY.F.flags = $(cc.flags) $(o.flags) $(S.flags) $(cpp.flags) $(copt.flags) $(f.flags)
PREPROCESS.flags = -E $(copt.flags) $(cc.flags) $(cpp.flags)
PREPROCESS.lds.flags = -D__LINKER__ $(filter-out -g%,$(PREPROCESS.flags)) -P -xc
@@ -327,7 +363,7 @@ PREPROCESS = $(CC) $(PREPROCESS.flags)
PREPROCESS.lds = $(CC) $(PREPROCESS.lds.flags)
LINK = $(LD) $(LINK.flags)
ELF = o/libc/elf/elf.lds
ELFLINK = $(COMPILE) -ALINK.elf $(LINK) $(LINKARGS) $(OUTPUT_OPTION)
ELFLINK = $(COMPILE) -ALINK.elf $(LINK) $(LINKARGS) $(OUTPUT_OPTION) && $(COMPILE) -AFIXUP.ape -T$@ $(FIXUPOBJ) $@
LINKARGS = $(patsubst %.lds,-T %.lds,$(call uniqr,$(LD.libs) $(filter-out %.pkg,$^)))
LOLSAN = build/lolsan -b $(IMAGE_BASE_VIRTUAL)
@@ -344,7 +380,6 @@ OBJECTIFY.greg.c = \
-fno-optimize-sibling-calls \
-fno-sanitize=all \
-ffreestanding \
$(MNO_FENTRY) \
-fwrapv \
-c
@@ -384,7 +419,6 @@ OBJECTIFY.ncabi.c = \
$(OBJECTIFY.c.flags) \
-mno-sse \
-mfpmath=387 \
$(MNO_FENTRY) \
-fno-stack-protector \
-fno-instrument-functions \
-fno-optimize-sibling-calls \
@@ -403,7 +437,6 @@ OBJECTIFY.ncabi.c = \
OBJECTIFY.initabi.c = \
$(GCC) \
$(OBJECTIFY.c.flags) \
$(MNO_FENTRY) \
-fno-stack-protector \
-fno-instrument-functions \
-fno-optimize-sibling-calls \
+1 -2
View File
@@ -1,6 +1,5 @@
#!/bin/sh
for last; do true; done
if printf '%s\n' "$last" | grep aarch64 >/dev/null 2>&1; then
if printf '%s\n' "$*" | grep aarch64 >/dev/null 2>&1; then
exec o/third_party/gcc/bin/aarch64-linux-musl-objdump "$@"
else
exec o/third_party/gcc/bin/x86_64-linux-musl-objdump "$@"
+3 -3
View File
@@ -23,9 +23,9 @@
# - tool/build/runitd.c
.PRECIOUS: o/$(MODE)/%.com.ok
o/$(MODE)/%.com.ok: .PLEDGE = stdio rpath wpath cpath proc fattr inet
o/$(MODE)/%.com.ok: private .PLEDGE = stdio rpath wpath cpath proc fattr inet
o/$(MODE)/%.com.ok: \
o/$(MODE)/tool/build/runit.com \
o/$(MODE)/tool/build/runitd.com \
o//tool/build/runit.com \
o//tool/build/runitd.com \
o/$(MODE)/%.com
@$(COMPILE) -wATEST -tT$@ $^ $(HOSTS)
+35 -20
View File
@@ -16,18 +16,22 @@
MAKEFLAGS += --no-builtin-rules
MAKE_ZIPCOPY = $(COMPILE) -AZIPCOPY -wT$@ $(ZIPCOPY) $< $@
ifneq ($(ARCH), aarch64)
MAKE_OBJCOPY = $(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@ && $(MAKE_ZIPCOPY)
else
MAKE_OBJCOPY = $(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S $< $@ && $(MAKE_ZIPCOPY)
endif
o/%.lds: %.lds ; @$(COMPILE) -APREPROCESS $(PREPROCESS.lds) $(OUTPUT_OPTION) $<
o/%.inc: %.h ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) -D__ASSEMBLER__ -P $<
o/%.greg.o: %.greg.c ; @$(COMPILE) -AOBJECTIFY.greg $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%: o/$(MODE)/%.dbg ; @$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
o/$(MODE)/%: o/$(MODE)/%.dbg ; @$(MAKE_OBJCOPY)
o/$(MODE)/%.o: %.f ; @$(COMPILE) -AOBJECTIFY.f $(OBJECTIFY.f) $(OUTPUT_OPTION) $<
o/$(MODE)/%.o: %.F ; @$(COMPILE) -AOBJECTIFY.F $(OBJECTIFY.F) $(OUTPUT_OPTION) $<
o/$(MODE)/%.h: %.c ; @$(COMPILE) -AAMALGAMATE $(PREPROCESS) $(OUTPUT_OPTION) -fdirectives-only -P $<
o/$(MODE)/%.h: o/$(MODE)/%.c ; @$(COMPILE) -AAMALGAMATE $(PREPROCESS) $(OUTPUT_OPTION) -fdirectives-only -P $<
o/$(MODE)/%.o: %.cc ; @$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
o/$(MODE)/%.lds: %.lds ; @$(COMPILE) -APREPROCESS $(PREPROCESS.lds) $(OUTPUT_OPTION) $<
o/$(MODE)/%.o: %.greg.c ; @$(COMPILE) -AOBJECTIFY.greg $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.greg.o: %.greg.c ; @$(COMPILE) -AOBJECTIFY.greg $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.initabi.o: %.initabi.c ; @$(COMPILE) -AOBJECTIFY.init $(OBJECTIFY.initabi.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.ncabi.o: %.ncabi.c ; @$(COMPILE) -AOBJECTIFY.nc $(OBJECTIFY.ncabi.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.real.o: %.c ; @$(COMPILE) -AOBJECTIFY.real $(OBJECTIFY.real.c) $(OUTPUT_OPTION) $<
@@ -76,6 +80,18 @@ o/$(MODE)/%.o: o/$(MODE)/%.cc
@$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
@$(COMPILE) -AFIXUPOBJ -wT$@ $(FIXUPOBJ) $@
o/%.greg.o: %.greg.c
@$(COMPILE) -AOBJECTIFY.greg $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $<
@$(COMPILE) -AFIXUPOBJ -wT$@ $(FIXUPOBJ) $@
o/$(MODE)/%.o: %.greg.c
@$(COMPILE) -AOBJECTIFY.greg $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $<
@$(COMPILE) -AFIXUPOBJ -wT$@ $(FIXUPOBJ) $@
o/$(MODE)/%.greg.o: %.greg.c
@$(COMPILE) -AOBJECTIFY.greg $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $<
@$(COMPILE) -AFIXUPOBJ -wT$@ $(FIXUPOBJ) $@
o/%.a:
$(file >$(TMPDIR)/$(subst /,_,$@),$^)
@$(COMPILE) -AARCHIVE -wT$@ $(AR) $(ARFLAGS) $@ @$(TMPDIR)/$(subst /,_,$@)
@@ -88,21 +104,21 @@ o/$(MODE)/%.pkg:
$(file >$(TMPSAFE).args,$(filter %.o,$^))
@$(COMPILE) -APACKAGE -wT$@ $(PKG) $(OUTPUT_OPTION) $(addprefix -d,$(filter %.pkg,$^)) @$(TMPSAFE).args
o/$(MODE)/%.o: %.py o/$(MODE)/third_party/python/pyobj.com
@$(COMPILE) -wAPYOBJ o/$(MODE)/third_party/python/pyobj.com $(PYFLAGS) -o $@ $<
o/$(MODE)/%.o: %.py o/$(MODE)/third_party/python/pyobj.com $(VM)
@$(COMPILE) -wAPYOBJ $(VM) o/$(MODE)/third_party/python/pyobj.com $(PYFLAGS) -o $@ $<
o/$(MODE)/%.pyc: %.py o/$(MODE)/third_party/python/pycomp.com
@$(COMPILE) -wAPYCOMP o/$(MODE)/third_party/python/pycomp.com $(PYCFLAGS) -o $@ $<
o/$(MODE)/%.pyc: %.py o/$(MODE)/third_party/python/pycomp.com $(VM)
@$(COMPILE) -wAPYCOMP $(VM) o/$(MODE)/third_party/python/pycomp.com $(PYCFLAGS) -o $@ $<
o/$(MODE)/%.lua: %.lua o/$(MODE)/third_party/lua/luac.com
@$(COMPILE) -wALUAC o/$(MODE)/third_party/lua/luac.com -s -o $@ $<
o/$(MODE)/%.lua: %.lua o/$(MODE)/third_party/lua/luac.com $(VM)
@$(COMPILE) -wALUAC $(VM) o/$(MODE)/third_party/lua/luac.com -s -o $@ $<
o/$(MODE)/%.lua.runs: %.lua o/$(MODE)/tool/net/redbean.com
@$(COMPILE) -wALUA -tT$@ o/$(MODE)/tool/net/redbean.com $(LUAFLAGS) -i $<
o/$(MODE)/%.lua.runs: %.lua o/$(MODE)/tool/net/redbean.com $(VM)
@$(COMPILE) -wALUA -tT$@ $(VM) o/$(MODE)/tool/net/redbean.com $(LUAFLAGS) -i $<
o/$(MODE)/%: o/$(MODE)/%.com o/$(MODE)/tool/build/cp.com o/$(MODE)/tool/build/assimilate.com
@$(COMPILE) -wACP -T$@ o/$(MODE)/tool/build/cp.com $< $@
@$(COMPILE) -wAASSIMILATE -T$@ o/$(MODE)/tool/build/assimilate.com $@
o/$(MODE)/%: o/$(MODE)/%.com o/$(MODE)/tool/build/cp.com o/$(MODE)/tool/build/assimilate.com $(VM)
@$(COMPILE) -wACP -T$@ $(VM) o/$(MODE)/tool/build/cp.com $< $@
@$(COMPILE) -wAASSIMILATE -T$@ $(VM) o/$(MODE)/tool/build/assimilate.com $@
################################################################################
# LOCAL UNIT TESTS
@@ -199,18 +215,16 @@ o/$(MODE)/%.okk: %
################################################################################
# EXECUTABLE HELPERS
MAKE_OBJCOPY = \
$(COMPILE) -AOBJCOPY -T$@ \
$(OBJCOPY) -S -O binary $< $@
MAKE_SYMTAB_CREATE = \
$(COMPILE) -wASYMTAB \
$(VM) \
o/$(MODE)/tool/build/symtab.com \
-o $(TMPSAFE)/.symtab \
$<
MAKE_SYMTAB_ZIP = \
$(COMPILE) -AZIP -T$@ \
$(VM) \
o/$(MODE)/third_party/zip/zip.com \
-b$(TMPDIR) \
-9qj \
@@ -232,7 +246,8 @@ o/$(MODE)/%-clang.asm: private .UNSANDBOXED = 1
o/$(MODE)/%-clang.asm: %.c
@$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) -S -g0 $(OUTPUT_OPTION) $<
o/$(MODE)/%-clang.asm: CC = $(CLANG)
# TODO(jart): Make intrinsics support Clang.
# o/$(MODE)/%-clang.asm: CC = $(CLANG)
o/$(MODE)/%-clang.asm: private .UNSANDBOXED = 1
o/$(MODE)/%-clang.asm: %.cc
@$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.cxx) -S -g0 $(OUTPUT_OPTION) $<
+1 -2
View File
@@ -1,6 +1,5 @@
#!/bin/sh
for last; do true; done
if printf '%s\n' "$last" | grep aarch64 >/dev/null 2>&1; then
if printf '%s\n' "$*" | grep aarch64 >/dev/null 2>&1; then
if [ ! -f o/third_party/qemu/qemu-aarch64 ]; then
make -j8 o/third_party/qemu/qemu-aarch64
fi
+3 -4
View File
@@ -25,8 +25,7 @@ DSP_BMP_A_CHECKS = \
DSP_BMP_A_DIRECTDEPS = \
LIBC_NEXGEN32E \
LIBC_TINYMATH \
LIBC_STUBS
LIBC_TINYMATH
DSP_BMP_A_DEPS := \
$(call uniq,$(foreach x,$(DSP_BMP_A_DIRECTDEPS),$($(x))))
@@ -41,11 +40,11 @@ $(DSP_BMP_A).pkg: \
o/$(MODE)/dsp/bmp/float2short.o \
o/$(MODE)/dsp/bmp/scalevolume.o: private \
OVERRIDE_CFLAGS += \
CFLAGS += \
$(MATHEMATICAL)
o/tiny/dsp/bmp/scalevolume.o: private \
OVERRIDE_CFLAGS += \
CFLAGS += \
-Os
DSP_BMP_LIBS = $(foreach x,$(DSP_BMP_ARTIFACTS),$($(x)))
+1 -2
View File
@@ -26,7 +26,7 @@
* @see ITU G.711
*/
int alaw(int x) {
int a, b, e, i;
int a, b, i;
if ((a = x) < 0) a = ~a;
a >>= 4;
if (a > 15) {
@@ -36,7 +36,6 @@ int alaw(int x) {
a -= 16;
a += (b + 1) << 4;
} else {
e = 1;
a -= 16;
a += 16;
}
+1 -2
View File
@@ -7,8 +7,7 @@
*
* @define (a + b) / 2
*/
static inline pureconst artificial unsigned char C11(unsigned char al,
unsigned char bl) {
__funline unsigned char C11(unsigned char al, unsigned char bl) {
short ax;
ax = al;
ax += bl;
+2 -3
View File
@@ -3,9 +3,8 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
forceinline pureconst artificial unsigned char C121(unsigned char al,
unsigned char bl,
unsigned char cl) {
__funline unsigned char C121(unsigned char al, unsigned char bl,
unsigned char cl) {
unsigned short ax, bx;
ax = al;
ax += bl;
+1 -3
View File
@@ -2,9 +2,7 @@
#define COSMOPOLITAN_DSP_CORE_C121S_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
forceinline pureconst artificial signed char C121S(signed char al,
signed char bl,
signed char cl) {
__funline signed char C121S(signed char al, signed char bl, signed char cl) {
short ax, bx;
ax = al;
ax += bl;
+2 -4
View File
@@ -9,10 +9,8 @@
* @see C161() afterward for superior sin(𝑥)/𝑥
* @limit [0,255] → [0..2,044] → [0..255]
*/
forceinline pureconst artificial unsigned char C1331(unsigned char al,
unsigned char bl,
unsigned char cl,
unsigned char dl) {
__funline unsigned char C1331(unsigned char al, unsigned char bl,
unsigned char cl, unsigned char dl) {
short ax, bx;
bx = bl;
bx += cl;
+2 -4
View File
@@ -8,10 +8,8 @@
* @define (1*(a-128)+3*(a-128)+3*(a-128)+1*(a-128))/(1+3+3+1)+128
* @see C1331(), Y420CbCr2RgbScale()
*/
forceinline pureconst artificial signed char C1331S(signed char al,
signed char bl,
signed char cl,
signed char dl) {
__funline signed char C1331S(signed char al, signed char bl, signed char cl,
signed char dl) {
short ax, bx;
bx = bl;
bx += cl;
+2 -3
View File
@@ -12,9 +12,8 @@
* @limit [0..255] → [-510..1,532] → [-127..383] → [0..255]
* @see C1331()
*/
forceinline pureconst artificial unsigned char C161(unsigned char al,
unsigned char bl,
unsigned char cl) {
__funline unsigned char C161(unsigned char al, unsigned char bl,
unsigned char cl) {
short ax, bx, cx;
ax = al;
bx = bl;
+1 -3
View File
@@ -4,9 +4,7 @@
#include "libc/macros.internal.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
forceinline pureconst artificial signed char C161S(signed char al,
signed char bl,
signed char cl) {
__funline signed char C161S(signed char al, signed char bl, signed char cl) {
short ax, bx, cx;
ax = al;
bx = bl;
+2 -3
View File
@@ -9,9 +9,8 @@ COSMOPOLITAN_C_START_
* @define (3*a + 3*b + 1*c) / 7
* @see C1331()
*/
static inline pureconst artificial unsigned char C331(unsigned char al,
unsigned char bl,
unsigned char cl) {
__funline unsigned char C331(unsigned char al, unsigned char bl,
unsigned char cl) {
unsigned eax, ebx, ecx;
eax = al;
ebx = bl;
+6 -15
View File
@@ -8,16 +8,8 @@ DSP_CORE = $(DSP_CORE_A_DEPS) $(DSP_CORE_A)
DSP_CORE_A = o/$(MODE)/dsp/core/core.a
DSP_CORE_A_FILES := $(wildcard dsp/core/*)
DSP_CORE_A_HDRS = $(filter %.h,$(DSP_CORE_A_FILES))
DSP_CORE_A_SRCS_S = $(filter %.S,$(DSP_CORE_A_FILES))
DSP_CORE_A_SRCS_C = $(filter %.c,$(DSP_CORE_A_FILES))
DSP_CORE_A_SRCS = \
$(DSP_CORE_A_SRCS_S) \
$(DSP_CORE_A_SRCS_C)
DSP_CORE_A_OBJS = \
$(DSP_CORE_A_SRCS_S:%.S=o/$(MODE)/%.o) \
$(DSP_CORE_A_SRCS_C:%.c=o/$(MODE)/%.o)
DSP_CORE_A_SRCS = $(filter %.c,$(DSP_CORE_A_FILES))
DSP_CORE_A_OBJS = $(DSP_CORE_A_SRCS:%.c=o/$(MODE)/%.o)
DSP_CORE_A_CHECKS = \
$(DSP_CORE_A).pkg \
@@ -28,8 +20,7 @@ DSP_CORE_A_DIRECTDEPS = \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_STR \
LIBC_TINYMATH \
LIBC_STUBS
LIBC_TINYMATH
DSP_CORE_A_DEPS := \
$(call uniq,$(foreach x,$(DSP_CORE_A_DIRECTDEPS),$($(x))))
@@ -48,15 +39,15 @@ o/$(MODE)/dsp/core/magikarp.o \
o/$(MODE)/dsp/core/c93654369.o \
o/$(MODE)/dsp/core/float2short.o \
o/$(MODE)/dsp/core/scalevolume.o: private \
OVERRIDE_CFLAGS += \
CFLAGS += \
$(MATHEMATICAL)
o/tiny/dsp/core/scalevolume.o: private \
OVERRIDE_CFLAGS += \
CFLAGS += \
-Os
o/$(MODE)/dsp/core/det3.o: private \
OVERRIDE_CFLAGS += \
CFLAGS += \
-ffast-math
DSP_CORE_LIBS = $(foreach x,$(DSP_CORE_ARTIFACTS),$($(x)))
+2 -2
View File
@@ -11,11 +11,11 @@
*
* @see round(), rint()
*/
static inline pureconst artificial long ituround(double x) {
__funline long ituround(double x) {
return floor(x + .5);
}
static inline pureconst artificial int ituroundf(float x) {
__funline int ituroundf(float x) {
return floorf(x + .5f);
}
-39
View File
@@ -1,39 +0,0 @@
/*-*- 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 2020 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"
.balign 16
// Mixes audio.
//
// @param rdi is # aligned int16[16] sample chunks to process
// @param rsi points to aligned pcm s16le input/output memory
// @param rdx points to aligned pcm s16le [0..1] input memory
sad16x8n:
.leafprologue
.profilable
test %rdi,%rdi
jz 1f
shl $3,%rdi
0: sub $8,%rdi
movdqa (%rsi,%rdi,2),%xmm0
paddsw (%rdx,%rdi,2),%xmm0
movdqa %xmm0,(%rsi,%rdi,2)
jnz 0b
1: .leafepilogue
.endfn sad16x8n,globl,hidden
+46
View File
@@ -0,0 +1,46 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 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 "dsp/core/core.h"
#include "libc/limits.h"
#include "libc/macros.internal.h"
#include "third_party/aarch64/arm_neon.internal.h"
#include "third_party/intel/emmintrin.internal.h"
/**
* Mixes audio.
*
* This function performs saturated addition on an array of shorts.
*
* @param x needs to be 16-byte aligned
* @param y needs to be 16-byte aligned
*/
void sad16x8n(size_t n, short x[n][8], const short y[n][8]) {
size_t i, j;
for (i = 0; i < n; ++i) {
#ifdef __x86_64__
*(__m128i *)x[i] = _mm_adds_epi16(*(__m128i *)x[i], *(__m128i *)y[i]);
#elif defined(__aarch64__)
*(int16x4_t *)x[i] = vqadd_s16(*(int16x4_t *)x[i], *(int16x4_t *)y[i]);
#else
for (j = 0; j < 8; ++j) {
x[i][j] = MIN(MAX(x[i][j] + y[i][j], INT16_MIN), INT16_MAX);
}
#endif
}
}
+2 -3
View File
@@ -6,9 +6,8 @@ COSMOPOLITAN_C_START_
/**
* 8-bit linear interpolation kernel.
*/
static inline pureconst artificial unsigned char twixt8(unsigned char al,
unsigned char bl,
unsigned char p) {
__funline unsigned char twixt8(unsigned char al, unsigned char bl,
unsigned char p) {
short bx;
bx = bl;
bx -= al;
+3 -3
View File
@@ -34,10 +34,10 @@ DSP_MPEG_A_DIRECTDEPS = \
LIBC_RUNTIME \
LIBC_STDIO \
LIBC_STR \
LIBC_STUBS \
LIBC_SYSV \
LIBC_TIME \
LIBC_TINYMATH
LIBC_TINYMATH \
THIRD_PARTY_COMPILER_RT
DSP_MPEG_A_DEPS := \
$(call uniq,$(foreach x,$(DSP_MPEG_A_DIRECTDEPS),$($(x))))
@@ -51,7 +51,7 @@ $(DSP_MPEG_A).pkg: \
$(foreach x,$(DSP_MPEG_A_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/dsp/mpeg/clamp4int256-k8.o: private \
OVERRIDE_CFLAGS += \
CFLAGS += \
-Os
DSP_MPEG_LIBS = $(foreach x,$(DSP_MPEG_ARTIFACTS),$($(x)))
+5 -5
View File
@@ -38,11 +38,11 @@
signed char g_magikarp[8];
const signed char kMagikarp[8][8] = {
{-1, -3, 3, 17, 17, 3, -3, -1}, /* 1331+161 derived w/ one off cas */
{-1, -3, 6, 28, 6, -3, -1, 0}, /* no due to the convolution theorem? */
{0, 0, -11, 53, -11, 0, 0, 0}, /* no plus, some random experimenting */
{-2, -6, 2, 22, 22, 2, -6, -2}, /* one a line please clang-format? */
{-3, -9, 1, 27, 27, 1, -9, -3},
{-1, -1, 3, 15, 15, 3, -1, -1}, // magic kernel sharp
{-1, -3, 6, 28, 6, -3, -1, 0}, //
{0, 0, -11, 53, -11, 0, 0, 0}, //
{-2, -6, 2, 22, 22, 2, -6, -2}, //
{-3, -9, 1, 27, 27, 1, -9, -3}, //
};
signed char g_magkern[8];
+1 -3
View File
@@ -31,8 +31,6 @@ DSP_SCALE_A_DIRECTDEPS = \
LIBC_NEXGEN32E \
LIBC_RUNTIME \
LIBC_STR \
LIBC_STUBS \
LIBC_STUBS \
LIBC_TIME \
LIBC_TINYMATH \
LIBC_X
@@ -52,7 +50,7 @@ o/$(MODE)/dsp/scale/cdecimate2xuint8x8.o \
o/$(MODE)/dsp/scale/gyarados.o \
o/$(MODE)/dsp/scale/magikarp.o \
o/$(MODE)/dsp/scale/scale.o: private \
OVERRIDE_CFLAGS += \
CFLAGS += \
$(MATHEMATICAL)
DSP_SCALE_LIBS = $(foreach x,$(DSP_SCALE_ARTIFACTS),$($(x)))
+1 -1
View File
@@ -31,7 +31,7 @@
*/
int ttyconfig(int ttyfd, ttyconf_f fn, int64_t arg,
struct termios *opt_out_oldconf) {
struct termios conf[2];
struct termios conf[2] = {0};
if (tcgetattr(ttyfd, &conf[0]) != -1 &&
fn(memcpy(&conf[1], &conf[0], sizeof(conf[0])), arg) != -1 &&
tcsetattr(ttyfd, TCSAFLUSH, &conf[1]) != -1) {
-1
View File
@@ -17,7 +17,6 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "dsp/tty/tty.h"
#include "libc/intrin/pushpop.h"
#include "libc/dce.h"
#include "libc/log/internal.h"
#include "libc/log/log.h"
+1 -1
View File
@@ -75,7 +75,7 @@ extern char *ttyraster(char *, const struct TtyRgb *, size_t, size_t,
#ifndef ttyquant
#define ttyquant() (&g_ttyquant_)
#define TTYQUANT() VEIL("r", &g_ttyquant_)
#define TTYQUANT() __veil("r", &g_ttyquant_)
#define rgb2tty(...) (ttyquant()->rgb2tty(__VA_ARGS__))
#define tty2rgb(...) (ttyquant()->tty2rgb(__VA_ARGS__))
#define rgb2ttyf(...) (ttyquant()->rgb2ttyf(__VA_ARGS__))
+7 -2
View File
@@ -35,7 +35,6 @@ DSP_TTY_A_DIRECTDEPS = \
LIBC_NT_KERNEL32 \
LIBC_STR \
LIBC_STDIO \
LIBC_STUBS \
LIBC_SOCK \
LIBC_SYSV \
LIBC_TINYMATH \
@@ -54,9 +53,15 @@ $(DSP_TTY_A).pkg: \
$(foreach x,$(DSP_TTY_A_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/dsp/tty/ttyraster.o: private \
OVERRIDE_CFLAGS += \
CFLAGS += \
$(MATHEMATICAL)
ifeq ($(ARCH), aarch64)
# takes 14 seconds to compile with aarch64 gcc
o/$(MODE)/dsp/tty/ttyraster.o: private CFLAGS += -O1
o/$(MODE)/dsp/tty/ttyraster.o: private QUOTA += -C128
endif
DSP_TTY_LIBS = $(foreach x,$(DSP_TTY_ARTIFACTS),$($(x)))
DSP_TTY_SRCS = $(foreach x,$(DSP_TTY_ARTIFACTS),$($(x)_SRCS))
DSP_TTY_HDRS = $(foreach x,$(DSP_TTY_ARTIFACTS),$($(x)_HDRS))
+2 -1
View File
@@ -23,10 +23,11 @@
// @param rdi points to nonempty array
// @param rsi is item count divisible by 16
// @note needs avx2 (haswell+)
.ftrace1
windex_avx2:
.ftrace2
push %rbp
mov %rsp,%rbp
.profilable
and $-32,%rsp
sub $32,%rsp
vmovdqa (%rdi),%ymm1
+2 -1
View File
@@ -23,10 +23,11 @@
// @param rdi points to nonempty array
// @param esi is 16-byte aligned 8+ / 8 multiple array item count
// @note needs sse4 (nehalem+)
.ftrace1
windex_sse4:
.ftrace2
push %rbp
mov %rsp,%rbp
.profilable
mov $8,%eax
sub $32,%rsp
movdqa (%rdi),%xmm2
-41
View File
@@ -1,41 +0,0 @@
/*-*- 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 2020 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/nexgen32e/x86feature.h"
#include "libc/macros.internal.h"
// Dispatches to fastest windex() implementation.
.initbss 300,_init_windex
windex: .quad 0
.endobj windex,globl
.previous
.init.start 300,_init_windex
ezlea windex_avx2,ax
#if !X86_NEED(AVX2)
ezlea windex_sse4,dx
testb X86_HAVE(AVX2)+kCpuids(%rip)
cmovz %rdx,%rax
#endif /* AVX2 */
#if !X86_NEED(SSE4_2)
ezlea windex_k8,dx
testb X86_HAVE(SSE4_2)+kCpuids(%rip)
cmovz %rdx,%rax
#endif /* SSE4 */
stosq
.init.end 300,_init_windex
+41
View File
@@ -0,0 +1,41 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 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 "dsp/tty/windex.h"
#include "dsp/tty/tty.h"
#include "libc/nexgen32e/x86feature.h"
extern unsigned windex_avx2(uint16_t *, size_t);
extern unsigned windex_sse4(uint16_t *, size_t);
extern unsigned windex_k8(uint16_t *, size_t);
unsigned (*windex)(uint16_t *, size_t);
__attribute__((__constructor__)) static void init_windex(void) {
#ifdef __x86_64__
if (X86_HAVE(AVX2)) {
windex = windex_avx2;
} else if (X86_HAVE(SSE4_2)) {
windex = windex_sse4;
} else {
windex = windex_k8;
}
#else
windex = windex_k8;
#endif
}
+1 -1
View File
@@ -3,7 +3,7 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
extern unsigned (*const windex)(uint16_t *, size_t);
extern unsigned (*windex)(uint16_t *, size_t);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
+2 -2
View File
@@ -7,7 +7,7 @@
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/log/log.h"
#include "libc/runtime/runtime.h"
/**
* Automatically launches GDB Debugger TUI during crash.
@@ -41,6 +41,6 @@
int main(int argc, char *argv[]) {
ShowCrashReports();
asm("int3"); /* cf. __die(), perror("msg"), abort(), exit(1), _Exit(1) */
__builtin_trap();
return 0;
}
+1 -7
View File
@@ -23,13 +23,7 @@ int main(int argc, char *argv[]) {
kprintf("try running: o//tool/build/strace.com %s%n", argv[0]);
}
asm volatile("mov\t%4,%%r10\n\t"
"mov\t%5,%%r8\n\t"
"mov\t%6,%%r9\n\t"
"int3"
: /* no outputs */
: "a"(0), "D"(1), "S"(2), "d"(3), "g"(4), "g"(5), "g"(6)
: "r8", "r9", "r10");
__builtin_trap();
printf("recovered from SIGTRAP without handler\r\n");
return 0;
+1 -1
View File
@@ -25,7 +25,7 @@
#include "third_party/mbedtls/ssl.h"
#include "third_party/mbedtls/x509_crt.h"
STATIC_YOINK("ssl_root_support");
__static_yoink("ssl_root_support");
#define MODE_NONE 0
#define MODE_FILE 1
+2 -2
View File
@@ -75,8 +75,8 @@
* the following functions to further expand the information shown by
* the NDEBUG check failure:
*
* STATIC_YOINK("__die");
* STATIC_YOINK("strerror");
* __static_yoink("__die");
* __static_yoink("strerror");
*
* Please note that backtraces aren't ever available in MODE=tiny.
*/
+3 -1
View File
@@ -7,15 +7,17 @@
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/calls/calls.h"
#include "libc/calls/struct/timespec.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/time/time.h"
/**
* @fileoverview clock() function demo
*/
int main(int argc, char *argv[]) {
ShowCrashReports();
unsigned long i;
volatile unsigned long x;
struct timespec now, start, next, interval;
+1
View File
@@ -9,6 +9,7 @@
#endif
#include "libc/calls/struct/timespec.h"
#include "libc/errno.h"
#include "libc/fmt/magnumstrs.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/str/str.h"
+52 -16
View File
@@ -12,14 +12,14 @@
#include "libc/errno.h"
#include "libc/fmt/conv.h"
#include "libc/log/check.h"
#include "libc/mem/mem.h"
#include "libc/mem/gc.internal.h"
#include "libc/mem/mem.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/ex.h"
#include "libc/sysv/consts/exit.h"
#include "third_party/getopt/getopt.h"
#include "third_party/getopt/getopt.internal.h"
#include "third_party/zlib/zlib.h"
#define CHUNK 32768
@@ -48,26 +48,62 @@ FLAGS\n\
// clang-format off
// make -j8 o//examples && dd if=/dev/urandom count=100 | tee a | o//examples/compress.com | o//examples/decompress.com >b && sha1sum a b
/*
#!/bin/bash
# data file is o/dbg/third_party/python/python.com
# level 0 147517 compress 495 MB/s decompress 1.4 GB/s
# level 1 80274 compress 29.2 MB/s decompress 303 MB/s
# level 2 79384 compress 33.8 MB/s decompress 212 MB/s
# level 3 78875 compress 28.9 MB/s decompress 224 MB/s
# level 4 78010 compress 27.1 MB/s decompress 319 MB/s <-- sweet spot?
# level 5 77107 compress 19.5 MB/s decompress 273 MB/s
# level 6 75081 compress 10.0 MB/s decompress 99.3 MB/s
# level 7 75022 compress 7.5 MB/s decompress 287 MB/s
# level 8 75016 compress 5.4 MB/s decompress 109 MB/s
# level 9 75016 compress 5.4 MB/s decompress 344 MB/s
# level 1 348739 compress 22.8 MB/s decompress 444 MB/s
# level 2 347549 compress 37.8 MB/s decompress 457 MB/s
# level 3 346902 compress 33.3 MB/s decompress 463 MB/s
# level 4 345671 compress 29.3 MB/s decompress 467 MB/s
# level 5 344392 compress 22.4 MB/s decompress 506 MB/s
# level 6 342105 compress 10.9 MB/s decompress 516 MB/s
# level 7 342046 compress 7.9 MB/s decompress 515 MB/s
# level 8 342009 compress 5.8 MB/s decompress 518 MB/s
# level 9 342001 compress 5.7 MB/s decompress 524 MB/s
# level F 1 362426 compress 48.2 MB/s decompress 488 MB/s
# level F 2 360875 compress 42.7 MB/s decompress 484 MB/s
# level F 3 359992 compress 37.1 MB/s decompress 499 MB/s
# level F 4 358460 compress 32.9 MB/s decompress 503 MB/s
# level F 5 356431 compress 24.0 MB/s decompress 547 MB/s
# level F 6 352274 compress 11.6 MB/s decompress 558 MB/s
# level F 7 352155 compress 8.7 MB/s decompress 554 MB/s
# level F 8 352065 compress 6.3 MB/s decompress 554 MB/s
# level F 9 352051 compress 6.2 MB/s decompress 556 MB/s
# level L 1 348739 compress 41.1 MB/s decompress 446 MB/s
# level L 2 347549 compress 37.4 MB/s decompress 443 MB/s
# level L 3 346902 compress 32.3 MB/s decompress 462 MB/s
# level L 4 351932 compress 28.8 MB/s decompress 511 MB/s
# level L 5 351384 compress 23.6 MB/s decompress 520 MB/s
# level L 6 351328 compress 12.1 MB/s decompress 522 MB/s
# level L 7 351230 compress 7.3 MB/s decompress 518 MB/s
# level L 8 351192 compress 5.7 MB/s decompress 522 MB/s
# level L 9 351182 compress 6.5 MB/s decompress 519 MB/s
# level R 1 388209 compress 83.1 MB/s decompress 371 MB/s
# level R 2 388209 compress 82.3 MB/s decompress 362 MB/s
# level R 3 388209 compress 81.8 MB/s decompress 361 MB/s
# level R 4 388209 compress 81.7 MB/s decompress 364 MB/s
# level R 5 388209 compress 81.7 MB/s decompress 363 MB/s
# level R 6 388209 compress 80.1 MB/s decompress 359 MB/s
# level R 7 388209 compress 80.3 MB/s decompress 354 MB/s
# level R 8 388209 compress 80.3 MB/s decompress 363 MB/s
# level R 9 388209 compress 81.3 MB/s decompress 364 MB/s
# level H 1 390207 compress 87.6 MB/s decompress 371 MB/s
# level H 2 390207 compress 87.5 MB/s decompress 372 MB/s
# level H 3 390207 compress 85.5 MB/s decompress 364 MB/s
# level H 4 390207 compress 87.3 MB/s decompress 375 MB/s
# level H 5 390207 compress 89.0 MB/s decompress 373 MB/s
# level H 6 390207 compress 87.3 MB/s decompress 372 MB/s
# level H 7 390207 compress 87.0 MB/s decompress 368 MB/s
# level H 8 390207 compress 86.2 MB/s decompress 367 MB/s
# level H 9 390207 compress 86.9 MB/s decompress 369 MB/s
m=
make -j8 MODE=$m o/$m/examples || exit
for strategy in ' ' F L R H; do
for level in $(seq 1 9); do
for strategy in F L R H; do
o/$m/examples/compress.com -$strategy$level <o/dbg/third_party/python/python.com | dd count=10000 2>/tmp/info >/tmp/comp
o/$m/examples/compress.com -$level$strategy <o/dbg/third_party/python/python.com | dd count=10000 2>/tmp/info >/tmp/comp
compspeed=$(grep -Po '[.\d]+ \w+/s' /tmp/info)
o/$m/examples/decompress.com </tmp/comp | dd count=10000 2>/tmp/info >/dev/null
decompspeed=$(grep -Po '[.\d]+ \w+/s' /tmp/info)
size=$(o/$m/examples/compress.com -$strategy$level <o/$m/examples/compress.com | wc -c)
size=$(o/$m/examples/compress.com -$level$strategy <o/$m/examples/compress.com | wc -c)
echo "level $strategy $level $size compress $compspeed decompress $decompspeed"
done
done
@@ -174,7 +210,7 @@ const char *zerr(int rc) {
case Z_VERSION_ERROR:
return "zlib version mismatch!";
default:
unreachable;
__builtin_unreachable();
}
}
+9 -4
View File
@@ -8,7 +8,8 @@
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/intrin/kprintf.h"
#include "libc/log/log.h"
#include "libc/math.h"
#include "libc/runtime/runtime.h"
#include "libc/runtime/symbols.internal.h"
/**
@@ -24,14 +25,18 @@
* o//examples/crashreport.com
*/
noubsan int main(int argc, char *argv[]) {
dontubsan int main(int argc, char *argv[]) {
kprintf("----------------\n");
kprintf(" THIS IS A TEST \n");
kprintf("SIMULATING CRASH\n");
kprintf("----------------\n");
volatile int64_t x;
ShowCrashReports();
volatile double a = 0;
volatile double b = 23;
volatile double c = exp(b) / a;
volatile int64_t x;
return 1 / (x = 0);
}
+1 -1
View File
@@ -9,7 +9,7 @@
#endif
#include "libc/calls/calls.h"
#include "libc/calls/struct/sigset.h"
#include "libc/log/log.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
/**
+1 -1
View File
@@ -14,7 +14,7 @@
#include "libc/x/x.h"
#include "net/http/escape.h"
#include "net/http/http.h"
#include "third_party/getopt/getopt.h"
#include "third_party/getopt/getopt.internal.h"
#include "third_party/stb/stb_image.h"
#define USAGE \
+57 -6
View File
@@ -7,15 +7,66 @@
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/mem/gc.h"
#include "libc/stdio/stdio.h"
#include "libc/x/xiso8601.h"
#include "libc/calls/calls.h"
#include "libc/calls/struct/timespec.h"
#include "libc/str/str.h"
#include "libc/time/struct/tm.h"
/**
* @fileoverview ISO-8601 international high-precision timestamp printer.
* @fileoverview High performance ISO-8601 timestamp formatter.
*/
char *GetTimestamp(void) {
int x;
struct timespec ts;
_Thread_local static long last;
_Thread_local static char s[27];
_Thread_local static struct tm tm;
clock_gettime(0, &ts);
if (ts.tv_sec != last) {
localtime_r(&ts.tv_sec, &tm);
x = tm.tm_year + 1900;
s[0] = '0' + x / 1000;
s[1] = '0' + x / 100 % 10;
s[2] = '0' + x / 10 % 10;
s[3] = '0' + x % 10;
s[4] = '-';
x = tm.tm_mon + 1;
s[5] = '0' + x / 10;
s[6] = '0' + x % 10;
s[7] = '-';
x = tm.tm_mday;
s[8] = '0' + x / 10;
s[9] = '0' + x % 10;
s[10] = 'T';
x = tm.tm_hour;
s[11] = '0' + x / 10;
s[12] = '0' + x % 10;
s[13] = ':';
x = tm.tm_min;
s[14] = '0' + x / 10;
s[15] = '0' + x % 10;
s[16] = ':';
x = tm.tm_sec;
s[17] = '0' + x / 10;
s[18] = '0' + x % 10;
s[19] = '.';
s[26] = 0;
last = ts.tv_sec;
}
x = ts.tv_nsec;
s[20] = '0' + x / 100000000;
s[21] = '0' + x / 10000000 % 10;
s[22] = '0' + x / 1000000 % 10;
s[23] = '0' + x / 100000 % 10;
s[24] = '0' + x / 10000 % 10;
s[25] = '0' + x / 1000 % 10;
return s;
}
int main(int argc, char *argv[]) {
puts(_gc(xiso8601ts(NULL)));
return 0;
char buf[128], *p = buf;
p = stpcpy(p, GetTimestamp());
p = stpcpy(p, "\n");
write(1, buf, p - buf);
}
+2 -31
View File
@@ -10,43 +10,14 @@
#include "libc/assert.h"
#include "libc/calls/calls.h"
#include "libc/errno.h"
#include "libc/mem/mem.h"
#include "libc/mem/gc.internal.h"
#include "libc/mem/mem.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "third_party/zlib/zlib.h"
#define CHUNK 32768
// clang-format off
// make -j8 o//examples && dd if=/dev/urandom count=100 | tee a | o//examples/compress.com | o//examples/decompress.com >b && sha1sum a b
/*
# data file is o/dbg/third_party/python/python.com
# level 0 147517 compress 495 MB/s decompress 1.4 GB/s
# level 1 80274 compress 29.2 MB/s decompress 303 MB/s
# level 2 79384 compress 33.8 MB/s decompress 212 MB/s
# level 3 78875 compress 28.9 MB/s decompress 224 MB/s
# level 4 78010 compress 27.1 MB/s decompress 319 MB/s <-- sweet spot?
# level 5 77107 compress 19.5 MB/s decompress 273 MB/s
# level 6 75081 compress 10.0 MB/s decompress 99.3 MB/s
# level 7 75022 compress 7.5 MB/s decompress 287 MB/s
# level 8 75016 compress 5.4 MB/s decompress 109 MB/s
# level 9 75016 compress 5.4 MB/s decompress 344 MB/s
m=
make -j8 MODE=$m o/$m/examples || exit
for level in $(seq 0 9); do
for strategy in F L R H; do
o/$m/examples/compress.com -$strategy$level <o/dbg/third_party/python/python.com | dd count=10000 2>/tmp/info >/tmp/comp
compspeed=$(grep -Po '[.\d]+ \w+/s' /tmp/info)
o/$m/examples/decompress.com </tmp/comp | dd count=10000 2>/tmp/info >/dev/null
decompspeed=$(grep -Po '[.\d]+ \w+/s' /tmp/info)
size=$(o/$m/examples/compress.com -$strategy$level <o/$m/examples/compress.com | wc -c)
echo "level $strategy $level $size compress $compspeed decompress $decompspeed"
done
done
*/
// clang-format on
int decompressor(int infd, int outfd) {
int rc;
unsigned have;
@@ -111,7 +82,7 @@ const char *zerr(int rc) {
case Z_VERSION_ERROR:
return "zlib version mismatch!";
default:
unreachable;
__builtin_unreachable();
}
}
+5 -5
View File
@@ -59,7 +59,6 @@ EXAMPLES_DIRECTDEPS = \
LIBC_SOCK \
LIBC_STDIO \
LIBC_STR \
LIBC_STUBS \
LIBC_SYSV \
LIBC_SYSV_CALLS \
LIBC_TESTLIB \
@@ -77,10 +76,10 @@ EXAMPLES_DIRECTDEPS = \
THIRD_PARTY_DOUBLECONVERSION \
THIRD_PARTY_GDTOA \
THIRD_PARTY_GETOPT \
THIRD_PARTY_HIREDIS \
THIRD_PARTY_LIBCXX \
THIRD_PARTY_LINENOISE \
THIRD_PARTY_LUA \
THIRD_PARTY_HIREDIS \
THIRD_PARTY_MBEDTLS \
THIRD_PARTY_MUSL \
THIRD_PARTY_NSYNC \
@@ -103,7 +102,7 @@ o/$(MODE)/examples/examples.pkg: \
$(foreach x,$(EXAMPLES_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/examples/unbourne.o: private \
OVERRIDE_CPPFLAGS += \
CPPFLAGS += \
-DSTACK_FRAME_UNLIMITED \
-fpie
@@ -162,13 +161,14 @@ o/$(MODE)/examples/nesemu1.com.dbg: \
o/$(MODE)/examples/symtab.com: \
o/$(MODE)/examples/symtab.com.dbg \
o/$(MODE)/third_party/zip/zip.com \
o/$(MODE)/tool/build/symtab.com
o/$(MODE)/tool/build/symtab.com \
$(VM)
@$(MAKE_OBJCOPY)
@$(MAKE_SYMTAB_CREATE)
@$(MAKE_SYMTAB_ZIP)
o/$(MODE)/examples/picol.o: private \
OVERRIDE_CPPFLAGS += \
CPPFLAGS += \
-DSTACK_FRAME_UNLIMITED
o/$(MODE)/examples/picol.com.dbg: \
+1 -1
View File
@@ -13,7 +13,7 @@
#include "libc/stdio/stdio.h"
#include "libc/sysv/consts/sig.h"
STATIC_YOINK("strerror");
__static_yoink("strerror");
int main(int argc, char *argv[]) {
sigset_t ss;
+3 -3
View File
@@ -29,7 +29,7 @@
#include "libc/sysv/consts/grnd.h"
#include "libc/sysv/consts/sig.h"
#include "libc/testlib/hyperion.h"
#include "third_party/getopt/getopt.h"
#include "third_party/getopt/getopt.internal.h"
#define B 4096
@@ -77,8 +77,8 @@ uint64_t unixv7(void) {
uint64_t ape(void) {
static int i;
if ((i += 8) > _end - _base) i = 8;
return READ64LE(_base + i);
if ((i += 8) > _end - __executable_start) i = 8;
return READ64LE(__executable_start + i);
}
uint64_t moby(void) {
+2 -2
View File
@@ -176,7 +176,7 @@ void *Worker(void *id) {
// inherited by the accepted sockets, but using them also has the
// side-effect that the listening socket fails with EAGAIN, every
// several seconds. we can use that to our advantage to check for
// the ctrl-c shutdowne event; otherwise, we retry the accept call
// the ctrl-c shutdowne event; otherwise we retry the accept call
continue;
}
@@ -189,7 +189,7 @@ void *Worker(void *id) {
// we're not terrible concerned when errors happen here
if ((got = read(client, inbuf, sizeof(inbuf))) <= 0) break;
// check that client message wasn't fragmented into more reads
if (!(inmsglen = ParseHttpMessage(&msg, inbuf, got))) break;
if ((inmsglen = ParseHttpMessage(&msg, inbuf, got)) <= 0) break;
++messages;
#if LOGGING
+1 -4
View File
@@ -7,12 +7,9 @@
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/calls/calls.h"
#include "libc/stdio/stdio.h"
STATIC_YOINK("mmap"); // TODO: fix bandaid for MODE=asan
int main() {
printf("%s\n", "hello world");
printf("hello world\n");
return 0;
}
+2 -2
View File
@@ -8,10 +8,10 @@
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/errno.h"
#include "libc/fmt/fmt.h"
#include "libc/math.h"
#include "libc/stdio/stdio.h"
int main() {
printf("%`'s\n", "hello\1\2world→→");
printf("%g %`'s\n", M_PI, "hello\1\2world→→");
return errno;
}
+1 -1
View File
@@ -16,7 +16,7 @@
#include "libc/x/xasprintf.h"
#include "net/http/escape.h"
#include "net/http/http.h"
#include "third_party/getopt/getopt.h"
#include "third_party/getopt/getopt.internal.h"
#include "third_party/stb/stb_image.h"
#define USAGE \
+1 -1
View File
@@ -355,7 +355,7 @@ int getCursorPosition(int64_t ifd, int64_t ofd, int *rows, int *cols) {
* Returns 0 on success, -1 on error. */
int getWindowSize(int64_t ifd, int64_t ofd, int *rows, int *cols) {
struct winsize ws;
if (_getttysize(1, &ws) == -1 || ws.ws_col == 0) {
if (tcgetwinsize(1, &ws) == -1 || ws.ws_col == 0) {
/* ioctl() failed. Try to query the terminal itself. */
int orig_row, orig_col, retval;
+1 -1
View File
@@ -25,7 +25,7 @@
#include "libc/sysv/consts/so.h"
#include "libc/sysv/consts/sock.h"
#include "libc/sysv/consts/sol.h"
#include "third_party/getopt/getopt.h"
#include "third_party/getopt/getopt.internal.h"
/**
* @fileoverview netcat clone
+5 -4
View File
@@ -14,6 +14,7 @@
#include "libc/calls/calls.h"
#include "libc/calls/struct/itimerval.h"
#include "libc/calls/struct/winsize.h"
#include "libc/calls/termios.h"
#include "libc/errno.h"
#include "libc/fmt/conv.h"
#include "libc/fmt/fmt.h"
@@ -41,13 +42,13 @@
#include "libc/time/time.h"
#include "libc/x/xasprintf.h"
#include "libc/x/xsigaction.h"
#include "libc/zip.h"
#include "libc/zip.internal.h"
#include "libc/zipos/zipos.internal.h"
#include "third_party/getopt/getopt.h"
#include "third_party/getopt/getopt.internal.h"
#include "third_party/libcxx/vector"
#include "tool/viz/lib/knobs.h"
STATIC_YOINK("zipos");
__static_yoink("zipos");
#define USAGE \
" [ROM] [FMV]\n\
@@ -287,7 +288,7 @@ void GetTermSize(void) {
struct winsize wsize_;
wsize_.ws_row = 25;
wsize_.ws_col = 80;
_getttysize(0, &wsize_);
tcgetwinsize(0, &wsize_);
FreeSamplingSolution(ssy_);
FreeSamplingSolution(ssx_);
tyn_ = wsize_.ws_row * 2;
+1 -1
View File
@@ -20,7 +20,7 @@
*/
int main(int argc, char *argv[]) {
if (_base[0] == 'M' && _base[1] == 'Z') {
if (__executable_start[0] == 'M' && __executable_start[1] == 'Z') {
printf("success: %s spawned without needing to modify its "
"executable header",
argv[0]);
-1
View File
@@ -43,7 +43,6 @@ EXAMPLES_PACKAGE_DIRECTDEPS = \
EXAMPLES_PACKAGE_LIB \
LIBC_INTRIN \
LIBC_STDIO \
LIBC_STUBS \
LIBC_TINYMATH
# Evaluates the set of transitive package dependencies.
+5 -2
View File
@@ -69,10 +69,9 @@ EXAMPLES_PACKAGE_LIB_A_CHECKS = \
# Lists packages whose symbols are or may be directly referenced here.
# Note that linking stubs is always a good idea due to synthetic code.
EXAMPLES_PACKAGE_LIB_A_DIRECTDEPS = \
LIBC_STDIO \
LIBC_INTRIN \
LIBC_NEXGEN32E \
LIBC_STUBS
LIBC_STDIO
# Evaluates variable as set of transitive package dependencies.
EXAMPLES_PACKAGE_LIB_A_DEPS := \
@@ -96,6 +95,10 @@ $(EXAMPLES_PACKAGE_LIB_A).pkg: \
# Invalidates objects in package when makefile is edited.
$(EXAMPLES_PACKAGE_LIB_A_OBJS): examples/package/lib/build.mk
# let these assembly objects build on aarch64
o/$(MODE)/examples/package/lib/myasm.o: examples/package/lib/myasm.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
EXAMPLES_PACKAGE_LIB_LIBS = $(foreach x,$(EXAMPLES_PACKAGE_LIB_ARTIFACTS),$($(x)))
EXAMPLES_PACKAGE_LIB_SRCS = $(foreach x,$(EXAMPLES_PACKAGE_LIB_ARTIFACTS),$($(x)_SRCS))
EXAMPLES_PACKAGE_LIB_HDRS = $(foreach x,$(EXAMPLES_PACKAGE_LIB_ARTIFACTS),$($(x)_HDRS))
Loaded 100 of 8891 files, more files were not shown because too many files have changed in this diff. Show more