Compare commits

..
288 Commits
Author SHA1 Message Date
Gautham ace523c79b Tell _frozen_importlib to consider bytecode first (#248) 2021-08-17 22:07:27 -07:00
Justine Tunney c70422586a Support optimize flag 2021-08-17 14:07:59 -07:00
Justine Tunney cabb0a7ede Get Python compiler working
It turns out we needed a file length field.
2021-08-17 12:14:47 -07:00
Justine Tunney 38aece42ba Add Python object dump tool 2021-08-17 12:11:29 -07:00
Justine Tunney f66ef5d58e Change stuff 2021-08-17 10:20:55 -07:00
Justine Tunney 0c6581f912 Attempt to build Python compiler program 2021-08-17 06:28:23 -07:00
Justine Tunney d522a88def Get freeze importlib program working 2021-08-17 01:27:03 -07:00
Justine Tunney 795d6fd6cd Disable zipos trace 2021-08-17 01:26:48 -07:00
Justine Tunney d3a735702b Use real malloc so we can test Python with ASAN 2021-08-17 01:25:04 -07:00
Justine Tunney 214e3a68a9 Let's make imports simple 2021-08-17 00:10:24 -07:00
Justine Tunney 3d0347e26e Improve deltaify.com program
This program deserves its own project page on http://justine.lol since
it's so good at troubleshooting latency, e.g. `make |& deltaify.com`
2021-08-17 00:06:45 -07:00
Justine Tunney bc464a8898 Fix a few more Python tests 2021-08-16 23:47:47 -07:00
Justine Tunney 59e1c245d1 Get more Python tests passing (#141) 2021-08-16 15:26:31 -07:00
Paul Kulchenko 916f19eea1 Add GetRandomBytes to redbean Lua (#244) 2021-08-16 12:12:29 -07:00
Justine Tunney 5029e20bef Improve linenoise and get it working on Windows
Some progress has been made on introducing completion but there's been
difficulties using the Python C API to get local shell variables.
2021-08-15 14:34:05 -07:00
Gautham 968474d291 Fix typo bug in strtoll (#245) 2021-08-15 12:07:33 -07:00
Justine Tunney 228fb7428b Improve isystem includes and magic numbers 2021-08-14 23:36:36 -07:00
Justine Tunney 1e5bd4d23e Ues linenoise in Lua, Python, and SQLite 2021-08-14 11:26:23 -07:00
Justine Tunney fe29710e4e Add linenoise to third party 2021-08-14 11:09:54 -07:00
Justine Tunney 579b597ded Refactor out some duplicated code 2021-08-14 06:17:56 -07:00
Justine Tunney e963d9c8e3 Add cpu / mem / fsz limits to build system
Thanks to all the refactorings we now have the ability to enforce
reasonable limitations on the amount of resources any individual
compile or test can consume. Those limits are currently:

- `-C 8` seconds of 3.1ghz CPU time
- `-M 256mebibytes` of virtual memory
- `-F 100megabyte` limit on file size

Only one file currently needs to exceed these limits:

    o/$(MODE)/third_party/python/Objects/unicodeobject.o: \
        QUOTA += -C16  # overrides cpu limit to 16 seconds

This change introduces a new sizetol() function to LIBC_FMT for parsing
byte or bit size strings with Si unit suffixes. Functions like atoi()
have been rewritten too.
2021-08-13 23:40:53 -07:00
Justine Tunney 9b29358511 Make whitespace changes
Status lines for Emacs and Vim have been added to Python sources so
they'll be easier to edit using Python's preferred coding style.

Some DNS helper functions have been broken up into multiple files. It's
nice to have one function per file whenever possible, since that way we
don't need -ffunction-sections.  Another reason it's good to have small
source files, is because the build will be enforcing resource limits on
compilation and testing soon.
2021-08-13 03:20:45 -07:00
Justine Tunney 71273bc5c9 Revert explicit Lua GC pass (#241) 2021-08-13 03:06:23 -07:00
Gautham 1aa0df696c Test changes to Actually Portable Python (#240)
- Add missing `os.pipe` and `os.getuid`
- Commented out _dummy_thread from Lib/threading.py so tests
  don't simulate multi-threading and waste time/error out
- Revert test_hashlib to avoid blake2
2021-08-13 02:24:43 -07:00
Paul Kulchenko a22f0736d8 Improve Redbean Lua memory (#241)
- Update redbean Lua to check there is enough stack to use
- Add explicit Lua gc pass after each message is processed
- Add Lua memory reporting to redbean
2021-08-13 02:11:49 -07:00
Justine Tunney b420ed8248 Undiamond Python headers
This change gets the Python codebase into a state where it conforms to
the conventions of this codebase. It's now possible to include headers
from Python, without worrying about ordering. Python has traditionally
solved that problem by "diamonding" everything in Python.h, but that's
problematic since it means any change to any Python header invalidates
all the build artifacts. Lastly it makes tooling not work. Since it is
hard to explain to Emacs when I press C-c C-h to add an import line it
shouldn't add the header that actually defines the symbol, and instead
do follow the nonstandard Python convention.

Progress has been made on letting Python load source code from the zip
executable structure via the standard C library APIs. System calss now
recognizes zip!FILENAME alternative URIs as equivalent to zip:FILENAME
since Python uses colon as its delimiter.

Some progress has been made on embedding the notice license terms into
the Python object code. This is easier said than done since Python has
an extremely complicated ownership story.

- Some termios APIs have been added
- Implement rewinddir() dirstream API
- GetCpuCount() API added to Cosmopolitan Libc
- More bugs in Cosmopolitan Libc have been fixed
- zipobj.com now has flags for mangling the path
- Fixed bug a priori with sendfile() on certain BSDs
- Polyfill F_DUPFD and F_DUPFD_CLOEXEC across platforms
- FIOCLEX / FIONCLEX now polyfilled for fast O_CLOEXEC changes
- APE now supports a hybrid solution to no-self-modify for builds
- Many BSD-only magnums added, e.g. O_SEARCH, O_SHLOCK, SF_NODISKIO
2021-08-12 14:07:40 -07:00
Paul Kulchenko 20bb8db9f8 Fix type signature of new Lua hooks (#239) 2021-08-12 00:15:39 -07:00
Paul Kulchenko a2e443edd7 Update redbean to show Lua stack traces (#237)
- Update redbean to include stack trace in Lua errors
- Extend Lua in redbean to include stack trace in all logged errors
- Update default error page in redbean with error details (when allowed)
- Prepend `@` to Lua paths in redbean to recognize them as paths in error messages
- Replace GetClientAddr with GetRemoteAddr to avoid backtrace leak in proxy scenarios
- Fix typo in GetRemoteAddr documentation
2021-08-11 23:27:39 -07:00
Gautham 9454788223 Fix sysconfig check for build vars (#238) 2021-08-11 23:21:54 -07:00
Justine Tunney 31a37aeb1a Fix some example code 2021-08-10 13:38:27 -07:00
Justine Tunney 79ba5233db Fix regression caused by state assertions change 2021-08-10 11:36:17 -07:00
Justine Tunney d26d7ae0e4 Perform build and magnum tuning
Building o//third_party/python now takes 5 seconds on my PC

This change works towards modifying Python to use runtime dispatching
when appropriate. For example, when loading the magnums in the socket
module, it's a good idea to check if the magnum is zero, because that
means the local system platform doesn't support it.
2021-08-10 10:26:13 -07:00
Justine Tunney ee7e296339 Add state assertions to redbean Lua APIs
Many of the API functions provided by redbean are only appropriate to
call in certain contexts, such as request handling or .init.lua, etc.
For example, Fetch can't be called from the global scope of .init.lua
because SSL hasn't been configured yet. Earlier if this happened then
redbean would crash, which was confusing. What we'll do now is show a
friendly error message. See #97

This change also undocuments redbean ssl compression support since it
seems to be causing a flake in the testing infrastructure.
2021-08-09 15:35:38 -07:00
Justine Tunney 3bfb7580c5 Add Lua compiler
Redbean Lua Server Pages may now be stored in the zip as byte code. This
can improve performance, since redbean currently doesn't cache byte code
but it might be more useful for anyone wanting to create a closed source
redbean. The .lua extension should be used for byte code files. Lua will
tell them apart based on a magic number at the start of the file.

This change also improves some Lua error reporting conditions. See #97
2021-08-09 13:09:14 -07:00
Justine Tunney b703eee96e Fix obvious Python performance suboptimality 2021-08-09 10:41:06 -07:00
Justine Tunney 5a441ea57f Remove Python gitignore 2021-08-09 09:15:23 -07:00
Justine Tunney 10aade69e3 Remove wildcard from Python build config
It's important for build performance to use := rather than = notation so
that $(wildcard foo/*) isn't a lazily evaluated lambda. In the case of
Python where we need a lot of tuning and excludes, it should help to
spell things out a bit more to just not use wildcard for now.
2021-08-09 08:59:18 -07:00
Justine Tunney 53b9f83e1c Make redbean SSL more tunable
This change enables SSL compression. It significantly reduces the
network load of the testing infrastructure, for free, since this
revision didn't need to change any runit protocol code. However we
turn it off by default in redbean since no browsers support it.

It turns out that some TLSv1.0 clients (e.g. curl command on RHEL5) will
send an SSLv2-style ClientHello. These types of clients are usually ten+
years old and were designed to interop with servers ten years older than
them. Your redbean is now able to interop with these clients even though
redbean doesn't actually support SSLv2 or SSLv3. Please note that the -B
flag may be passed to disable this along with TLSv1.0, TLSv1.1, 3DES, &c

The following Lua APIs have been added to redbean:

  - ProgramSslCompression(bool)
  - ProgramSslCiphersuite(name:str)
  - ProgramSslPresharedKey(key:str,identity:str)

Lastly the DHE ciphersuites have been enabled. IANA recommends DHE and
with old clients like RHEL5 it's the only perfect forward secrecy they
implement.
2021-08-09 07:38:57 -07:00
Justine Tunney d86027fe90 Integrate Chromium Zlib changes 2021-08-09 06:59:10 -07:00
Justine Tunney 798d542f15 Fix build and delete superfluous files
- Make Python make formatting pristine
- Add missing `#pragma weak` to Python source
- Fix Clang script flake due to missing directory
2021-08-09 06:57:14 -07:00
ahgamut 295b3d6ca5 removed unnecessary libs from zip store 2021-08-09 05:39:42 -07:00
ahgamut f9eae9794a stdlib sysconfig import fix 2021-08-09 05:39:42 -07:00
ahgamut 98f330b764 Added build config to get python.com
Modules/Setup and Modules/Setup.local contain the build recipes for
various extensions, wrote a custom script to translate them for
python.mk. Modules/config.c needs to be changed if any extensions are
removed or added.

Most of the source modifications are for missing headers or compile time
build vars like ABIFLAGS.

Created separate mk files for the C extensions and the Python stdlib.
Can use find for adding the python files to the APE ZIP store, but right
now necessary files are just hardcoded.

python.com loads but some build configs are still missing (showing 1 Jan
1970 as time of compilation).
2021-08-09 05:39:42 -07:00
ahgamut 5ef64dbcdb Source changes for compilation
These are the commits from
https://github.com/ahgamut/cpython/tree/cosmo_py36 squashed for
simplicity.

Also included is the pyconfig.h used for compilation. The pyconfig.h has
to be changed manually in case Cosmopolitan gets new features.
2021-08-09 05:39:42 -07:00
ahgamut 0c4c56ff39 python-3.6.zip added from Github
README.cosmo contains the necessary links.
2021-08-09 05:39:42 -07:00
Robert Hencke 75fc601ff5 Only re-open executable as O_RDWR if .ape present (#234)
AWS Lambda uses a nonstandard kernel behavior that causes
OpenExecutable() to SIGSEGV after redbean restores its APE
header. This change fixes a bug so that Lambda users may
work around the issue by removing the `.ape` file inside the
zip structure of redbean.com.

Fixes #233
2021-08-09 00:52:54 -07:00
Justine Tunney 28a592f2d4 Clarify kLogFatal documentation
Fixes #231
2021-08-07 18:18:12 -07:00
w13b3 d8faadf44e Fix redbean Log() in global scope (#230) 2021-08-07 17:30:49 -07:00
Justine Tunney 4daafef63a Implement RFC8442 2021-08-07 16:43:00 -07:00
Paul Kulchenko 2bc0901ce3 Revert adding lua array per discussion in #222 (#229)
This reverts commit 55a15c204e.
2021-08-07 15:20:33 -07:00
Paul Kulchenko 6bbb44c165 Add GetHostOs to redbean (#228) 2021-08-07 14:25:55 -07:00
Justine Tunney 0cdba6878b Secure the testing infrastructure 2021-08-07 13:22:35 -07:00
Justine Tunney 1f766a332f Add function for creating hex string literals 2021-08-07 07:05:19 -07:00
Justine Tunney aeeb851422 Fix bugs and make improvements to redbean
- Abort if .init.lua fails
- Refactor redbean to use new append library
- Use first certificate if SNI routing fails
- Use function/data sections when building Lua
- Don't use self-signed auto-generated cert for client
- Add -D staging dirs to redbean lua module default path
2021-08-06 14:18:34 -07:00
Paul Kulchenko 55a15c204e Add arrays to Lua (#222)
You can now have O(1) length and append.
2021-08-06 04:55:01 -07:00
Paul Kulchenko b142ea7176 Add following redirects to redbean Fetch (#226) 2021-08-06 04:48:46 -07:00
Paul Kulchenko fd76fa0016 Fix OnServerStart/Stop hooks (#225)
Fixes #224
2021-08-06 04:27:50 -07:00
Justine Tunney 533f3d1ef1 Reduce build latency and fix old cpu bugs 2021-08-05 14:43:53 -07:00
Justine Tunney df8ab0aa0c Restore Referer-Policy and wrap up MbedTLS changes
redbean will now set Referer-Policy to no-referrer-when-downgrade on
text/html responses by default. There's better explanations on the bits
of security redbean is offering. In short, it's 128+ for modern clients
and 112+ for legacy. If the -B flag is used then it's 192+ for modern
and 150+ for non-EC.
2021-08-04 01:05:49 -07:00
Paul Kulchenko 344d2dc356 Redbean doc update (#221)
- Update redbean documentation for consistency and fix typo (#97)
- Update redbean constants for consistency
- Add Fetch documentation to redbean (#97)
2021-08-03 17:57:15 -07:00
Paul Kulchenko f7b4804251 Add Sleep API to redbean (#220) 2021-08-02 14:53:24 -07:00
Paul Kulchenko 64d87d4e5a Add GetRedbeanVersion & rename GetVersion (#219)
- Add GetRedbeanVersion() to redbean (#97)
- Rename GetVersion to GetHttpVersion() for consistency (#97)
- Update Content-Length format to use a proper size modifier (#97, #218)
2021-08-02 14:46:43 -07:00
Paul Kulchenko 0b317523a0 Accept table arg in redbean Fetch() API (#218) 2021-07-28 09:33:10 -07:00
Paul Kulchenko a73e808b25 Upgrade Lua to 5.4.3 (#217)
Based on https://github.com/lua/lua/releases/tag/v5.4.3 (commit eadd8c7).
2021-07-28 09:26:35 -07:00
Paul Kulchenko 3ac6576fe5 Improve type descriptions in redbean help (#213) 2021-07-28 09:22:13 -07:00
Paul Kulchenko 312ccc919b Fix redbean help typos (#212) 2021-07-28 09:20:24 -07:00
Justine Tunney ea83cc0ad0 Make stronger crypto nearly as fast
One of the disadvantages of x25519 and ℘256 is it only provides 126 bits
of security, so that seems like a weak link in the chain, if we're using
ECDHE-ECDSA-AES256-GCM-SHA384. The U.S. government wants classified data
to be encrypted using a curve at least as strong as ℘384, which provides
192 bits of security, but if you read the consensus of stack exchange it
would give you the impression that ℘384 is three times slower.

This change (as well as the previous one) makes ℘384 three times as fast
by tuning its modulus and multiplication subroutines with new tests that
should convincingly show: the optimized code behaves the same way as the
old code. Some of the diff noise from the previous change is now removed
too, so that our vendored fork can be more easily compared with upstream
sources. So you can now have stronger cryptography without compromises.

℘384 modulus Justine                        l:         28𝑐          9𝑛𝑠
℘384 modulus MbedTLS NIST                   l:        127𝑐         41𝑛𝑠
℘384 modulus MbedTLS MPI                    l:      1,850𝑐        597𝑛𝑠

The benchmarks above show the improvements made by secp384r1() which is
an important function since it needs to be called 13,000 times whenever
someone establishes a connection to your web server. The same's true of
Mul6x6Adx() which is able to multiply 384-bit numbers in 73 cycles, but
only if your CPU was purchased after 2014 when Broadwell was introduced
2021-07-26 16:19:45 -07:00
Justine Tunney 398f0c16fb Add SNI support to redbean and improve SSL perf
This change makes SSL virtual hosting possible. You can now load
multiple certificates for multiple domains and redbean will just
figure out which one to use, even if you only have 1 ip address.
You can also use a jumbo certificate that lists all your domains
in the the subject alternative names.

This change also makes performance improvements to MbedTLS. Here
are some benchmarks vs. cc1920749e

                                   BEFORE    AFTER   (microsecs)
suite_ssl.com                     2512881   191738 13.11x faster
suite_pkparse.com                   36291     3295 11.01x faster
suite_x509parse.com                854669   120293  7.10x faster
suite_pkwrite.com                    6549     1265  5.18x faster
suite_ecdsa.com                     53347    18778  2.84x faster
suite_pk.com                        49051    18717  2.62x faster
suite_ecdh.com                      19535     9502  2.06x faster
suite_shax.com                      15848     7965  1.99x faster
suite_rsa.com                      353257   184828  1.91x faster
suite_x509write.com                162646    85733  1.90x faster
suite_ecp.com                       20503    11050  1.86x faster
suite_hmac_drbg.no_reseed.com       19528    11417  1.71x faster
suite_hmac_drbg.nopr.com            12460     8010  1.56x faster
suite_mpi.com                      687124   442661  1.55x faster
suite_hmac_drbg.pr.com              11890     7752  1.53x faster

There aren't any special tricks to the performance imporvements.
It's mostly due to code cleanup, assembly and intel instructions
like mulx, adox, and adcx.
2021-07-23 13:56:13 -07:00
Justine Tunney f3e28aa192 Make SSL handshakes much faster
This change boosts SSL handshake performance from 2,627 to ~10,000 per
second which is the same level of performance as NGINX at establishing
secure connections. That's impressive if we consider that redbean is a
forking frontend application server. This was accomplished by:

  1. Enabling either SSL session caching or SSL tickets. We choose to
     use tickets since they reduce network round trips too and that's
     a more important metric than wrk'ing localhost.

  2. Fixing mbedtls_mpi_sub_abs() which is the most frequently called
     function. It's called about 12,000 times during an SSL handshake
     since it's the basis of most arithmetic operations like addition
     and for some strange reason it was designed to make two needless
     copies in addition to calling malloc and free. That's now fixed.

  3. Improving TLS output buffering during the SSL handshake only, so
     that only a single is write and read system call is needed until
     blocking on the ping pong.

redbean will now do a better job wiping sensitive memory from a child
process as soon as it's not needed. The nice thing about fork is it's
much faster than reverse proxying so the goal is to use the different
address spaces along with setuid() to minimize the risk that a server
key will be compromised in the event that application code is hacked.
2021-07-11 23:17:47 -07:00
Justine Tunney 8c4cce043c Make improvements to redbean
The following Lua APIs have been added:

  - IsDaemon() → bool
  - ProgramPidPath(str)

The following Lua hooks have been added:

  - OnClientConnection(ip:int,port:int,serverip:int,serverport:int) → bool
  - OnProcessCreate(pid:int,ip:int,port:int,serverip:int,serverport:int)
  - OnProcessDestroy(pid:int)
  - OnServerStart()
  - OnServerStop()
  - OnWorkerStart()
  - OnWorkerStop()

redbean now does a better job at applying gzip on the fly from the local
filesystem, using a streaming chunked api with constant memory, which is
useful for doing things like serving a 4gb text file off NFS, and having
it start transmitting in milliseconds. redbean will also compute entropy
on the beginnings of files to determine if compression is profitable.

This change pays off technical debts relating to memory, such as relying
on exit() to free() allocations. That's now mostly fixed so it should be
easier now to spot memory leaks in malloc traces.

This change also fixes bugs and makes improvements to our SSL support.
Uniprocess mode failed handshakes are no longer an issue. Token Alpn is
offered so curl -v looks less weird. Hybrid SSL certificate loading is
now smarter about naming conflicts. Self-signed CA root anchors will no
longer be delivered to the client during the handshake.
2021-07-10 15:19:37 -07:00
Paul Kulchenko 98c674d915 Update Fetch() to POST if body is provided (#211) 2021-07-10 12:39:02 -07:00
Gautham e99a4dcc8c Add protoent and netent (#209)
The implementations of the getproto* functions follow from the getserv*
functions: same static name allocation, same type of internal function
that opens a file to search, aliases are not written to the struct, same
type of error handling/returns.

This changes also fixes a getaddrinfo AI_PASSIVE memory error. When
getaddrinfo is passed name = NULL and AI_PASSIVE in hints->ai_flags, it was
setting the s_addr value to INADDR_ANY but *not* returning the addrinfo
pointer via *res = ai. This caused a free(NULL) memory error when the caller
tried to free res, because the caller expects res to be a valid pointer to a
struct addrinfo.

Our non-standard API parseport() has been updated to use strtoimax.
strtoimax has an extra parameter endptr to store where the parsing was
terminated. endptr is used in parseport to check if the provided string
was valid.
2021-07-10 12:36:35 -07:00
Justine Tunney c002e4ba76 Support hybrid ECDSA / RSA certificate loading 2021-07-09 19:21:00 -07:00
Justine Tunney fe881982b5 Make slight SSL performance improvements 2021-07-08 21:54:21 -07:00
Justine Tunney 4178896aa0 Fix bug with redbean help flag 2021-07-08 18:28:11 -07:00
Justine Tunney 3641e99042 Add Lua API documentation to redbean -h | less 2021-07-08 17:55:35 -07:00
Justine Tunney 45d72920ba Fix chained certificate loading 2021-07-08 17:29:32 -07:00
Justine Tunney feb0f9fb3a Make improvements to redbean
- Fix Content-Type inference when file extension has number
- Remove shoddy Class A granular IP classiifcation
- Have setuid() and setgid() take effect w/o daemonization
- Make GetParams() return empty table instead of nil
- Change SetLogLevel(int) to only apply to one message
- Make SetLogLevel(int) good enough to be access_log off
- Introduce ProgramUid(int) which is same as -U INT
- Introduce ProgramGid(int) which is same as -G INT
- Introduce ProgramLogPath(str) which is same as -L PATH
- Introduce ProgramDirectory(str) which is same as -D PATH
- Introduce ProgramLogBodies(bool) which is same as -b
- Introduce ProgramLogMessages(bool) which is same as -m
2021-07-08 15:56:23 -07:00
Justine Tunney cc9366b200 Add file Slurp() API to redbean 2021-07-08 13:21:16 -07:00
Justine Tunney c89bc56f6a Add HTTP/HTTPS Fetch() API to redbean
You can now say the following in your redbean Lua code:

    status,headers,payload = Fetch("https://foo.example")

The following Lua APIs have been introduced:

  - Fetch(str) → str,{str:str},str
  - GetHttpReason(int) → str
  - GetHttpReason(int) → str
  - ProgramSslFetchVerify(bool)
  - ProgramSslClientVerify(bool)

The following flags have been introduced:

  - `-j` enables client SSL verification
  - `-k` disables Fetch() SSL verification
  - `-t INT` may now be passed a negative value for keepalive

Lua exceptions now invoke Cosmopolitan's garbage collector when
unwinding the stack. So it's now safe to use _gc() w/ Lua 𝔱𝔥𝔯𝔬𝔴

See #97
2021-07-07 21:44:27 -07:00
Justine Tunney 36b2710e1a Update curl example to support ssl / https
Now that we know our SSL client works, and that it's able to verify
certificates, the next step will be adding it as an API to redbean.

See #97
2021-07-06 13:39:18 -07:00
Justine Tunney e51034bab3 Make GCM AES faster
13.22% mbedtls_aesni_gcm_mult
    13.03% mbedtls_gcm_update
     9.85% mbedtls_aesni_crypt_ecb

Overhead improvement (perf record)

    10.97% mbedtls_aesni_gcm_mult
    10.59% mbedtls_aesni_crypt_ecb
     2.26% mbedtls_gcm_update
2021-07-06 08:27:16 -07:00
Justine Tunney f8b9bd2b47 Attempt to make LLD happy
Things are a little better. The LLD that comes with Linux seems to work.
Old versions like LLVM 8 haven't been supported since Cosmopolitan v0.2.
Running Clang on Windows with --target=x86_64-pc-linux-gnu doesn't seem
to work. It has something to do with the recently added .zip section in
the linker script. But even if that's removed, LLD on Windows thinks it
is building an EFI application for some reason. Linker scripts are such
a brittle house of cards, even for just ld.bfd alone..

We should just find a way to run our one true musl-cross-make linux gcc
toolchain under Blinkenlights on non-Linux because GCC and Clang are so
nondeterministic, inconsistent, and unreproducible when built for other
operating systems. We need an actually portable compiler/linker that'll
always behave the same way no matter what.

See #180
2021-07-05 19:10:06 -07:00
Justine Tunney 0ecd71f697 Make chacha20 go faster 2021-07-05 14:03:50 -07:00
Gautham c0bec24fa2 Improve getservbyname and getservbyport (#207)
- support aliases in /etc/services
- use case insensitive comparisons
- add tests
2021-07-05 12:25:26 -07:00
Justine Tunney 58fb2fb3d3 Add chunked transfer decoding to redbean 2021-07-05 01:05:10 -07:00
Justine Tunney 8d5f60a9cd Add more hashing apis to redbean 2021-07-05 01:05:10 -07:00
Gautham 0ea2907730 Add getservbyname and getservbyport (#204)
For every call of getservbyname/getservbyport the lookup of
/etc/services is done by opening the file and parsing each line
one-by-one. This is slow, but the implementation is simple.

This change also adds fixes for the gethostbyname function.
2021-07-04 16:31:42 -07:00
Justine Tunney cfbd2afc19 Add example for printing <img> tag 2021-07-04 15:41:43 -07:00
Justine Tunney a7bd4ed9ea Make redbean tinier
Under MODE=tiny or MODE=tinylinux we now go back to using my homebrew
version of DEFLATE decompression which is 10x smaller but 10x slower
than Chromium Zlib. In tiny mode we also disable compressed responses
howewver redbean will still serve precompressed responses. This change
also removes a few other dependencies like strftime() and getaddrinfo()
which means you can't say `-l localhost` in tiny mode, you have to say
something like `-l 127.0.0.1`.

    m=tinylinux
    make -j8 MODE=$m o/$m/tool/net/redbean-original.com
    ls -hal o/$m/tool/net/redbean-original.com

This change reduces the above size from 191.4 to 150.9 kb.
2021-07-04 12:26:54 -07:00
Justine Tunney 300876ee50 Fix typo 2021-07-03 10:16:38 -07:00
Justine Tunney e6b22f1f65 Remove remaining build references to zip command 2021-07-03 08:37:15 -07:00
Justine Tunney d6873f637f Release redbean 1.4 2021-07-03 05:58:47 -07:00
Justine Tunney 74200a0ea0 Make redbean ssl handshake go a little faster 2021-07-03 05:51:04 -07:00
Justine Tunney 87222aad35 Improve PrintMemoryIntervals 2021-07-03 04:19:10 -07:00
Justine Tunney 053ee714bd Add Braille Dump tool 2021-07-02 10:24:12 -07:00
Justine Tunney 8e69cf133a Restore basicidea.c from gist 2021-07-02 08:09:56 -07:00
Gautham 3fe7b95fd0 Add gethostbyname and gethostbyaddr (#200)
gethostbyname, gethostbyaddr follow simple implementations: they
internally call getaddrinfo and getnameinfo respectively, and fill out
the minimum details. remaining functions are stubs.
2021-07-01 07:55:11 -07:00
Justine Tunney 014d4bdab2 Make minor revisions to previous change 2021-06-30 10:45:27 -07:00
Justine Tunney a68cc690ff Merge HTTP request / response parsing code
This change also fixes a bug so that DNS lookups work correctly when the
first answer is a CNAME record.
2021-06-27 17:04:32 -07:00
fabriziobertocci 5a6c0f27c3 Fix redundancy in ioctl(SIOCGIFADDR) (#198) 2021-06-27 09:03:14 -07:00
Justine Tunney 2d79ab6c15 Make sha1 / sha256 / sha512 go faster 2021-06-26 00:11:12 -07:00
Justine Tunney 5144c22189 Add test for ioctl(SIOCGIFCONF) and polyfill on BSDs
- Use nullness checks when calling weakly linked functions.

- Avoid typedef for reasons described in Linux Kernel style guide.

- Avoid enum in in Windows headers. Earlier in Cosmo's history all one
  hundred files in libc/nt/enum/ used to be enums and it resulted in
  gigabytes of DWARF data almost as large as everything else in the
  codebase combined.

- Bitfields aren't our friends. They have frequent ABI breakages,
  inconsistent arithmetic across compilers, and different endianness
  between cpus. Compiler authors also haven't invested much roi into
  making bit fields go fast so they produce poor assembly.

- Use memccpy() instead of strncpy() or snprintf() for length-bounded
  copying of C strings. strncpy() is a misunderstood function and
  snprintf() is awesome but memccpy() deserves more love.
2021-06-25 18:44:04 -07:00
Justine Tunney 86ab24ce56 Correct minor issues with recent SSL change 2021-06-24 15:22:24 -07:00
Justine Tunney cc1920749e Add SSL to redbean
Your redbean can now interoperate with clients that require TLS crypto.
This is accomplished using a protocol polyglot that lets us distinguish
between HTTP and HTTPS regardless of the port number. Certificates will
be generated automatically, if none are supplied by the user. Footprint
increases by only a few hundred kb so redbean in MODY=tiny is now 1.0mb

- Add lseek() polyfills for ZIP executable
- Automatically polyfill /tmp/FOO paths on NT
- Fix readdir() / ftw() / nftw() bugs on Windows
- Introduce -B flag for slower SSL that's stronger
- Remove mbedtls features Cosmopolitan doesn't need
- Have base64 decoder support the uri-safe alternative
- Remove Truncated HMAC because it's forbidden by the IETF
- Add all the mbedtls test suites and make them go 3x faster
- Support opendir() / readdir() / closedir() on ZIP executable
- Use Everest for ECDHE-ECDSA because it's so good it's so good
- Add tinier implementation of sha1 since it's not worth the rom
- Add chi-square monte-carlo mean correlation tests for getrandom()
- Source entropy on Windows from the proper interface everyone uses

We're continuing to outperform NGINX and other servers on raw message
throughput. Using SSL means that instead of 1,000,000 qps you can get
around 300,000 qps. However redbean isn't as fast as NGINX yet at SSL
handshakes, since redbean can do 2,627 per second and NGINX does 4.3k

Right now, the SSL UX story works best if you give your redbean a key
signing key since that can be easily generated by openssl using a one
liner then redbean will do all the things that are impossibly hard to
do like signing ecdsa and rsa certificates that'll work in chrome. We
should integrate the let's encrypt acme protocol in the future.

Live Demo: https://redbean.justine.lol/
Root Cert: https://redbean.justine.lol/redbean1.crt
2021-06-24 13:20:50 -07:00
Justine Tunney 1beeb7a829 Flatten Mbed TLS directory structure 2021-06-24 11:13:12 -07:00
Justine Tunney d0ac995dc0 Get Mbed TLS to build
This change configures Mbed TLS to support the fewest number of things
possible required to run an HTTPS server that caters to the sweet spot
of being legacy enough to support the vast majority of user agents but
modern enough that Chrome and Firefox remain happy. That should entail

- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_RSA_WITH_AES_128_CBC_SHA

Even though other suites still get included so what usually happens in
practice is ECDHE-RSA-AES256-GCM-SHA384 under TLS 1.2 will be selected
and the binary footprint is reasonable, and should cost us about 200kb
2021-06-24 11:12:59 -07:00
Justine Tunney 19bd27358a Import Mbed TLS v2.26.0 2021-06-24 11:12:45 -07:00
Justine Tunney 1ba33d233c Add root certificates 2021-06-24 11:12:23 -07:00
fabriziobertocci fd0eefce17 Add ioctl(SIOCGIFxxx) support (#197)
- SIOCGIFCONFIG: reads and enumerate all the network interfaces
- SIOCGIFADDR: reads network address for a given interface
- SIOCGIFFLAGS: reads network flags for a given interface
- SIOCGIFNETMASK: reads network netmask for a given interface
- SIOCGIFBRDADDR: reads network broadcast address for a given interface
- SIOCGIFDSTADDR: reads peer destination address for a given
  interface (not supported for Windows)

This change defines Linux ABI structs for the above interfaces and adds
polyfills to ensure they behave consistently on XNU and Windows.
2021-06-24 10:53:27 -07:00
ahgamut 4d8f884e76 Get Info-ZIP's zip to build
* removed unnecessary files (like amiga/osdep.h)
* makefile has 4 targets: zip, zipnote, zipcloak, zipsplit
* added clang-format off at the start of all source files
* added necessary headers
2021-06-22 12:38:56 -07:00
ahgamut 4ce5664c4b added zip from Info-ZIP 2021-06-22 12:38:56 -07:00
Gautham 98c53ae526 Simplify getnameinfo (#196)
The getnameinfo implementation requires an address -> name lookup on the
hosts file (ie struct HostsTxt) and the previous implementation used
flags to check whether HostsTxt was sorted according to address or name,
and then re-sorted it if necessary. Now getnameinfo lookup does not
require sorting, it does a simple linear lookup, and so the related code
was simplified

See #172 for discussion.
2021-06-22 12:35:58 -07:00
Justine Tunney 1f87640d17 Add half close flag to netcat example 2021-06-15 11:24:24 -07:00
Justine Tunney e4ef38403b Make port optional in X-Forwarded-For
This parser was being overly restrictive which presented integration
issues with haproxy which doesn't make it easy to pass the port info
2021-06-15 06:46:30 -07:00
Justine Tunney 87d7010495 Improve performance of bitscanning intrinsics
This change helps spectre more intelligently plan execution, by working
around false output dependencies, impacting ops like popcnt bsr and bsf
2021-06-15 06:29:51 -07:00
Justine Tunney 29cb53881e Fix SQLite home directory discovery on Windows
See #193
2021-06-12 00:28:06 -07:00
Justine Tunney 8d7d00af3a Pacify file locks on Windows
This change gets redbean SQLite working in write mode on Windows.
Warnings have been added to the appropriate and responsible places.
Hacking proprietary PC systems into production-worthy servers isn't
terribly high on the list of priorities. Consider BSD or Linux when
building online systems that service requests from multiple people.

Fixes #193
2021-06-12 00:01:55 -07:00
Justine Tunney 9504ebaf7e Introduce fsum() 2021-06-11 16:49:30 -07:00
Justine Tunney 8b08e81a07 Fix build in opt mode 2021-06-11 16:47:48 -07:00
Justine Tunney a3ccc5af1f Fix redbean hidden path bug 2021-06-10 08:55:50 -07:00
Justine Tunney f271ffcf90 Release redbean 1.2 2021-06-10 08:14:45 -07:00
Justine Tunney 88806b79b1 Tune SQLite build for redbean (#97)
redbean lua handlers that perform sql queries can do 400k qps.

We now use a separate compile-time options for SQLite, when building the
SQLite shell versus building the production web serving code. It doesn't
seem appropriate for something like redbean to include backups, progress
callbacks, query completion, profiling, EXPLAIN, ALTER, ANALYZE, VACUUM,
etc. since those tasks are better left to the sqlite3.com shell program.

Lua SQLite pointer APIs have been removed since we're not using threads.
The Lua APIs for installing update / commit / rollback hooks are removed
due to a general sense of disagreement and an overall lack of comfort.

Full-Text Search and R*Tree are as large as the rest of SQLite combined.
Turning those off keeps redbean under 1mb when built for MODE=tiny which
is nice for marketing purposes.

If you need something that was removed, file an issue, and we'll add it.
2021-06-10 08:00:08 -07:00
Justine Tunney eb08b9fbeb Fix redbean inappropriately linking ASAN
Fixes #188
2021-06-10 07:59:50 -07:00
Gautham 248c6d54bb Added getnameinfo with only name lookup (#172)
Added necessary constants (DNS_TYPE_PTR, NI_NUMERICHOST etc.).
Implementation of getnameinfo is similar to getaddrinfo, with internal
functions:

* ResolveDnsReverse: performs rDNS query and parses the PTR record
* ResolveHostsReverse: reads /etc/hosts to map hostname to
  address

Earlier, the HOSTS.txt would only need to be sorted at loading time,
because the only kind of lookup was name -> address. Now since address
-> name lookups are also possible, so the HostsTxt struct, the sorting
method (and the related tests) was changed to reflect this.
2021-06-09 19:35:44 -07:00
Gautham 05350eca60 Added wcstok and wmemcmp (#183) 2021-06-09 19:34:27 -07:00
Justine Tunney f721d61b54 Fix build to not require bash #190 2021-06-09 04:39:52 -07:00
Paul Kulchenko cd2f984ec2 Fix lsqlite make #187 2021-06-08 14:55:30 -07:00
Paul Kulchenko b3a08d9286 Add sqlite3 support to Lua scripts in redbean. 2021-06-05 18:38:38 -07:00
Paul Kulchenko 067c14891f Add lsqlite source (v0.9.5). 2021-06-05 18:38:38 -07:00
dosisod b8f38cf55d Add ISO 646 header (#168) 2021-05-16 23:18:33 -07:00
Justine Tunney 7cbc2bc083 Cosmopolitan 1.0 2021-05-16 20:35:10 -07:00
Justine Tunney 1a3d22b2fd Improve LLVM compatibility a little bit 2021-05-16 20:34:46 -07:00
Justine Tunney 3057315a1b Make default redbean lua module path zip:.lua/...
Fixes #157
2021-05-16 19:05:35 -07:00
Justine Tunney 6a8c21269f Make trivial code size enhancements 2021-05-16 18:22:39 -07:00
Justine Tunney b3838173ec Remove undefined behaviors 2021-05-16 11:16:28 -07:00
Justine Tunney 4864565198 Make minor improvements 2021-05-15 21:53:26 -07:00
Justine Tunney 221817e537 Further polish SQLite vendoring
- Now integrated with `make tags` for Emacs IDE features
- Delete some old deprecated broken full-text search engines
- Rename .h → .inc files that don't meet our definition of header
- Make sure every #include line is normal form so tools understand

See #162
2021-05-14 10:43:58 -07:00
Justine Tunney 690be544da Make redbean StoreAsset() work better
- Better UBSAN error messages
- POSIX Advisory Locks polyfills
- Move redbean manual to /.help.txt
- System call memory safety in ASAN mode
- Character classification now does UNICODE
2021-05-14 05:44:37 -07:00
ahgamut 919b6fec10 Get SQLite to build
* changed headers
* removed redundant declarations
* ran clang-format
* added sqlite3.mk
2021-05-14 02:40:04 -07:00
Justine Tunney 644f290035 Added sqlite-preprocessed-3350500
From https://www.sqlite.org/2021/sqlite-preprocessed-3350500.zip
2021-05-14 02:07:09 -07:00
Dan Tocchini IV 4577f7fe11 Add MacOS toolchain instructions (#163) 2021-05-07 07:52:32 -07:00
Justine Tunney 1b5a5719c3 Improve some unicode functions 2021-05-05 07:25:39 -07:00
Justine Tunney b9187061a7 Let redbean use its own ZIP EXE as NoSQL database 2021-05-03 13:07:58 -07:00
Justine Tunney e56a9d0e23 Mold the redbean binary to minimize page faults
This change brings page faults for precompressed static asset serving
down from 27 to 20 (or fewer) after fork. This is more of an art than
science. Hopefully Blinkenlights can visualize page faults soon.
2021-05-03 12:14:13 -07:00
Justine Tunney 2d34819779 Escape LaunchBrowser path
This also fix a bug where CTRL-C'ing redbean on Linux would kill the
browser process. It furthermore fixes a regression with the APE self
repair process that happened in a recent change.

See #158
2021-05-03 11:52:24 -07:00
Rowan Easter-Robinson 6215c91e90 Added Parameter to LaunchBrowser to set path (#158) 2021-05-03 10:55:21 -07:00
Justine Tunney af59806a42 Add integration test for redbean 2021-05-03 01:59:27 -07:00
Justine Tunney 01e6b3ad8d Reduce number of disk seeks in redbean 2021-05-03 01:21:50 -07:00
Justine Tunney daa32d27d4 Add live reindexing to redbean when zip changes 2021-05-02 11:50:43 -07:00
Justine Tunney 84001a246c Fix redbean date header in daemonize mode 2021-05-02 11:11:26 -07:00
Justine Tunney 1f2288be6e Improve backwards compatibility with GNU Make 2021-05-02 07:48:59 -07:00
Justine Tunney fabf7f9f02 Fix popen_test in MODE=dbg
ASAN and vfork() don't appear to play well together. Maybe in later
versions of GCC it'll be better. But vfork() is flirting with danger
after all and that probably doesn't make sense in ASAN mode anyway.
2021-05-01 17:13:48 -07:00
Justine Tunney cef08d47b6 Fix typo in redbean.c 2021-05-01 05:42:02 -07:00
Justine Tunney 41801c9802 Change default redbean log level to info
A new -s flag has been added to increase silence. This change is
intended to make it a little less weird opening the redbean binary
directly from the browser and seeing an empty terminal window.
2021-05-01 05:28:15 -07:00
Justine Tunney 1966369e8e Fix bugs and make improvements
- Fix regression with `%lu`
- Added some more headers witnessed in the wild
- Added `-M INT` option to redbean to tune max payload size
- Work around InfoZIP 256 character limit on comment line size
2021-05-01 05:11:35 -07:00
Gautham 3aa8983ec1 Add strxfrm (#160) 2021-05-01 04:53:23 -07:00
Justine Tunney c029e83dd8 Set up http://redbean.justine.lol/ demo server 2021-04-24 19:49:49 -07:00
Justine Tunney 472b95fea3 Support OnHttpRequest Lua callback
If your redbean `/.init.lua` file defines a global callable named
`OnHttpRequest` then redbean will delegate all serving control to
your function. You may then restore the default serving paths, by
calling the new `Route()`, `RouteHost()`, and `RoutePath()` APIs.

Closes #150
2021-04-24 17:27:12 -07:00
Justine Tunney dc6d11a031 Improve performance of printf functions 2021-04-24 13:58:50 -07:00
Justine Tunney b107d2709f Add /statusz page to redbean plus other enhancements
redbean improvements:

- Explicitly disable corking
- Simulate Python regex API for Lua
- Send warmup requests in main process on startup
- Add Class-A granular IPv4 network classification
- Add /statusz page so you can monitor your redbean's health
- Fix regressions on OpenBSD/NetBSD caused by recent changes
- Plug Authorization header into Lua GetUser and GetPass APIs
- Recognize X-Forwarded-{For,Host} from local reverse proxies
- Add many additional functions to redbean Lua server page API
- Report resource usage of child processes on `/` listing page
- Introduce `-a` flag for logging child process resource usage
- Introduce `-t MILLIS` flag and `ProgramTimeout(ms)` init API
- Introduce `-H "Header: value"` flag and `ProgramHeader(k,v)` API

Cosmopolitan Libc improvements:

- Make strerror() simpler
- Make inet_pton() not depend on sscanf()
- Fix OpenExecutable() which broke .data section earlier
- Fix stdio in cases where it overflows kernel tty buffer
- Fix bugs in crash reporting w/o .com.dbg binary present
- Add polyfills for SO_LINGER, SO_RCVTIMEO, and SO_SNDTIMEO
- Polyfill TCP_CORK on BSD and XNU using TCP_NOPUSH magnums

New netcat clone in examples/nc.c:

While testing some of the failure conditions for redbean, I noticed that
BusyBox's `nc` command is pretty busted, if you use it as an interactive
tool, rather than having it be part of a pipeline. Unfortunately this'll
only work on UNIX since Windows doesn't let us poll on stdio and sockets
at the same time because I don't think they want tools like this running
on their platform. So if you want forbidden fruit, it's here so enjoy it
2021-04-23 18:53:57 -07:00
Justine Tunney 4effa23528 Make more major improvements to redbean
- POSIX regular expressions for Lua
- Improved protocol parsing and encoding
- Additional APIs for ZIP storage retrieval
- Fix st_mode issue on NT for regular files
- Generalized APIs for URL and Host handling
- Worked out the kinks in resource resolution
- Allow for custom error pages like /404.html
2021-04-20 19:14:21 -07:00
Justine Tunney 26ac6871da Add TUI paneling example 2021-04-18 12:40:48 -07:00
Justine Tunney bf03b2e64c Make major improvements to redbean and libraries
The most exciting improvement is dynamic pages will soon be able to use
the executable itself as an object store. it required a heroic technique
for overcoming ETXTBSY restrictions which lets us open the executable in
read/write mode, which means (1) wa can restore the APE header, and (2)
we can potentially containerize redbean extension code so that modules
you download for your redbean online will only impact your redbean.

Here's a list of breaking changes to redbean:

- Remove /tool/net/ prefix from magic ZIP paths
- GetHeader() now returns NIL if header is absent

Here's a list of fixes and enhancements to redbean:

- Support 64-bit ZIP archives
- Record User-Agent header in logs
- Add twelve error handlers to accept()
- Display octal st_mode on listing page
- Show ZIP file comments on listing page
- Restore APE MZ header on redbean startup
- Track request count on redbean index page
- Report server uptime on redbean index page
- Don't bind server socket using SO_REUSEPORT
- Fix #151 where Lua LoadAsset() could free twice
- Report rusage accounting when workers exit w/ -vv
- Use ZIP iattr field as text/plain vs. binary hint
- Add ParseUrl() API for parsing things like a.href
- Add ParseParams() API for parsing HTTP POST bodies
- Add IsAcceptablePath() API for checking dots, etc.
- Add IsValidHttpToken() API for validating sane ASCII
- Add IsAcceptableHostPort() for validating HOST[:PORT]
- Send 400 response to HTTP/1.1 requests without a Host
- Send 403 response if ZIP or file isn't other readable
- Add virtual hosting that tries prepending Host to path
- Route requests based on Host in Request-URI if present
- Host routing will attempt to remove or add the www. prefix
- Sign-extend UNIX timestamps and don't adjust FileTime zone

Here's some of the improvements made to Cosmopolitan Libc:

- Fix ape.S indentation
- Improve consts.sh magnums
- Write pretty good URL parser
- Improve rusage accounting apis
- Bring mremap() closer to working
- Added ZIP APIs which will change
- Check for overflow in reallocarray()
- Remove overly fancy linkage in strerror()
- Fix GDB attach on crash w/ OpenBSD msyscall()
- Make sigqueue() portable to most UNIX distros
- Make integer serialization macros more elegant
- Bring back 34x tprecode8to16() performance boost
- Make malloc() more resilient to absurdly large sizes
2021-04-18 12:34:15 -07:00
Rowan Easter-Robinson 69c508729e Added LaunchBrowser API (#153)
You can now add LaunchBrowser() to .init.lua which will ask
redbean to open your website in the local desktop browser
when the server is launched.
2021-04-18 07:24:36 -07:00
Justine Tunney 7ed524ca31 Disable fesetround() tests temporarily
This isn't working as intended in the Travis CI build environment.
There's likely some kind of microarchitectural issue. This change
gets us back into the green for the time being.
2021-04-11 01:42:31 -07:00
Justine Tunney 052682c2c0 Add CONTRIBUTING.md 2021-04-11 00:55:53 -07:00
Justine Tunney 8a91518633 Fix issues revealed by ECMAScript test262
Cosmopolitan's QuickJS is now equally conformant and performant, with
the exception of Atomics, which have been disabled since Cosmopolitan
currently doesn't support pthreads.

QuickJS memory usage -- BigNum 2021-03-27 version, 64-bit, malloc limit: -1

NAME                    COUNT     SIZE
memory allocated          937   131764  (140.6 per block)
memory used               938   116103  (8 overhead, 16.7 average slack)
atoms                     513    21408  (41.7 per atom)
objects                   170    12279  (72.2 per object)
  properties              864    15531  (5.1 per object)
  shapes                   58    12995  (224.1 per shape)
bytecode functions         13     1512
  bytecode                 13      867  (66.7 per function)
C functions                99
arrays                      1
  fast arrays               1
  elements                  1       16  (1.0 per fast array)

Result: 35/74740 errors, 1279 excluded, 485 skipped, 19 new, 2 fixed

real    2m40.828s
user    2m29.764s
sys     0m10.939s
2021-04-10 17:15:35 -07:00
Justine Tunney 8f52c0d773 Get Fabrice Bellard's JavaScript engine to build
$ m=tiny
$ make -j12 MODE=$m o/$m/third_party/quickjs/qjs.com
$ o/$m/third_party/quickjs/qjs.com -e 'console.log(2 + 2)'
4
$ ls -hal o/$m/third_party/quickjs/qjs.com
631.5K

See #97
2021-04-09 01:06:57 -07:00
Justine Tunney 1fbfbb3192 Add quickjs-2021-03-27 to third_party 2021-04-08 20:55:43 -07:00
Justine Tunney f40f97bd07 Fix test failure on Windows
The send{,to,msg} and recv{,from,msg} functions have been updated to
delegate to WriteFile and ReadFile when appropriate, due to the fact
that socketpair(AF_UNIX) is implemented using kFdFile.

Thanks @fabriziobertocci for writing the test that caught this.

See #148 and #122
2021-04-07 23:36:05 -07:00
fabriziobertocci 24d79599cc Add sendmsg and recvmsg (#148) 2021-04-07 22:53:23 -07:00
Justine Tunney da8a08fd58 Provide option to have APE not modify itself
This change introduces ape-no-modify-self.o to the amalgamated release
binaries, which may be used as an alternative to ape.o to make it easier
to use APE in cases where the self-modifying behavior isn't acceptable.

Please note that this alternative copying behavior isn't necessarily
better. It introduces a whole bunch of questions of its own, which are
documented in the ape.S source comment and should be considered by both
the program author as well as the end-user of programs linked this way.

For example, build environments that use read-only file systems and
would prefer to not have a launcher wrapper (like we use in our build)
can use ape-no-modify-self.o instead of ape.o and then set the $TMPDIR
environment variable to point to a sane read-write-exec location.

Fixes #146
See #82
2021-04-07 21:01:57 -07:00
Justine Tunney 59575f7e80 Perform some minor code cleanup 2021-04-06 12:46:52 -07:00
Justine Tunney 6c16f208b5 Remove unintended log statements 2021-04-01 20:01:26 -07:00
Justine Tunney bb96099c65 Define assert as an expression
Fixes #138
2021-04-01 19:42:02 -07:00
fabriziobertocci 2584a86ab4 Added struct ip_mreq (#143) 2021-04-01 19:38:11 -07:00
dosisod 9e98d6893d Add some missing prototypes (#142) 2021-04-01 19:36:37 -07:00
fabriziobertocci 6682013d12 Implement syslog (#136) 2021-04-01 19:32:39 -07:00
Justine Tunney 83abd68029 Parse Content-Range with missing right hand side
Fixes #144
2021-04-01 18:52:54 -07:00
Justine Tunney 7abca1531f Cosmopolitan 0.3 2021-03-29 03:20:03 -07:00
Justine Tunney 7dc8973567 Enable serving zip directory entries 2021-03-29 03:10:11 -07:00
Justine Tunney 1753b669cf Have redbean show zip listing as default / handler
If an "index.lua" or "index.html" doesn't exist in zip file or the
filesystem, and no redirects have been defined for it either, then
redbean will render a listing of the zip central directory content
only if the request uri points to the root path.
2021-03-29 01:22:49 -07:00
Justine Tunney ae300d0c40 Remove colliding name in syscalls.sh
Credit goes to @fabriziobertocci for finding this. See #136.
2021-03-28 18:26:56 -07:00
Justine Tunney c6f75bf95a Fix issue with testing service
What was I thinking imposing arbitrary limits. I hate limits.
2021-03-28 18:22:36 -07:00
Justine Tunney 52565e7af3 Make minor performance improvement to HTTP parser
redbean's message parser now takes 300 nanoseconds to parse a standard
request sent by chrome, whereas it previous took 600 nanoseconds.
2021-03-28 18:00:29 -07:00
Justine Tunney 3c19b6e352 Add support for serving directly from filesystem
You can now pass `-D directory` to redbean which will serve assets from
the local filesystem. This is useful for development since it allows us
to skip needing to shut down the server and run InfoZIP when testing an
iteration of a lua server page script.

See #97
2021-03-28 08:02:17 -07:00
Justine Tunney a1677d605a Transcode ISO-8859-1 in HTTP headers
If we keep making changes like this, redbean might not be a toy anymore.
Additional steps are also being taken now to prevent ANSI control codes
sent by the client from slipping into logs.
2021-03-28 00:10:17 -07:00
Justine Tunney dcbd2b8668 Add base64 support
Lua Server Pages may now call the EncodeBase64() and DecodeBase64()
functions should they wish to do things like emit embeded data URIs

See #97
2021-03-27 18:17:54 -07:00
Justine Tunney 4d21cd315d Support POST parameters in redbean server pages
See #97
2021-03-27 07:29:55 -07:00
Justine Tunney da36e7e256 Make major improvements to stdio
Buffering now has optimal performance, bugs have been fixed, and some
missing apis have been introduced. This implementation is also now more
production worthy since it's less brittle now in terms of system errors.
That's going to help redbean since lua i/o is all based on stdio.

See #97
2021-03-26 22:31:41 -07:00
Justine Tunney 09bcfa23d5 Make major improvements to redbean
- lua server pages
- lua http library
- http v0.9 support
- request uri parsing
- fork failure recovery
- accelerated redirects
- http pipelining support
- lenient message framing
- html / uri / js escaping
- fix shutdown signal handling
2021-03-25 02:24:05 -07:00
Justine Tunney 6b90ff60cd Add preliminary lua support to redbean
This change only implements enough Lua support to send a Hello World
response. The redbean executable size increases from ~128kb to 260kb
and the requests per second decreases from 1000k to 600k. That's the
fastest it can go and that's extremely impressive compared to Python

See #97
2021-03-21 17:27:53 -07:00
fabriziobertocci 2f41b4dcc6 Add prototype for srandom() (#132) 2021-03-21 07:33:33 -07:00
fabriziobertocci 5af25f687a Rename eai2str to gai_strerror (#131) 2021-03-20 20:48:40 -07:00
Alison Winters 9c81729008 Remove unused variable in fflush (#129) 2021-03-17 20:15:00 -07:00
dosisod 8a236433a2 Add more math functions (#128) 2021-03-17 20:05:12 -07:00
Justine Tunney ab64ef7364 Make fflush() return 0 on success (#114) 2021-03-17 13:02:15 -07:00
Justine Tunney 4177489762 Perform fine-tuning of socketpair and pipe
- removed unneeded share parameter from pipe on nt
- socktpair(type | SOCK_CLOEXEC) is now polyfilled
- use textwindows for linker micro-optimization
- apologies for auto clang-format diff noise :(
- improve socketpair docstring

See #122
2021-03-16 22:44:54 -07:00
Justine Tunney 4e93750afd Perform some minor fixups 2021-03-16 22:19:51 -07:00
fabriziobertocci ca88ce5026 Add socketpair (#122) 2021-03-16 22:05:59 -07:00
dosisod 6388ef21f8 Add noreturn macro (#118) 2021-03-13 20:46:12 -08:00
dosisod 7ffeb29bfc Add missing functions to tgmath (#124) 2021-03-13 20:43:57 -08:00
Justine Tunney da4dffccc5 Add random() and srandom()
Closes #123
2021-03-13 20:24:29 -08:00
Justine Tunney 807706a099 Perform minor fixups
One of those fixups is making sure that AF_LOCAL is equal to AF_UNIX on
the New Technology. See #122
2021-03-13 19:40:04 -08:00
Justine Tunney 83d0c3b870 Fix writev() on the New Technology (#117) 2021-03-09 11:33:48 -08:00
Alison Winters 6cd1037692 Get VSCode working with Linux and WSL (#116) 2021-03-09 10:12:39 -08:00
Justine Tunney e0566c9675 Fix Lua build config 2021-03-08 17:51:26 -08:00
Justine Tunney 3f35b37b68 Remove nonstandard defines from limits.h (#115) 2021-03-08 17:34:44 -08:00
Justine Tunney 67c27d9e6e Add Hello World example for LUA C API (#97) 2021-03-08 14:15:59 -08:00
Justine Tunney 2a3037d4e8 Delete Duktape (#97) 2021-03-08 13:17:52 -08:00
Justine Tunney 0a61fe4ea0 Add smoke test for timezone loading (#114) 2021-03-08 11:46:04 -08:00
Justine Tunney 33e8fc8687 Expose public garbage collector API for C language
You can now do epic things like this:

    puts(_gc(xasprintf("%d", 123)));

The _gc() API is shorthand for _defer() which works like Go's keyword:

    const char *s = xasprintf("%d", 123);
    _defer(free, s);
    puts(s);

Be sure to always use -fno-omit-frame-pointer which makes code fast too.

Enjoy! See also #114
2021-03-08 10:59:34 -08:00
Justine Tunney 0ad609268f Improve system call polyfills
- Polyfill open() w/ O_CLOEXEC on RHEL5
- Remove old workaround from rmdir() on the New Technology
- preadv() and pwritev() are now smarter about demodernization
- preadv() and pwritev() are now available on the New Technology
2021-03-08 10:07:02 -08:00
Justine Tunney 816b0e1851 Improve tmpfile api (#114) 2021-03-07 21:08:27 -08:00
Justine Tunney 2bd1e72d5a Remove garbage collector macro from header (#114)
We can put this back the moment someone requests it. Pain-free garbage
collection for the C language is pretty cool. All it does is overwrite
the return address with a trampoline that calls free(). It's not clear
what it should be named if it's made a public API.
2021-03-07 20:23:29 -08:00
Justine Tunney 5ce83b08c8 Add posix_spawn (#114) 2021-03-07 20:14:07 -08:00
Justine Tunney 5f088cec23 Rename Lua test folder 2021-03-07 18:22:53 -08:00
Justine Tunney a8945714e8 Make gdtoa less tunable (#104)
The -fno-math-errno flag shouldn't impact libraries since it's mostly
intended for permitting the compiler to generate sqrt() instructions.
2021-03-07 16:41:59 -08:00
Alison Winters 8a6ac6dd63 Set errno when out of range in strtoimax (#111) 2021-03-07 14:38:56 -08:00
Alison Winters f5da4efcaf Set errno in strtol family of functions (#110) 2021-03-07 14:18:08 -08:00
Justine Tunney b16b332539 Get Lua to build with all tests passing
Fixes #61
2021-03-07 13:31:09 -08:00
Justine Tunney 4d3195f57a Add Lua 2021-03-07 12:50:34 -08:00
Justine Tunney aad841610e Fix freopen so it resets stream buffer (#61) 2021-03-07 12:12:02 -08:00
Justine Tunney 7583b3accc Show better error on bind() error
See #51
2021-03-07 11:31:44 -08:00
Justine Tunney 06a4e2d29b Disable Travis emails 2021-03-07 08:29:43 -08:00
dosisod 67b9675c81 Make tgmath.h available (#109) 2021-03-06 22:40:18 -08:00
Justine Tunney 4d4aa9e791 Add automatic tests for pull requests
Now when you send a pull request Travis CI will build the entire
repository and run all the tests for you automatically. It takes
approximately two minutes to finish so you can get fast feedback
2021-03-06 21:39:03 -08:00
Alison Winters 813e11b90b Fix int parsing with base 2 and 16 (#107) 2021-03-06 21:12:32 -08:00
dosisod fb7b7c6e21 Fix isystem headers including wrong files (#108) 2021-03-06 21:06:29 -08:00
Justine Tunney d769df3482 Fix issues with stdio needed for Lua
See #61
2021-03-06 19:04:26 -08:00
Justine Tunney c3ed8d6c7f Make %p consistent with glibc and musl
See #61
2021-03-06 14:36:44 -08:00
Justine Tunney 937d921018 Add tests for the greatest of all libm functions 2021-03-06 12:59:35 -08:00
Justine Tunney bfef17eb6d Add more math fixes 2021-03-06 11:44:40 -08:00
Justine Tunney 11ec99931b Add Musl multibyte functions
These are standard functions that are needed to help support the Skull
language. Note that normally this codebase uses libc/str/thompike.h

See #105
2021-03-06 09:53:16 -08:00
Justine Tunney cfd453d125 Add more real formatting tests
See #61
2021-03-06 08:45:44 -08:00
dosisod 6fa049c9c7 Add macro for static_assert (#106) 2021-03-05 20:32:25 -08:00
Justine Tunney 3364fc5b03 Add modf(), modff(), and modfl()
See #104
2021-03-05 10:47:14 -08:00
Justine Tunney f064183646 Support proper %g, %f, and %a float formatting
See #61
See #104
2021-03-05 10:31:16 -08:00
Justine Tunney e26bdbec52 Make examples folder somewhat more focused 2021-03-05 06:09:12 -08:00
Justine Tunney 5141d00992 Perform some minor code cleanup 2021-03-04 13:22:32 -08:00
Justine Tunney b9f73e6a4d Clarify APE self-modifying behavior in README
See #102
2021-03-04 07:54:41 -08:00
Justine Tunney 43b2475aaa Handle more pow cases (#61) 2021-03-04 06:14:07 -08:00
Justine Tunney 1a08594f95 Add honeybadger to ape.S 2021-03-03 15:00:41 -08:00
Justine Tunney e55e71ab48 Delete some old build code 2021-03-03 14:30:25 -08:00
Justine Tunney 3573814e45 Change release process to use default mode
See #101
2021-03-03 13:47:22 -08:00
Justine Tunney 2134ffe005 Add features needed by Janet language
See #97
See https://github.com/ahgamut/janet/tree/f838e36#compiling-janet-on-cosmopolitan
2021-03-03 13:26:46 -08:00
Justine Tunney e3ee3c78e9 Refactor some Blinkenlights code 2021-03-03 13:09:06 -08:00
Justine Tunney 8af91bcbe7 Make pow() conform to standard definition 2021-03-03 09:21:27 -08:00
Justine Tunney 754974faaa Remove SOCK_NONBLOCK from Echo Server example
See #102 for further explanation.
2021-03-03 06:17:56 -08:00
Justine Tunney 9367253b4d Add more libm unit tests and fixes
See #61
2021-03-02 13:57:23 -08:00
Justine Tunney 32e289b1d8 Add error and gamma functions
Fixes #99
2021-03-02 11:58:00 -08:00
Justine Tunney d53a344e18 Remove getc() optimization
This has been reported as causing issues in #61 although it isn't clear
why that's happening. Having a function boundary is bullet proof.
2021-03-02 07:34:38 -08:00
Justine Tunney 3e19b96ab8 Add more POSIX function stubs
Cosmopolitan currently doesn't support threads and it doesn't do
anything fancy in longjmp/setjmp so this change was simple to do

- localeconv
- _setjmp (same as setjmp)
- _longjmp (same as longjmp)
- strcoll (same as strcmp)
- flockfile (does nothing)
- funlockfile (does nothing)
- ftrylockfile (does nothing)

See #61
2021-03-02 03:27:55 -08:00
Justine Tunney 1831e3ccf7 Bring life.com executable size back down to 12kb 2021-03-02 01:13:32 -08:00
Justine Tunney 4651962070 Limit frame size restriction to internal repo
Fixes #91
2021-03-02 01:05:37 -08:00
Justine Tunney 8a6a1e25b1 Fix redbean daemonization
Fixes #94
2021-03-02 00:43:30 -08:00
Justine Tunney 7e4021bf82 Put Redbean in uniprocess mode on NT temporarily
The Windows fork() polyfill (which we implement using pure WIN32)
appears to be acting strangely. It's possible a regression was
introduced by recent changes that our tests didn't catch.

This change is workaround so we can upload a new working binary release
to the Redbean website until we can fully fix the problem.

See also #90
2021-03-01 23:45:49 -08:00
Justine Tunney 2596a59374 Use noasan attribute on XNU signal trampoline
The ucontext_t data structure XNU passes us doesn't appear to be part of
known memory. So we can't use ASAN during the trampoline, which converts
it to a Linux ucontext_t data structure. Please note that this change
doesn't impact the signal handler itself, only the trampoline.
2021-03-01 22:02:27 -08:00
tomberek 0eaad9dd7b Fix APE error if unable to modify self
See PR #96 and issue #85
2021-03-01 21:13:22 -08:00
Justine Tunney f4298f10c2 Generate ZIP files the same way as Windows 2021-03-01 06:24:11 -08:00
Justine Tunney d932948fb4 Remove more nonstandard stuff from cosmopolitan.h
Fixes #61
2021-03-01 00:18:23 -08:00
Justine Tunney 5e069a64d4 Improve limits.h
Fixes #84
See also #61
2021-02-28 20:59:19 -08:00
Justine Tunney 3c24c12068 Document support vector
Fixes #87
2021-02-28 16:41:53 -08:00
Justine Tunney 839e2f4cfb Add hyperbolic math functions
See #61
2021-02-28 01:27:50 -08:00
Justine Tunney c42dbe0e9e Issue new Blinkenlights release 2021-02-27 22:35:50 -08:00
Justine Tunney 94afa982c3 Fix zip executables on MacOS
Here's why we got those `Killed: 11` failures on MacOS after modifying
the contentns of the redbean.com executable. If you were inserting a
small file, such as a HelloWorld.html file, then InfoZIP might have
decreased the size of the executable to less than what the Mach-O
section had been expecting.

That's because when zipobj.com put things like time zone data in the
executable, it aligned each zip file entry on a 64-byte boundary, simply
for the sake of readability in binary dumps. But when InfoZIP edited the
file it would rewrite every entry using ZIP's usual 2-byte alignment.
Thus causing shrinkage.

The solution was to reconfigure the linker script so that zip file bits
that get put into the executable at link-time, such as timezone data,
aren't officially part of the executable image, i.e. we don't want the
operating system to load that part.

The original decision to put the linked zip files into the .data section
was mostly made so that when the executable was run in its .com.dbg form
it would still have the zip entries be accessible, even though there was
tons of GNU debug data following the central directory. We're not going
to be able to do that. The .com executable should be the canonical
executable. We have really good tools for automatically attaching and
configuring GDB correctly with debug symbols even when the .com is run.
We'll have to rely on those in cases where zip embedding is used.

See #53
See #54
See #68
2021-02-27 18:16:59 -08:00
Justine Tunney cc56038b05 Fix memzoom on Windows
Right now we can't call poll() on file and fifos on Windows. So we work
around that by simply blocking on keyboard input. This is OK because on
Windows we can't use /proc/*/mem for realtime monitoring, so there's no
reason not to block.

See #65
2021-02-27 15:01:00 -08:00
Justine Tunney f3baa05195 Define console.log() in hellojs.com example
Fixes #69
2021-02-27 14:15:13 -08:00
Thomas Bernard 1c9065510f redbean.c: remove duplicate png content-types 2021-02-27 13:37:36 -08:00
Justine Tunney da199b7a45 Further refine printf long double change (#66) 2021-02-27 13:30:17 -08:00
Waldir Pimenta 98fba078a3 Add title to the LICENSE file 2021-02-27 13:25:59 -08:00
Alison Winters 5d334b9ce0 Support %lf and %lF in format string
Per C99 this should resolve to double.
2021-02-27 13:14:09 -08:00
Justine Tunney 35c7edac49 Restore Windows command prompt mode on exit
Fixes #60
2021-02-27 12:53:51 -08:00
Justine Tunney 218ef49147 Fix redbean zip central directory lookup
This regression snuck in at some point. It resulted in the program
sometimes failing to load when the zip content was changed.
2021-02-27 12:08:28 -08:00
Justine Tunney 19d0c15e03 Perform some code cleanup 2021-02-27 10:33:32 -08:00
Justine Tunney 3e17c7b20f Make Reddit users happy 2021-02-26 20:18:10 -08:00
Justine Tunney fcfe7c1080 Rename LICENSE file 2021-02-26 16:09:33 -08:00
Justine Tunney 91f4167a45 Add root redirect for redbean webserver
We have a webserver demo:

    make -j8 o//tool/net/redbean.com
    o/tool/net/redbean.com -v

It's been a little bit confusing that until now you had to visit the
following URL in order to see the default web page:

    http://127.0.0.1:8080/tool/net/redbean.html

The following URLs will now redirect to the above page, but only if
nothing's been defined for those paths and they would otherwise result
in a 404 response:

    http://127.0.0.1:8080/
    http://127.0.0.1:8080/index.html
2021-02-25 19:14:22 -08:00
Justine Tunney 40291c9db3 Improve signal handling and math
- Polyfill ucontext_t on FreeBSD/OpenBSD/NetBSD
- Add tests confirming signals can edit CPU state
- Work towards supporting ZIP filesystem on bare metal
- Add more tinymath unit tests for POSIX conformance
- Add X87 and SSE status flags to crash report
- Fix some bugs in blinkenlights
- Fix llvm build breakage
2021-02-25 18:33:33 -08:00
Justine Tunney cdc54ea1fd Use unsigned leb128 for magnums 2021-02-24 04:00:38 -08:00
Justine Tunney edd9297eba Support malloc() on bare metal
Your Actually Portable Executables now contains a simple virtual memory
that works similarly to the Linux Kernel in the sense that it maps your
physical memory to negative addresses. This is needed to support mmap()
and malloc(). This functionality has zero code size impact. For example
the MODE=tiny LIFE.COM executable is still only 12KB in size.

The APE bootloader code has also been simplified to improve readibility
and further elevate the elegance by which we're able to support so many
platforms thereby enhancing verifiability so that we may engender trust
in this bootloading process.
2021-02-24 00:53:24 -08:00
Justine Tunney ac3b1dfb21 Parse EFI command line arguments (#12) 2021-02-21 23:33:44 -08:00
Justine Tunney 537c21338b Add UEFI support
This is mutually exclusive with Windows support. Documentation for how
to use it has been written in libc/runtime/efimain.c
2021-02-21 21:33:04 -08:00
Justine Tunney c6c9b5dfde Further refine hypot implementation
Thanks go to Fabian Giesen on Twitter for code review and advice.
2021-02-21 12:53:01 -08:00
Justine Tunney 4a5698b5c9 Implement better hypot function 2021-02-21 11:06:18 -08:00
Justine Tunney 6c7b8facaa Delete accidental file 2021-02-21 00:58:50 -08:00
Justine Tunney 7a393c06fe Add IP address conversion helpers
Fixes #47
2021-02-20 22:53:22 -08:00
8039 changed files with 2124910 additions and 153002 deletions

No files matched your search

+3
View File
@@ -0,0 +1,3 @@
# -*- conf -*-
/build/bootstrap/*.com binary
/usr/share/zoneinfo/* binary
+5
View File
@@ -1,5 +1,10 @@
# -*- conf -*-
/o
# TODO: Find some way to have Python write to o/
__pycache__
*.tmp
/.bochs.log
/HTAGS
+6
View File
@@ -0,0 +1,6 @@
virt: lxd
os: linux
language: c
script: make -j4 V=0
notifications:
email: false
+45 -2
View File
@@ -1,13 +1,12 @@
{
"configurations": [
{
"name": "Linux",
"name": "Win32",
"includePath": [
"${workspaceFolder}"
],
"cStandard": "c11",
"cppStandard": "c++11",
"compilerPath": "${workspaceFolder}/o/third_party/gcc/bin/x86_64-linux-musl-gcc",
"forcedInclude": ["${workspaceFolder}/.vscode/vscode.h"],
"defines": [
"libcesque=",
@@ -63,6 +62,50 @@
"attributeallocalign(x)=",
"nullterminated(x)="
]
},
{
"name": "Linux",
"includePath": [
"${workspaceFolder}"
],
"cStandard": "gnu17",
"compilerPath": "${workspaceFolder}/o/third_party/gcc/bin/x86_64-linux-musl-gcc",
"compilerArgs": [
"-Wall",
"-Werror",
"-fdebug-prefix-map=${workspaceFolder}=",
"-frecord-gcc-switches",
"-Wa,-W",
"-Wa,-I.",
"-Wa,--noexecstack",
"-Wa,--nocompress-debug-sections",
"-Og",
"-g",
"-gdescribe-dies",
"-msse3",
"-mno-red-zone",
"-fno-math-errno",
"-fno-trapping-math",
"-fno-fp-int-builtin-inexact",
"-fno-ident",
"-fno-common",
"-fno-gnu-unique",
"-fstrict-aliasing",
"-fstrict-overflow",
"-fno-semantic-interposition",
"-mno-omit-leaf-frame-pointer",
"-fno-jump-tables",
"-nostdinc",
"-iquote."
],
"forcedInclude": [
"libc/integral/normalize.inc"
],
"defines": [
"COSMO",
"MODE=",
"IMAGE_BASE_VIRTUAL=0x400000"
]
}
],
"version": 4
-158
View File
@@ -1,160 +1,2 @@
#define __VSCODE_INTELLISENSE__ 1
#include "libc/integral/normalize.inc"
#if 0
#define __VSCODE_INTELLISENSE__ 1
#define __BIGGEST_ALIGNMENT__ 1
#define __CHAR_MAX__ 0x7F
#define __SCHAR_MAX__ __CHAR_MAX__
#define __SHRT_MAX__ 0x7FFF
#define __INT_MAX__ 0x7FFFFFFF
#define __LONG_MAX__ 0x7FFFFFFFFFFFFFFF
#define __LONG_LONG_MAX__ __LONG_MAX__
#define __CHAR_MIN__ -((__CHAR_MAX__) + 1)
#define __SHRT_MIN__ -((__SHRT_MAX__) + 1)
#define __INT_MIN__ -((__INT_MAX__) + 1)
#define __LONG_MIN__ -((__LONG_MAX__) + 1)
#define __LONG_LONG_MIN__ -((__LONG_LONG_MAX__) + 1)
#define __UCHAR_MAX__ 0xFF
#define __USHRT_MAX__ 0xFFFF
#define __UINT_MAX__ 0xFFFFFFFF
#define __ULONG_MAX__ 0xFFFFFFFFFFFFFFFF
#define __SIZE_MAX__ __ULONG_MAX__
#define __SSIZE_MAX__ __LONG_MAX__
#define __UINTPTR_MAX__ __SIZE_MAX__
#define __INTPTR_MAX__ __SSIZE_MAX__
#define __WCHAR_MAX__ __UINT_MAX__
#define __PTRDIFF_MAX__ __UINTPTR_MAX__
#define __INTMAX_MAX__ __ULONG_MAX__
#define __SIZEOF_POINTER__ 8
#define __SIZEOF_SHORT__ 2
#define __SIZEOF_INT__ 4
#define __SIZEOF_LONG__ 8
#define __SIZEOF_LONG_LONG__ 8
#define __SIZEOF_PTRDIFF_T__ 8
#define __SIZEOF_SIZE_T__ 8
#define __SIZEOF_WCHAR_T__ 4
#define __SIZEOF_WINT_T__ 4
#define __SIZEOF_FLOAT__ 4
#define __SIZEOF_FLOAT128__ 16
#define __SIZEOF_DOUBLE__ 8
#define __SIZEOF_FLOAT80__ 10
#define __SIZEOF_LONG_DOUBLE__ 16
#define __FLT_MAX__ 1
#define __DBL_MAX__ 1
#define __INT_LEAST8_TYPE__ signed char
#define __INT_LEAST16_TYPE__ signed short
#define __INT_LEAST32_TYPE__ signed int
#define __INT_LEAST64_TYPE__ signed long long
#define __UINT_LEAST8_TYPE__ unsigned char
#define __UINT_LEAST16_TYPE__ unsigned short
#define __UINT_LEAST32_TYPE__ unsigned int
#define __UINT_LEAST64_TYPE__ unsigned long long
#define __UINT8_MAX__ __UCHAR_MAX__
#define __UINT16_MAX__ __USHRT_MAX__
#define __UINT32_MAX__ __UINT_MAX__
#define __UINT64_MAX__ __ULONG_MAX__
#define __INT8_MAX__ __CHAR_MAX__
#define __INT16_MAX__ __SHRT_MAX__
#define __INT32_MAX__ __INT_MAX__
#define __INT64_MAX__ __LONG_MAX__
#define ATEXIT_MAX 1
#define STACKSIZE 0x10000
#define ARG_MAX 255
#define OPEN_MAX 0x7FFF
#define CHAR_BIT 7
#define NSIG 1
#define NULL (0)
#define false 0
#define true (!(false))
#define COSMOPOLITAN_C_START_
#define COSMOPOLITAN_C_END_
#define PAGESIZE 0x1000
#define BIGPAGESIZE 0x10000
#define NAME_MAX 255
#define SWITCHEROO(...) 0
extern unsigned g_loglevel;
typedef void * va_list;
#define va_start(...) 0
#define va_end(...) 0
#define va_arg(x, y) (y)(0)
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
#define int64_t long long
#define int128_t int64_t
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
typedef unsigned long long uint128_t;
typedef int errno_t;
typedef uint64_t size_t;
typedef unsigned long long ssize_t;
typedef uint64_t uintptr_t;
typedef long long intptr_t;
typedef unsigned long long uintmax_t;
typedef long long intmax_t;
typedef uint32_t bool32;
#ifndef __cplusplus
typedef uint8_t bool;
typedef uint16_t char16_t;
typedef uint32_t char32_t;
#endif /* __cplusplus */
typedef char32_t wint_t;
typedef char32_t wchar_t;
typedef struct { int ax, dx; } axdx_t;
/* duplicate and replace xmmintrin.internal.h to fix it for IntelliSense
* SEE: <> */
#define _Vector_size(x) __attribute__((__vector_size__(x)))
#define IMAGE_BASE_VIRTUAL 0x400000
#define __SIGACTION(...) (0)
#define VEIL(x, y) (y)
#define STATIC_YOINK(x)
#define BUFSIZ 1
#define FRAMESIZE 0x10000
#define PATH_MAX 252
#define concat(x, y, z) 0
#define CONCAT(a, b, c, d, e) 0
#define shuffle(...) 0
#define reverse(x, y) 0
#define autotype(x) intptr_t
#define _Generic_(...) (void*)(0)
#define _Generic(...) _Generic_
#define _Alignas(...)
#define _Section(...)
#define offsetof(x, y) 0
#define INITIALIZER(...) struct _dummy
#define __far
#define tinystrstr(...) 0
#define BENCHLOOP(...) 0
#ifdef __hook
#undef __hook
#endif /* __hook */
#ifdef UriKeyval
#undef UriKeyval
#endif /* UriKeyval */
#define _Static_assert(...) 0
#endif /* 0 */
+62
View File
@@ -0,0 +1,62 @@
# Contributing Guidelines
We'd love to accept your patches! Please read this guide first.
## Copyright Assignment
Please send an email to Justine Tunney <jtunney@gmail.com> stating that
you intend to assign her the copyright to the changes you contribute to
Cosmopolitan. Please use the same email address you use for git commits
which should only contain original source code from you or other people
who are also assigning copyright. Please note that, if you're employed,
you may need to get your employer's approval beforehand. If you can not
assign copyright due to local laws, then you may alternatively consider
disclaiming it using the language in [Unlicense](https://unlicense.org)
or [CC-0](http://creativecommons.org/share-your-work/public-domain/cc0)
This is important because we can't produce 12kb single-file executables
that comply with license requirements if we have to embed lots of them.
Although that's less of an issue depending on the purpose of the files.
For example, ownership is much less of a concern in the unit test files
so you're encouraged to put your copyright on those, provided it's ISC.
## Style Guide
You can use clang-format to automatically format your files:
```sh
clang-format -i -style=file tool/net/redbean.c
```
If you use Emacs this can be automated on save for Cosmopolitan using
[tool/emacs/cosmo-format.el]([tool/emacs/cosmo-format.el]).
### Source Files
- Must use include paths relative to the root of the repository
- Must have comment at top of file documenting copyright and license
- Must have notice embedding if not owned by Justine (exception: tests)
- May use language extensions that are supported by both GCC and Clang
- Should use Google indentation (otherwise use `/* clang-format off */`)
- Should use asm() instead of compiler APIs (exception: ctz, clz, memcpy)
### Header Files
- Must not have copyright or license comments
- Must have once guards (otherwise change `.h` to `.inc`)
- Must be ANSI C89 compatible to be included in the amalgamation header
- Must include its dependencies (exception: libc/integral/normalize.inc)
- Must not define objects (i.e. `cc -c -xc foo.h` will produce empty `.o`)
- Should not use typedefs
- Should not use forward declarations
- Should not include documentation comments
- Should not include parameter names in prototypes
- Should not pose problems if included by C++ or Assembly sources
- Should not declare non-ANSI code, at all, when the user requests ANSI
### Build Config
- Must not write files outside `o/`
- Must not communicate with Internet
- Must not depend on system libraries
- Must not depend on system commands (exception: sh, make, gzip, zip)
+16
View File
@@ -0,0 +1,16 @@
ISC License
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.
+38 -26
View File
@@ -40,8 +40,7 @@
# o/dbg/examples/crashreport.com
# less examples/crashreport.c
#
# # extremely tiny binaries (scout's honor escape hatch)
# # please pay the $1k for commercial license if you can
# # extremely tiny binaries
# make -j8 -O MODE=tiny \
# LDFLAGS+=-s \
# CPPFLAGS+=-DIM_FEELING_NAUGHTY \
@@ -101,7 +100,6 @@ include libc/str/str.mk # │
include third_party/xed/xed.mk # │
include third_party/zlib/zlib.mk # │
include libc/elf/elf.mk # │
include ape/lib/apelib.mk # │
include ape/ape.mk # │
include libc/fmt/fmt.mk #─┘
include libc/calls/calls.mk #─┐
@@ -131,21 +129,28 @@ include libc/libc.mk #─┘
include libc/sock/sock.mk #─┐
include dsp/tty/tty.mk # ├──ONLINE RUNTIME
include libc/dns/dns.mk # │ You can communicate with the network
include libc/crypto/crypto.mk # │
include net/http/http.mk #─┘
include third_party/duktape/duktape.mk
include third_party/regex/regex.mk
include net/http/http.mk # │
include third_party/mbedtls/mbedtls.mk # │
include net/https/https.mk # │
include third_party/regex/regex.mk #─┘
include third_party/third_party.mk
include libc/testlib/testlib.mk
include tool/viz/lib/vizlib.mk
include examples/examples.mk
include third_party/linenoise/linenoise.mk
include third_party/lua/lua.mk
include third_party/sqlite3/sqlite3.mk
include third_party/mbedtls/test/test.mk
include third_party/quickjs/quickjs.mk
include third_party/lz4cli/lz4cli.mk
include third_party/infozip/infozip.mk
include third_party/python/python.mk
include tool/build/lib/buildlib.mk
include third_party/chibicc/chibicc.mk
include third_party/chibicc/test/test.mk
include tool/build/emucrt/emucrt.mk
include tool/build/emubin/emubin.mk
include tool/build/build.mk
include examples/examples.mk
include tool/decode/lib/decodelib.mk
include tool/decode/decode.mk
include tool/hash/hash.mk
@@ -160,7 +165,6 @@ include test/libc/nexgen32e/test.mk
include test/libc/runtime/test.mk
include test/libc/sock/test.mk
include test/libc/bits/test.mk
include test/libc/crypto/test.mk
include test/libc/str/test.mk
include test/libc/unicode/test.mk
include test/libc/calls/test.mk
@@ -173,14 +177,14 @@ include test/libc/time/test.mk
include test/libc/stdio/test.mk
include test/libc/release/test.mk
include test/libc/test.mk
include test/ape/lib/test.mk
include test/ape/test.mk
include test/net/http/test.mk
include test/net/https/test.mk
include test/net/test.mk
include test/tool/build/lib/test.mk
include test/tool/build/test.mk
include test/tool/viz/lib/test.mk
include test/tool/viz/test.mk
include test/tool/net/test.mk
include test/tool/test.mk
include test/dsp/core/test.mk
include test/dsp/scale/test.mk
@@ -191,13 +195,13 @@ include examples/package/build.mk
#-φ-examples/package/new.sh
include test/test.mk
OBJS = $(foreach x,$(PKGS),$($(x)_OBJS))
SRCS = $(foreach x,$(PKGS),$($(x)_SRCS))
HDRS = $(foreach x,$(PKGS),$($(x)_HDRS))
INCS = $(foreach x,$(PKGS),$($(x)_INCS))
BINS = $(foreach x,$(PKGS),$($(x)_BINS))
TESTS = $(foreach x,$(PKGS),$($(x)_TESTS))
CHECKS = $(foreach x,$(PKGS),$($(x)_CHECKS))
OBJS = $(foreach x,$(PKGS),$($(x)_OBJS))
SRCS := $(foreach x,$(PKGS),$($(x)_SRCS))
HDRS := $(foreach x,$(PKGS),$($(x)_HDRS))
INCS = $(foreach x,$(PKGS),$($(x)_INCS))
BINS = $(foreach x,$(PKGS),$($(x)_BINS))
TESTS = $(foreach x,$(PKGS),$($(x)_TESTS))
CHECKS = $(foreach x,$(PKGS),$($(x)_CHECKS))
bins: $(BINS)
check: $(CHECKS)
@@ -208,14 +212,24 @@ tags: TAGS HTAGS
o/$(MODE)/.x:
@mkdir -p $(@D) && touch $@
ifneq ($(findstring 4.,,$(MAKE_VERSION)),$(MAKE_VERSION))
o/$(MODE)/srcs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(SRCS),$(dir $(x))))
$(file >$@) $(foreach x,$(SRCS),$(file >>$@,$(x)))
o/$(MODE)/hdrs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(HDRS) $(INCS),$(dir $(x))))
$(file >$@) $(foreach x,$(HDRS) $(INCS),$(file >>$@,$(x)))
o/$(MODE)/incs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(INCS) $(INCS),$(dir $(x))))
$(file >$@) $(foreach x,$(INCS) $(INCS),$(file >>$@,$(x)))
else
o/$(MODE)/srcs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(SRCS),$(dir $(x))))
$(MAKE) MODE=rel -j8 -pn bopit 2>/dev/null | sed -ne '/^SRCS/ {s/.*:= //;s/ */\n/g;p;q}' >$@
o/$(MODE)/hdrs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(HDRS) $(INCS),$(dir $(x))))
$(MAKE) MODE=rel -j8 -pn bopit 2>/dev/null | sed -ne '/^HDRS/ {s/.*:= //;s/ */\n/g;p;q}' >$@
o/$(MODE)/incs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(INCS) $(INCS),$(dir $(x))))
$(MAKE) MODE=rel -j8 -pn bopit 2>/dev/null | sed -ne '/^INCS/ {s/.*:= //;s/ */\n/g;p;q}' >$@
endif
o/$(MODE)/depend: o/$(MODE)/.x o/$(MODE)/srcs.txt o/$(MODE)/hdrs.txt $(SRCS) $(HDRS) $(INCS)
@$(COMPILE) -AMKDEPS $(MKDEPS) -o $@ -r o/$(MODE)/ o/$(MODE)/srcs.txt o/$(MODE)/hdrs.txt
o/$(MODE)/depend: o/$(MODE)/.x o/$(MODE)/srcs.txt o/$(MODE)/hdrs.txt o/$(MODE)/incs.txt $(SRCS) $(HDRS) $(INCS)
@$(COMPILE) -AMKDEPS $(MKDEPS) -o $@ -r o/$(MODE)/ o/$(MODE)/srcs.txt o/$(MODE)/hdrs.txt o/$(MODE)/incs.txt
TAGS: o/$(MODE)/srcs.txt $(SRCS)
@rm -f $@
@@ -230,23 +244,22 @@ loc: o/$(MODE)/tool/build/summy.com
$(XARGS) wc -l | grep total | awk '{print $$1}' | $<
COSMOPOLITAN_OBJECTS = \
LIBC_CRYPTO \
LIBC_DNS \
LIBC_SOCK \
LIBC_NT_WS2_32 \
LIBC_NT_IPHLPAPI \
LIBC_NT_MSWSOCK \
LIBC_OHMYPLUS \
LIBC_X \
THIRD_PARTY_GDTOA \
THIRD_PARTY_GETOPT \
LIBC_LOG \
LIBC_UNICODE \
LIBC_TIME \
LIBC_ZIPOS \
THIRD_PARTY_ZLIB \
APE_LIB \
THIRD_PARTY_MUSL \
LIBC_STDIO \
THIRD_PARTY_GDTOA \
THIRD_PARTY_REGEX \
LIBC_ALG \
LIBC_MEM \
@@ -269,8 +282,8 @@ COSMOPOLITAN_OBJECTS = \
LIBC_FMT \
THIRD_PARTY_COMPILER_RT \
LIBC_TINYMATH \
LIBC_SYSV \
LIBC_STR \
LIBC_SYSV \
LIBC_INTRIN \
LIBC_NT_KERNEL32 \
LIBC_NEXGEN32E
@@ -280,7 +293,6 @@ COSMOPOLITAN_HEADERS = \
LIBC_ALG \
LIBC_BITS \
LIBC_CALLS \
LIBC_CRYPTO \
LIBC_DNS \
LIBC_ELF \
LIBC_FMT \
-14
View File
@@ -1,14 +0,0 @@
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.
+55 -10
View File
@@ -19,32 +19,77 @@ 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:
five files to get started. Here's what you do on Linux:
```sh
wget https://justine.lol/cosmopolitan/cosmopolitan-amalgamation-0.2.zip
unzip cosmopolitan-amalgamation-0.2.zip
wget https://justine.lol/cosmopolitan/cosmopolitan-amalgamation-1.0.zip
unzip cosmopolitan-amalgamation-1.0.zip
printf 'main() { printf("hello world\\n"); }\n' >hello.c
gcc -g -O -static -nostdlib -nostdinc -fno-pie -no-pie -mno-red-zone \
gcc -g -Os -static -nostdlib -nostdinc -fno-pie -no-pie -mno-red-zone \
-fno-omit-frame-pointer -pg -mnop-mcount \
-o hello.com.dbg hello.c -fuse-ld=bfd -Wl,-T,ape.lds \
-include cosmopolitan.h crt.o ape.o cosmopolitan.a
objcopy -S -O binary hello.com.dbg hello.com
./hello.com
```
If you're developing on Windows or MacOS then you need to download an
You now have a portable program. Please note that your APE binary will
assimilate itself as a conventional resident of your platform after the
first run, so it can be fast and efficient for subsequent executions.
```sh
./hello.com
bash -c './hello.com' # zsh/fish workaround (we upstreamed patches)
```
So if you intend to copy the binary to Windows or Mac then please do
that before you run it, not after.
### 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 can also be compiled from source on any Linux distro.
## Source Builds
Cosmopolitan can be compiled from source on any Linux distro. GNU make
needs to be installed beforehand. This is a freestanding hermetic
repository that bootstraps using a vendored static gcc9 executable.
No further dependencies are required.
```sh
wget https://justine.lol/cosmopolitan/cosmopolitan-0.2.tar.gz
tar xf cosmopolitan-0.2.tar.gz # see releases page
cd cosmopolitan-0.2
wget https://justine.lol/cosmopolitan/cosmopolitan-1.0.tar.gz
tar xf cosmopolitan-1.0.tar.gz # see releases page
cd cosmopolitan
make -j16
o//examples/hello.com
find o -name \*.com | xargs ls -rShal | less
```
## Support Vector
| Platform | Min Version | Circa |
| :--- | ---: | ---: |
| AMD | K8 Venus | 2005 |
| Intel | Core | 2006 |
| New Technology | Vista | 2006 |
| GNU/Systemd | 2.6.18 | 2007 |
| XNU's Not UNIX! | 15.6 | 2018 |
| FreeBSD | 12 | 2018 |
| OpenBSD | 6.4 | 2018 |
| NetBSD | 9.1 | 2020 |
| GNU Make | 3.80 | 2010 |
+339 -397
View File
File diff suppressed because it is too large. Load diff
+55 -41
View File
@@ -175,7 +175,7 @@
#ifdef __LINKER__
#include "ape/macros.internal.h"
#include "ape/config.h"
#include "ape/relocations.h"
#include "libc/dce.h"
#include "libc/nt/pedef.internal.h"
#include "libc/zip.h"
@@ -196,20 +196,20 @@ SECTIONS {
/*BEGIN: linux addressability guarantee */
/*BEGIN: bsd addressability guarantee */
.head SEGMENT_START("text-segment", IMAGE_BASE_VIRTUAL) : {
.head SEGMENT_START("text-segment", IMAGE_BASE_VIRTUAL) : AT(IMAGE_BASE_REAL) {
HIDDEN(_base = .);
/* Real Mode */
KEEP(*(.head))
KEEP(*(.apesh))
KEEP(*(.head2))
KEEP(*(.text.head))
/* Executable & Linkable Format */
. = ALIGN(__SIZEOF_POINTER__);
HIDDEN(ape_phdrs = .);
KEEP(*(.elf.phdrs))
HIDDEN(ape_phdrs_end = .);
HIDDEN(ape_phdrs32 = .);
KEEP(*(.elf.phdrs32))
HIDDEN(ape_phdrs32_end = .);
/* OpenBSD */
. = ALIGN(__SIZEOF_POINTER__);
@@ -223,16 +223,14 @@ SECTIONS {
HIDDEN(ape_pe_sections = .);
KEEP(*(.pe.sections))
HIDDEN(ape_pe_sections_end = .);
. += 1;
/* Mach-O */
KEEP(*(.macho))
. = ALIGN(__SIZEOF_POINTER__);
HIDDEN(ape_macho_end = .);
. += 1;
KEEP(*(.ape.pad.head))
. = ALIGN(SupportsWindows() ? PAGESIZE : 16);
. = ALIGN(SupportsWindows() || SupportsMetal() ? PAGESIZE : 16);
HIDDEN(_ehead = .);
} :Head
@@ -242,14 +240,13 @@ SECTIONS {
/* Code that needs to be addressable in Real Mode */
*(.text.real)
KEEP(*(SORT_BY_NAME(.sort.text.real.*)))
*(.rodata.real)
KEEP(*(SORT_BY_NAME(.sort.rodata.real.*)))
HIDDEN(_ereal = .);
. += 1;
/*END: realmode addressability guarantee */
/* Normal Code */
KEEP(*(.start))
*(.start)
KEEP(*(.initprologue))
KEEP(*(SORT_BY_NAME(.init.*)))
KEEP(*(.init))
@@ -277,17 +274,17 @@ SECTIONS {
KEEP(*(SORT_BY_NAME(.sort.text.*)))
KEEP(*(.ape.pad.test));
HIDDEN(__test_start = .);
*(.test.unlikely)
*(.test .test.*)
/* Privileged code invulnerable to magic */
KEEP(*(.ape.pad.privileged));
. += . > 0 ? 1 : 0;
HIDDEN(__privileged_start = .);
HIDDEN(__test_end = .);
. += 1;
. += . > 0 ? 1 : 0;
*(.privileged)
HIDDEN(__privileged_end = .);
. += . > 0 ? 1 : 0;
/*BEGIN: Read Only Data */
@@ -307,11 +304,10 @@ SECTIONS {
KEEP(*(.comment))
KEEP(*(.commentepilogue))
#endif
/* Windows DLL Import Directory */
KEEP(*(.idata.ro));
KEEP(*(SORT_BY_NAME(.idata.ro.*)))
. += 1;
. = ALIGN(__SIZEOF_POINTER__);
PROVIDE_HIDDEN(__init_array_start = .);
@@ -370,11 +366,23 @@ SECTIONS {
PROVIDE_HIDDEN(edata = .);
} :Ram
.bss . : {
/*END: file content that's loaded by o/s */
/*BEGIN: bss memory void */
.zip . : {
KEEP(*(SORT_BY_NAME(.zip.*)))
HIDDEN(_ezip = .);
}
/*END: file content */
/*BEGIN: bss memory that's addressable */
.bss ALIGN(64) : {
KEEP(*(SORT_BY_NAME(.piro.bss.init.*)))
*(.piro.bss)
KEEP(*(SORT_BY_NAME(.piro.bss.sort.*)))
HIDDEN(__piro_end = .);
. += . > 0 ? 1 : 0;
/*END: Post-Initialization Read-Only */
/* Statically Allocated Empty Space */
@@ -384,15 +392,10 @@ SECTIONS {
KEEP(*(SORT_BY_NAME(.sort.bss.*)))
/* eXtreme Low Memory w/ Userspace Remapping */
. = ALIGN(0x1000);
*(.xlm)
. = ALIGN(0x1000);
. = ALIGN(0x10000); /* for brk()/sbrk() allocation */
. = ALIGN(FRAMESIZE); /* for brk()/sbrk() allocation */
HIDDEN(_end = .);
PROVIDE_HIDDEN(end = .);
} :Ram
}
/*END: nt addressability guarantee */
/*END: bsd addressability guarantee */
@@ -448,13 +451,6 @@ PFSTUB4(ape_elf_phnum, (ape_phdrs_end - ape_phdrs) / 56);
PFSTUB4(ape_elf_shnum, 0);
PFSTUB4(ape_elf_shstrndx, 0);
PFSTUB4(ape_elf32_entry, _start32);
PFSTUB4(ape_elf32_phoff, RVA(ape_phdrs32));
PFSTUB4(ape_elf32_shoff, 0);
PFSTUB4(ape_elf32_phnum, (ape_phdrs32_end - ape_phdrs32) / 32);
PFSTUB4(ape_elf32_shnum, 0);
PFSTUB4(ape_elf32_shstrndx, 0);
HIDDEN(__privileged_addr = ROUNDDOWN(__privileged_start, PAGESIZE));
HIDDEN(__privileged_size = (ROUNDUP(__privileged_end, PAGESIZE) -
ROUNDDOWN(__privileged_start, PAGESIZE)));
@@ -470,11 +466,18 @@ HIDDEN(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 = LOADADDR(.bss) - 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));
HIDDEN(ape_stack_offset = ape_ram_offset + ape_ram_filesz);
HIDDEN(ape_stack_vaddr = 0x700000000000 - STACKSIZE);
HIDDEN(ape_stack_paddr = ape_ram_paddr + ape_ram_filesz);
HIDDEN(ape_stack_filesz = 0);
HIDDEN(ape_stack_memsz = STACKSIZE);
HIDDEN(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);
@@ -510,20 +513,30 @@ SHSTUB2(ape_macho_dd_skip, RVA(ape_macho) / 8);
SHSTUB2(ape_macho_dd_count, (ape_macho_end - ape_macho) / 8);
#endif
#if SupportsWindows()
#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_idata_idtsize = ape_idata_idtend - ape_idata_idt);
HIDDEN(ape_idata_iatsize = ape_idata_iatend - ape_idata_iat);
HIDDEN(v_ntsubsystem = (DEFINED(GetMessage)
? kNtImageSubsystemWindowsGui
: kNtImageSubsystemWindowsCui));
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);
#endif
#if SupportsMetal()
HIDDEN(v_ape_realsectors =
MIN(REAL_SCRATCH_AREA - IMAGE_BASE_REAL,
MIN(0x70000 - IMAGE_BASE_REAL,
ROUNDUP(RVA(_edata), 4096)) / 512);
HIDDEN(v_ape_realpages = v_ape_realsectors / (4096 / 512));
HIDDEN(v_ape_highsectors =
@@ -534,8 +547,9 @@ HIDDEN(v_ape_highsectors =
#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, _edata - __zip_end - kZipCdirHdrMinSize);
ZIPCONST(v_zip_commentsize, _ezip - __zip_end - kZipCdirHdrMinSize);
#if SupportsXnu()
/* Generates deterministic ID. */
@@ -613,7 +627,7 @@ CHURN(v_ape_realsectors);
#if SupportsXnu()
CHURN(ape_macho);
#endif
#if SupportsWindows()
#if SupportsWindows() || SupportsMetal()
CHURN(ape_mz);
CHURN(ape_pe);
CHURN(ape_pe_offset);
+12 -3
View File
@@ -19,6 +19,11 @@ APE = $(APE_DEPS) \
$(APE_OBJS) \
o/$(MODE)/ape/ape.lds
APE_BUILDSAFE = \
$(APE_DEPS) \
o/$(MODE)/ape/ape-buildsafe.o \
o/$(MODE)/ape/ape.lds
APELINK = \
$(COMPILE) \
-ALINK.ape \
@@ -31,12 +36,10 @@ APE_HDRS = $(filter %.h,$(APE_FILES))
APE_INCS = $(filter %.inc,$(APE_FILES))
APE_SRCS = $(filter %.S,$(APE_FILES))
APE_OBJS = $(APE_SRCS:%.S=o/$(MODE)/%.o)
APE_DEPS = $(APE_LIB)
APE_CHECKS = $(APE_HDRS:%=o/%.ok)
o/$(MODE)/ape/ape.lds: \
ape/ape.lds \
ape/config.h \
ape/macros.internal.h \
libc/dce.h \
libc/zip.h
@@ -48,7 +51,13 @@ o/ape/idata.inc: \
$(APE_OBJS): $(BUILD_FILES) \
ape/ape.mk
o/$(MODE)/ape/ape-no-modify-self.o: ape/ape.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -DAPE_NO_MODIFY_SELF $<
o/$(MODE)/ape/ape-buildsafe.o: ape/ape.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -DAPE_BUILDSAFE $<
.PHONY: o/$(MODE)/ape
o/$(MODE)/ape: $(APE) \
$(APE_CHECKS) \
o/$(MODE)/ape/lib
o/$(MODE)/ape/ape-no-modify-self.o
-118
View File
@@ -1,118 +0,0 @@
#ifndef APE_CONFIG_H_
#define APE_CONFIG_H_
#include "ape/relocations.h"
#include "libc/macros.h"
/*
* Post-Initialization Read-Only Code Size Threshold.
*
* An executable needs to have at least this much code, before the
* linker adds non-mandatory 4kb alignments. The benefit is better
* memory protection. The tradeoff is sparser binaries.
*/
#ifndef APE_PIRO_THRESHOLD
#ifdef CONFIG_DBG
#define APE_PIRO_THRESHOLD 0x1000
#else
#define APE_PIRO_THRESHOLD 0x10000
#endif
#endif
#ifndef METAL_STDIN
#define METAL_STDIN COM1
#endif
#ifndef METAL_STDOUT
#define METAL_STDOUT COM1
#endif
#ifndef METAL_STDERR
#define METAL_STDERR COM1
#endif
#ifndef VIDYA_MODE
#define VIDYA_MODE VIDYA_MODE_CGA
#endif
/* FPU Control Word (x87) Exception Masks
@see Intel Manual V1 §8.1.5
IM: Invalid Operation ───────────────┐
DM: Denormal Operand ───────────────┐│
ZM: Zero Divide ───────────────────┐││
OM: Overflow ─────────────────────┐│││
UM: Underflow ───────────────────┐││││
PM: Precision ──────────────────┐│││││
PC: Precision Control ────────┐ ││││││
{float,∅,double,long double} │ ││││││
RC: Rounding Control ───────┐ │ ││││││
{even, →-∞, →+∞, →0} │┌┤ ││││││
┌┤││ ││││││
d││││rr││││││*/
#define X87_NORMAL 0b000000000001101111111
#define X87_DTOA 0b000000000001000000000
#define X87_DTOA_MASK 0b000000000001100000000
#ifndef X87_DEFAULT
#define X87_DEFAULT X87_NORMAL
#endif
#ifndef UART_BAUD_RATE
#define UART_BAUD_RATE 9600 /* bits per second ∈ [50,115200] */
#endif
#define UART_CONF_DLR (1843200 /*hz*/ / 16 /*wut*/ / (UART_BAUD_RATE))
#ifndef UART_CONF_IIR
/* ┌interrupt trigger level {1,4,8,14}
│ ┌enable 64 byte fifo (UART 16750+)
│ │ ┌select dma mode
│ │ │┌clear transmit fifo
│ │ ││┌clear receive fifo
├┐│ │││┌enable fifos*/
#define UART_CONF_IIR 0b00000000
#endif
#ifndef UART_CONF_LCR
/* ┌dlab: flips configuration mode state
│┌enable break signal
││ ┌parity {none,odd,even,high,low}
││ │ ┌extra stop bit
││ │ │┌data word length (bits+5)
││┌┴┐│├┐*/
#define UART_CONF_LCR 0b01000011
#endif
#define XLM(VAR) (XLM_BASE_REAL + XLM_##VAR)
#define XLMV(VAR) (__xlm + XLM_##VAR)
#define XLM_BASE_REAL 0x1000
#define XLM_E820 0
#define XLM_E820_SIZE 0x2000
#define XLM_BIOS_DATA_AREA 0x2000
#define XLM_BIOS_DATA_AREA_SIZE 256
#define XLM_DRIVE_BASE_TABLE 0x2200 /* drive values are contiguous */
#define XLM_DRIVE_BASE_TABLE_SIZE 11
#define XLM_DRIVE_TYPE 0x220b
#define XLM_DRIVE_TYPE_SIZE 1
#define XLM_DRIVE_LAST_SECTOR 0x220c /* 1-based inclusive, e.g. 18 */
#define XLM_DRIVE_LAST_SECTOR_SIZE 1
#define XLM_DRIVE_LAST_CYLINDER 0x220d /* 0-based incl, e.g. 79 */
#define XLM_DRIVE_LAST_CYLINDER_SIZE 2
#define XLM_DRIVE_ATTACHED 0x220f
#define XLM_DRIVE_ATTACHED_SIZE 1
#define XLM_DRIVE_LAST_HEAD 0x2210 /* 0-based inclusive, e.g. 1 */
#define XLM_DRIVE_LAST_HEAD_SIZE 1
#define XLM_DRIVE 0x2211
#define XLM_DRIVE_SIZE 1
#define XLM_HAVEEXTMEMKB 0x2212
#define XLM_HAVEEXTMEMKB_SIZE 4
#define XLM_VIDEO_POSITION_FAR_POINTER 0x2216 /* video cursor far pointer */
#define XLM_VIDEO_POSITION_FAR_POINTER_SIZE 4
#define XLM_PAGE_TABLE_STACK_POINTER 0x2220
#define XLM_PAGE_TABLE_STACK_POINTER_SIZE 8
#define XLM_BADIDT 0x2230
#define XLM_BADIDT_SIZE 6
#define XLM_LOADSTATE 0x2240
#define XLM_LOADSTATE_SIZE 8
#define XLM_SIZE ROUNDUP(XLM_LOADSTATE + XLM_LOADSTATE_SIZE, 0x1000)
#define IMAGE_BASE_REAL (XLM_BASE_REAL + XLM_SIZE)
#if !defined(__LINKER__) && !defined(__ASSEMBLER__)
extern char __xlm[XLM_SIZE];
#endif /* !defined(__LINKER__) && !defined(__ASSEMBLER__) */
#endif /* APE_CONFIG_H_ */
-1279
View File
File diff suppressed because it is too large. Load diff
-1294
View File
File diff suppressed because it is too large. Load diff
-45
View File
@@ -1,45 +0,0 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += APE_LIB
APE_LIB_ARTIFACTS += APE_LIB_A
APE_LIB = $(APE_LIB_A_DEPS) $(APE_LIB_A)
APE_LIB_A = o/$(MODE)/ape/lib/apelib.a
APE_LIB_A_FILES := $(wildcard ape/lib/*)
APE_LIB_A_HDRS = $(filter %.h,$(APE_LIB_A_FILES))
APE_LIB_A_SRCS_S = $(filter %.S,$(APE_LIB_A_FILES))
APE_LIB_A_SRCS_C = $(filter %.c,$(APE_LIB_A_FILES))
APE_LIB_A_SRCS = \
$(APE_LIB_A_SRCS_S) \
$(APE_LIB_A_SRCS_C)
APE_LIB_A_OBJS = \
$(APE_LIB_A_SRCS_S:%.S=o/$(MODE)/%.o) \
$(APE_LIB_A_SRCS_C:%.c=o/$(MODE)/%.o)
APE_LIB_A_DIRECTDEPS = \
LIBC_NEXGEN32E \
LIBC_INTRIN \
LIBC_STR \
LIBC_STUBS
APE_LIB_A_CHECKS = $(APE_LIB_A_HDRS:%=o/$(MODE)/%.ok)
APE_LIB_A_DEPS = $(call uniq,$(foreach x,$(APE_LIB_A_DIRECTDEPS),$($(x))))
$(APE_LIB_A): ape/lib/ $(APE_LIB_A).pkg $(APE_LIB_A_OBJS)
$(APE_LIB_A).pkg: $(APE_LIB_A_OBJS) $(foreach x,$(APE_LIB_A_DIRECTDEPS),$($(x)_A).pkg)
APE_LIB_LIBS = $(foreach x,$(APE_LIB_ARTIFACTS),$($(x)))
APE_LIB_SRCS = $(foreach x,$(APE_LIB_ARTIFACTS),$($(x)_SRCS))
APE_LIB_HDRS = $(foreach x,$(APE_LIB_ARTIFACTS),$($(x)_HDRS))
APE_LIB_BINS = $(foreach x,$(APE_LIB_ARTIFACTS),$($(x)_BINS))
APE_LIB_CHECKS = $(foreach x,$(APE_LIB_ARTIFACTS),$($(x)_CHECKS))
APE_LIB_OBJS = $(foreach x,$(APE_LIB_ARTIFACTS),$($(x)_OBJS))
$(APE_LIB_OBJS): $(BUILD_FILES) libc/str/str.mk
.PHONY: o/$(MODE)/ape/lib
o/$(MODE)/ape/lib: \
$(APE_LIB_CHECKS) \
$(APE_LIB_A)
-58
View File
@@ -1,58 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=8 sts=2 sw=2 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. │
╠──────────────────────────────────────────────────────────────────────────────╣
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
│░░░░░░░█▀█░█▀█░▀█▀░█░█░█▀█░█░░░█░░░█░█░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
│░░░░░░░█▀█░█░▄░░█░░█░█░█▀█░█░░░█░░░▀█▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
│░░░░░░░▀░▀░▀▀▀░░▀░░▀▀▀░▀░▀░▀▀▀░▀▀▀░░▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
│░░░░░░░█▀█░█▀█░█▀█░▀█▀░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
│░░░░░░░█▀▀░█ █░██▀░░█░░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
│░░░░░░░▀░░░▀▀▀░▀░▀░░▀░░▀░▀░▀▀▀░▀▀▀░▀▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
│░░░░░░░█▀▀░█░█░█▀▀░█▀█░█░█░▀█▀░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░▄▄░░░▐█░░│
│░░░░░░░█▀▀░▄▀▄░█▀▀░█░▄░█░█░░█░░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░▄▄▄░░░▄██▄░░█▀░░░█░▄░│
│░░░░░░░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀░░▀░░▀░▀░▀▀▀░▀▀░▀▀▀░░░░░░░░░░▄██▀█▌░██▄▄░░▐█▀▄░▐█▀░░│
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▐█▀▀▌░░░▄▀▌░▌░█░▌░░▌░▌░░│
╠──────────────────────────────────────────────────────▌▀▄─▐──▀▄─▐▄─▐▄▐▄─▐▄─▐▄─│
│ αcτµαlly pδrταblε εxεcµταblε § green energy │
╚─────────────────────────────────────────────────────────────────────────────*/
#ifndef APE_LIB_APM_H_
#define APE_LIB_APM_H_
/**
* @fileoverview Advanced Power Management.
*
* <p>APM is useful for exiting programs, without needing to ask the
* human to flip a physical switch or pass QEMU's -no-reboot flag.
*
* <p><b>Implementation Detail:</b> Supporting ACPI would literally
* require implementing a programming language.
*
* @see APM BIOS Interface Specification v1.2
* @since IBM PC/AT
*/
#define APM_SERVICE 0x15
#if !(__ASSEMBLER__ + __LINKER__ + 0)
void apmoff(void) wontreturn;
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* APE_LIB_APM_H_ */
-35
View File
@@ -1,35 +0,0 @@
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
│vi: set et ft=asm ts=8 sw=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 "ape/macros.internal.h"
#include "ape/notice.inc"
.section .real,"ax",@progbits
.source __FILE__
.code16
// Resets personal computer.
//
// @param di drive number, e.g. A:\ is 0x00, C:\ is 0x80
// @mode real
// @noreturn
bootdr: push %bp
mov %sp,%bp
mov %di,%dx
int $0x19
ljmp $0xf000,$0xfff0
.endfn bootdr,globl
-37
View File
@@ -1,37 +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 "ape/lib/pc.h"
#include "ape/config.h"
#include "ape/macros.internal.h"
#include "ape/notice.inc"
.section .real,"ax",@progbits
.source __FILE__
.code16
.globl e820map
.hidden e820map
.type e820map,@object
.size e820map,XLM_E820_SIZE
e820map = ape_xlm + XLM_E820
.globl e820map_xlm
.hidden e820map_xlm
.type e820map_xlm,@object
.size e820map_xlm,XLM_E820_SIZE
e820map_xlm = XLM(E820)
-55
View File
@@ -1,55 +0,0 @@
/*-*- 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 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 "ape/config.h"
#include "ape/lib/pc.h"
#include "libc/bits/bits.h"
#include "libc/macros.h"
/**
* Virtualizes physical memory.
*
* This function removes memory holes (discovered by e820() earlier) and
* creates the illusion of flat contiguous memory for as much RAM as the
* BIOS reports usable. Memory is safe to use and remap afterwards.
*
* @see ape/ape.S
*/
textreal void flattenhighmemory(struct SmapEntry *e820, struct PageTable *pml4t,
uint64_t *ptsp) {
uint64_t *entry, paddr, vaddr;
struct SmapEntry *smap, *hole;
for (smap = hole = e820, vaddr = IMAGE_BASE_VIRTUAL; smap->size; ++smap) {
while (smap->size && smap->type != kMemoryUsable) smap++;
paddr = ROUNDUP(MAX(IMAGE_BASE_PHYSICAL, smap->addr), PAGESIZE);
while (paddr < ROUNDDOWN(smap->addr + smap->size, PAGESIZE)) {
while (hole->size &&
(hole->type == kMemoryUsable || hole->addr + hole->size < paddr)) {
hole++;
}
if (paddr >= hole->addr && paddr < hole->addr + hole->size) {
paddr = ROUNDUP(hole->addr + hole->size, PAGESIZE);
} else {
entry = __getpagetableentry(vaddr, 3, pml4t, ptsp);
*entry = paddr | PAGE_V | PAGE_RW;
vaddr += 0x1000;
paddr += 0x1000;
}
}
}
}
-31
View File
@@ -1,31 +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 "ape/lib/pc.h"
#include "ape/config.h"
#include "ape/macros.internal.h"
#include "ape/notice.inc"
.section .real,"ax",@progbits
.source __FILE__
.code16
.globl g_pml4t
.hidden g_pml4t
.type g_pml4t,@object
.size g_pml4t,0x1000
g_pml4t = REAL_STACK_FRAME - 0x1000
-37
View File
@@ -1,37 +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 "ape/lib/pc.h"
#include "ape/config.h"
#include "ape/macros.internal.h"
#include "ape/notice.inc"
.section .real,"ax",@progbits
.source __FILE__
.code16
.globl g_ptsp
.hidden g_ptsp
.type g_ptsp,@object
.size g_ptsp,XLM_PAGE_TABLE_STACK_POINTER_SIZE
g_ptsp = ape_xlm + XLM_PAGE_TABLE_STACK_POINTER
.globl g_ptsp_xlm
.hidden g_ptsp_xlm
.type g_ptsp_xlm,@object
.size g_ptsp_xlm,XLM_PAGE_TABLE_STACK_POINTER_SIZE
g_ptsp_xlm = XLM(PAGE_TABLE_STACK_POINTER)
-42
View File
@@ -1,42 +0,0 @@
/*-*- 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 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 "ape/lib/pc.h"
#include "libc/assert.h"
static textreal uint64_t __pushpagetable(uint64_t *ptsp) {
return (*ptsp -= PAGESIZE) | PAGE_V | PAGE_RW;
}
textreal uint64_t *__getpagetableentry(int64_t vaddr, unsigned depth,
struct PageTable *pml4t,
uint64_t *ptsp) {
uint64_t *entry;
unsigned char shift;
assert(depth <= 3);
assert(!(*ptsp & 0xfff));
assert(!((uintptr_t)pml4t & 0xfff));
shift = 39;
for (;;) {
entry = &pml4t->p[(vaddr >> shift) & 511];
if (!depth--) return entry;
shift -= 9;
if (!*entry) *entry = __pushpagetable(ptsp);
pml4t = (void *)(*entry & PAGE_TA);
}
}
-45
View File
@@ -1,45 +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 "ape/lib/pc.h"
#include "ape/config.h"
#include "ape/macros.internal.h"
#include "ape/notice.inc"
.section .real,"ax",@progbits
.source __FILE__
.code16
.globl kBiosDataArea
.hidden kBiosDataArea
.type kBiosDataArea,@object
.size kBiosDataArea,XLM_BIOS_DATA_AREA_SIZE
kBiosDataArea = ape_xlm + XLM_BIOS_DATA_AREA
.globl kBiosDataAreaXlm
.hidden kBiosDataAreaXlm
.type kBiosDataAreaXlm,@object
.size kBiosDataAreaXlm,XLM_BIOS_DATA_AREA_SIZE
kBiosDataAreaXlm = XLM(BIOS_DATA_AREA)
.section .sort.text.real.init.2.kBiosDataArea,"ax",@progbits
movpp %ds,%es # copy bios data to valid page
mov $PC_BIOS_DATA_AREA,%si
mov $XLM(BIOS_DATA_AREA),%di
mov $XLM_BIOS_DATA_AREA_SIZE,%cx
rep movsb
.previous
-36
View File
@@ -1,36 +0,0 @@
/*-*- 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 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 "ape/lib/pc.h"
#include "ape/relocations.h"
#include "libc/runtime/runtime.h"
textreal static void __map_segment(uint64_t k, uint64_t a, uint64_t b) {
uint64_t *e;
for (; a < b; a += 0x1000) {
e = __getpagetableentry(IMAGE_BASE_VIRTUAL + a, 3, &g_pml4t, &g_ptsp_xlm);
*e = (IMAGE_BASE_REAL + a) | k;
}
}
textreal void __map_image(void) {
__map_segment(PAGE_V | PAGE_U, 0, (uintptr_t)_etext - IMAGE_BASE_VIRTUAL);
__map_segment(PAGE_V | PAGE_U | PAGE_RW,
(uintptr_t)_etext - IMAGE_BASE_VIRTUAL,
(uintptr_t)_end - IMAGE_BASE_VIRTUAL);
}
-26
View File
@@ -1,26 +0,0 @@
/*-*- 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 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 "ape/lib/pc.h"
textreal void pageunmap(int64_t vaddr) {
uint64_t *entry;
entry = __getpagetableentry(vaddr, 3, &g_pml4t, &g_ptsp_xlm);
*entry &= ~PAGE_V;
asm volatile("invlpg\t(%0)" : /* no outputs */ : "r"(vaddr) : "memory");
}
-242
View File
@@ -1,242 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=8 sts=2 sw=2 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. │
╠──────────────────────────────────────────────────────────────────────────────╣
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
│░░░░░░░█▀█░█▀█░▀█▀░█░█░█▀█░█░░░█░░░█░█░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
│░░░░░░░█▀█░█░▄░░█░░█░█░█▀█░█░░░█░░░▀█▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
│░░░░░░░▀░▀░▀▀▀░░▀░░▀▀▀░▀░▀░▀▀▀░▀▀▀░░▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
│░░░░░░░█▀█░█▀█░█▀█░▀█▀░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
│░░░░░░░█▀▀░█ █░██▀░░█░░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
│░░░░░░░▀░░░▀▀▀░▀░▀░░▀░░▀░▀░▀▀▀░▀▀▀░▀▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
│░░░░░░░█▀▀░█░█░█▀▀░█▀█░█░█░▀█▀░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░▄▄░░░▐█░░│
│░░░░░░░█▀▀░▄▀▄░█▀▀░█░▄░█░█░░█░░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░▄▄▄░░░▄██▄░░█▀░░░█░▄░│
│░░░░░░░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀░░▀░░▀░▀░▀▀▀░▀▀░▀▀▀░░░░░░░░░░▄██▀█▌░██▄▄░░▐█▀▄░▐█▀░░│
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▐█▀▀▌░░░▄▀▌░▌░█░▌░░▌░▌░░│
╠──────────────────────────────────────────────────────▌▀▄─▐──▀▄─▐▄─▐▄▐▄─▐▄─▐▄─│
│ αcτµαlly pδrταblε εxεcµταblε § ibm personal computer │
╚─────────────────────────────────────────────────────────────────────────────*/
#ifndef APE_LIB_PC_H_
#define APE_LIB_PC_H_
#define BOOTSIG 0xaa55 /* master boot record signature */
#define PC_BIOS_DATA_AREA 0x400
#define kInterruptFlag (1u << 9)
/* FPU Status Word (x87)
@see Intel Manual V1 §8.1.3
IE: Invalid Operation ────────────────┐
DE: Denormalized Operand ────────────┐│
ZE: Zero Divide ────────────────────┐││
OE: Overflow Flag ─────────────────┐│││
UE: Underflow Flag ───────────────┐││││
PE: Precision Flag ──────────────┐│││││
SF: Stack Fault ────────────────┐││││││
ES: Exception Summary Status ──┐│││││││
C0-3: Condition Codes ──┬────┐ ││││││││
TOP of Stack Pointer ─────┐ │ ││││││││
B: FPU Busy ───────────┐│ │ │ ││││││││
││┌┴┐┌┼┐││││││││
│↓│ │↓↓↓││││││││*/
#define FPU_IE 0b0000000000100000000000001
#define FPU_ZE 0b0000000000100000000000100
#define FPU_SF 0b0000000000000000001000000
#define FPU_C0 0b0000000000000000100000000
#define FPU_C1 0b0000000000000001000000000
#define FPU_C2 0b0000000000000010000000000
#define FPU_C3 0b0000000000100000000000000
#define CR0_PE 0x01 /* protected mode enabled */
#define CR0_MP 0x02 /* monitor coprocessor */
#define CR0_EM 0x04 /* no x87 fpu present if set */
#define CR0_TS 0x08 /* task switched x87 */
#define CR0_ET 0x10 /* extension type 287 or 387 */
#define CR0_NE 0x20 /* enable x87 error reporting */
#define CR0_WP 0x00010000 /* write protect read-only pages @pl0 */
#define CR0_AM 0x00040000 /* alignment mask */
#define CR0_NW 0x20000000 /* global write-through cache disable */
#define CR0_CD 0x40000000 /* global cache disable */
#define CR0_PG 0x80000000 /* paging enabled */
#define CR4_VME 0x01 /* virtual 8086 mode extension */
#define CR4_PVI 0x02 /* protected mode virtual interrupts */
#define CR4_TSD 0x04 /* time stamp disable (rdtsc) */
#define CR4_DE 0x08 /* debugging extensions */
#define CR4_PSE 0x10 /* page size extension */
#define CR4_PAE 0x20 /* physical address extension */
#define CR4_MCE 0x40 /* machine check exception */
#define CR4_PGE 0x80 /* page global enabled */
#define CR4_OSFXSR 0x0200 /* enable SSE and fxsave/fxrestor */
#define CR4_OSXMMEXCPT 0x0400 /* enable unmasked SSE exceptions */
#define CR4_LA57 0x1000 /* enable level-5 paging */
#define CR4_VMXE 0x2000 /* enable VMX operations */
#define CR4_SMXE 0x4000 /* enable SMX operations */
#define CR4_FSGSBASE 0x00010000 /* enable *FSBASE and *GSBASE instructions */
#define CR4_PCIDE 0x00020000 /* enable process-context identifiers */
#define CR4_OSXSAVE 0x00040000 /* enable XSAVE */
#define XCR0_X87 0x01
#define XCR0_SSE 0x02
#define XCR0_AVX 0x04
#define XCR0_BNDREG 0x08
#define XCR0_BNDCSR 0x10
#define XCR0_OPMASK 0x20
#define XCR0_ZMM_HI256 0x40
#define XCR0_HI16_ZMM 0x80
#define EFER 0xc0000080 /* extended feature enable register */
#define EFER_SCE 0x01 /* system call extensions */
#define EFER_LME 0x0100 /* long mode enable */
#define EFER_LMA 0x0400 /* long mode active */
#define EFER_NXE 0x0800 /* no-execute enable */
#define GDT_REAL_CODE 8
#define GDT_REAL_DATA 16
#define GDT_LEGACY_CODE 24
#define GDT_LEGACY_DATA 32
#define GDT_LONG_CODE 40
#define GDT_LONG_DATA 48
#define PIC1 0x20 /* IO base address for master PIC */
#define PIC2 0xA0 /* IO base address for slave PIC */
#define PIC1_CMD PIC1
#define PIC1_DATA (PIC1 + 1)
#define PIC2_CMD PIC2
#define PIC2_DATA (PIC2 + 1)
#define PIC_EOI 0x20 /* End-of-interrupt command code */
#define PIC_READ_IRR 0x0a /* OCW3 irq ready next CMD read */
#define PIC_READ_ISR 0x0b /* OCW3 irq service next CMD read */
/* Long Mode Paging
@see Intel Manual V.3A §4.1 §4.5
IsValid (ignored on CR3) V┐
┌XD:No Inst. Fetches (if NXE) IsWritable (ignored on CR3) RW┐│
│ Permit User-Mode Access - u┐││
│ Page-level Write-Through - PWT┐│││
│ Page-level Cache Disable - PCD┐││││
│ Set if has been read - Accessed┐│││││
│ Set if has been written - Dirty┐││││││
│ IsPage (if PDPTE/PDE) or PAT (if PT)┐│││││││
│ (If this maps 2MB/1GB page and CR4.PGE) Global┐││││││││
│ (If IsPage 2MB/1GB, see Intel V3A § 11.12) PAT │││││││││
│ │ │││││││││
│ ┌────────────────────────────────────┤ │││││││││
│ Must Be 0┐│ Next Page Table Address (!IsPage) │ │││││││││
│ │├────────────────────────────────────┤ │││││││││
│ ││ Physical Address 4KB │ │││││││││
│┌───┐┌─────┐│├───────────────────────────┐ │ign│││││││││
││PKE││ ign │││ Physical Address 2MB │ │┌┴┐│││││││││
││ ││ ││├──────────────────┐ │ ││ ││││││││││
││ ││ │││ Phys. Addr. 1GB │ │ ││ ││││││││││
││ ││ │││ │ │ ││ ││││││││││
6666555555555544444444443333333333222222222211111111110000000000
3210987654321098765432109876543210987654321098765432109876543210*/
#define PAGE_V /* */ 0b000000001
#define PAGE_RW /* */ 0b000000010
#define PAGE_U /* */ 0b000000100
#define PAGE_4KB /* */ 0b010000000
#define PAGE_2MB /* */ 0b110000000
#define PAGE_1GB /* */ 0b110000000
#define PAGE_TA 0b11111111111111111111111111111111111111000000000000
#define PAGE_PA2 0b11111111111111111111111111111000000000000000000000
#define PAGE_XD 0x8000000000000000
#if !(__ASSEMBLER__ + __LINKER__ + 0)
#include "ape/config.h"
struct thatispacked GlobalDescriptorTable {
uint16_t size;
uint64_t *entries;
};
/**
* Memory hole map.
* @see wiki.osdev.org/Detecting_Memory_(x86)
* @since 2002
*/
struct SmapEntry {
uint64_t addr;
uint64_t size;
enum {
kMemoryUsable = 1,
kMemoryUnusable = 2,
kMemoryAcpiReclaimable = 3,
kMemoryAcpiNvs = 4,
kMemoryBad = 5
} type;
uint32_t __acpi3; /* is abstracted */
};
struct IdtDescriptor {
uint16_t offset_1; /* offset bits 0..15 */
uint16_t selector; /* a code segment selector in GDT or LDT */
uint8_t ist; /* bits 0..2 hold stack table offset, rest are zero */
uint8_t type_attr; /* type and attributes */
uint16_t offset_2; /* offset bits 16..31 */
uint32_t offset_3; /* offset bits 32..63 */
uint32_t zero; /* reserved */
};
struct thatispacked PageTable {
uint64_t p[512];
} forcealign(PAGESIZE);
extern struct PageTable g_pml4t;
extern struct GlobalDescriptorTable gdt;
extern const unsigned char kBiosDataArea[256];
extern const unsigned char kBiosDataAreaXlm[256];
extern struct SmapEntry e820map[XLM_E820_SIZE / sizeof(struct SmapEntry)];
extern struct SmapEntry e820map_xlm[XLM_E820_SIZE / sizeof(struct SmapEntry)];
extern uint64_t g_ptsp;
extern uint64_t g_ptsp_xlm;
void bootdr(char drive) wontreturn;
void smapsort(struct SmapEntry *);
uint64_t *__getpagetableentry(int64_t, unsigned, struct PageTable *,
uint64_t *);
void flattenhighmemory(struct SmapEntry *, struct PageTable *, uint64_t *);
void pageunmap(int64_t);
forceinline unsigned long eflags(void) {
unsigned long res;
asm("pushf\n\t"
"pop\t%0"
: "=rm"(res));
return res;
}
forceinline unsigned char inb(unsigned short port) {
unsigned char al;
asm volatile("inb\t%1,%0" : "=a"(al) : "dN"(port));
return al;
}
forceinline void outb(unsigned short port, unsigned char byte) {
asm volatile("outb\t%0,%1"
: /* no inputs */
: "a"(byte), "dN"(port));
}
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* APE_LIB_PC_H_ */
-46
View File
@@ -1,46 +0,0 @@
/*-*- 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 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 "ape/lib/pc.h"
textreal static unsigned smapcount(const struct SmapEntry *se) {
unsigned i = 0;
while (se[i].size) ++i;
return i;
}
textreal static void smapsorter(size_t n, struct SmapEntry a[n]) {
struct SmapEntry t;
unsigned i, j;
for (i = 1; i < n; ++i) {
j = i;
t = a[i];
while (j > 0 && (intptr_t)t.addr - (intptr_t)a[j - 1].addr) {
a[j] = a[j - 1];
--j;
}
a[j] = t;
}
}
/**
* Sorts BIOS e820 memory map.
*/
textreal void smapsort(struct SmapEntry *smap) {
smapsorter(smapcount(smap), smap);
}
+1 -8
View File
@@ -18,7 +18,7 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#ifndef APE_MACROS_H_
#define APE_MACROS_H_
#include "libc/macros.h"
#include "libc/macros.internal.h"
#ifdef __ASSEMBLER__
/* clang-format off */
@@ -26,13 +26,6 @@
* @fileoverview Macros relevant to αcτµαlly pδrταblε εxεcµταblε.
*/
// Calls function in real mode.
// It's needed because LLVM 8 LLD doesn't support R_X86_64_PC16.
.macro call16 name:req
mov $REAL(\name),%ax
call *%ax
.endm
// Calls near (i.e. pc+pcrel<64kB) FUNCTION.
// @mode long,legacy,real
// @cost 9 bytes overhead
+2 -20
View File
@@ -11,6 +11,8 @@
In some cases it's necessary to use addend macros that change virtual
addresses into the other two types: physical and real. */
#define IMAGE_BASE_REAL 0x2000
#ifndef IMAGE_BASE_VIRTUAL
#define IMAGE_BASE_VIRTUAL 0x400000
#endif
@@ -19,26 +21,6 @@
#define IMAGE_BASE_PHYSICAL 0x100000
#endif
#ifndef REAL_SCRATCH_AREA
/**
* Location of anything goes memory for real mode.
*
* The MBR won't load program content beyond this address, so we have
* room for buffers, page tables, etc. before we reach the stack frame.
*/
#define REAL_SCRATCH_AREA 0x40000
#endif
#ifndef REAL_STACK_FRAME
/**
* Location of real mode 64kb stack frame.
*
* This address was chosen because memory beyond 0x80000 can't be
* accessed safely without consulting e820.
*/
#define REAL_STACK_FRAME 0x70000
#endif
/**
* Returns Relative Virtual Address.
*/
-29
View File
@@ -1,29 +0,0 @@
#!/bin/sh
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
#
# SYNOPSIS
#
# Program Deprioritizer
#
# OVERVIEW
#
# This is a drop-in replacement for the traditional Unix `nice`
# command that also invokes `ionice`, which is important, since
# network and traffic is usually what clobber the system.
if [ -z "$IONICE" ]; then
if IONICE=$(command -v ionice 2>/dev/null); then
IONICE="$IONICE -c3"
fi
fi
if [ -z "$NICE" ]; then
NICE=$(command -v nice 2>/dev/null)
fi
if [ -z "$IONICE$NICE" ]; then
echo "error: can't be nice" >&2
fi
exec $IONICE $NICE "$@"
-9
View File
@@ -1,9 +0,0 @@
#!/bin/sh
# -*- mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8 -*-
# vi: set net ft=sh ts=2 sts=2 sw=2 fenc=utf-8 :vi
echo c |
bochs \
-q \
-f ape/etc/bochsrc.dbg \
floppya:1_44=$1,status=inserted
-51
View File
@@ -1,51 +0,0 @@
#!/bin/sh
# -*- mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8 -*-
# vi: set net ft=sh ts=2 sts=2 sw=2 fenc=utf-8 :vi
#
# bochs-scriptable executes a disk with serial uart stdio.
#
# USAGE
#
# build/bochs-scriptable IMAGE...
#
# DESCRIPTION
#
# This script is useful for end-to-end testing metal apps in <100ms.
#
# SEE ALSO
#
# build/boot(1)
while getopts h X; do
case $X in
h) exec less "$0" ;;
\?) echo "$0: bad arg" >&2; exit 1 ;;
esac
done
shift $((OPTIND - 1))
trap '' INT
IMG=$1
OUT=/tmp/$USER.$$.bochs.stdout
ERR=/tmp/$USER.$$.bochs.stderr
mkfifo $OUT || exit
cat <$OUT &
CAT=$!
exec 4>$OUT
rm -f $OUT
echo c |
bochs \
-q \
-f ape/etc/bochsrc.ffs \
display_library:nogui \
floppya:1_44=$1,status=inserted \
>>$ERR 2>>$ERR
RC=$?
kill $CAT
exec 4>&-
rm -f $ERR
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-21
View File
@@ -1,21 +0,0 @@
#!/bin/sh
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
#
# OVERVIEW
#
# Source File Concatenation Tool
#
# DESCRIPTION
#
# This program is the same as cat, but inserts preprocessor directives
# that allow compiler errors to point back to the original lines.
if [ $# -eq 0 ]; then
cat
else
for x; do
printf '# 1 "%s"\n' "$x"
cat "$x"
done
fi
+45 -15
View File
@@ -50,6 +50,8 @@ endif
# Release Mode
#
# Follows traditional closed source release binary norms.
#
# - `make MODE=rel`
# - More optimized
# - Reasonably small
@@ -69,16 +71,45 @@ CONFIG_CCFLAGS += \
$(BACKTRACES) \
-O2
TARGET_ARCH ?= \
-msse3
endif
# Asan Mode
#
# Safer binaries good for backend production serving.
#
# - `make MODE=asan`
# - Memory safety
# - Production worthy
# - Backtraces
# - Debuggability
# - Larger binaries
ifeq ($(MODE), asan)
CONFIG_CCFLAGS += \
$(BACKTRACES) \
-O2
CONFIG_COPTS += \
-fsanitize=address
TARGET_ARCH ?= \
-msse3
endif
# Debug Mode
#
# - `make MODE=dbg`
# - Backtraces
# - Zero optimization
# - Enables sanitization
# - Enables stack canaries
# - Enormous binaries (b/c ubsan suboptimalities)
# - Enables asan
# - Enables ubsan (TODO)
# - Stack canaries
# - No optimization (TODO)
# - Enormous binaries
ifeq ($(MODE), dbg)
@@ -91,8 +122,7 @@ CONFIG_CCFLAGS += \
-O2
CONFIG_COPTS += \
$(SECURITY_BLANKETS) \
$(SANITIZER)
-fsanitize=address
TARGET_ARCH ?= \
-msse3
@@ -113,6 +143,7 @@ endif
# - No backtraces
# - No algorithmics
# - YOLO
ifeq ($(MODE), tiny)
CONFIG_CPPFLAGS += \
-DTINY \
@@ -130,7 +161,7 @@ endif
# Linux-Only Tiny Mode
#
# - `make MODE=tiny`
# - `make MODE=tinylinux`
# - No checks
# - No asserts
# - No canaries
@@ -140,6 +171,7 @@ endif
# - No portability
# - No algorithmics
# - YOLO
ifeq ($(MODE), tinylinux)
CONFIG_CPPFLAGS += \
-DTINY \
@@ -158,7 +190,7 @@ endif
# Linux+BSD Tiny Mode
#
# - `make MODE=tiny`
# - `make MODE=tinylinuxbsd`
# - No apple
# - No checks
# - No asserts
@@ -169,6 +201,7 @@ endif
# - No backtraces
# - No algorithmics
# - YOLO
ifeq ($(MODE), tinylinuxbsd)
CONFIG_CPPFLAGS += \
-DTINY \
@@ -187,7 +220,7 @@ endif
# Unix Tiny Mode
#
# - `make MODE=tiny`
# - `make MODE=tinysysv`
# - No checks
# - No asserts
# - No canaries
@@ -197,6 +230,7 @@ endif
# - No backtraces
# - No algorithmics
# - YOLO
ifeq ($(MODE), tinysysv)
CONFIG_CPPFLAGS += \
-DTINY \
@@ -215,7 +249,7 @@ endif
# Tiny Metallic Unix Mode
#
# - `make MODE=tiny`
# - `make MODE=tinynowin`
# - No checks
# - No asserts
# - No canaries
@@ -225,6 +259,7 @@ endif
# - No backtraces
# - No algorithmics
# - YOLO
ifeq ($(MODE), tinynowin)
CONFIG_CPPFLAGS += \
-DTINY \
@@ -282,11 +317,6 @@ 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.
#
# Lastly note that in some cases, such as gc(), there simply isn't any
# ANSI workaround available. It's only in cases like that when we'll use
# the __asm__() header workaround, rather than simply removing it. We do
# however try to do that much less often than mainstream C libraries.
ifeq ($(MODE), ansi)
+5 -10
View File
@@ -50,10 +50,9 @@ TAGS ?= /usr/bin/ctags # emacs source builds or something breaks it
ARFLAGS = rcsD
ZFLAGS ?=
XARGS ?= xargs -P4 -rs8000
NICE ?= build/actuallynice
DOT ?= dot
GZ ?= gzip
CLANG = clang-10
CLANG = clang
FC = gfortran #/opt/cross9f/bin/x86_64-linux-musl-gfortran
# see build/compile, etc. which run third_party/gcc/unbundle.sh
@@ -78,7 +77,8 @@ PWD := $(shell pwd)
IMAGE_BASE_VIRTUAL ?= 0x400000
HELLO := $(shell build/hello)
TMPDIR := $(shell build/findtmp)
COMPILE := $(shell build/getcompile) -V$(shell build/getccversion $(CC))
SPAWNER := $(shell build/getcompile) -V$(shell build/getccversion $(CC))
COMPILE = $(SPAWNER) $(QUOTA)
export ADDR2LINE
export LC_ALL
@@ -91,7 +91,6 @@ FTRACE = \
-pg
SANITIZER = \
-fsanitize=leak \
-fsanitize=address
NO_MAGIC = \
@@ -138,6 +137,8 @@ MATHEMATICAL = \
-fwrapv
DEFAULT_CPPFLAGS = \
-DCOSMO \
-DMODE='"$(MODE)"' \
-DIMAGE_BASE_VIRTUAL=$(IMAGE_BASE_VIRTUAL) \
-nostdinc \
-iquote.
@@ -181,7 +182,6 @@ DEFAULT_LDLIBS =
MCA = llvm-mca-10 \
-mtriple=x86_64-pc-linux-gnu \
-iterations=3 \
-instruction-info \
-iterations=3 \
-all-stats \
@@ -299,11 +299,6 @@ OBJECTIFY.greg.c = \
-fno-sanitize=all \
-c
OBJECTIFY.i386.c = \
$(OBJECTIFY.c) \
-m32 \
-wrapper build/i386ify.sh
OBJECTIFY.ansi.c = $(CC) $(OBJECTIFY.c.flags) -ansi -Wextra -Werror -pedantic-errors -c
OBJECTIFY.c99.c = $(CC) $(OBJECTIFY.c.flags) -std=c99 -Wextra -Werror -pedantic-errors -c
OBJECTIFY.c11.c = $(CC) $(OBJECTIFY.c.flags) -std=c11 -Wextra -Werror -pedantic-errors -c
+1 -1
View File
@@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/bin/sh
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
#
Executable
+5
View File
@@ -0,0 +1,5 @@
#!/bin/sh
exec gdb -q -nh -i=mi $1 \
-ex "set confirm off" \
-ex "add-symbol-file $1.dbg 0x401000" \
-ex "run"
-35
View File
@@ -1,35 +0,0 @@
#!/bin/sh
#
# SYNOPSIS
#
# gcc -m32 -wrapper build/i386ify.sh -c -o foo.o foo.c
#
# OVERVIEW
#
# Compiles 32-bit code inside 64-bit ELF objects.
if [ "${1##*/}" = as ]; then
FIRST=0
for x; do
if [ $FIRST -eq 0 ]; then
set --
FIRST=1
fi
if [ "$x" = "--32" ]; then
continue
fi
if [ "${x##*.}" = s ]; then
{
printf "\t.section .yoink\n"
printf "\tnopl\t_start32\n"
printf "\t.previous\n"
printf "\t.code32\n"
cat "$x"
} >"$x".tmp
mv -f "$x".tmp "$x"
fi
set -- "$@" "$x"
done
fi
exec "$@"
-7
View File
@@ -1,7 +0,0 @@
#!/bin/sh
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
for x; do
printf '#include "%s"\n' "$x"
done
-2189
View File
File diff suppressed because it is too large. Load diff
-7
View File
@@ -1,7 +0,0 @@
#!/bin/sh
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
for x; do
printf '#include "%s"\n' "$x"
done
+3 -1
View File
@@ -64,7 +64,6 @@ o/$(MODE)/%.lds: %.lds ; @$(COMPILE) -APREPROCESS $(PREPROCESS.lds)
o/$(MODE)/%.h.ok: %.h ; @$(COMPILE) -ACHECK.h $(COMPILE.c) -x c -g0 -o $@ $<
o/$(MODE)/%.h.okk: %.h ; @$(COMPILE) -ACHECK.h $(COMPILE.cxx) -x c++ -g0 -o $@ $<
o/$(MODE)/%.o: %.greg.c ; @$(COMPILE) -AOBJECTIFY.greg $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.i386.o: %.i386.c ; @$(COMPILE) -AOBJECTIFY.i386 $(OBJECTIFY.i386.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.greg.o: %.greg.c ; @$(COMPILE) -AOBJECTIFY.greg $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.ansi.o: %.ansi.c ; @$(COMPILE) -AOBJECTIFY.ansi $(OBJECTIFY.ansi.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.ansi.o: %.c ; @$(COMPILE) -AOBJECTIFY.ansi $(OBJECTIFY.ansi.c) $(OUTPUT_OPTION) $<
@@ -80,4 +79,7 @@ o/$(MODE)/%.zip.o: % ; @$(COMPILE) -AZIPOBJ $(ZIPOBJ) $(ZIPOBJ_FLA
o/$(MODE)/%-gcc.asm: %.c ; @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) -S -g0 $(OUTPUT_OPTION) $<
o/$(MODE)/%-clang.asm: %.c ; @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) -S -g0 $(OUTPUT_OPTION) $< || echo / need $(CLANG) >$@
o/$(MODE)/%.lua: %.lua o/$(MODE)/third_party/lua/luac.com
@$(COMPILE) -ALUAC -T$@ o/$(MODE)/third_party/lua/luac.com -s -o $@ $<
o/$(MODE)/%-clang.asm: CC = $(CLANG)
-14
View File
@@ -1,14 +0,0 @@
#!/bin/sh
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
#
# OVERVIEW
#
# SSH Command Wrapper
#
# DESCRIPTION
#
# This script, like most of our wrappers, asks the tooling to whine
# less often.
exec ${SSH:-ssh} -o LogLevel=QUIET "$@"
+1 -1
View File
@@ -1,6 +1,6 @@
#ifndef COSMOPOLITAN_DSP_CORE_C161_H_
#define COSMOPOLITAN_DSP_CORE_C161_H_
#include "libc/macros.h"
#include "libc/macros.internal.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
#define EXTRA_SHARP 2
+1 -1
View File
@@ -1,7 +1,7 @@
#ifndef COSMOPOLITAN_DSP_CORE_C161S_H_
#define COSMOPOLITAN_DSP_CORE_C161S_H_
#include "dsp/core/c161.h"
#include "libc/macros.h"
#include "libc/macros.internal.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
forceinline pureconst artificial signed char C161S(signed char al,
+1 -1
View File
@@ -17,7 +17,7 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "dsp/core/core.h"
#include "libc/macros.h"
#include "libc/macros.internal.h"
#include "libc/math.h"
#include "libc/mem/mem.h"
+1 -1
View File
@@ -17,7 +17,7 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/limits.h"
#include "libc/macros.h"
#include "libc/macros.internal.h"
#include "libc/math.h"
#include "libc/str/str.h"
+1 -1
View File
@@ -20,7 +20,7 @@
#include "libc/assert.h"
#include "libc/dce.h"
#include "libc/limits.h"
#include "libc/macros.h"
#include "libc/macros.internal.h"
#include "libc/math.h"
#include "libc/str/str.h"
+1 -1
View File
@@ -19,7 +19,7 @@
#include "dsp/core/core.h"
#include "dsp/core/q.h"
#include "libc/dce.h"
#include "libc/macros.h"
#include "libc/macros.internal.h"
#include "libc/math.h"
#include "libc/str/str.h"
+1 -1
View File
@@ -1,6 +1,6 @@
#ifndef COSMOPOLITAN_DSP_CORE_HALF_H_
#define COSMOPOLITAN_DSP_CORE_HALF_H_
#include "libc/macros.h"
#include "libc/macros.internal.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
/**
+1 -1
View File
@@ -1,6 +1,6 @@
#ifndef COSMOPOLITAN_DSP_CORE_KS8_H_
#define COSMOPOLITAN_DSP_CORE_KS8_H_
#include "libc/macros.h"
#include "libc/macros.internal.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
/**
+1 -1
View File
@@ -1,7 +1,7 @@
#ifndef COSMOPOLITAN_DSP_CORE_KSS8_H_
#define COSMOPOLITAN_DSP_CORE_KSS8_H_
#include "libc/limits.h"
#include "libc/macros.h"
#include "libc/macros.internal.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
/**
+1 -1
View File
@@ -16,7 +16,7 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/macros.h"
#include "libc/macros.internal.h"
#define BIAS 0x84
+1 -1
View File
@@ -1,7 +1,7 @@
#ifndef COSMOPOLITAN_DSP_CORE_Q_H_
#define COSMOPOLITAN_DSP_CORE_Q_H_
#include "libc/limits.h"
#include "libc/macros.h"
#include "libc/macros.internal.h"
#include "libc/math.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
+1 -1
View File
@@ -16,7 +16,7 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/macros.h"
#include "libc/macros.internal.h"
.align 16
// Mixes audio.
+1 -1
View File
@@ -18,7 +18,7 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#include "dsp/core/core.h"
#include "libc/bits/bits.h"
#include "libc/bits/safemacros.h"
#include "libc/bits/safemacros.internal.h"
#include "libc/limits.h"
/**
+1 -1
View File
@@ -16,7 +16,7 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/macros.h"
#include "libc/macros.internal.h"
.source __FILE__
clamp4int256$core:
+1 -1
View File
@@ -35,7 +35,7 @@
#include "libc/bits/initializer.internal.h"
#include "libc/fmt/conv.h"
#include "libc/log/log.h"
#include "libc/macros.h"
#include "libc/macros.internal.h"
#include "libc/math.h"
#include "libc/mem/mem.h"
#include "libc/str/str.h"
+1 -1
View File
@@ -28,7 +28,7 @@
│ SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "dsp/mpeg/mpeg.h"
#include "libc/macros.h"
#include "libc/macros.internal.h"
asm(".ident\t\"\\n\\n\
PL_MPEG (MIT License)\\n\
+2 -2
View File
@@ -24,11 +24,11 @@
#include "libc/limits.h"
#include "libc/log/check.h"
#include "libc/log/log.h"
#include "libc/macros.h"
#include "libc/macros.internal.h"
#include "libc/math.h"
#include "libc/mem/mem.h"
#include "libc/nexgen32e/bsr.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/gc.internal.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
+1 -1
View File
@@ -20,7 +20,7 @@
#include "dsp/core/ks8.h"
#include "dsp/core/kss8.h"
#include "dsp/scale/cdecimate2xuint8x8.h"
#include "libc/macros.h"
#include "libc/macros.internal.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/str/str.h"
#include "libc/x/x.h"
+1 -1
View File
@@ -17,7 +17,7 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "dsp/tty/tty.h"
#include "libc/bits/safemacros.h"
#include "libc/bits/safemacros.internal.h"
#include "libc/bits/weaken.h"
#include "libc/calls/calls.h"
#include "libc/calls/termios.h"
+1 -1
View File
@@ -16,7 +16,7 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/macros.h"
#include "libc/macros.internal.h"
// TODO(jart): write me
+1 -1
View File
@@ -22,7 +22,7 @@
#include "libc/bits/initializer.internal.h"
#include "libc/limits.h"
#include "libc/log/log.h"
#include "libc/macros.h"
#include "libc/macros.internal.h"
#include "libc/math.h"
#include "libc/str/str.h"
+1 -1
View File
@@ -18,7 +18,7 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#include "dsp/tty/quant.h"
#include "libc/log/check.h"
#include "libc/macros.h"
#include "libc/macros.internal.h"
struct TtyRgb rgb2ttyi2f_(int r, int g, int b) {
return rgb2ttyf((__m128){r, g, b} / 255);
+1 -1
View File
@@ -17,7 +17,7 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "dsp/tty/quant.h"
#include "libc/macros.h"
#include "libc/macros.internal.h"
struct TtyRgb rgb2xterm24_(int r, int g, int b) {
return (struct TtyRgb){MAX(MIN(r, 255), 0), MAX(MIN(g, 255), 0),
+1 -1
View File
@@ -18,7 +18,7 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#include "dsp/tty/tty.h"
#include "libc/alg/arraylist2.internal.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/gc.internal.h"
#include "libc/x/x.h"
/* TODO(jart): DELETE */
+1 -1
View File
@@ -18,7 +18,7 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#include "dsp/tty/itoa8.h"
#include "dsp/tty/tty.h"
#include "libc/bits/safemacros.h"
#include "libc/bits/safemacros.internal.h"
#include "libc/limits.h"
#include "libc/log/check.h"
+2 -2
View File
@@ -23,11 +23,11 @@
#include "dsp/tty/windex.h"
#include "libc/assert.h"
#include "libc/bits/bits.h"
#include "libc/bits/safemacros.h"
#include "libc/bits/safemacros.internal.h"
#include "libc/limits.h"
#include "libc/log/check.h"
#include "libc/log/log.h"
#include "libc/macros.h"
#include "libc/macros.internal.h"
#include "libc/math.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/runtime/runtime.h"
+2 -2
View File
@@ -26,8 +26,8 @@
#include "libc/calls/typedef/sigaction_f.h"
#include "libc/calls/ucontext.h"
#include "libc/log/log.h"
#include "libc/macros.h"
#include "libc/runtime/gc.h"
#include "libc/macros.internal.h"
#include "libc/runtime/gc.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/fileno.h"
+1 -1
View File
@@ -16,7 +16,7 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/macros.h"
#include "libc/macros.internal.h"
.source __FILE__
// Returns index of minimum uint16 in array.
+1 -1
View File
@@ -16,7 +16,7 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/macros.h"
#include "libc/macros.internal.h"
.source __FILE__
// Returns index of minimum positive int16 in array.
+1 -1
View File
@@ -17,7 +17,7 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/nexgen32e/x86feature.h"
#include "libc/macros.h"
#include "libc/macros.internal.h"
.source __FILE__
// Dispatches to fastest windex() implementation.
+403
View File
@@ -0,0 +1,403 @@
/*-*- 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 The Mbed TLS Contributors │
│ │
│ Licensed under the Apache License, Version 2.0 (the "License"); │
│ you may not use this file except in compliance with the License. │
│ You may obtain a copy of the License at │
│ │
│ http://www.apache.org/licenses/LICENSE-2.0 │
│ │
│ Unless required by applicable law or agreed to in writing, software │
│ distributed under the License is distributed on an "AS IS" BASIS, │
│ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. │
│ See the License for the specific language governing permissions and │
│ limitations under the License. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/fmt/conv.h"
#include "libc/stdio/stdio.h"
#include "libc/sysv/consts/exit.h"
#include "third_party/mbedtls/ctr_drbg.h"
#include "third_party/mbedtls/debug.h"
#include "third_party/mbedtls/entropy.h"
#include "third_party/mbedtls/net_sockets.h"
#include "third_party/mbedtls/ssl.h"
#include "third_party/mbedtls/x509_crt.h"
STATIC_YOINK("ssl_root_support");
#define MODE_NONE 0
#define MODE_FILE 1
#define MODE_SSL 2
#define DFL_MODE MODE_NONE
#define DFL_FILENAME "cert.crt"
#define DFL_CA_FILE ""
#define DFL_CRL_FILE ""
#define DFL_CA_PATH "zip:usr/share/ssl/root"
#define DFL_SERVER_NAME "localhost"
#define DFL_SERVER_PORT "4433"
#define DFL_DEBUG_LEVEL 0
#define DFL_PERMISSIVE 0
#define USAGE_IO \
" ca_file=%%s file containing top-level CAs\n" \
" ca_path=%%s dir containing top-level CAs\n" \
" crl_file=%%s The single CRL file you want to use\n"
#define USAGE \
"\n usage: %s param=<>...\n" \
"\n acceptable parameters:\n" \
" mode=file|ssl default: none\n" \
" filename=%%s default: cert.crt\n" USAGE_IO \
" server_name=%%s default: localhost\n" \
" server_port=%%d default: 4433\n" \
" debug_level=%%d default: 0 (disabled)\n" \
" permissive=%%d default: 0 (disabled)\n" \
"\n"
/*
* global options
*/
struct options {
int mode; /* the mode to run the application in */
const char *filename; /* filename of the certificate file */
const char *ca_file; /* the file with the CA certificate(s) */
const char *crl_file; /* the file with the CRL to use */
const char *ca_path; /* the path with the CA certificate(s) reside */
const char *server_name; /* hostname of the server (client only) */
const char *server_port; /* port on which the ssl service runs */
int debug_level; /* level of debugging */
int permissive; /* permissive parsing */
} opt;
static void my_debug(void *ctx, int level, const char *file, int line,
const char *str) {
fprintf((FILE *)ctx, "%s:%04d: %s", file, line, str);
fflush((FILE *)ctx);
}
static int my_verify(void *data, mbedtls_x509_crt *crt, int depth,
uint32_t *flags) {
char buf[1024];
printf("\nVerify requested for (Depth %d):\n", depth);
mbedtls_x509_crt_info(buf, sizeof(buf) - 1, "", crt);
printf("%s", buf);
if (*flags) {
mbedtls_x509_crt_verify_info(buf, sizeof(buf), " ! ", *flags);
printf("%s\n", buf);
}
return 0;
}
mbedtls_net_context server_fd;
unsigned char buf[1024];
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;
mbedtls_x509_crt cacert;
mbedtls_x509_crl cacrl;
int main(int argc, char *argv[]) {
int ret = 1;
int exit_code = EXIT_FAILURE;
int i, j;
uint32_t flags;
int verify = 0;
char *p, *q;
const char *pers = "cert_app";
/*
* Set to sane values
*/
mbedtls_net_init(&server_fd);
mbedtls_ctr_drbg_init(&ctr_drbg);
mbedtls_ssl_init(&ssl);
mbedtls_ssl_config_init(&conf);
mbedtls_x509_crt_init(&cacert);
#if defined(MBEDTLS_X509_CRL_PARSE_C)
mbedtls_x509_crl_init(&cacrl);
#else
/* Zeroize structure as CRL parsing is not supported and we have to pass
it to the verify function */
memset(&cacrl, 0, sizeof(mbedtls_x509_crl));
#endif
if (argc == 0) {
usage:
printf(USAGE, program_invocation_name);
goto exit;
}
opt.mode = DFL_MODE;
opt.filename = DFL_FILENAME;
opt.ca_file = DFL_CA_FILE;
opt.crl_file = DFL_CRL_FILE;
opt.ca_path = DFL_CA_PATH;
opt.server_name = DFL_SERVER_NAME;
opt.server_port = DFL_SERVER_PORT;
opt.debug_level = DFL_DEBUG_LEVEL;
opt.permissive = DFL_PERMISSIVE;
for (i = 1; i < argc; i++) {
p = argv[i];
if ((q = strchr(p, '=')) == NULL) goto usage;
*q++ = '\0';
for (j = 0; p + j < q; j++) {
if (argv[i][j] >= 'A' && argv[i][j] <= 'Z') argv[i][j] |= 0x20;
}
if (strcmp(p, "mode") == 0) {
if (strcmp(q, "file") == 0)
opt.mode = MODE_FILE;
else if (strcmp(q, "ssl") == 0)
opt.mode = MODE_SSL;
else
goto usage;
} else if (strcmp(p, "filename") == 0)
opt.filename = q;
else if (strcmp(p, "ca_file") == 0)
opt.ca_file = q;
else if (strcmp(p, "crl_file") == 0)
opt.crl_file = q;
else if (strcmp(p, "ca_path") == 0)
opt.ca_path = q;
else if (strcmp(p, "server_name") == 0)
opt.server_name = q;
else if (strcmp(p, "server_port") == 0)
opt.server_port = q;
else if (strcmp(p, "debug_level") == 0) {
opt.debug_level = atoi(q);
if (opt.debug_level < 0 || opt.debug_level > 65535) goto usage;
} else if (strcmp(p, "permissive") == 0) {
opt.permissive = atoi(q);
if (opt.permissive < 0 || opt.permissive > 1) goto usage;
} else
goto usage;
}
/*
* 1.1. Load the trusted CA
*/
printf(" . Loading the CA root certificate ...");
fflush(stdout);
if (strlen(opt.ca_path)) {
if ((ret = mbedtls_x509_crt_parse_path(&cacert, opt.ca_path)) < 0) {
printf(" failed\n ! mbedtls_x509_crt_parse_path returned -0x%x\n\n",
(unsigned int)-ret);
goto exit;
}
verify = 1;
} else if (strlen(opt.ca_file)) {
if ((ret = mbedtls_x509_crt_parse_file(&cacert, opt.ca_file)) < 0) {
printf(" failed\n ! mbedtls_x509_crt_parse_file returned -0x%x\n\n",
(unsigned int)-ret);
goto exit;
}
verify = 1;
}
printf(" ok (%d skipped)\n", ret);
#if defined(MBEDTLS_X509_CRL_PARSE_C)
if (strlen(opt.crl_file)) {
if ((ret = mbedtls_x509_crl_parse_file(&cacrl, opt.crl_file)) != 0) {
printf(" failed\n ! mbedtls_x509_crl_parse returned -0x%x\n\n",
(unsigned int)-ret);
goto exit;
}
verify = 1;
}
#endif
if (opt.mode == MODE_FILE) {
mbedtls_x509_crt crt;
mbedtls_x509_crt *cur = &crt;
mbedtls_x509_crt_init(&crt);
/*
* 1.1. Load the certificate(s)
*/
printf("\n . Loading the certificate(s) ...");
fflush(stdout);
ret = mbedtls_x509_crt_parse_file(&crt, opt.filename);
if (ret < 0) {
printf(" failed\n ! mbedtls_x509_crt_parse_file returned -0x%04x\n\n",
-ret);
mbedtls_x509_crt_free(&crt);
goto exit;
}
if (opt.permissive == 0 && ret > 0) {
printf(" failed\n ! mbedtls_x509_crt_parse failed to parse %d "
"certificates\n\n",
ret);
mbedtls_x509_crt_free(&crt);
goto exit;
}
printf(" ok\n");
/*
* 1.2 Print the certificate(s)
*/
while (cur != NULL) {
printf(" . Peer certificate information ...\n");
ret = mbedtls_x509_crt_info((char *)buf, sizeof(buf) - 1, " ", cur);
if (ret == -1) {
printf(" failed\n ! mbedtls_x509_crt_info returned -0x%04x\n\n",
-ret);
mbedtls_x509_crt_free(&crt);
goto exit;
}
printf("%s\n", buf);
cur = cur->next;
}
/*
* 1.3 Verify the certificate
*/
if (verify) {
printf(" . Verifying X.509 certificate...");
if ((ret = mbedtls_x509_crt_verify(&crt, &cacert, &cacrl, NULL, &flags,
my_verify, NULL)) != 0) {
char vrfy_buf[512];
printf(" failed\n");
mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), " ! ", flags);
printf("%s\n", vrfy_buf);
} else
printf(" ok\n");
}
mbedtls_x509_crt_free(&crt);
} else if (opt.mode == MODE_SSL) {
/*
* 1. Initialize the RNG and the session data
*/
printf("\n . Seeding the random number generator...");
fflush(stdout);
mbedtls_entropy_init(&entropy);
if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
(const unsigned char *)pers,
strlen(pers))) != 0) {
printf(" failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret);
goto ssl_exit;
}
printf(" ok\n");
#if defined(MBEDTLS_DEBUG_C)
mbedtls_debug_set_threshold(opt.debug_level);
#endif
/*
* 2. Start the connection
*/
printf(" . Connecting to tcp/%s/%s...\n", opt.server_name,
opt.server_port);
if ((ret = mbedtls_net_connect(&server_fd, opt.server_name, opt.server_port,
MBEDTLS_NET_PROTO_TCP)) != 0) {
printf(" ! mbedtls_net_connect returned -0x%04x\n\n", -ret);
goto ssl_exit;
}
/*
* 3. Setup stuff
*/
if ((ret = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
printf(" ! mbedtls_ssl_config_defaults returned -0x%04x\n\n", -ret);
goto exit;
}
if (verify) {
mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED);
mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL);
mbedtls_ssl_conf_verify(&conf, my_verify, NULL);
} else
mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_NONE);
mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
mbedtls_ssl_conf_dbg(&conf, my_debug, stdout);
if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) {
printf(" ! mbedtls_ssl_setup returned -0x%04x\n\n", -ret);
goto ssl_exit;
}
if ((ret = mbedtls_ssl_set_hostname(&ssl, opt.server_name)) != 0) {
printf(" ! mbedtls_ssl_set_hostname returned -0x%04x\n\n", -ret);
goto ssl_exit;
}
mbedtls_ssl_set_bio(&ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv,
NULL);
/*
* 4. Handshake
*/
while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
if (ret != MBEDTLS_ERR_SSL_WANT_READ &&
ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
printf(" ! mbedtls_ssl_handshake returned -0x%04x\n\n", -ret);
goto ssl_exit;
}
}
/*
* 5. Print the certificate
*/
#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
printf(" . Peer certificate information ... skipped\n");
#else
printf(" . Peer certificate information ...\n");
ret = mbedtls_x509_crt_info((char *)buf, sizeof(buf) - 1, " ",
mbedtls_ssl_get_peer_cert(&ssl));
if (ret == -1) {
printf(" failed\n ! mbedtls_x509_crt_info returned -0x%04x\n\n", -ret);
goto ssl_exit;
}
printf("%s\n", buf);
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
mbedtls_ssl_close_notify(&ssl);
ssl_exit:
mbedtls_ssl_free(&ssl);
mbedtls_ssl_config_free(&conf);
} else
goto usage;
exit_code = MBEDTLS_EXIT_SUCCESS;
exit:
mbedtls_net_free(&server_fd);
mbedtls_x509_crt_free(&cacert);
#if defined(MBEDTLS_X509_CRL_PARSE_C)
mbedtls_x509_crl_free(&cacrl);
#endif
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free(&entropy);
mbedtls_exit(exit_code);
}
+1 -1
View File
@@ -73,7 +73,7 @@ void GetOpts(int argc, char *argv[]) {
int cp(const char *src, const char *dst) {
if (endswith(dst, "/") || isdirectory(dst)) {
dst = gc(xasprintf("%s/%s", dst, basename));
dst = _gc(xasprintf("%s/%s", dst, basename));
}
if (!force && access(dst, W_OK) == -1 && errno != ENOENT) goto OnFail;
if (copyfile(src, dst, flags) == -1) goto OnFail;
+1 -1
View File
@@ -16,7 +16,7 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/safemacros.h"
#include "libc/bits/safemacros.internal.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
+8 -73
View File
@@ -7,88 +7,23 @@
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/bits/pushpop.h"
#include "libc/calls/calls.h"
#include "libc/calls/ucontext.h"
#include "libc/log/log.h"
#include "libc/math.h"
#include "libc/nt/enum/errormodeflags.h"
#include "libc/nt/signals.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
/**
* @fileoverview Demonstrates SEGFAULT via NULL pointer dereference.
* @fileoverview How to print backtraces and cpu state on crash.
*
* In MODE=dbg mode, UBSAN should catch this and display a backtrace.
* In most other modes, e.g. MODE=balanced, the oncrash.c sig handler
* will either launch GDB or display a very fancy report.
*
* make -j8 -O MODE=opt o/opt/examples/crashreportdemo.com
* o/opt/examples/crashreportdemo.com
* make -j8 -O o//examples/crashreport.com
* o//examples/crashreport.com
*
* To prevent the GDB GUI from popping up:
*
* export GDB=""
* make -j8 -O MODE=opt o/opt/examples/crashreportdemo.com
* o/opt/examples/crashreportdemo.com
* export GDB=
* make -j8 -O o//examples/crashreport.com
* o//examples/crashreport.com
*/
int boo;
void boop(void);
int main(int argc, char *argv[]) {
int64_t res;
volatile int64_t x;
showcrashreports();
res = 0;
asm volatile("mov\t$0x1111111111111111,%rax\n\t"
"mov\t$0x3333333333333333,%rcx\n\t"
"mov\t$0x4444444444444444,%rdx\n\t"
"mov\t$0x8888888888888888,%r8\n\t"
"mov\t$0x9999999999999999,%r9d\n\t"
"mov\t$0xaaaaaaaaaaaaaaaa,%r10d\n\t"
"mov\t$0xbbbbbbbbbbbbbbbb,%r11d\n\t"
"mov\t$0x0000000000000000,%rax\n\t"
"movd\t%rax,%xmm0\n\t"
"mov\t$0x1111111111111111,%rax\n\t"
"push\t%rax\n\t"
"push\t%rax\n\t"
"movdqu\t(%rsp),%xmm1\n\t"
"pop\t%rax\n\t"
"pop\t%rax\n\t"
"mov\t$0x2222222222220022,%rax\n\t"
"movd\t%rax,%xmm2\n\t"
"mov\t$0x3333333333333333,%rax\n\t"
"movd\t%rax,%xmm3\n\t"
"mov\t$0x4444444444444444,%rax\n\t"
"movd\t%rax,%xmm4\n\t"
"mov\t$0x5555555555555555,%rax\n\t"
"movd\t%rax,%xmm5\n\t"
"mov\t$0x6666666666666666,%rax\n\t"
"movd\t%rax,%xmm6\n\t"
"mov\t$0x7777777777777777,%rax\n\t"
"movd\t%rax,%xmm7\n\t"
"mov\t$0x8888888888888888,%rax\n\t"
"movd\t%rax,%xmm8\n\t"
"mov\t$0x9999999999999999,%rax\n\t"
"movd\t%rax,%xmm9\n\t"
"mov\t$0xaaaaaaaaaaaaaaaa,%rax\n\t"
"movd\t%rax,%xmm10\n\t"
"mov\t$0xbbbbbbbbbbbbbbbb,%rax\n\t"
"movd\t%rax,%xmm11\n\t"
"mov\t$0xcccccccccccccccc,%rax\n\t"
"movd\t%rax,%xmm12\n\t"
"mov\t$0xdddddddddddddddd,%rax\n\t"
"movd\t%rax,%xmm13\n\t"
"mov\t$0xeeeeeeeeeeeeeeee,%rax\n\t"
"movd\t%rax,%xmm14\n\t"
"mov\t$0xffffffffffffffff,%rax\n\t"
"movd\t%rax,%xmm15\n\t"
"fldpi\n\t"
"xor\t%eax,%eax\n\t"
"div\t%eax\n\t");
return res;
return 1 / (x = 0);
}
+2 -3
View File
@@ -14,7 +14,6 @@
#include "libc/log/log.h"
#include "libc/mem/mem.h"
#include "libc/nt/thread.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
@@ -32,9 +31,9 @@ int main(int argc, char *argv[]) {
ssize_t rc;
size_t got, wrote;
unsigned char buf[512];
struct sigaction saint = {.sa_handler = GotCtrlC};
fprintf(stderr, "This echos stdio until Ctrl+C is pressed.\n");
CHECK_NE(
-1, sigaction(SIGINT, &(struct sigaction){.sa_handler = GotCtrlC}, NULL));
CHECK_NE(-1, sigaction(SIGINT, &saint, NULL));
for (;;) {
rc = read(0, buf, BUFSIZ);
if (rc != -1) {
+364 -65
View File
@@ -7,25 +7,50 @@
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/bits/safemacros.h"
#include "libc/bits/safemacros.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/struct/iovec.h"
#include "libc/dce.h"
#include "libc/dns/dns.h"
#include "libc/errno.h"
#include "libc/fmt/conv.h"
#include "libc/fmt/fmt.h"
#include "libc/log/check.h"
#include "libc/log/log.h"
#include "libc/macros.h"
#include "libc/macros.internal.h"
#include "libc/rand/rand.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/runtime.h"
#include "libc/sock/goodsocket.internal.h"
#include "libc/sock/sock.h"
#include "libc/stdio/append.internal.h"
#include "libc/stdio/stdio.h"
#include "libc/str/slice.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/af.h"
#include "libc/sysv/consts/ai.h"
#include "libc/sysv/consts/dt.h"
#include "libc/sysv/consts/ex.h"
#include "libc/sysv/consts/exit.h"
#include "libc/sysv/consts/ipproto.h"
#include "libc/sysv/consts/shut.h"
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/consts/so.h"
#include "libc/sysv/consts/sock.h"
#include "libc/sysv/consts/sol.h"
#include "libc/sysv/consts/tcp.h"
#include "libc/time/struct/tm.h"
#include "libc/x/x.h"
#include "net/http/uri.h"
#include "net/http/http.h"
#include "net/http/url.h"
#include "net/https/https.h"
#include "net/https/sslcache.h"
#include "third_party/getopt/getopt.h"
#include "third_party/mbedtls/ctr_drbg.h"
#include "third_party/mbedtls/debug.h"
#include "third_party/mbedtls/error.h"
#include "third_party/mbedtls/pk.h"
#include "third_party/mbedtls/ssl.h"
#include "third_party/mbedtls/ssl_ticket.h"
/**
* @fileoverview Downloads HTTP URL to stdout.
@@ -34,73 +59,347 @@
* o//examples/curl.com http://justine.lol/ape.html
*/
#define HasHeader(H) (!!msg.headers[H].a)
#define HeaderData(H) (p + msg.headers[H].a)
#define HeaderLength(H) (msg.headers[H].b - msg.headers[H].a)
#define HeaderEqualCase(H, S) \
SlicesEqualCase(S, strlen(S), HeaderData(H), HeaderLength(H))
static bool TuneSocket(int fd, int a, int b, int x) {
if (!b) return false;
return setsockopt(fd, a, b, &x, sizeof(x)) != -1;
}
static int TlsSend(void *c, const unsigned char *p, size_t n) {
int rc;
NOISEF("begin send %zu", n);
CHECK_NE(-1, (rc = write(*(int *)c, p, n)));
NOISEF("end send %zu", n);
return rc;
}
static int TlsRecv(void *c, unsigned char *p, size_t n, uint32_t o) {
int r;
struct iovec v[2];
static unsigned a, b;
static unsigned char t[4096];
if (a < b) {
r = MIN(n, b - a);
memcpy(p, t + a, r);
if ((a += r) == b) a = b = 0;
return r;
}
v[0].iov_base = p;
v[0].iov_len = n;
v[1].iov_base = t;
v[1].iov_len = sizeof(t);
NOISEF("begin recv %zu", n + sizeof(t) - b);
CHECK_NE(-1, (r = readv(*(int *)c, v, 2)));
NOISEF("end recv %zu", r);
if (r > n) b = r - n;
return MIN(n, r);
}
static wontreturn void PrintUsage(FILE *f, int rc) {
fprintf(f, "usage: %s [-ksvV] URL\n", program_invocation_name);
exit(rc);
}
int main(int argc, char *argv[]) {
int sock;
ssize_t rc;
unsigned long need;
struct UriSlice path;
size_t i, got, toto, msglen;
char buf[1500], host[256], port[7];
const char *url, *msg, *pathstr, *crlfcrlf, *contentlength;
struct UriSlice us[16];
struct Uri u = {.segs.p = us, .segs.n = ARRAYLEN(us)};
struct addrinfo *addr, *addrs;
if (!NoDebug()) showcrashreports();
xsigaction(SIGPIPE, SIG_IGN, 0, 0, 0);
/*
* Read flags.
*/
int opt;
struct Headers {
size_t n;
char **p;
} headers = {0};
int method = kHttpGet;
bool authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
const char *agent = "hurl/1.o (https://github.com/jart/cosmopolitan)";
__log_level = kLogWarn;
while ((opt = getopt(argc, argv, "qksvVIX:H:A:")) != -1) {
switch (opt) {
case 's':
case 'q':
break;
case 'v':
++__log_level;
break;
case 'I':
method = kHttpHead;
break;
case 'A':
agent = optarg;
break;
case 'H':
headers.p = realloc(headers.p, ++headers.n * sizeof(*headers.p));
headers.p[headers.n - 1] = optarg;
break;
case 'X':
CHECK((method = GetHttpMethod(optarg, strlen(optarg))));
break;
case 'V':
++mbedtls_debug_threshold;
break;
case 'k':
authmode = MBEDTLS_SSL_VERIFY_NONE;
break;
case 'h':
PrintUsage(stdout, EXIT_SUCCESS);
default:
PrintUsage(stderr, EX_USAGE);
}
}
/*
* Get argument.
*/
const char *urlarg;
if (optind == argc) PrintUsage(stderr, EX_USAGE);
urlarg = argv[optind];
/*
* Parse URL.
*/
struct Url url;
char *host, *port;
bool usessl = false;
_gc(ParseUrl(urlarg, -1, &url));
_gc(url.params.p);
if (url.scheme.n) {
if (url.scheme.n == 5 && !memcasecmp(url.scheme.p, "https", 5)) {
usessl = true;
} else if (!(url.scheme.n == 4 && !memcasecmp(url.scheme.p, "http", 4))) {
fprintf(stderr, "error: not an http/https url: %s\n", urlarg);
exit(1);
}
}
if (url.host.n) {
host = _gc(strndup(url.host.p, url.host.n));
if (url.port.n) {
port = _gc(strndup(url.port.p, url.port.n));
} else {
port = usessl ? "443" : "80";
}
} else {
host = "127.0.0.1";
port = usessl ? "443" : "80";
}
if (!IsAcceptableHost(host, -1)) {
fprintf(stderr, "error: invalid host: %s\n", urlarg);
exit(1);
}
url.fragment.p = 0, url.fragment.n = 0;
url.scheme.p = 0, url.scheme.n = 0;
url.user.p = 0, url.user.n = 0;
url.pass.p = 0, url.pass.n = 0;
url.host.p = 0, url.host.n = 0;
url.port.p = 0, url.port.n = 0;
if (!url.path.n || url.path.p[0] != '/') {
char *p = _gc(xmalloc(1 + url.path.n));
mempcpy(mempcpy(p, "/", 1), url.path.p, url.path.n);
url.path.p = p;
++url.path.n;
}
/*
* Create HTTP message.
*/
char *request = 0;
appendf(&request,
"%s %s HTTP/1.1\r\n"
"Host: %s:%s\r\n"
"Connection: close\r\n"
"User-Agent: %s\r\n",
kHttpMethod[method], _gc(EncodeUrl(&url, 0)), host, port, agent);
for (int i = 0; i < headers.n; ++i) {
appendf(&request, "%s\r\n", headers.p[i]);
}
appendf(&request, "\r\n");
/*
* Setup crypto.
*/
mbedtls_ssl_config conf;
mbedtls_ssl_context ssl;
mbedtls_x509_crt *cachain = 0;
mbedtls_ctr_drbg_context drbg;
if (usessl) {
mbedtls_ssl_init(&ssl);
mbedtls_ctr_drbg_init(&drbg);
mbedtls_ssl_config_init(&conf);
cachain = GetSslRoots();
CHECK_EQ(0, mbedtls_ctr_drbg_seed(&drbg, GetEntropy, 0, "justine", 7));
CHECK_EQ(0, mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT));
mbedtls_ssl_conf_authmode(&conf, authmode);
mbedtls_ssl_conf_ca_chain(&conf, cachain, 0);
mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &drbg);
if (!IsTiny()) mbedtls_ssl_conf_dbg(&conf, TlsDebug, 0);
CHECK_EQ(0, mbedtls_ssl_setup(&ssl, &conf));
CHECK_EQ(0, mbedtls_ssl_set_hostname(&ssl, host));
}
/*
* Perform DNS lookup.
*/
struct addrinfo *addr;
struct addrinfo hints = {.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM,
.ai_protocol = IPPROTO_TCP,
.ai_flags = AI_NUMERICSERV};
if (argc != 2) {
fprintf(stderr, "USAGE: %s URL\n", argv[0]);
exit(1);
}
url = argv[1];
CHECK_NE(-1, uriparse(&u, url, strlen(url)), "BAD URL: %`'s", url);
CHECK_EQ(kUriSchemeHttp, urischeme(u.scheme, url));
urislice2cstr(host, sizeof(host), u.host, url, "127.0.0.1");
urislice2cstr(port, sizeof(port), u.port, url, "80");
path = uripath(&u);
pathstr = path.n ? url + path.i : "/";
msg = gc(xstrcat("GET ", pathstr,
" HTTP/1.1\r\n"
"Host: ",
host,
"\r\n"
"Connection: close\r\n"
"Content-Length: 0\r\n"
"Accept: text/plain; */*\r\n"
"Accept-Encoding: identity\r\n"
"User-Agent: github.com/jart/cosmopolitan\r\n"
"\r\n"));
msglen = strlen(msg);
CHECK_EQ(EAI_SUCCESS, getaddrinfo(host, port, &hints, &addrs));
for (addr = addrs; addr; addr = addr->ai_next) {
CHECK_NE(-1, (sock = socket(addr->ai_family, addr->ai_socktype,
addr->ai_protocol)));
CHECK_NE(-1, connect(sock, addr->ai_addr, addr->ai_addrlen));
CHECK_EQ(msglen, write(sock, msg, msglen));
shutdown(sock, SHUT_WR);
buf[0] = '\0';
CHECK_NE(-1, (rc = read(sock, buf, sizeof(buf))));
got = rc;
CHECK(startswith(buf, "HTTP/1.1 200"), "%`'.*s", got, buf);
CHECK_NOTNULL((crlfcrlf = memmem(buf, got, "\r\n\r\n", 4)));
need = strtol((char *)firstnonnull(
memmem(buf, crlfcrlf - buf, "\r\nContent-Length: ", 18),
firstnonnull(memmem(buf, crlfcrlf - buf,
"\r\ncontent-length: ", 18),
"\r\nContent-Length: -1")) +
18,
NULL, 10);
got = MIN(got - (crlfcrlf + 4 - buf), need);
CHECK_EQ(got, write(1, crlfcrlf + 4, got));
for (toto = got; toto < need; toto += got) {
CHECK_NE(-1, (rc = read(sock, buf, sizeof(buf))));
if (!(got = rc)) exit(18);
got = MIN(got, need - toto);
CHECK_EQ(got, write(1, buf, got));
CHECK_EQ(EAI_SUCCESS, getaddrinfo(host, port, &hints, &addr));
/*
* Connect to server.
*/
int ret, sock;
CHECK_NE(-1, (sock = GoodSocket(addr->ai_family, addr->ai_socktype,
addr->ai_protocol, false,
&(struct timeval){-60})));
CHECK_NE(-1, connect(sock, addr->ai_addr, addr->ai_addrlen));
freeaddrinfo(addr);
if (usessl) {
mbedtls_ssl_set_bio(&ssl, &sock, TlsSend, 0, TlsRecv);
if ((ret = mbedtls_ssl_handshake(&ssl))) {
TlsDie("ssl handshake", ret);
}
close(sock);
break;
}
/*
* Send HTTP Message.
*/
size_t n;
n = appendz(request).i;
if (usessl) {
ret = mbedtls_ssl_write(&ssl, request, n);
if (ret != n) TlsDie("ssl write", ret);
} else {
CHECK_EQ(n, write(sock, request, n));
}
/*
* Handle response.
*/
int t;
char *p;
ssize_t rc;
struct HttpMessage msg;
struct HttpUnchunker u;
size_t g, i, hdrlen, paylen;
InitHttpMessage(&msg, kHttpResponse);
for (p = 0, hdrlen = paylen = t = i = n = 0;;) {
if (i == n) {
n += 1000;
n += n >> 1;
p = realloc(p, n);
}
if (usessl) {
if ((rc = mbedtls_ssl_read(&ssl, p + i, n - i)) < 0) {
if (rc == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
rc = 0;
} else {
TlsDie("ssl read", rc);
}
}
} else {
CHECK_NE(-1, (rc = read(sock, p + i, n - i)));
}
g = rc;
i += g;
switch (t) {
case kHttpClientStateHeaders:
CHECK(g);
CHECK_NE(-1, (rc = ParseHttpMessage(&msg, p, i)));
if (rc) {
hdrlen = rc;
if (100 <= msg.status && msg.status <= 199) {
CHECK(!HasHeader(kHttpContentLength) ||
HeaderEqualCase(kHttpContentLength, "0"));
CHECK(!HasHeader(kHttpTransferEncoding) ||
HeaderEqualCase(kHttpTransferEncoding, "identity"));
DestroyHttpMessage(&msg);
InitHttpMessage(&msg, kHttpResponse);
memmove(p, p + hdrlen, i - hdrlen);
i -= hdrlen;
break;
}
if (method == kHttpHead) {
CHECK_EQ(hdrlen, write(1, p, hdrlen));
goto Finished;
} else if (msg.status == 204 || msg.status == 304) {
goto Finished;
}
if (HasHeader(kHttpTransferEncoding) &&
!HeaderEqualCase(kHttpTransferEncoding, "identity")) {
CHECK(HeaderEqualCase(kHttpTransferEncoding, "chunked"));
t = kHttpClientStateBodyChunked;
memset(&u, 0, sizeof(u));
goto Chunked;
} else if (HasHeader(kHttpContentLength)) {
CHECK_NE(-1, (rc = ParseContentLength(
HeaderData(kHttpContentLength),
HeaderLength(kHttpContentLength))));
t = kHttpClientStateBodyLengthed;
paylen = rc;
if (paylen > i - hdrlen) {
CHECK_EQ(i - hdrlen, write(1, p + hdrlen, i - hdrlen));
} else {
CHECK_EQ(paylen, write(1, p + hdrlen, paylen));
goto Finished;
}
} else {
t = kHttpClientStateBody;
CHECK_EQ(i - hdrlen, write(1, p + hdrlen, i - hdrlen));
}
}
break;
case kHttpClientStateBody:
if (!g) goto Finished;
CHECK_EQ(g, write(1, p + i - g, g));
break;
case kHttpClientStateBodyLengthed:
CHECK(g);
if (i - hdrlen > paylen) g = hdrlen + paylen - (i - g);
CHECK_EQ(g, write(1, p + i - g, g));
if (i - hdrlen >= paylen) goto Finished;
break;
case kHttpClientStateBodyChunked:
Chunked:
CHECK_NE(-1, (rc = Unchunk(&u, p + hdrlen, i - hdrlen, &paylen)));
if (rc) {
CHECK_EQ(paylen, write(1, p + hdrlen, paylen));
goto Finished;
}
break;
default:
abort();
}
}
/*
* Close connection.
*/
Finished:
CHECK_NE(-1, close(sock));
/*
* Free memory.
*/
free(p);
free(headers.p);
if (usessl) {
mbedtls_ssl_free(&ssl);
mbedtls_ctr_drbg_free(&drbg);
mbedtls_ssl_config_free(&conf);
mbedtls_x509_crt_free(cachain);
mbedtls_ctr_drbg_free(&drbg);
}
return 0;
}
+1 -1
View File
@@ -16,6 +16,6 @@
*/
int main(int argc, char *argv[]) {
puts(gc(xiso8601ts(NULL)));
puts(_gc(xiso8601ts(NULL)));
return 0;
}
-376
View File
@@ -1,376 +0,0 @@
#if 0
/*─────────────────────────────────────────────────────────────────╗
│ To the extent possible under law, Justine Tunney has waived │
│ all copyright and related or neighboring rights to this file, │
│ as it is written in the following disclaimers: │
│ • http://unlicense.org/ │
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "dsp/core/core.h"
#include "dsp/core/twixt8.h"
#include "dsp/scale/scale.h"
#include "dsp/tty/itoa8.h"
#include "dsp/tty/quant.h"
#include "libc/alg/arraylist2.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/ioctl.h"
#include "libc/calls/struct/stat.h"
#include "libc/calls/struct/winsize.h"
#include "libc/limits.h"
#include "libc/log/check.h"
#include "libc/log/log.h"
#include "libc/macros.h"
#include "libc/math.h"
#include "libc/mem/mem.h"
#include "libc/runtime/gc.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/fileno.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/prot.h"
#include "libc/sysv/consts/termios.h"
#include "libc/x/x.h"
#include "third_party/stb/stb_image.h"
/**
* Hat tips go out to Hornet, CRTC, DESiRE, Hans Petter Jansson, Guihua
* Cui, Ming Ronnier Luoand anyone else Mister Rogers would describe as
* the The Helpers Of This World who've helped us learn more about the
* cool yet exceedingly difficult things possible to do with graphics.
*/
#define DIN99 1
#define GAMMA 4.1
#define GAMMA_A .05
#define GAMMA_B 50.
#define GAMMA_C .055
#define COLORSPACE_SRC kSrgbD65ToXyzD50
#define COLORSPACE_TTY kSrgbD65ToXyzD50
#define SQR(X) ((X) * (X))
#define DEG(X) ((X)*M_PI / 180)
const double kXyzKappa = 24389 / 27.;
const double kXyzEpsilon = 216 / 24389.;
const double kSrgbD65ToXyzD50[3][3] = {
{.4360747, .3850649, .1430804},
{.2225045, .7168786, .0606169},
{.0139322, .0971045, .7141733},
};
const double kCieRgbEToXyz[3][3] = {
{.4887180, .3106803, .2006017},
{.1762044, .8129847, .0108109},
{.0000000, .0102048, .9897952},
};
const unsigned char kShadePct[] = {0300, 0200, 0100};
const unsigned short kShadeRune[] = {u'▓', u'▒', u'░'};
const unsigned char kAnsiTango[16][3] = {
{46, 52, 54}, {204, 0, 0}, {78, 154, 6}, {196, 160, 0},
{52, 101, 164}, {117, 80, 123}, {6, 152, 154}, {211, 215, 207},
{85, 87, 83}, {239, 41, 41}, {138, 226, 52}, {252, 233, 79},
{114, 159, 207}, {173, 127, 168}, {52, 226, 226}, {238, 238, 236},
};
const unsigned char kCga[16][3] = {
{0, 0, 0}, {170, 0, 0}, {0, 170, 0}, {170, 85, 0},
{0, 0, 170}, {170, 0, 170}, {0, 170, 170}, {170, 170, 170},
{85, 85, 85}, {255, 85, 85}, {85, 255, 85}, {255, 255, 85},
{85, 85, 255}, {255, 85, 255}, {85, 255, 255}, {255, 255, 255},
};
struct Blends {
size_t i, n;
struct Blend {
unsigned char color[4];
unsigned char bg, fg;
unsigned short rune;
} * p;
} blends;
static double Gamma(double x) {
if (x < GAMMA_A) return x / GAMMA_B;
return pow(1 / (1 + GAMMA_C) * (x + GAMMA_C), GAMMA);
}
static void *LoadRgb(double rgb[3], const unsigned char pix[3]) {
rgb[0] = Gamma(1. / 255 * pix[0]);
rgb[1] = Gamma(1. / 255 * pix[1]);
rgb[2] = Gamma(1. / 255 * pix[2]);
return rgb;
}
static double Lab(double x) {
return x > kXyzEpsilon ? cbrtf(x) : (kXyzKappa * x + 16) / 116;
}
static void XyzToLab(double lab[3], const double d50xyz[3]) {
double Y, L, a, b;
Y = Lab(d50xyz[1]);
L = 116 * Y - 16;
a = 500 * (Lab(d50xyz[0]) - Y);
b = 200 * (Y - Lab(d50xyz[2]));
lab[0] = L, lab[1] = a, lab[2] = b;
}
static void XyzToDin99d(unsigned char din99d[3], const double d50xyz[3]) {
double e, f, G, C, h, xyz[3], lab[3];
memcpy(xyz, d50xyz, sizeof(xyz));
xyz[0] = 1.12f * xyz[0] - .12f * xyz[2];
XyzToLab(lab, xyz);
e = (+lab[1] * cosf(DEG(50)) + lab[2] * sinf(DEG(50)));
f = (-lab[1] * sinf(DEG(50)) + lab[2] + cosf(DEG(50))) * 1.14;
G = sqrtf(SQR(e) + SQR(f));
C = logf(1 + .06 * G) * 22.5f;
h = atan2f(f, e) + DEG(50);
h = fmodf(h, DEG(360));
if (h < 0) h += DEG(360);
din99d[0] = MIN(255, MAX(0, 325.22f * logf(1 + .0036 * lab[0]) * 2.5f));
din99d[1] = MIN(255, MAX(0, C * cos(h) * 2.5f + 128));
din99d[2] = MIN(255, MAX(0, C * sin(h) * 2.5f + 128));
}
static void AddColor(int bg, int fg, int rune, int r, int g, int b, int x) {
int i;
if (blends.i) {
for (i = blends.i; --i;) {
if (blends.p[i].color[0] == r && blends.p[i].color[1] == g &&
blends.p[i].color[2] == b) {
return;
}
}
}
CHECK_NE(
-1,
APPEND(&blends.p, &blends.i, &blends.n,
(&(struct Blend){
.bg = bg, .fg = fg, .rune = rune, .color = {r, g, b, x}})));
}
static void AddBlend(int bgxterm, int fgxterm, int rune, int shade,
const unsigned char bgrgb[4],
const unsigned char fgrgb[4]) {
AddColor(bgxterm, fgxterm, rune, twixt8(bgrgb[0], fgrgb[0], shade),
twixt8(bgrgb[1], fgrgb[1], shade), twixt8(bgrgb[2], fgrgb[2], shade),
0);
}
static void MakeBlends(const unsigned char palette[16][3]) {
int r, i, j, k;
double rgb[3], xyz[3];
unsigned char tab[256][4];
unsigned char cube[6] = {0, 0137, 0207, 0257, 0327, 0377};
unsigned char seqs[2][2] = {{16, 255}};
for (i = 0; i < 16; ++i) {
tab[i][0] = palette[i][0];
tab[i][1] = palette[i][1];
tab[i][2] = palette[i][2];
tab[i][3] = i;
}
for (i = 16; i < 232; ++i) {
tab[i][0] = cube[((i - 020) / 044) % 6];
tab[i][1] = cube[((i - 020) / 6) % 6];
tab[i][2] = cube[(i - 020) % 6];
tab[i][3] = i;
}
for (i = 232; i < 256; ++i) {
tab[i][0] = 8 + (i - 232) * 10;
tab[i][1] = 8 + (i - 232) * 10;
tab[i][2] = 8 + (i - 232) * 10;
tab[i][3] = i;
}
#if DIN99
for (i = 0; i < 256; ++i) {
LoadRgb(rgb, tab[i]);
vmatmul3(xyz, rgb, COLORSPACE_TTY);
XyzToDin99d(tab[i], xyz);
}
#endif
for (r = 0; r < ARRAYLEN(seqs); ++r) {
for (i = seqs[r][0]; i <= seqs[r][1]; ++i) {
for (j = seqs[r][0]; j <= seqs[r][1]; ++j) {
if (i == j) {
AddColor(i, 0, 0, tab[i][0], tab[i][1], tab[i][2], 0);
} else {
for (k = 0; k < ARRAYLEN(kShadeRune); ++k) {
AddBlend(i, j, kShadeRune[k], kShadePct[k], tab[i], tab[j]);
AddBlend(j, i, kShadeRune[k], kShadePct[k], tab[j], tab[i]);
}
}
}
}
}
}
static int PickColor(unsigned char color[3]) {
int i, best, least, dist;
best = -1;
least = INT_MAX;
for (i = 0; i < blends.i; ++i) {
dist = SQR(blends.p[i].color[0] - color[0]) +
SQR(blends.p[i].color[1] - color[1]) +
SQR(blends.p[i].color[2] - color[2]);
if (dist < least) {
least = dist;
best = i;
}
}
return best;
}
static void SetBg(int x) {
if (0 <= x && x < 16) {
if (x < 8) {
x += 40;
} else {
x -= 8;
x *= 100;
}
printf("\e[%dm", x);
} else {
/* assert(false); */
printf("\e[48;5;%dm", x);
}
}
static void SetFg(int x) {
if (0 <= x && x < 16) {
if (x < 8) {
x += 30;
} else {
x -= 8;
x *= 90;
}
printf("\e[%dm", x);
} else {
/* assert(false); */
printf("\e[38;5;%dm", x);
}
}
static void PrintImage(long yn, long xn, unsigned char src[4][yn][xn]) {
int y, x, c;
double rgb[3], xyz[3];
unsigned char din99d[3];
for (y = 0; y < yn; ++y) {
printf("\n");
for (x = 0; x < xn; ++x) {
din99d[0] = src[0][y][x];
din99d[1] = src[1][y][x];
din99d[2] = src[2][y][x];
#if DIN99
LoadRgb(rgb, din99d);
vmatmul3(xyz, rgb, COLORSPACE_SRC);
XyzToDin99d(din99d, xyz);
#endif
c = PickColor(din99d);
if (blends.p[c].rune) {
SetBg(blends.p[c].bg);
SetFg(blends.p[c].fg);
printf("%hc", blends.p[c].rune);
} else {
SetBg(blends.p[c].bg);
printf(" ");
}
}
printf("\e[0m");
}
printf("\r");
}
static void *Deinterlace(long dcn, long dyn, long dxn,
unsigned char dst[dcn][dyn][dxn], long syw, long sxw,
long scw, const unsigned char src[syw][sxw][scw],
long syn, long sxn, long sy0, long sx0, long sc0) {
long y, x, c;
for (y = 0; y < dyn; ++y) {
for (x = 0; x < dxn; ++x) {
for (c = 0; c < dcn; ++c) {
dst[c][y][x] = src[sy0 + y][sx0 + x][sc0 + c];
}
}
}
return dst;
}
static void GetTermSize(int out_rows[1], int out_cols[1]) {
struct winsize ws;
ws.ws_row = 24;
ws.ws_col = 80;
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1) {
ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
}
out_rows[0] = ws.ws_row;
out_cols[0] = ws.ws_col;
}
static void ProcessImage(long syn, long sxn, unsigned char img[syn][sxn][4]) {
int dyn, dxn;
double ry, rx;
GetTermSize(&dyn, &dxn);
ry = syn, rx = sxn;
ry /= dyn, rx /= dxn;
PrintImage(
dyn, dxn,
EzGyarados(4, dyn, dxn, gc(xmemalign(32, dyn * dxn * 4)), 4, syn, sxn,
Deinterlace(4, syn, sxn, gc(xmemalign(32, syn * sxn * 4)), syn,
sxn, 4, img, syn, sxn, 0, 0, 0),
0, 4, dyn, dxn, syn, sxn, ry, rx, 0, 0));
}
static void WithImageFile(const char *path,
void fn(long yn, long xn,
unsigned char src[yn][xn][4])) {
struct stat st;
void *map, *data;
int fd, yn, xn, cn;
CHECK_NE(-1, (fd = open(path, O_RDONLY)), "%s", path);
CHECK_NE(-1, fstat(fd, &st));
CHECK_GT(st.st_size, 0);
CHECK_LE(st.st_size, INT_MAX);
CHECK_NE(MAP_FAILED,
(map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)));
CHECK_NOTNULL(
(data = stbi_load_from_memory(map, st.st_size, &xn, &yn, NULL, 4)), "%s",
path);
CHECK_NE(-1, munmap(map, st.st_size));
CHECK_NE(-1, close(fd));
fn(yn, xn, data);
free(data);
}
static void PrintData(void) {
int i;
for (i = 0; i < blends.i; ++i) {
printf("%3d %3d %3d %3d %3d %d\n", blends.p[i].color[0],
blends.p[i].color[1], blends.p[i].color[2], blends.p[i].bg,
blends.p[i].fg, blends.p[i].rune);
}
}
void *OpenRgbMap(const char *path) {
int fd;
void *map;
size_t size;
size = 256 * 256 * 256 * 3;
CHECK_NE(-1, (fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0644)));
CHECK_NE(-1, ftruncate(fd, size));
CHECK_NE(MAP_FAILED,
(map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)));
CHECK_NE(-1, close(fd));
return map;
}
int main(int argc, char *argv[]) {
int i;
MakeBlends(kCga);
for (i = 1; i < argc; ++i) {
WithImageFile(argv[i], ProcessImage);
}
return 0;
}
+9 -7
View File
@@ -33,7 +33,6 @@ EXAMPLES_BINS = \
$(EXAMPLES_COMS:%=%.dbg)
EXAMPLES_DIRECTDEPS = \
APE_LIB \
DSP_CORE \
DSP_SCALE \
DSP_TTY \
@@ -46,6 +45,7 @@ EXAMPLES_DIRECTDEPS = \
LIBC_LOG \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_NT_IPHLPAPI \
LIBC_NT_KERNEL32 \
LIBC_NT_NTDLL \
LIBC_NT_USER32 \
@@ -66,14 +66,19 @@ EXAMPLES_DIRECTDEPS = \
LIBC_X \
LIBC_ZIPOS \
NET_HTTP \
NET_HTTPS \
THIRD_PARTY_COMPILER_RT \
THIRD_PARTY_DLMALLOC \
THIRD_PARTY_QUICKJS \
THIRD_PARTY_GDTOA \
THIRD_PARTY_GETOPT \
THIRD_PARTY_LUA \
THIRD_PARTY_MBEDTLS \
THIRD_PARTY_MUSL \
THIRD_PARTY_STB \
THIRD_PARTY_XED \
THIRD_PARTY_ZLIB \
TOOL_BUILD_LIB \
TOOL_VIZ_LIB
EXAMPLES_DEPS := \
@@ -81,7 +86,6 @@ EXAMPLES_DEPS := \
o/$(MODE)/examples/examples.pkg: \
$(EXAMPLES_OBJS) \
$(THIRD_PARTY_DUKTAPE_A).pkg \
$(foreach x,$(EXAMPLES_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/examples/unbourne.o: \
@@ -96,11 +100,10 @@ o/$(MODE)/examples/%.com.dbg: \
$(APE)
@$(APELINK)
o/$(MODE)/examples/hellojs.com.dbg: \
o/$(MODE)/examples/hellolua.com.dbg: \
$(EXAMPLES_DEPS) \
$(THIRD_PARTY_DUKTAPE) \
o/$(MODE)/examples/hellojs.o \
o/$(MODE)/examples/hello.js.zip.o \
o/$(MODE)/examples/hellolua.o \
o/$(MODE)/examples/hellolua.lua.zip.o \
o/$(MODE)/examples/examples.pkg \
$(CRT) \
$(APE)
@@ -117,7 +120,6 @@ o/$(MODE)/examples/ispell.com.dbg: \
o/$(MODE)/examples/nesemu1.com.dbg: \
$(EXAMPLES_DEPS) \
$(THIRD_PARTY_DUKTAPE) \
o/$(MODE)/examples/nesemu1.o \
o/$(MODE)/usr/share/rom/mario.nes.zip.o \
o/$(MODE)/usr/share/rom/zelda.nes.zip.o \
-17
View File
@@ -1,17 +0,0 @@
#if 0
/*─────────────────────────────────────────────────────────────────╗
│ To the extent possible under law, Justine Tunney has waived │
│ all copyright and related or neighboring rights to this file, │
│ as it is written in the following disclaimers: │
│ • http://unlicense.org/ │
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/calls/calls.h"
#include "libc/runtime/runtime.h"
int main(int argc, char *argv[]) {
if (argc < 2) return 1;
execv(argv[1], argv + 1);
abort();
}
+62
View File
@@ -0,0 +1,62 @@
#if 0
/*─────────────────────────────────────────────────────────────────╗
│ To the extent possible under law, Justine Tunney has waived │
│ all copyright and related or neighboring rights to this file, │
│ as it is written in the following disclaimers: │
│ • http://unlicense.org/ │
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/calls/calls.h"
#include "libc/macros.internal.h"
#include "libc/stdio/stdio.h"
#include "libc/sysv/consts/sig.h"
#include "libc/testlib/ezbench.h"
/**
* @fileoverview Fast Division Using Multiplication Tutorial
*
* Expected program output:
*
* 23 / 3 = 7
* 0x5555555555555556 1 1
* division l: 16𝑐 5𝑛𝑠
* fast div l: 5𝑐 2𝑛𝑠
* precomps l: 70𝑐 23𝑛𝑠
*/
struct Divisor {
uint64_t m;
uint8_t s;
uint8_t t;
};
struct Divisor GetDivisor(uint64_t d) {
int b;
uint128_t x;
if (!d) raise(SIGFPE);
b = __builtin_clzll(d) ^ 63;
x = -d & (((1ull << b) - 1) | (1ull << b));
return (struct Divisor){(x << 64) / d + 1, MIN(1, b + 1), MAX(0, b)};
}
uint64_t Divide(uint64_t x, struct Divisor d) {
uint128_t t;
uint64_t l, h;
t = d.m;
t *= x;
l = t;
h = t >> 64;
l = (x - h) >> d.s;
return (h + l) >> d.t;
}
int main(int argc, char *argv[]) {
printf("23 / 3 = %ld\n", Divide(23, GetDivisor(3)));
volatile struct Divisor v = GetDivisor(3);
volatile uint64_t x = 23, y = 3, z;
EZBENCH2("division", donothing, z = x / y);
EZBENCH2("fast div", donothing, z = Divide(x, v));
EZBENCH2("precomp ", donothing, v = GetDivisor(y));
return 0;
}
+47
View File
@@ -0,0 +1,47 @@
#if 0
/*─────────────────────────────────────────────────────────────────╗
│ To the extent possible under law, Justine Tunney has waived │
│ all copyright and related or neighboring rights to this file, │
│ as it is written in the following disclaimers: │
│ • http://unlicense.org/ │
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/stdio/stdio.h"
#include "libc/testlib/ezbench.h"
/**
* @fileoverview Fast Modulus Using Multiplication Tutorial
*
* Expected program output:
*
* 23 / 3 = 7
* 0x5555555555555556 1 1
* modulus l: 15𝑐 5𝑛𝑠
* fastmod l: 4𝑐 1𝑛𝑠
* precomp l: 18𝑐 6𝑛𝑠
*/
struct Modulus {
uint64_t c;
uint64_t d;
};
struct Modulus GetModulus(uint64_t d) {
return (struct Modulus){0xFFFFFFFFFFFFFFFFull / d + 1, d};
}
uint64_t Modulus(uint64_t x, struct Modulus m) {
return ((uint128_t)(m.c * x) * m.d) >> 64;
}
int main(int argc, char *argv[]) {
printf("%#lx %% %d = %d\n", 0x23, 3, Modulus(23, GetModulus(3)));
printf("%#lx %% %d = %d\n", 0x123, 17, Modulus(0x123, GetModulus(17)));
volatile struct Modulus v = GetModulus(3);
volatile uint64_t x = 23, y = 3, z;
EZBENCH2("modulus", donothing, z = x % y);
EZBENCH2("fastmod", donothing, z = Modulus(x, v));
EZBENCH2("precomp", donothing, v = GetModulus(y));
return 0;
}
-66
View File
@@ -1,66 +0,0 @@
#if 0
/*─────────────────────────────────────────────────────────────────╗
│ To the extent possible under law, Justine Tunney has waived │
│ all copyright and related or neighboring rights to this file, │
│ as it is written in the following disclaimers: │
│ • http://unlicense.org/ │
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/bits/bits.h"
#include "libc/calls/calls.h"
#include "libc/calls/struct/itimerval.h"
#include "libc/fmt/conv.h"
#include "libc/limits.h"
#include "libc/log/check.h"
#include "libc/log/color.internal.h"
#include "libc/log/log.h"
#include "libc/math.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/sysv/consts/itimer.h"
#include "libc/sysv/consts/sig.h"
#include "libc/time/time.h"
static const struct itimerval kTimer = {{0, 10000}, {0, 10000}}; /* 10ms */
static volatile bool32 showprogress_;
static const char *magic_;
void OnInterrupt(int sig) {
showprogress_ = true;
}
void ShowProgress(uintmax_t i, uintmax_t j, uintmax_t n) {
fprintf(stderr, "%s%,40jd%,40jd%,40jd\r\n", magic_, i, j, n);
showprogress_ = false;
}
static bool IsPrime(uintmax_t i) {
uintmax_t j, n;
for (j = 3, n = (unsigned long)floorl(sqrtl(i)); j <= n; j += 2) {
if (showprogress_) ShowProgress(i, j, n);
if (i % j == 0) return false;
}
return true;
}
static void TryNumber(uintmax_t x, uintmax_t i) {
if (IsPrime(i)) {
printf("%s%,jd%s%,jd\n", "the prime nearest ", x, " is ", i);
exit(0);
}
}
int main(int argc, char **argv) {
uintmax_t x, i, j;
CHECK_EQ(2, argc);
signal(SIGALRM, OnInterrupt);
setitimer(ITIMER_REAL, &kTimer, NULL);
magic_ = cancolor() ? "\e[F\e[K" : "";
if ((x = strtoumax(argv[1], NULL, 0)) % 2 == 0) ++x;
TryNumber(x, x);
for (i = x, j = x;;) {
if (i < UINTMAX_MAX) TryNumber(x, i), i += 2;
if (j > 1) TryNumber(x, j), j -= 2;
}
}
-18
View File
@@ -1,18 +0,0 @@
#if 0
/*─────────────────────────────────────────────────────────────────╗
│ To the extent possible under law, Justine Tunney has waived │
│ all copyright and related or neighboring rights to this file, │
│ as it is written in the following disclaimers: │
│ • http://unlicense.org/ │
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/calls/calls.h"
#include "libc/stdio/stdio.h"
int main(int argc, char *argv[]) {
int pid;
pid = fork();
fprintf(stderr, "fork returned %d\n", pid);
return 0;
}
+25
View File
@@ -0,0 +1,25 @@
#if 0
/*─────────────────────────────────────────────────────────────────╗
│ To the extent possible under law, Justine Tunney has waived │
│ all copyright and related or neighboring rights to this file, │
│ as it is written in the following disclaimers: │
│ • http://unlicense.org/ │
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/calls/calls.h"
#include "libc/fmt/itoa.h"
#include "libc/runtime/sysconf.h"
#include "libc/stdio/stdio.h"
int main(int argc, char *argv[]) {
int c, n;
char a[22];
if ((c = GetCpuCount())) {
n = int64toarray_radix10(c, a);
a[n++] = '\n';
return write(1, a, n) == n ? 0 : 1;
} else {
return 1;
}
}
+291
View File
@@ -0,0 +1,291 @@
#if 0
/*─────────────────────────────────────────────────────────────────╗
│ To the extent possible under law, Justine Tunney has waived │
│ all copyright and related or neighboring rights to this file, │
│ as it is written in the following disclaimers: │
│ • http://unlicense.org/ │
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/bits/bits.h"
#include "libc/calls/calls.h"
#include "libc/errno.h"
#include "libc/fmt/conv.h"
#include "libc/log/check.h"
#include "libc/log/log.h"
#include "libc/macros.internal.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/rand/rand.h"
#include "libc/rand/xorshift.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/ex.h"
#include "libc/sysv/consts/exit.h"
#include "libc/sysv/consts/grnd.h"
#include "libc/sysv/consts/sig.h"
#include "libc/testlib/hyperion.h"
#include "third_party/getopt/getopt.h"
#define B 4096
bool isdone;
bool isbinary;
unsigned long count = -1;
uint64_t bcast(uint64_t f(void)) {
unsigned i;
uint64_t x;
for (x = i = 0; i < 8; ++i) {
x <<= 8;
x |= f() & 255;
}
return x;
}
uint64_t randv6(void) {
static int16_t gorp;
gorp = (gorp + 625) & 077777;
return gorp;
}
uint64_t randv7(void) {
static uint32_t randx = 1;
return ((randx = randx * 1103515245 + 12345) >> 16) & 077777;
}
uint64_t zero(void) {
return 0;
}
uint64_t inc(void) {
static uint64_t x;
return x++;
}
uint64_t unixv6(void) {
return bcast(randv6);
}
uint64_t unixv7(void) {
return bcast(randv7);
}
uint64_t ape(void) {
static int i;
if ((i += 8) > _end - _base) i = 8;
return READ64LE(_base + i);
}
uint64_t moby(void) {
static int i;
if ((i += 8) > kMobySize) i = 8;
return READ64LE(kMoby + i);
}
uint64_t knuth(void) {
uint64_t a, b;
static uint64_t x = 1;
x *= 6364136223846793005;
x += 1442695040888963407;
a = x >> 32;
x *= 6364136223846793005;
x += 1442695040888963407;
b = x >> 32;
return a | b << 32;
}
uint64_t vigna(void) {
static uint64_t x;
uint64_t z = (x += 0x9e3779b97f4a7c15);
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
return z ^ (z >> 31);
}
uint64_t rngset64(void) {
static unsigned i;
static uint64_t s;
if (!i) {
s = rand64();
i = (s + 1) & (511);
}
return MarsagliaXorshift64(&s);
}
uint64_t xorshift64(void) {
static uint64_t s = kMarsagliaXorshift64Seed;
return MarsagliaXorshift64(&s);
}
uint64_t xorshift32(void) {
static uint32_t s = kMarsagliaXorshift32Seed;
uint64_t a = MarsagliaXorshift32(&s);
uint64_t b = MarsagliaXorshift32(&s);
return (uint64_t)a << 32 | b;
}
uint64_t libc(void) {
uint64_t x;
CHECK_EQ(8, getrandom(&x, 8, 0));
return x;
}
uint64_t kernel(void) {
uint64_t x;
CHECK_EQ(8, getrandom(&x, 8, GRND_NORDRND));
return x;
}
uint64_t hardware(void) {
uint64_t x;
CHECK_EQ(8, getrandom(&x, 8, GRND_NOSYSTEM));
return x;
}
uint64_t rdrnd(void) {
char cf;
int i = 0;
uint64_t x;
CHECK(X86_HAVE(RDRND));
for (;;) {
asm volatile(CFLAG_ASM("rdrand\t%1")
: CFLAG_CONSTRAINT(cf), "=r"(x)
: /* no inputs */
: "cc");
if (cf) return x;
if (++i < 10) continue;
asm volatile("pause");
i = 0;
}
}
uint64_t rdseed(void) {
char cf;
int i = 0;
uint64_t x;
CHECK(X86_HAVE(RDSEED));
for (;;) {
asm volatile(CFLAG_ASM("rdseed\t%1")
: CFLAG_CONSTRAINT(cf), "=r"(x)
: /* no inputs */
: "cc");
if (cf) return x;
if (++i < 10) continue;
asm volatile("pause");
i = 0;
}
}
const struct Function {
const char *s;
uint64_t (*f)(void);
} kFunctions[] = {
{"ape", ape}, //
{"hardware", hardware}, //
{"inc", inc}, //
{"kernel", kernel}, //
{"knuth", knuth}, //
{"libc", libc}, //
{"moby", moby}, //
{"rand64", rand64}, //
{"rdrand", rdrnd}, //
{"rdrnd", rdrnd}, //
{"rdseed", rdseed}, //
{"rngset64", rngset64}, //
{"unixv6", unixv6}, //
{"unixv7", unixv7}, //
{"vigna", vigna}, //
{"xorshift32", xorshift32}, //
{"xorshift64", xorshift64}, //
{"zero", zero}, //
};
void OnInt(int sig) {
isdone = true;
}
wontreturn void PrintUsage(FILE *f, int rc) {
fprintf(f, "Usage: %s [-b] [-n NUM] [FUNC]\n", program_invocation_name);
exit(rc);
}
int main(int argc, char *argv[]) {
char *p;
int i, opt;
ssize_t rc;
uint64_t x;
static char buf[B];
uint64_t (*f)(void);
while ((opt = getopt(argc, argv, "hbc:n:")) != -1) {
switch (opt) {
case 'b':
isbinary = true;
break;
case 'c':
case 'n':
count = strtoul(optarg, 0, 0);
break;
case 'h':
PrintUsage(stdout, EXIT_SUCCESS);
default:
PrintUsage(stderr, EX_USAGE);
}
}
if (optind == argc) {
f = libc;
} else {
for (f = 0, i = 0; i < ARRAYLEN(kFunctions); ++i) {
if (!strcasecmp(argv[optind], kFunctions[i].s)) {
f = kFunctions[i].f;
break;
}
}
if (!f) {
fprintf(stderr, "unknown function: %`'s\n", argv[optind]);
fprintf(stderr, "try: ");
for (i = 0; i < ARRAYLEN(kFunctions); ++i) {
if (i) fprintf(stderr, ", ");
fprintf(stderr, "%s", kFunctions[i].s);
}
fprintf(stderr, "\n");
return 1;
}
}
signal(SIGINT, OnInt);
signal(SIGPIPE, SIG_IGN);
if (!isbinary) {
for (; count && !isdone && !feof(stdout); --count) {
printf("0x%016lx\n", f());
}
fflush(stdout);
return ferror(stdout) ? 1 : 0;
}
while (count && !isdone) {
if (count >= B) {
for (i = 0; i < B / 8; ++i) {
x = f();
p = buf + i * 8;
WRITE64LE(p, x);
}
for (i = 0; i < B; i += rc) {
rc = write(1, buf + i, B - i);
if (rc == -1 && errno == EPIPE) exit(1);
if (rc == -1) perror("write"), exit(1);
}
} else {
x = f();
rc = write(1, &x, MIN(8, count));
}
if (!rc) break;
if (rc == -1 && errno == EPIPE) exit(1);
if (rc == -1) perror("write"), exit(1);
count -= rc;
}
return 0;
}
+65 -1
View File
@@ -7,9 +7,73 @@
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/dce.h"
#include "libc/nexgen32e/nt2sysv.h"
#include "libc/nt/dll.h"
#include "libc/nt/enum/cw.h"
#include "libc/nt/enum/mb.h"
#include "libc/nt/enum/sw.h"
#include "libc/nt/enum/wm.h"
#include "libc/nt/enum/ws.h"
#include "libc/nt/events.h"
#include "libc/nt/messagebox.h"
#include "libc/nt/struct/msg.h"
#include "libc/nt/struct/wndclass.h"
#include "libc/nt/windows.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
/**
* @fileoverview GUI Example
*
* Cosmopolitan has had a razor sharp focus on making sockets and stdio
* work well across platforms. When you call a function like read(), it
* will just work on platforms like Windows too. In order to do that we
* need to support the WIN32 API, which you can use, but please note it
* isn't polyfilled on other platforms in the same way as POSIX APIs.
*/
static const char16_t kClassName[] = u"cosmopolitan";
static int64_t WindowProc(int64_t hwnd, uint32_t uMsg, uint64_t wParam,
int64_t lParam) {
switch (uMsg) {
case kNtWmDestroy:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
static void Gui(void) {
int64_t h;
struct NtMsg msg;
struct NtWndClass wc;
memset(&wc, 0, sizeof(wc));
wc.lpfnWndProc = NT2SYSV(WindowProc);
wc.hInstance = GetModuleHandle(NULL);
wc.lpszClassName = kClassName;
RegisterClass(&wc);
h = CreateWindowEx(0, kClassName, u"Hello Cosmopolitan",
kNtWsOverlappedwindow, kNtCwUsedefault, kNtCwUsedefault,
kNtCwUsedefault, kNtCwUsedefault, 0, 0, wc.hInstance, 0);
ShowWindow(h, kNtSwNormal);
/*
* NOTE: Cosmopolitan linker script is hard-coded to change the
* subsystem from CUI to GUI when GetMessage() is linked.
*/
while (GetMessage(&msg, 0, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
int main(int argc, char *argv[]) {
return MessageBox(0, u"hello world", u"cosmopolitan", kNtMbOk) ? 0 : 1;
if (!IsWindows()) {
fputs("Sorry! This GUI demo only runs on Windows\n", stderr);
fputs("https://github.com/jart/cosmopolitan/issues/57\n", stderr);
return 1;
}
Gui();
}
-7
View File
@@ -10,13 +10,6 @@
#include "libc/stdio/stdio.h"
int main() {
/*
* Cosmopolitan's "Hello World" demonstrates a best practice.
*
* Since we conditionally link heavyweight features based on which
* characters are present in the format string, it's a good idea to
* have that string consist solely of directives.
*/
printf("%s\n", "hello world");
return 0;
}
-2
View File
@@ -1,2 +0,0 @@
NativePrint('Hello world!\n');
NativePrint('2+3=' + NativeAdd(2, 3) + '\n');
+3 -5
View File
@@ -8,12 +8,10 @@
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/errno.h"
#include "libc/runtime/gc.h"
#include "libc/calls/calls.h"
#include "libc/sysv/consts/fileno.h"
#include "libc/x/x.h"
#include "libc/fmt/fmt.h"
#include "libc/stdio/stdio.h"
int main() {
dprintf(STDOUT_FILENO, "%s\n", gc(xasprintf("%'s", "(╯°□°)╯︵' ┻━┻")));
printf("%`'s\n", "hello\1\2world→→");
return errno;
}
Loaded 100 of 8039 files, more files were not shown because too many files have changed in this diff. Show more